Move labels and insets out of moving arguments

Fixes: #2154
This commit is contained in:
Juergen Spitzmueller 2019-03-14 14:24:43 +01:00
parent de9b1ae5fa
commit 262e436fc3
9 changed files with 87 additions and 4 deletions

View File

@ -24,8 +24,8 @@ OutputParams::OutputParams(Encoding const * enc)
master_language(0), encoding(enc), free_spacing(false), master_language(0), encoding(enc), free_spacing(false),
use_babel(false), use_polyglossia(false), use_CJK(false), use_babel(false), use_polyglossia(false), use_CJK(false),
use_indices(false), use_japanese(false), linelen(0), depth(0), use_indices(false), use_japanese(false), linelen(0), depth(0),
exportdata(new ExportData), inDisplayMath(false), wasDisplayMath(false), exportdata(new ExportData), postpone_fragile_stuff(false), inDisplayMath(false),
inComment(false), openbtUnit(false), only_childbibs(false), wasDisplayMath(false), inComment(false), openbtUnit(false), only_childbibs(false),
inTableCell(NO), inFloat(NONFLOAT), inTableCell(NO), inFloat(NONFLOAT),
inIndexEntry(false), inIPA(false), inDeletedInset(0), inIndexEntry(false), inIPA(false), inDeletedInset(0),
changeOfDeletedInset(Change::UNCHANGED), changeOfDeletedInset(Change::UNCHANGED),

View File

@ -197,6 +197,19 @@ public:
*/ */
std::shared_ptr<ExportData> exportdata; 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. /** Whether we are entering a display math inset.
* Needed to correctly strike out deleted math in change tracking. * Needed to correctly strike out deleted math in change tracking.
*/ */

View File

@ -2833,6 +2833,9 @@ void Paragraph::latex(BufferParams const & bparams,
// such as Note that do not produce any output, so that no // such as Note that do not produce any output, so that no
// command is ever executed but its opening was recorded. // command is ever executed but its opening was recorded.
runparams.inulemcmd = rp.inulemcmd; 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 // If we have an open font definition, we have to close it

View File

@ -264,7 +264,16 @@ void InsetCaption::latex(otexstream & os,
// \caption{...}, later we will make it take advantage // \caption{...}, later we will make it take advantage
// of the one of the caption packages. (Lgb) // of the one of the caption packages. (Lgb)
OutputParams runparams = runparams_in; 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); 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 // Backwards compatibility: We always had a linebreak after
// the caption (see #8514) // the caption (see #8514)
os << breakln; os << breakln;

View 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); OutputParams runparams(runparams_in);
runparams.inIndexEntry = true; runparams.inIndexEntry = true;
otexstringstream os;
if (buffer().masterBuffer()->params().use_indices && !params_.index.empty() if (buffer().masterBuffer()->params().use_indices && !params_.index.empty()
&& params_.index != "idx") { && params_.index != "idx") {
os << "\\sindex["; os << "\\sindex[";
@ -170,6 +172,13 @@ void InsetIndex::latex(otexstream & os, OutputParams const & runparams_in) const
os << "|" << cmd; os << "|" << cmd;
} }
os << '}'; 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();
} }

View File

@ -28,6 +28,7 @@
#include "output_xhtml.h" #include "output_xhtml.h"
#include "ParIterator.h" #include "ParIterator.h"
#include "sgml.h" #include "sgml.h"
#include "texstream.h"
#include "Text.h" #include "Text.h"
#include "TextClass.h" #include "TextClass.h"
#include "TocBackend.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, int InsetLabel::plaintext(odocstringstream & os,
OutputParams const &, size_t) const OutputParams const &, size_t) const
{ {

View File

@ -48,6 +48,8 @@ public:
/// ///
InsetCode lyxCode() const { return LABEL_CODE; } InsetCode lyxCode() const { return LABEL_CODE; }
/// ///
void latex(otexstream & os, OutputParams const & runparams_in) const;
///
int plaintext(odocstringstream & ods, OutputParams const & op, int plaintext(odocstringstream & ods, OutputParams const & op,
size_t max_length = INT_MAX) const; size_t max_length = INT_MAX) const;
/// ///

View File

@ -509,6 +509,8 @@ void InsetText::latex(otexstream & os, OutputParams const & runparams) const
// Output the contents of the inset // Output the contents of the inset
latexParagraphs(buffer(), text_, os, rp); latexParagraphs(buffer(), text_, os, rp);
runparams.encoding = rp.encoding; runparams.encoding = rp.encoding;
// Pass the post_macros upstream
runparams.post_macro = rp.post_macro;
if (!il.rightdelim().empty()) if (!il.rightdelim().empty())
os << il.rightdelim(); os << il.rightdelim();

View File

@ -777,6 +777,11 @@ void TeXOnePar(Buffer const & buf,
if (style.pass_thru) { if (style.pass_thru) {
Font const outerfont = text.outerFont(pit); Font const outerfont = text.outerFont(pit);
parStartCommand(par, os, runparams, style); 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) if (intitle_command)
os << '{'; os << '{';
@ -861,6 +866,11 @@ void TeXOnePar(Buffer const & buf,
// (see #10849); thus open the command here. // (see #10849); thus open the command here.
if (intitle_command) { if (intitle_command) {
parStartCommand(par, os, runparams, style); 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 << '{'; os << '{';
} }
@ -1071,8 +1081,14 @@ void TeXOnePar(Buffer const & buf,
// For InTitle commands, we already started the command before // For InTitle commands, we already started the command before
// the language switch // the language switch
if (!intitle_command) if (!intitle_command) {
parStartCommand(par, os, runparams, style); 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); Font const outerfont = text.outerFont(pit);
@ -1092,6 +1108,12 @@ void TeXOnePar(Buffer const & buf,
os << '}'; os << '}';
if (!style.postcommandargs().empty()) if (!style.postcommandargs().empty())
latexArgInsets(par, os, runparams, style.postcommandargs(), "post:"); 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) { if (runparams.encoding != prev_encoding) {
runparams.encoding = prev_encoding; runparams.encoding = prev_encoding;
os << setEncoding(prev_encoding->iconvName()); os << setEncoding(prev_encoding->iconvName());
@ -1246,6 +1268,12 @@ void TeXOnePar(Buffer const & buf,
os << '}'; os << '}';
if (!style.postcommandargs().empty()) if (!style.postcommandargs().empty())
latexArgInsets(par, os, runparams, style.postcommandargs(), "post:"); 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) { if (runparams.encoding != prev_encoding) {
runparams.encoding = prev_encoding; runparams.encoding = prev_encoding;
os << setEncoding(prev_encoding->iconvName()); os << setEncoding(prev_encoding->iconvName());
@ -1324,6 +1352,9 @@ void TeXOnePar(Buffer const & buf,
else else
runparams_in.encoding = runparams.encoding; 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!!! // we don't need a newline for the last paragraph!!!
// Note from JMarc: we will re-add a \n explicitly in // Note from JMarc: we will re-add a \n explicitly in