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
This commit is contained in:
Juergen Spitzmueller 2019-03-12 14:08:05 +01:00
parent de78dc8e79
commit 8b92a2a689
12 changed files with 249 additions and 14 deletions

View File

@ -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

View File

@ -7,7 +7,7 @@
# Author: Juergen Spitzmueller <spitz@lyx.org>
# Uwe Stöhr <uwestoehr@lyx.org>
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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -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?

View File

@ -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;

View File

@ -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");