From 7e3494c293b94e1f7bc80915da0f9b49fd0e0ccc Mon Sep 17 00:00:00 2001 From: Enrico Forestieri Date: Tue, 27 Sep 2016 23:00:29 +0200 Subject: [PATCH] Also track local language switches Until now this was not done for essentially two reasons. The first one is that local switches are used for short text insertions, so that they are unlikely crossing environment boundaries. The second one is that if we have to close a language at the end of an environment we would be missing the right termination command. As this last issue can be overcome by simply storing in the stack the current nest level with a sign denoting the kind of switch, there is no reason anymore not to track also local languages switches. Also factor out some commonly used constructs in order to improve readability. --- src/Font.cpp | 2 +- src/output_latex.cpp | 102 +++++++++++++++++++++---------------------- src/output_latex.h | 3 +- 3 files changed, 54 insertions(+), 53 deletions(-) diff --git a/src/Font.cpp b/src/Font.cpp index 95d015b867..d4de17a5d3 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -287,7 +287,7 @@ int Font::latexWriteStartChanges(odocstream & os, BufferParams const & bparams, tmp += "{"; os << from_ascii(tmp); count += tmp.length(); - pushPolyglossiaLang(language()->polyglossia()); + pushPolyglossiaLang(language()->polyglossia(), true); } else if (language()->encoding()->package() != Encoding::CJK) { os << '{'; count += 1; diff --git a/src/output_latex.cpp b/src/output_latex.cpp index 4e40b6f3c7..b6ed0cec18 100644 --- a/src/output_latex.cpp +++ b/src/output_latex.cpp @@ -107,7 +107,25 @@ bool atSameLastLangSwitchDepth(OutputState const * state) return state->lang_switch_depth_.size() == 0 ? true - : state->lang_switch_depth_.top() == state->nest_level_; + : abs(state->lang_switch_depth_.top()) == state->nest_level_; +} + + +bool isLocalSwitch(OutputState const * state) +{ + // Return true if the language was opened by the \text command. + + return state->lang_switch_depth_.size() + && state->lang_switch_depth_.top() < 0; +} + + +bool langOpenedAtThisLevel(OutputState const * state) +{ + // Return true if the language was opened at the current nesting level. + + return state->lang_switch_depth_.size() + && abs(state->lang_switch_depth_.top()) == state->nest_level_; } @@ -204,10 +222,8 @@ static TeXEnvironmentData prepareEnvironment(Buffer const & buf, prev_par_lang)) // the '%' is necessary to prevent unwanted whitespace << "%\n"; - if (use_polyglossia) { - state->lang_switch_depth_.pop(); - state->open_polyglossia_lang_.pop(); - } + if (use_polyglossia) + popPolyglossiaLang(); } // If no language was explicitly opened and we are using @@ -229,10 +245,8 @@ static TeXEnvironmentData prepareEnvironment(Buffer const & buf, os << bc; // the '%' is necessary to prevent unwanted whitespace os << "%\n"; - if (use_polyglossia) { - state->lang_switch_depth_.push(state->nest_level_); - state->open_polyglossia_lang_.push(par_lang); - } + if (use_polyglossia) + pushPolyglossiaLang(par_lang); } } @@ -298,13 +312,15 @@ static void finishEnvironment(otexstream & os, OutputParams const & runparams, os << breakln; // Close any polyglossia language opened at this nest level if (runparams.use_polyglossia) { - OutputState * state = getOutputState(); - while (state->lang_switch_depth_.size() - && state->lang_switch_depth_.top() == state->nest_level_) { - os << "\\end{" << openPolyglossiaLang(state) - << "}%\n"; - state->lang_switch_depth_.pop(); - state->open_polyglossia_lang_.pop(); + while (langOpenedAtThisLevel(state)) { + if (isLocalSwitch(state)) { + os << "}"; + } else { + os << "\\end{" + << openPolyglossiaLang(state) + << "}%\n"; + } + popPolyglossiaLang(); } } state->nest_level_ -= 1; @@ -486,11 +502,12 @@ void getArgInsets(otexstream & os, OutputParams const & runparams, Layout::LaTeX } // namespace anon -void pushPolyglossiaLang(string const & lang_name) +void pushPolyglossiaLang(string const & lang_name, bool localswitch) { OutputState * state = getOutputState(); - state->lang_switch_depth_.push(state->nest_level_); + int nest_level = localswitch ? -state->nest_level_ : state->nest_level_; + state->lang_switch_depth_.push(nest_level); state->open_polyglossia_lang_.push(lang_name); } @@ -790,10 +807,8 @@ void TeXOnePar(Buffer const & buf, "$$lang", prev_lang)) << lang_command_termination; - if (use_polyglossia && !localswitch) { - state->lang_switch_depth_.pop(); - state->open_polyglossia_lang_.pop(); - } + if (use_polyglossia) + popPolyglossiaLang(); } // We need to open a new language if we couldn't close the previous @@ -850,10 +865,8 @@ void TeXOnePar(Buffer const & buf, : subst(lang_begin_command, "$$lang", par_lang); os << bc; os << lang_command_termination; - if (use_polyglossia && !localswitch) { - state->lang_switch_depth_.push(state->nest_level_); - state->open_polyglossia_lang_.push(par_lang); - } + if (use_polyglossia) + pushPolyglossiaLang(par_lang, localswitch); } } } @@ -912,10 +925,8 @@ void TeXOnePar(Buffer const & buf, "$$lang", par_lang)) << lang_command_termination; - if (use_polyglossia && !localswitch) { - state->lang_switch_depth_.push(state->nest_level_); - state->open_polyglossia_lang_.push(par_lang); - } + if (use_polyglossia) + pushPolyglossiaLang(par_lang, localswitch); } runparams.encoding = encoding; } @@ -1081,11 +1092,8 @@ void TeXOnePar(Buffer const & buf, os << bc; pending_newline = !localswitch; unskip_newline = !localswitch; - if (use_polyglossia && !localswitch) { - state->lang_switch_depth_.push( - state->nest_level_); - state->open_polyglossia_lang_.push(current_lang); - } + if (use_polyglossia) + pushPolyglossiaLang(current_lang, localswitch); } } else if (!par_lang.empty()) { // If we are in an environment, we have to close the "outer" language afterwards @@ -1110,10 +1118,8 @@ void TeXOnePar(Buffer const & buf, par_lang)); pending_newline = !localswitch; unskip_newline = !localswitch; - if (use_polyglossia && !localswitch) { - state->lang_switch_depth_.pop(); - state->open_polyglossia_lang_.pop(); - } + if (use_polyglossia) + popPolyglossiaLang(); } } } @@ -1291,10 +1297,8 @@ void latexParagraphs(Buffer const & buf, : subst(lang_begin_command, "$$lang", mainlang); os << bc; os << '\n'; - if (runparams.use_polyglossia) { - state->lang_switch_depth_.push(state->nest_level_); - state->open_polyglossia_lang_.push(mainlang); - } + if (runparams.use_polyglossia) + pushPolyglossiaLang(mainlang); } ParagraphList const & paragraphs = text.paragraphs(); @@ -1399,10 +1403,8 @@ void latexParagraphs(Buffer const & buf, "$$lang", mainlang)) << '\n'; - if (runparams.use_polyglossia) { - state->lang_switch_depth_.pop(); - state->open_polyglossia_lang_.pop(); - } + if (runparams.use_polyglossia) + popPolyglossiaLang(); } // If the last paragraph is an environment, we'll have to close @@ -1418,10 +1420,8 @@ void latexParagraphs(Buffer const & buf, "$$lang", pol_lang)) << '\n'; - if (runparams.use_polyglossia) { - state->lang_switch_depth_.pop(); - state->open_polyglossia_lang_.pop(); - } + if (runparams.use_polyglossia) + popPolyglossiaLang(); } // reset inherited encoding diff --git a/src/output_latex.h b/src/output_latex.h index 71af3221c9..fdbc38febb 100644 --- a/src/output_latex.h +++ b/src/output_latex.h @@ -30,8 +30,9 @@ class OutputParams; class Text; /** Register a language switch when using polyglossia. + Set \p localswitch to true if the \text command is used. */ -void pushPolyglossiaLang(std::string const & lang); +void pushPolyglossiaLang(std::string const & lang, bool localswitch = false); /** Unregister the last language switch when using polyglossia. */ -- 2.39.2