From 8b92a2a689c2548a263065a24c0d3aa917785cce Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Tue, 12 Mar 2019 14:08:05 +0100 Subject: [PATCH] Add NeedMBoxProtect [inset]layout option This accesses the inulemcmd output param which protects specific commands (\cite, \ref) in an \mbox. This is needed in ulem and soul commands, since their complex detokenization makes such commands (who produce multiple words via local assignment) fail. So now it is possible to properly support ulem and soul via [inset]layout Fixes a case reported in #9404 --- lib/doc/Customization.lyx | 209 +++++++++++++++++++++++++++++++++- lib/layouts/pdfcomment.module | 4 +- lib/scripts/layout2layout.py | 9 +- src/Layout.cpp | 8 ++ src/Layout.h | 3 + src/OutputParams.h | 6 +- src/TextClass.cpp | 2 +- src/insets/InsetCaption.cpp | 2 + src/insets/InsetLayout.cpp | 11 +- src/insets/InsetLayout.h | 5 + src/insets/InsetText.cpp | 2 + src/output_latex.cpp | 2 + 12 files changed, 249 insertions(+), 14 deletions(-) diff --git a/lib/doc/Customization.lyx b/lib/doc/Customization.lyx index 8d045ae997..89f97ab153 100644 --- a/lib/doc/Customization.lyx +++ b/lib/doc/Customization.lyx @@ -1,5 +1,5 @@ #LyX 2.4 created this file. For more info see https://www.lyx.org/ -\lyxformat 566 +\lyxformat 567 \begin_document \begin_header \save_transient_properties true @@ -15097,7 +15097,7 @@ not \begin_layout Description -\change_inserted -712698321 1523696969 +\change_inserted -712698321 1552395557 \begin_inset Flex Code status collapsed @@ -15159,6 +15159,110 @@ cprotect cprotect \family default ) if necessary and thus allows (some) verbatim stuff in macros. +\end_layout + +\begin_layout Description + +\change_inserted -712698321 1552395844 +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1552395561 +NeedMBoxProtect +\end_layout + +\end_inset + + [ +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1552395557 + +\emph on +0 +\end_layout + +\end_inset + +, +\begin_inset space \thinspace{} +\end_inset + + +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1552395557 +1 +\end_layout + +\end_inset + +] Whether specific commands in this style (such as +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1552395655 + +\backslash +cite +\change_unchanged + +\end_layout + +\end_inset + + and +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1552395661 + +\backslash +ref +\change_unchanged + +\end_layout + +\end_inset + +) should be protected in an +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1552395631 + +\backslash +mbox +\change_unchanged + +\end_layout + +\end_inset + +. + This is particularly needed for styles that draw on +\family sans +ulem +\family default + or +\family sans +soul +\family default + commands which parse their content in complex ways. \change_unchanged \end_layout @@ -20096,7 +20200,7 @@ not \begin_layout Description -\change_inserted -712698321 1523634088 +\change_inserted -712698321 1552395786 \begin_inset Flex Code status collapsed @@ -20161,6 +20265,105 @@ cprotect \family default ) if necessary and thus allows (some) verbatim stuff in macros. Default is false. +\end_layout + +\begin_layout Description + +\change_inserted -712698321 1552395824 +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1552395787 +NeedMBoxProtect +\end_layout + +\end_inset + + [ +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1552395787 + +\emph on +0 +\end_layout + +\end_inset + +, +\begin_inset space \thinspace{} +\end_inset + + +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1552395787 +1 +\end_layout + +\end_inset + +] Whether specific commands in this inset (such as +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1552395787 + +\backslash +cite +\end_layout + +\end_inset + + and +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1552395787 + +\backslash +ref +\end_layout + +\end_inset + +) should be protected in an +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1552395787 + +\backslash +mbox +\end_layout + +\end_inset + +. + This is particularly needed for insets that draw on +\family sans +ulem +\family default + or +\family sans +soul +\family default + commands which parse their content in complex ways. + Default is false. \change_unchanged \end_layout diff --git a/lib/layouts/pdfcomment.module b/lib/layouts/pdfcomment.module index d2652df68b..7ca702fe17 100644 --- a/lib/layouts/pdfcomment.module +++ b/lib/layouts/pdfcomment.module @@ -7,7 +7,7 @@ # Author: Juergen Spitzmueller # Uwe Stöhr -Format 70 +Format 71 # # helper commands @@ -123,6 +123,7 @@ InsetLayout "Flex:PDF-Markup" CopyStyle "Flex:PDF-Margin" LabelString "PDF (Markup)" LatexName pdfmarkupcomment + NeedMBoxProtect 1 Argument post:1 LabelString "Comment" Mandatory 1 @@ -181,6 +182,7 @@ InsetLayout "Flex:PDF-Tooltip" CopyStyle "Flex:PDF-Markup" LabelString "PDF (Tooltip)" LatexName pdftooltip + NeedMBoxProtect 0 LabelFont Color red Size Small diff --git a/lib/scripts/layout2layout.py b/lib/scripts/layout2layout.py index 20f9e9c619..5d6c7ad0dc 100644 --- a/lib/scripts/layout2layout.py +++ b/lib/scripts/layout2layout.py @@ -11,7 +11,7 @@ # This script will update a .layout file to current format # The latest layout format is also defined in src/TextClass.cpp -currentFormat = 70 +currentFormat = 71 # Incremented to format 4, 6 April 2007, lasgouttes @@ -233,9 +233,12 @@ currentFormat = 70 # Incremented to format 69, 16 August 2018 by spitz # New argument type "listpreamble" -# Incremented to format 69, 5 June 2018 by rkh +# Incremented to format 70, 5 June 2018 by rkh # New InsetLayout tag EditExternal +# Incremented to format 71, 12 March 2019 by spitz +# New [Inset]Layout tag NeedMBoxProtect + # Do not forget to document format change in Customization # Manual (section "Declaring a new text class"). @@ -485,7 +488,7 @@ def convert(lines, end_format): i += 1 continue - if format >= 65 and format <= 69: + if format >= 65 and format <= 70: # nothing to do. i += 1 continue diff --git a/src/Layout.cpp b/src/Layout.cpp index a109c1d931..e4b6b3e3db 100644 --- a/src/Layout.cpp +++ b/src/Layout.cpp @@ -75,6 +75,7 @@ enum LayoutTags { LT_LEFTDELIM, LT_LEFTMARGIN, LT_NEED_CPROTECT, + LT_NEED_MBOXPROTECT, LT_NEED_PROTECT, LT_NEWLINE, LT_NEXTNOINDENT, @@ -132,6 +133,7 @@ Layout::Layout() inpreamble = false; needprotect = false; needcprotect = false; + needmboxprotect = false; keepempty = false; font = inherit_font; labelfont = inherit_font; @@ -245,6 +247,7 @@ bool Layout::readIgnoreForcelocal(Lexer & lex, TextClass const & tclass) { "leftmargin", LT_LEFTMARGIN }, { "margin", LT_MARGIN }, { "needcprotect", LT_NEED_CPROTECT }, + { "needmboxprotect", LT_NEED_MBOXPROTECT }, { "needprotect", LT_NEED_PROTECT }, { "newline", LT_NEWLINE }, { "nextnoindent", LT_NEXTNOINDENT }, @@ -401,6 +404,10 @@ bool Layout::readIgnoreForcelocal(Lexer & lex, TextClass const & tclass) lex >> needcprotect; break; + case LT_NEED_MBOXPROTECT: + lex >> needmboxprotect; + break; + case LT_KEEPEMPTY: lex >> keepempty; break; @@ -1230,6 +1237,7 @@ void Layout::write(ostream & os) const writeArgument(os, it->first, it->second); os << "\tNeedProtect " << needprotect << "\n" "\tNeedCProtect " << needcprotect << "\n" + "\tNeedMBoxProtect " << needmboxprotect << "\n" "\tKeepEmpty " << keepempty << '\n'; if (labelfont == font) lyxWrite(os, font, "Font", 1); diff --git a/src/Layout.h b/src/Layout.h index 4f4f1c7899..6c4b6c01d8 100644 --- a/src/Layout.h +++ b/src/Layout.h @@ -317,6 +317,9 @@ public: /** true when the verbatim stuff of this layout needs to be \cprotect'ed. */ bool needcprotect; + /** true when specific commands in this paragraph need to be + protected in an \mbox. */ + bool needmboxprotect; /// true when empty paragraphs should be kept. bool keepempty; /// Type of LaTeX object diff --git a/src/OutputParams.h b/src/OutputParams.h index 7bb21e8db8..8dbe00203d 100644 --- a/src/OutputParams.h +++ b/src/OutputParams.h @@ -103,9 +103,9 @@ public: bool intitle; /** inulemcmd > 0 means that the environment in which the - inset is typeset is part of a ulem command (\uline, \uuline, - \uwave, \sout or \xout). Insets that output latex commands relying - on local assignments (such as \cite) should enclose such + inset is typeset is part of a ulem or soul command (e.g., \uline, + \uuline, \uwave, \sout or \xout). Insets that output latex commands + relying on local assignments (such as \cite) should enclose such commands in \mbox{} in order to avoid breakage. */ mutable int inulemcmd; diff --git a/src/TextClass.cpp b/src/TextClass.cpp index 7e813626b7..d1cf13b3bf 100644 --- a/src/TextClass.cpp +++ b/src/TextClass.cpp @@ -62,7 +62,7 @@ namespace lyx { // You should also run the development/tools/updatelayouts.py script, // to update the format of all of our layout files. // -int const LAYOUT_FORMAT = 70; // rkh: InsetLayout EditExternal +int const LAYOUT_FORMAT = 71; // spitz: NeedMBoxProtect // Layout format for the current lyx file format. Controls which format is diff --git a/src/insets/InsetCaption.cpp b/src/insets/InsetCaption.cpp index 8778d78730..0ebbcea379 100644 --- a/src/insets/InsetCaption.cpp +++ b/src/insets/InsetCaption.cpp @@ -329,6 +329,8 @@ void InsetCaption::getArgument(otexstream & os, rp.pass_thru = true; if (il.isNeedProtect()) rp.moving_arg = true; + if (il.isNeedMBoxProtect()) + ++rp.inulemcmd; rp.par_begin = 0; rp.par_end = paragraphs().size(); diff --git a/src/insets/InsetLayout.cpp b/src/insets/InsetLayout.cpp index 5d9427d2ad..b62affd3d9 100644 --- a/src/insets/InsetLayout.cpp +++ b/src/insets/InsetLayout.cpp @@ -43,9 +43,9 @@ InsetLayout::InsetLayout() : forceplain_(false), passthru_(false), parbreakisnewline_(false), freespacing_(false), keepempty_(false), forceltr_(false), forceownlines_(false), needprotect_(false), needcprotect_(false), - intoc_(false), spellcheck_(true), resetsfont_(false), display_(true), - forcelocalfontswitch_(false), add_to_toc_(false), is_toc_caption_(false), - edit_external_(false) + needmboxprotect_(false), intoc_(false), spellcheck_(true), + resetsfont_(false), display_(true), forcelocalfontswitch_(false), + add_to_toc_(false), is_toc_caption_(false), edit_external_(false) { labelfont_.setColor(Color_error); } @@ -122,6 +122,7 @@ bool InsetLayout::read(Lexer & lex, TextClass const & tclass) IL_KEEPEMPTY, IL_MULTIPAR, IL_NEEDCPROTECT, + IL_NEEDMBOXPROTECT, IL_NEEDPROTECT, IL_PASSTHRU, IL_PASSTHRU_CHARS, @@ -179,6 +180,7 @@ bool InsetLayout::read(Lexer & lex, TextClass const & tclass) { "lyxtype", IL_LYXTYPE }, { "multipar", IL_MULTIPAR }, { "needcprotect", IL_NEEDCPROTECT }, + { "needmboxprotect", IL_NEEDMBOXPROTECT }, { "needprotect", IL_NEEDPROTECT }, { "obsoletedby", IL_OBSOLETEDBY }, { "parbreakisnewline", IL_PARBREAKISNEWLINE }, @@ -330,6 +332,9 @@ bool InsetLayout::read(Lexer & lex, TextClass const & tclass) case IL_NEEDCPROTECT: lex >> needcprotect_; break; + case IL_NEEDMBOXPROTECT: + lex >> needmboxprotect_; + break; case IL_CONTENTASLABEL: lex >> contentaslabel_; break; diff --git a/src/insets/InsetLayout.h b/src/insets/InsetLayout.h index 79390e522d..0eb27085fb 100644 --- a/src/insets/InsetLayout.h +++ b/src/insets/InsetLayout.h @@ -163,6 +163,9 @@ public: bool isNeedProtect() const { return needprotect_; } /// bool needsCProtect() const { return needcprotect_; } + /// Protection of some elements such as \ref and \cite + /// in \mbox (needed by commands building on soul or ulem) + bool isNeedMBoxProtect() const { return needmboxprotect_; } /// bool isFreeSpacing() const { return freespacing_; } /// @@ -289,6 +292,8 @@ private: bool needprotect_; /// bool needcprotect_; + /// + bool needmboxprotect_; /// should the contents be written to TOC strings? bool intoc_; /// check spelling of this inset? diff --git a/src/insets/InsetText.cpp b/src/insets/InsetText.cpp index de6da629f8..8f2ba0c5ff 100644 --- a/src/insets/InsetText.cpp +++ b/src/insets/InsetText.cpp @@ -499,6 +499,8 @@ void InsetText::latex(otexstream & os, OutputParams const & runparams) const rp.pass_thru = true; if (il.isNeedProtect()) rp.moving_arg = true; + if (il.isNeedMBoxProtect()) + ++rp.inulemcmd; if (!il.passThruChars().empty()) rp.pass_thru_chars += il.passThruChars(); rp.par_begin = 0; diff --git a/src/output_latex.cpp b/src/output_latex.cpp index 07007cce1d..7cc5b73e22 100644 --- a/src/output_latex.cpp +++ b/src/output_latex.cpp @@ -1036,6 +1036,8 @@ void TeXOnePar(Buffer const & buf, } runparams.moving_arg |= style.needprotect; + if (style.needmboxprotect) + ++runparams.inulemcmd; Encoding const * const prev_encoding = runparams.encoding; bool const useSetSpace = bparams.documentClass().provides("SetSpace");