3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
13 #include "MacroTable.h"
14 #include "MathMacroTemplate.h"
15 #include "MathMacroArgument.h"
16 #include "MathSupport.h"
17 #include "InsetMathSqrt.h"
19 #include "InsetMathNest.h"
22 #include "support/debug.h"
23 #include "DocIterator.h"
25 #include <boost/assert.hpp>
33 using std::istringstream;
41 /////////////////////////////////////////////////////////////////////
45 /////////////////////////////////////////////////////////////////////
47 MacroData::MacroData()
48 : numargs_(0), lockCount_(0), redefinition_(false)
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)
60 defaults_.resize(optionals);
64 void MacroData::expand(vector<MathData> const & args, MathData & to) const
66 InsetMathSqrt inset; // Hack. Any inset with a cell would do.
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()) {
74 if (it.nextInset()->lyxCode() != MATHMACROARG_CODE)
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]);
84 //lyxerr << "MathData::expand: res: " << inset.cell(0) << endl;
89 size_t MacroData::optionals() const
95 std::vector<docstring> const & MacroData::defaults() const
101 void MacroData::unlock() const
104 BOOST_ASSERT(lockCount_ >= 0);
108 /////////////////////////////////////////////////////////////////////
110 // The global table of macros
112 /////////////////////////////////////////////////////////////////////
114 MacroTable & MacroTable::globalMacros()
116 static MacroTable theGlobalMacros;
117 return theGlobalMacros;
121 bool MacroTable::has(docstring const & name) const
123 return find(name) != end();
127 MacroData const & MacroTable::get(docstring const & name) const
129 const_iterator it = find(name);
130 BOOST_ASSERT(it != end());
135 void MacroTable::insert(docstring const & name, MacroData const & data)
137 //lyxerr << "MacroTable::insert: " << to_utf8(name) << endl;
138 operator[](name) = data;
142 void MacroTable::insert(docstring const & def, string const & requires)
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);
152 void MacroTable::dump()
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()) << "] : "
160 lyxerr << "------------------------------------------" << endl;
164 MacroContext::MacroContext(Buffer const & buf, Paragraph const & par)
165 : buf_(buf), par_(par)
170 bool MacroContext::has(docstring const & name) const
172 // check if it's a local macro
173 if (macros_.has(name))
176 // otherwise ask the buffer
177 return buf_.hasMacro(name, par_);
181 MacroData const & MacroContext::get(docstring const & name) const
183 // check if it's a local macro
184 if (macros_.has(name))
185 return macros_.get(name);
187 // ask the buffer for its macros
188 return buf_.getMacro(name, par_);
192 void MacroContext::insert(docstring const & name, MacroData const & data)
194 macros_.insert(name, data);