From c30179a44992b7b65ad9af41771fefa9641955e7 Mon Sep 17 00:00:00 2001 From: Richard Kimberly Heck Date: Thu, 12 Nov 2020 16:16:15 -0500 Subject: [PATCH] Start moving updateMacros code into the insets. --- src/Buffer.cpp | 31 ++++++++++++ src/Buffer.h | 12 +++++ src/insets/InsetText.cpp | 107 +++++++++++++++++++++++++++++++++++++++ src/insets/InsetText.h | 2 + 4 files changed, 152 insertions(+) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 859f9ce4e3..c0a133fadd 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -3855,6 +3855,37 @@ void Buffer::Impl::updateMacros(DocIterator & it, DocIterator & scope) } +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(this), pos)); +} + + void Buffer::updateMacros() const { if (d->macro_lock) diff --git a/src/Buffer.h b/src/Buffer.h index c8946d625c..267bf94c1d 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -597,6 +597,10 @@ public: // // 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 @@ -614,10 +618,18 @@ public: /// 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 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); diff --git a/src/insets/InsetText.cpp b/src/insets/InsetText.cpp index 35c1d3b99c..9c32d491e0 100644 --- a/src/insets/InsetText.cpp +++ b/src/insets/InsetText.cpp @@ -56,6 +56,13 @@ #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" @@ -902,6 +909,106 @@ void InsetText::updateBuffer(ParIterator const & it, UpdateType utype, bool cons } +void InsetText::updateMacros(DocIterator const & us, DocIterator const & scope) +{ + DocIterator ourscope = scope; + // If we do not produce output, then we do not want our macros to + // affect anything outside this inset. So we set the scope to the + // position right after the inset. + if (!producesOutput()) { + ourscope = us; + ++ourscope.pos(); + } + + 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(*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); diff --git a/src/insets/InsetText.h b/src/insets/InsetText.h index cefd44cabf..9fdfb6fdfe 100644 --- a/src/insets/InsetText.h +++ b/src/insets/InsetText.h @@ -173,6 +173,8 @@ public: /// Update the counters of this inset and of its contents void updateBuffer(ParIterator const &, UpdateType, bool const deleted = false) override; /// + void updateMacros(DocIterator const & us, DocIterator const & scope); + /// void setMacrocontextPositionRecursive(DocIterator const & pos); /// void toString(odocstream &) const override; -- 2.39.5