commit 7e3494c293b94e1f7bc80915da0f9b49fd0e0ccc
Author: Enrico Forestieri <for...@lyx.org>
Date:   Tue Sep 27 23:00:29 2016 +0200

    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 95d015b..d4de17a 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 4e40b6f..b6ed0ce 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<lang> 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 71af322..fdbc38f 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<lang> 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.
  */

Reply via email to