}
+void Buffer::setMacroLock() const
+{
+ d->macro_lock = true;
+}
+
+
+void Buffer::clearMacroLock() const
+{
+ d->macro_lock = false;
+}
+
+
+void Buffer::registerChild(Buffer * child,
+ DocIterator const & pos, DocIterator const & scope) const
+{
+ // register its position, but only when it is
+ // included first in the buffer
+ d->children_positions.insert({child, pos});
+ // register child with its scope
+ d->position_to_children[pos] = Impl::ScopeBuffer(scope, child);
+}
+
+
+void Buffer::registerMacro(docstring const & name, DocIterator const & pos,
+ DocIterator const & scope)
+{
+ d->macro_table.addMacroDefinition(name, pos, scope,
+ MacroData(const_cast<Buffer *>(this), pos));
+}
+
+
void Buffer::updateMacros() const
{
if (d->macro_lock)
//
// Macro handling
//
+ ///
+ void setMacroLock() const;
+ ///
+ void clearMacroLock() const;
/// Collect macro definitions in paragraphs
void updateMacros() const;
/// Iterate through the whole buffer and try to resolve macros
/// Return macro defined before the inclusion of the child
MacroData const * getMacro(docstring const & name, Buffer const & child, bool global = true) const;
+ ///
+ void registerMacro(docstring const & name, DocIterator const & pos,
+ DocIterator const & scope);
+
/// Collect user macro names at loading time
typedef std::set<docstring> UserMacroSet;
mutable UserMacroSet usermacros;
+ ///
+ void registerChild(Buffer * child,
+ DocIterator const & pos, DocIterator const & scope) const;
+
/// Replace the inset contents for insets which InsetCode is equal
/// to the passed \p inset_code. Handles undo.
void changeRefsIfUnique(docstring const & from, docstring const & to);
#include "frontends/alert.h"
#include "frontends/Painter.h"
+// These are only temporarily here, until the relevant code
+// is moved into these insets
+#include "insets/InsetInclude.h"
+#include "mathed/InsetMathHull.h"
+#include "mathed/MacroTable.h"
+#include "mathed/InsetMathMacroTemplate.h"
+
#include "support/convert.h"
#include "support/debug.h"
#include "support/gettext.h"
}
+void InsetText::updateMacros(DocIterator const & us, DocIterator const & scope)
+{
+ LBUFERR(us.nextInset() == this);
+ DocIterator it = us;
+ pit_type const lastpit = it.lastpit();
+
+ // look for macros in each paragraph
+ while (it.pit() <= lastpit) {
+ Paragraph & par = it.paragraph();
+
+ // iterate over the insets of the current paragraph
+ for (auto const & insit : par.insetList()) {
+ it.pos() = insit.pos;
+
+ if (InsetText const * itext = insit.inset->asInsetText()) {
+ // collect macros in inset
+ it.push_back(CursorSlice(*insit.inset));
+ if (itext->producesOutput()) {
+ // the simple case
+ updateMacros(it, scope);
+ } else {
+ // We don't want macros declared in notes, comments, etc,
+ // to affect anything outside them.
+ // New scope which ends just behind the inset
+ DocIterator new_scope = it;
+ ++new_scope.pos();
+ updateMacros(it, new_scope);
+ }
+ it.pop_back();
+ continue;
+ }
+
+ if (insit.inset->asInsetTabular()) {
+ CursorSlice slice(*insit.inset);
+ size_t const numcells = slice.nargs();
+ for (; slice.idx() < numcells; slice.forwardIdx()) {
+ it.push_back(slice);
+ updateMacros(it, scope);
+ it.pop_back();
+ }
+ continue;
+ }
+
+ // is it an external file?
+ if (insit.inset->lyxCode() == INCLUDE_CODE) {
+ // get buffer of external file
+ InsetInclude const & incinset =
+ static_cast<InsetInclude const &>(*insit.inset);
+ buffer().setMacroLock();
+ Buffer * child = incinset.loadIfNeeded();
+ buffer().clearMacroLock();
+ if (!child)
+ continue;
+ buffer().registerChild(child, it, scope);
+ continue;
+ }
+
+ InsetMath * im = insit.inset->asInsetMath();
+ if (im) {
+ InsetMathHull * hull = im->asHullInset();
+ if (hull)
+ hull->recordLocation(it);
+ }
+
+ if (insit.inset->lyxCode() != MATHMACRO_CODE)
+ continue;
+
+ // get macro data
+ InsetMathMacroTemplate & macroTemplate =
+ *insit.inset->asInsetMath()->asMacroTemplate();
+ MacroContext mc(&buffer(), it);
+ macroTemplate.updateToContext(mc);
+
+ // valid?
+ bool valid = macroTemplate.validMacro();
+ // FIXME: Should be fixNameAndCheckIfValid() in fact,
+ // then the BufferView's cursor will be invalid in
+ // some cases which leads to crashes.
+ if (!valid)
+ continue;
+
+ // register macro
+ buffer().registerMacro(macroTemplate.name(), it, scope);
+ }
+
+ // next paragraph
+ it.pit()++;
+ it.pos() = 0;
+ }
+}
+
+
void InsetText::toString(odocstream & os) const
{
os << text().asString(0, 1, AS_STR_LABEL | AS_STR_INSETS);