]> git.lyx.org Git - features.git/commitdiff
Start moving updateMacros code into the insets.
authorRichard Kimberly Heck <rikiheck@lyx.org>
Thu, 12 Nov 2020 21:16:15 +0000 (16:16 -0500)
committerRichard Kimberly Heck <rikiheck@lyx.org>
Fri, 13 Nov 2020 00:17:13 +0000 (19:17 -0500)
src/Buffer.cpp
src/Buffer.h
src/insets/InsetText.cpp
src/insets/InsetText.h

index 859f9ce4e386c66378c5c9a89c0670404a59fa01..c0a133fadd0bdf6ca12520d8ed0ade09d0625429 100644 (file)
@@ -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<Buffer *>(this), pos));
+}
+
+
 void Buffer::updateMacros() const
 {
        if (d->macro_lock)
index c8946d625cdd5e2c98b8080415c4783c109d209a..267bf94c1d9a760fe905d23032da9e808531910d 100644 (file)
@@ -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<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);
index 35c1d3b99cd219e28556c372b46014dc647e5e9b..9c32d491e07eead0121b956d5415ad114aa4e1eb 100644 (file)
 #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<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);
index cefd44cabf0bb198d0e0c66c70c0882ad38942fa..9fdfb6fdfed4892930d6d489ad5150973f72db0b 100644 (file)
@@ -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;