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 "InsetMathSqrt.h"
14 #include "MacroTable.h"
15 #include "MathMacroTemplate.h"
16 #include "MathMacroArgument.h"
17 #include "MathStream.h"
18 #include "MathSupport.h"
19 #include "InsetMathNest.h"
22 #include "DocIterator.h"
23 #include "InsetList.h"
26 #include "support/debug.h"
27 #include "support/lassert.h"
36 /////////////////////////////////////////////////////////////////////
40 /////////////////////////////////////////////////////////////////////
42 MacroData::MacroData(Buffer
* buf
)
43 : buffer_(buf
), queried_(true), numargs_(0), optionals_(0), lockCount_(0),
44 redefinition_(false), type_(MacroTypeNewcommand
)
49 MacroData::MacroData(Buffer
* buf
, DocIterator
const & pos
)
50 : buffer_(buf
), pos_(pos
), queried_(false), numargs_(0),
51 optionals_(0), lockCount_(0), redefinition_(false),
52 type_(MacroTypeNewcommand
)
57 MacroData::MacroData(Buffer
* buf
, MathMacroTemplate
const & macro
)
58 : buffer_(buf
), queried_(false), numargs_(0), optionals_(0), lockCount_(0),
59 redefinition_(false), type_(MacroTypeNewcommand
)
65 void MacroData::expand(vector
<MathData
> const & args
, MathData
& to
) const
69 // Hack. Any inset with a cell would do.
70 static InsetMathSqrt
inset(0);
71 inset
.setBuffer(const_cast<Buffer
&>(*buffer_
));
74 asArray(display_
.empty() ? definition_
: display_
, inset
.cell(0));
75 //lyxerr << "MathData::expand: args: " << args << endl;
76 //lyxerr << "MathData::expand: ar: " << inset.cell(0) << endl;
77 for (DocIterator it
= doc_iterator_begin(buffer_
, &inset
); it
; it
.forwardChar()) {
80 if (it
.nextInset()->lyxCode() != MATH_MACROARG_CODE
)
82 //it.cell().erase(it.pos());
83 //it.cell().insert(it.pos(), it.nextInset()->asInsetMath()
84 size_t n
= static_cast<MathMacroArgument
*>(it
.nextInset())->number();
85 if (n
<= args
.size()) {
86 it
.cell().erase(it
.pos());
87 it
.cell().insert(it
.pos(), args
[n
- 1]);
90 //lyxerr << "MathData::expand: res: " << inset.cell(0) << endl;
95 size_t MacroData::optionals() const
102 vector
<docstring
> const & MacroData::defaults() const
109 void MacroData::unlock() const
112 LASSERT(lockCount_
>= 0, /**/);
116 void MacroData::queryData(MathMacroTemplate
const & macro
) const
122 definition_
= macro
.definition();
123 numargs_
= macro
.numArgs();
124 display_
= macro
.displayDefinition();
125 redefinition_
= macro
.redefinition();
126 type_
= macro
.type();
127 optionals_
= macro
.numOptionals();
129 macro
.getDefaults(defaults_
);
133 void MacroData::updateData() const
138 LASSERT(buffer_
!= 0, /**/);
140 // Try to fix position DocIterator. Should not do anything in theory.
143 // find macro template
144 Inset
* inset
= pos_
.nextInset();
145 if (inset
== 0 || inset
->lyxCode() != MATHMACRO_CODE
) {
146 lyxerr
<< "BUG: No macro template found by MacroData" << endl
;
150 // query the data from the macro template
151 queryData(static_cast<MathMacroTemplate
const &>(*inset
));
155 void MacroData::write(odocstream
& os
, bool overwriteRedefinition
) const
159 // find macro template
160 Inset
* inset
= pos_
.nextInset();
161 if (inset
== 0 || inset
->lyxCode() != MATHMACRO_CODE
) {
162 lyxerr
<< "BUG: No macro template found by MacroData" << endl
;
167 MathMacroTemplate
const & tmpl
=
168 static_cast<MathMacroTemplate
const &>(*inset
);
169 WriteStream
wi(os
, false, true, WriteStream::wsDefault
);
170 tmpl
.write(wi
, overwriteRedefinition
);
174 /////////////////////////////////////////////////////////////////////
176 // The global table of macros
178 /////////////////////////////////////////////////////////////////////
180 MacroTable
& MacroTable::globalMacros()
182 static MacroTable theGlobalMacros
;
183 return theGlobalMacros
;
187 MacroData
const * MacroTable::get(docstring
const & name
) const
189 const_iterator it
= find(name
);
190 return it
== end() ? 0 : &it
->second
;
194 void MacroTable::insert(docstring
const & name
, MacroData
const & data
)
196 //lyxerr << "MacroTable::insert: " << to_utf8(name) << endl;
197 operator[](name
) = data
;
201 void MacroTable::insert(Buffer
* buf
, docstring
const & def
, string
const & requires
)
203 //lyxerr << "MacroTable::insert, def: " << to_utf8(def) << endl;
204 MathMacroTemplate
mac(buf
, def
);
205 MacroData
data(buf
, mac
);
206 data
.requires() = requires
;
207 insert(mac
.name(), data
);
211 void MacroTable::getMacroNames(std::set
<docstring
> & names
) const
213 for (const_iterator it
= begin(); it
!= end(); ++it
)
214 names
.insert(it
->first
);
218 void MacroTable::dump()
220 lyxerr
<< "\n------------------------------------------" << endl
;
221 for (const_iterator it
= begin(); it
!= end(); ++it
)
222 lyxerr
<< to_utf8(it
->first
)
223 << " [" << to_utf8(it
->second
.definition()) << "] : "
224 << " [" << to_utf8(it
->second
.display()) << "] : "
226 lyxerr
<< "------------------------------------------" << endl
;
230 /////////////////////////////////////////////////////////////////////
234 /////////////////////////////////////////////////////////////////////
236 MacroContext::MacroContext(Buffer
const * buf
, DocIterator
const & pos
)
237 : buf_(buf
), pos_(pos
)
242 MacroData
const * MacroContext::get(docstring
const & name
) const
244 return buf_
->getMacro(name
, pos_
);