X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Foutput_latex.cpp;h=4124d2dd1c92fde9f5cf08cb62ca29808ed1277f;hb=b5722962fb0393299e02df0b146522770e98aef6;hp=7a8bf24c665c4370edcf9e0c8ea05aa74d37389e;hpb=130c7440696bf3c246636b1dabceb65827293ba4;p=lyx.git diff --git a/src/output_latex.cpp b/src/output_latex.cpp index 7a8bf24c66..4124d2dd1c 100644 --- a/src/output_latex.cpp +++ b/src/output_latex.cpp @@ -679,8 +679,12 @@ void parStartCommand(Paragraph const & par, otexstream & os, { switch (style.latextype) { case LATEX_COMMAND: - if (par.needsCProtection(runparams.moving_arg)) + if (par.needsCProtection(runparams.moving_arg)) { + if (contains(runparams.active_chars, '^')) + // cprotect relies on ^ being on catcode 7 + os << "\\begingroup\\catcode`\\^=7"; os << "\\cprotect"; + } os << '\\' << from_ascii(style.latexname()); // Command arguments @@ -776,7 +780,7 @@ void TeXOnePar(Buffer const & buf, Paragraph const * nextpar = runparams.isLastPar ? nullptr : ¶graphs.at(pit + 1); - bool const intitle_command = style.intitle && style.latextype == LATEX_COMMAND; + bool const intitle_command = style.intitle && style.isCommand(); if (style.pass_thru) { Font const outerfont = text.outerFont(pit); @@ -794,8 +798,13 @@ void TeXOnePar(Buffer const & buf, // I did not create a parEndCommand for this minuscule // task because in the other user of parStartCommand // the code is different (JMarc) - if (style.isCommand()) - os << "}\n"; + if (style.isCommand()) { + os << "}"; + if (par.needsCProtection(runparams.moving_arg) + && contains(runparams.active_chars, '^')) + os << "\\endgroup"; + os << "\n"; + } else os << '\n'; if (!style.parbreak_is_newline) { @@ -838,14 +847,31 @@ void TeXOnePar(Buffer const & buf, && priorpar->layout().isEnvironment() && (priorpar->getDepth() > par.getDepth() || (priorpar->getDepth() == par.getDepth() - && priorpar->layout() != par.layout())); + && priorpar->layout() != par.layout())); + + // We need to ignore previous intitle commands since languages + // are switched locally there (# 11514) + // There might be paragraphs before the title, so we check this. + Paragraph * prior_nontitle_par = nullptr; + if (!intitle_command) { + pit_type ppit = pit; + while (ppit > 0) { + --ppit; + Paragraph const * tmppar = ¶graphs.at(ppit); + if (tmppar->layout().intitle && tmppar->layout().isCommand()) + continue; + prior_nontitle_par = const_cast(tmppar); + break; + } + } Language const * const prev_language = - runparams_in.for_search ? - languages.getLanguage("ignore") - :(priorpar && !priorpar->isPassThru()) - ? (use_prev_env_language ? state->prev_env_language_ - : priorpar->getParLanguage(bparams)) - : outer_language; + runparams_in.for_search + ? languages.getLanguage("ignore") + : (prior_nontitle_par && !prior_nontitle_par->isPassThru()) + ? (use_prev_env_language + ? state->prev_env_language_ + : prior_nontitle_par->getParLanguage(bparams)) + : outer_language; bool const use_polyglossia = runparams.use_polyglossia; string const par_lang = use_polyglossia ? @@ -970,7 +996,7 @@ void TeXOnePar(Buffer const & buf, if ((runparams.encoding->package() != Encoding::CJK || bparams.useNonTeXFonts || runparams.for_search) - && (par_lang != openLanguageName(state) || localswitch) + && (par_lang != openLanguageName(state) || localswitch || intitle_command) && !par_lang.empty()) { string bc = use_polyglossia ? getPolyglossiaBegin(lang_begin_command, par_lang, @@ -1116,6 +1142,9 @@ void TeXOnePar(Buffer const & buf, os << runparams.post_macro; runparams.post_macro.clear(); } + if (par.needsCProtection(runparams.moving_arg) + && contains(runparams.active_chars, '^')) + os << "\\endgroup"; if (runparams.encoding != prev_encoding) { runparams.encoding = prev_encoding; os << setEncoding(prev_encoding->iconvName()); @@ -1270,20 +1299,21 @@ void TeXOnePar(Buffer const & buf, // InTitle commands need to be closed after the language has been closed. if (intitle_command) { - if (is_command) { - 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()); - } + 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 (par.needsCProtection(runparams.moving_arg) + && contains(runparams.active_chars, '^')) + os << "\\endgroup"; + if (runparams.encoding != prev_encoding) { + runparams.encoding = prev_encoding; + os << setEncoding(prev_encoding->iconvName()); } } @@ -1466,7 +1496,8 @@ void latexParagraphs(Buffer const & buf, && runparams.use_CJK)) ) { docstring const cjkenc = bparams.encoding().iconvName() == "UTF-8" - ? from_ascii("UTF8") : from_ascii(bparams.encoding().latexName()); + ? from_ascii("UTF8") + : from_ascii(bparams.encoding().latexName()); os << "\\begin{CJK}{" << cjkenc << "}{" << from_ascii(bparams.fonts_cjk) << "}%\n"; state->open_encoding_ = CJK; @@ -1604,8 +1635,10 @@ void latexParagraphs(Buffer const & buf, // if "auto end" is switched off, explicitly close the language at the end // but only if the last par is in a babel or polyglossia language + Language const * const lastpar_language = + paragraphs.at(lastpit).getParLanguage(bparams); if (maintext && !lyxrc.language_auto_end && !mainlang.empty() && - paragraphs.at(lastpit).getParLanguage(bparams)->encoding()->package() != Encoding::CJK) { + lastpar_language->encoding()->package() != Encoding::CJK) { os << from_utf8(subst(lang_end_command, "$$lang", mainlang)) @@ -1621,12 +1654,14 @@ void latexParagraphs(Buffer const & buf, state->open_encoding_ = none; } // Likewise for polyglossia or when using begin/end commands - // or after an active branch inset with a language switch + // or at the very end of an active branch inset with a language switch Language const * const outer_language = (runparams.local_font != nullptr) ? runparams.local_font->language() : bparams.language; string const & prev_lang = runparams.use_polyglossia ? getPolyglossiaEnvName(outer_language) : outer_language->babel(); + string const lastpar_lang = runparams.use_polyglossia ? + getPolyglossiaEnvName(lastpar_language): lastpar_language->babel(); string const & cur_lang = openLanguageName(state); if (((runparams.inbranch && langOpenedAtThisLevel(state) && prev_lang != cur_lang) || (maintext && !is_child)) && !cur_lang.empty()) { @@ -1636,7 +1671,11 @@ void latexParagraphs(Buffer const & buf, << '\n'; if (using_begin_end) popLanguageName(); - } else if (runparams.inbranch && !using_begin_end && prev_lang != cur_lang) { + } else if (runparams.inbranch && !using_begin_end + && prev_lang != lastpar_lang && !lastpar_lang.empty()) { + // with !using_begin_end, cur_lang is empty, so we need to + // compare against the paragraph language (and we are in the + // last paragraph at this point) os << subst(lang_begin_command, "$$lang", prev_lang) << '\n'; }