From 49e8e3567c72b86b02a89f025fb492790e50dd97 Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Wed, 12 Aug 2020 15:26:23 +0200 Subject: [PATCH] Font switches in \cprotect'ed context need to be \cprotect'ed themselves --- src/Font.cpp | 153 +++++++++++++++++++++++++++++++++++++++++++--- src/Font.h | 3 +- src/Paragraph.cpp | 6 +- 3 files changed, 150 insertions(+), 12 deletions(-) diff --git a/src/Font.cpp b/src/Font.cpp index 74ff2de4ed..112b51c5e3 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -228,7 +228,8 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams, OutputParams const & runparams, Font const & base, Font const & prev, - bool const & non_inherit_inset) const + bool const & non_inherit_inset, + bool const & needs_cprotection) const { int count = 0; @@ -237,13 +238,28 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams, && language()->lang() != base.language()->lang() && language() != prev.language()) { if (!language()->polyglossia().empty()) { - string tmp = "\\text" + language()->polyglossia(); + string tmp; + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + tmp += "\\begingroup\\catcode`\\^=7"; + tmp += "\\cprotect"; + } + tmp += "\\text" + language()->polyglossia(); if (!language()->polyglossiaOpts().empty()) { tmp += "[" + language()->polyglossiaOpts() + "]"; - if (runparams.use_hyperref && runparams.moving_arg) + if (runparams.use_hyperref && runparams.moving_arg) { // We need to strip the command for // the pdf string, see #11813 - tmp = "\\texorpdfstring{" + tmp + "}{}"; + string tmpp; + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + tmpp = "\\cprotect"; + } + tmp = tmpp + "\\texorpdfstring{" + tmp + "}{}"; + } } tmp += "{"; os << from_ascii(tmp); @@ -256,21 +272,56 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams, } else if (language()->babel() != base.language()->babel() && language() != prev.language()) { if (language()->lang() == "farsi") { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << "\\textFR{"; count += 8; } else if (!isRightToLeft() && base.language()->lang() == "farsi") { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << "\\textLR{"; count += 8; } else if (language()->lang() == "arabic_arabi") { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << "\\textAR{"; count += 8; } else if (!isRightToLeft() && base.language()->lang() == "arabic_arabi") { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << "\\textLR{"; count += 8; // currently the remaining RTL languages are arabic_arabtex and hebrew } else if (isRightToLeft() != prev.isRightToLeft()) { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } if (isRightToLeft()) { os << "\\R{"; count += 3; @@ -282,6 +333,13 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams, string const tmp = subst(lyxrc.language_command_local, "$$lang", language()->babel()); + if (needs_cprotection && !prefixIs(tmp, "\\begin{")) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << from_ascii(tmp); count += tmp.length(); if (!lyxrc.language_command_end.empty()) @@ -321,6 +379,13 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams, os << '\\' << LaTeXFamilySwitchNames[f.family()] << termcmd; count += strlen(LaTeXFamilySwitchNames[f.family()]) + 1; } else { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << '\\' << LaTeXFamilyCommandNames[f.family()] << '{'; @@ -334,6 +399,13 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams, os << '\\' << LaTeXSeriesSwitchNames[f.series()] << termcmd; count += strlen(LaTeXSeriesSwitchNames[f.series()]) + 1; } else { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << '\\' << LaTeXSeriesCommandNames[f.series()] << '{'; @@ -347,6 +419,13 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams, os << '\\' << LaTeXShapeSwitchNames[f.shape()] << termcmd; count += strlen(LaTeXShapeSwitchNames[f.shape()]) + 1; } else { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << '\\' << LaTeXShapeCommandNames[f.shape()] << '{'; @@ -359,6 +438,13 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams, os << '}'; ++count; } else if (f.color() != Color_none) { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << "\\textcolor{" << from_ascii(lcolor.getLaTeXName(f.color())) << "}{"; @@ -396,11 +482,25 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams, } } if (f.emph() == FONT_ON) { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << "\\emph{"; count += 6; } // \noun{} is a LyX special macro if (f.noun() == FONT_ON) { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << "\\noun{"; count += 6; } @@ -408,23 +508,51 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams, // because ulem puts every nested group or macro in a box, // which prevents linebreaks (#8424, #8733) if (f.underbar() == FONT_ON) { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << "\\uline{"; - count += 10; + count += 7; ++runparams.inulemcmd; } if (f.uuline() == FONT_ON) { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << "\\uuline{"; - count += 11; + count += 8; ++runparams.inulemcmd; } if (f.strikeout() == FONT_ON) { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << "\\sout{"; - count += 9; + count += 6; ++runparams.inulemcmd; } if (f.xout() == FONT_ON) { + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << "\\xout{"; - count += 9; + count += 6; ++runparams.inulemcmd; } if (f.uwave() == FONT_ON) { @@ -434,8 +562,15 @@ int Font::latexWriteStartChanges(otexstream & os, BufferParams const & bparams, os << "\\ULdepth=1000pt"; count += 15; } + if (needs_cprotection) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; + os << "\\cprotect"; + count += 9; + } os << "\\uwave{"; - count += 10; + count += 7; ++runparams.inulemcmd; } return count; diff --git a/src/Font.h b/src/Font.h index 5d8998a83e..9b08c8387c 100644 --- a/src/Font.h +++ b/src/Font.h @@ -76,7 +76,8 @@ public: OutputParams const & runparams, Font const & base, Font const & prev, - bool const & non_inherit_inset = false) const; + bool const & non_inherit_inset = false, + bool const & needs_cprotection = false) const; /** Writes the tail of the LaTeX needed to change to this font. Returns number of chars written. Base is the font state we want diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 8da3d13fc1..58feaf4f25 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -1044,7 +1044,8 @@ void Paragraph::Private::latexInset(BufferParams const & bparams, || basefont.isRightToLeft() == running_font.isRightToLeft(); unsigned int count = running_font.latexWriteStartChanges(os, bparams, runparams, basefont, - running_font, true); + running_font, true, + owner_->needsCProtection(runparams.moving_arg)); column += count; // if any font properties were closed, update the running_font, // making sure, however, to leave the language as it was @@ -2659,7 +2660,8 @@ void Paragraph::latex(BufferParams const & bparams, otexstringstream ots; if (!non_inherit_inset) { column += current_font.latexWriteStartChanges(ots, bparams, - runparams, basefont, last_font); + runparams, basefont, last_font, false, + needsCProtection(runparams.moving_arg)); } // Check again for display math in ulem commands as a // font change may also occur just before a math inset.