]> git.lyx.org Git - features.git/blob - src/mathed/MacroTable.cpp
cosmetics
[features.git] / src / mathed / MacroTable.cpp
1 /**
2  * \file MacroTable.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author André Pönitz
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "MacroTable.h"
14 #include "MathMacroTemplate.h"
15 #include "MathMacroArgument.h"
16 #include "MathSupport.h"
17 #include "InsetMathSqrt.h"
18
19 #include "InsetMathNest.h"
20 #include "Buffer.h"
21
22 #include "debug.h"
23 #include "DocIterator.h"
24
25 #include <boost/assert.hpp>
26
27 #include <sstream>
28
29
30 namespace lyx {
31
32 using std::endl;
33 using std::istringstream;
34 using std::map;
35 using std::pair;
36 using std::string;
37 using std::vector;
38 using std::size_t;
39
40
41 /////////////////////////////////////////////////////////////////////
42 //
43 // MacroData
44 //
45 /////////////////////////////////////////////////////////////////////
46
47 MacroData::MacroData()
48         : numargs_(0), lockCount_(0), redefinition_(false)
49 {}
50
51
52 MacroData::MacroData(docstring const & definition,
53                 std::vector<docstring> const & defaults, 
54                 int numargs, int optionals, docstring const & display,
55                 string const & requires)
56         : definition_(definition), numargs_(numargs), display_(display),
57                 requires_(requires), lockCount_(0), redefinition_(false),
58                 optionals_(optionals), defaults_(defaults)
59 {
60         defaults_.resize(optionals);
61 }
62
63
64 void MacroData::expand(vector<MathData> const & args, MathData & to) const
65 {
66         InsetMathSqrt inset; // Hack. Any inset with a cell would do.
67         // FIXME UNICODE
68         asArray(display_.empty() ? definition_ : display_, inset.cell(0));
69         //lyxerr << "MathData::expand: args: " << args << endl;
70         //lyxerr << "MathData::expand: ar: " << inset.cell(0) << endl;
71         for (DocIterator it = doc_iterator_begin(inset); it; it.forwardChar()) {
72                 if (!it.nextInset())
73                         continue;
74                 if (it.nextInset()->lyxCode() != MATHMACROARG_CODE)
75                         continue;
76                 //it.cell().erase(it.pos());
77                 //it.cell().insert(it.pos(), it.nextInset()->asInsetMath()
78                 size_t n = static_cast<MathMacroArgument*>(it.nextInset())->number();
79                 if (n <= args.size()) {
80                         it.cell().erase(it.pos());
81                         it.cell().insert(it.pos(), args[n - 1]);
82                 }
83         }
84         //lyxerr << "MathData::expand: res: " << inset.cell(0) << endl;
85         to = inset.cell(0);
86 }
87
88
89 size_t MacroData::optionals() const
90 {
91         return optionals_;
92 }
93
94
95 std::vector<docstring> const &  MacroData::defaults() const
96 {
97         return defaults_;
98 }
99
100
101 void MacroData::unlock() const
102 {
103         --lockCount_;
104         BOOST_ASSERT(lockCount_ >= 0);
105 }
106
107
108 /////////////////////////////////////////////////////////////////////
109 //
110 // The global table of macros
111 //
112 /////////////////////////////////////////////////////////////////////
113
114 MacroTable & MacroTable::globalMacros()
115 {
116         static MacroTable theGlobalMacros;
117         return theGlobalMacros;
118 }
119
120
121 bool MacroTable::has(docstring const & name) const
122 {
123         return find(name) != end();
124 }
125
126
127 MacroData const & MacroTable::get(docstring const & name) const
128 {
129         const_iterator it = find(name);
130         BOOST_ASSERT(it != end());
131         return it->second;
132 }
133
134
135 void MacroTable::insert(docstring const & name, MacroData const & data)
136 {
137         //lyxerr << "MacroTable::insert: " << to_utf8(name) << endl;
138         operator[](name) = data;
139 }
140
141
142 void MacroTable::insert(docstring const & def, string const & requires)
143 {
144         //lyxerr << "MacroTable::insert, def: " << to_utf8(def) << endl;
145         MathMacroTemplate mac(def);
146         MacroData data = mac.asMacroData();
147         data.requires() = requires;
148         insert(mac.name(), data);
149 }
150
151
152 void MacroTable::dump()
153 {
154         lyxerr << "\n------------------------------------------" << endl;
155         for (const_iterator it = begin(); it != end(); ++it)
156                 lyxerr << to_utf8(it->first)
157                         << " [" << to_utf8(it->second.definition()) << "] : "
158                         << " [" << to_utf8(it->second.display()) << "] : "
159                         << endl;
160         lyxerr << "------------------------------------------" << endl;
161 }
162
163
164 MacroContext::MacroContext(Buffer const & buf, Paragraph const & par)
165         : buf_(buf), par_(par)
166 {
167 }
168
169
170 bool MacroContext::has(docstring const & name) const
171 {
172         // check if it's a local macro
173         if (macros_.has(name))
174                 return true;
175         
176         // otherwise ask the buffer
177         return buf_.hasMacro(name, par_);
178 }
179
180
181 MacroData const & MacroContext::get(docstring const & name) const
182 {
183         // check if it's a local macro
184         if (macros_.has(name))
185                 return macros_.get(name);
186         
187         // ask the buffer for its macros
188         return buf_.getMacro(name, par_);
189 }
190
191
192 void MacroContext::insert(docstring const & name, MacroData const & data)
193 {
194         macros_.insert(name, data);
195 }
196
197
198 } // namespace lyx