]> git.lyx.org Git - features.git/commitdiff
Move labels and insets out of moving arguments
authorJuergen Spitzmueller <spitz@lyx.org>
Thu, 14 Mar 2019 13:24:43 +0000 (14:24 +0100)
committerJuergen Spitzmueller <spitz@lyx.org>
Thu, 14 Mar 2019 13:24:43 +0000 (14:24 +0100)
Fixes: #2154
src/OutputParams.cpp
src/OutputParams.h
src/Paragraph.cpp
src/insets/InsetCaption.cpp
src/insets/InsetIndex.cpp
src/insets/InsetLabel.cpp
src/insets/InsetLabel.h
src/insets/InsetText.cpp
src/output_latex.cpp

index cb9d50c175ed17416f4abf46567dd9f98290e603..36816c2f7f825060b00f12b8f79040f26b825c89 100644 (file)
@@ -24,8 +24,8 @@ OutputParams::OutputParams(Encoding const * enc)
          master_language(0), encoding(enc), free_spacing(false),
          use_babel(false), use_polyglossia(false), use_CJK(false),
          use_indices(false), use_japanese(false), linelen(0), depth(0),
-         exportdata(new ExportData), inDisplayMath(false), wasDisplayMath(false),
-         inComment(false), openbtUnit(false), only_childbibs(false),
+         exportdata(new ExportData), postpone_fragile_stuff(false), inDisplayMath(false),
+         wasDisplayMath(false), inComment(false), openbtUnit(false), only_childbibs(false),
          inTableCell(NO), inFloat(NONFLOAT),
          inIndexEntry(false), inIPA(false), inDeletedInset(0),
          changeOfDeletedInset(Change::UNCHANGED),
index ef7c16d11781bcd5dc30d1422c09b25df8499d78..5faa68e2e49001c091db9cc8739455fac06cf66f 100644 (file)
@@ -197,6 +197,19 @@ public:
        */
        std::shared_ptr<ExportData> exportdata;
 
+       /** Store labels, index entries (etc.) (in \ref post_macro)
+        *  and output them later. This is used in particular to get
+        *  labels and index entries (and potentially other fragile commands)
+        *  outside of moving arguments (bug 2154)
+        */
+       bool postpone_fragile_stuff;
+
+       /** Stuff to be postponed and output after the current macro
+        *  (if \ref postpone_fragile_stuff is true). Used for labels and index
+        *  entries in commands with moving arguments (\\section, \\caption etc.)
+        */
+       mutable docstring post_macro;
+
        /** Whether we are entering a display math inset.
         *  Needed to correctly strike out deleted math in change tracking.
         */
index 27aecb5eaee7fc4af6a211e6617136b572ed97a4..f1fc7bd886e903712eb4221e88fb8557ac061bd8 100644 (file)
@@ -2833,6 +2833,9 @@ void Paragraph::latex(BufferParams const & bparams,
                // such as Note that do not produce any output, so that no
                // command is ever executed but its opening was recorded.
                runparams.inulemcmd = rp.inulemcmd;
+
+               // And finally, pass the post_macros upstream
+               runparams.post_macro = rp.post_macro;
        }
 
        // If we have an open font definition, we have to close it
index 0ebbcea379c3d440a42a1939267807765c92d7fd..941047f337ecb055aa39819919259a941ae2f073 100644 (file)
@@ -264,7 +264,16 @@ void InsetCaption::latex(otexstream & os,
        // \caption{...}, later we will make it take advantage
        // of the one of the caption packages. (Lgb)
        OutputParams runparams = runparams_in;
+       // Some fragile commands (labels, index entries)
+       // are output after the caption (#2154)
+       runparams.postpone_fragile_stuff = true;
        InsetText::latex(os, runparams);
+       if (!runparams.post_macro.empty()) {
+               // Output the stored fragile commands (labels, indices etc.)
+               // that need to be output after the caption.
+               os << runparams.post_macro;
+               runparams.post_macro.clear();
+       }
        // Backwards compatibility: We always had a linebreak after
        // the caption (see #8514)
        os << breakln;
index 9ac768060fe8b7162338fff07c9b781c11b9bb43..f3fafce60b00d8af9d62813a074fa3314236634a 100644 (file)
@@ -59,11 +59,13 @@ InsetIndex::InsetIndex(Buffer * buf, InsetIndexParams const & params)
 {}
 
 
-void InsetIndex::latex(otexstream & os, OutputParams const & runparams_in) const
+void InsetIndex::latex(otexstream & ios, OutputParams const & runparams_in) const
 {
        OutputParams runparams(runparams_in);
        runparams.inIndexEntry = true;
 
+       otexstringstream os;
+
        if (buffer().masterBuffer()->params().use_indices && !params_.index.empty()
            && params_.index != "idx") {
                os << "\\sindex[";
@@ -170,6 +172,13 @@ void InsetIndex::latex(otexstream & os, OutputParams const & runparams_in) const
                os << "|" << cmd;
        }
        os << '}';
+
+       // In macros with moving arguments, such as \section,
+       // we store the index and output it after the macro (#2154)
+       if (runparams_in.postpone_fragile_stuff)
+               runparams_in.post_macro += os.str();
+       else
+               ios << os.release();
 }
 
 
index e325f1ea94c5431b6c019d9c9719b39e4ad0494f..9d6a031c281f414fb3ef8f0590b16c9efe6955c5 100644 (file)
@@ -28,6 +28,7 @@
 #include "output_xhtml.h"
 #include "ParIterator.h"
 #include "sgml.h"
+#include "texstream.h"
 #include "Text.h"
 #include "TextClass.h"
 #include "TocBackend.h"
@@ -294,6 +295,19 @@ void InsetLabel::doDispatch(Cursor & cur, FuncRequest & cmd)
 }
 
 
+void InsetLabel::latex(otexstream & os, OutputParams const & runparams_in) const
+{
+       OutputParams runparams = runparams_in;
+       docstring command = getCommand(runparams);
+       // In macros with moving arguments, such as \section,
+       // we store the label and output it after the macro (#2154)
+       if (runparams_in.postpone_fragile_stuff)
+               runparams_in.post_macro += command;
+       else
+               os << command;
+}
+
+
 int InsetLabel::plaintext(odocstringstream & os,
         OutputParams const &, size_t) const
 {
index 92c3380f7077ca066a79b6a3940e0c0a1e5475e0..ef4fed9cac2ee20eb5a7d752ca5ba4e7c4f76c7c 100644 (file)
@@ -48,6 +48,8 @@ public:
        ///
        InsetCode lyxCode() const { return LABEL_CODE; }
        ///
+       void latex(otexstream & os, OutputParams const & runparams_in) const;
+       ///
        int plaintext(odocstringstream & ods, OutputParams const & op,
                      size_t max_length = INT_MAX) const;
        ///
index 8f2ba0c5ffb062bb191ecc54fe5d3a26ed81d22c..85da8dd4ec4c35a18f608d1509b203b271631014 100644 (file)
@@ -509,6 +509,8 @@ void InsetText::latex(otexstream & os, OutputParams const & runparams) const
        // Output the contents of the inset
        latexParagraphs(buffer(), text_, os, rp);
        runparams.encoding = rp.encoding;
+       // Pass the post_macros upstream
+       runparams.post_macro = rp.post_macro;
 
        if (!il.rightdelim().empty())
                os << il.rightdelim();
index d515ef488606490cc77a717d64a6a34523638137..8ccb9f5eb6e66beeeaed41a3dc19384a6ac1d8e0 100644 (file)
@@ -777,6 +777,11 @@ void TeXOnePar(Buffer const & buf,
        if (style.pass_thru) {
                Font const outerfont = text.outerFont(pit);
                parStartCommand(par, os, runparams, style);
+               if (style.isCommand() && style.needprotect)
+                       // Due to the moving argument, some fragile
+                       // commands (labels, index entries)
+                       // are output after this command (#2154)
+                       runparams.postpone_fragile_stuff = true;
                if (intitle_command)
                        os << '{';
 
@@ -861,6 +866,11 @@ void TeXOnePar(Buffer const & buf,
        // (see #10849); thus open the command here.
        if (intitle_command) {
                parStartCommand(par, os, runparams, style);
+               if (style.isCommand() && style.needprotect)
+                       // Due to the moving argument, some fragile
+                       // commands (labels, index entries)
+                       // are output after this command (#2154)
+                       runparams.postpone_fragile_stuff = true;
                os << '{';
        }
 
@@ -1071,8 +1081,14 @@ void TeXOnePar(Buffer const & buf,
 
        // For InTitle commands, we already started the command before
        // the language switch
-       if (!intitle_command)
+       if (!intitle_command) {
                parStartCommand(par, os, runparams, style);
+               if (style.isCommand() && style.needprotect)
+                       // Due to the moving argument, some fragile
+                       // commands (labels, index entries)
+                       // are output after this command (#2154)
+                       runparams.postpone_fragile_stuff = true;
+       }
 
        Font const outerfont = text.outerFont(pit);
 
@@ -1092,6 +1108,12 @@ void TeXOnePar(Buffer const & buf,
                        os << '}';
                        if (!style.postcommandargs().empty())
                                latexArgInsets(par, os, runparams, style.postcommandargs(), "post:");
+                       if (!runparams.post_macro.empty()) {
+                               // Output the stored fragile commands (labels, indices etc.)
+                               // that need to be output after the command with moving argument.
+                               os << runparams.post_macro;
+                               runparams.post_macro.clear();
+                       }
                        if (runparams.encoding != prev_encoding) {
                                runparams.encoding = prev_encoding;
                                os << setEncoding(prev_encoding->iconvName());
@@ -1246,6 +1268,12 @@ void TeXOnePar(Buffer const & buf,
                        os << '}';
                        if (!style.postcommandargs().empty())
                                latexArgInsets(par, os, runparams, style.postcommandargs(), "post:");
+                       if (!runparams.post_macro.empty()) {
+                               // Output the stored fragile commands (labels, indices etc.)
+                               // that need to be output after the command with moving argument.
+                               os << runparams.post_macro;
+                               runparams.post_macro.clear();
+                       }
                        if (runparams.encoding != prev_encoding) {
                                runparams.encoding = prev_encoding;
                                os << setEncoding(prev_encoding->iconvName());
@@ -1324,6 +1352,9 @@ void TeXOnePar(Buffer const & buf,
        else
                runparams_in.encoding = runparams.encoding;
 
+       // Also pass the post_macros upstream
+       runparams_in.post_macro = runparams.post_macro;
+
 
        // we don't need a newline for the last paragraph!!!
        // Note from JMarc: we will re-add a \n explicitly in