commit ce447e1760b8503033a00567983aa3690cd92a5e
Author: Juergen Spitzmueller <sp...@lyx.org>
Date:   Wed Aug 14 13:10:42 2019 +0200

    Deactivate active - in tables with \cline or \cmidrule
    
    This introduces a new languages tag ActiveChar which also can be used
    for similar cases.
---
 lib/languages               |    6 ++
 src/Buffer.cpp              |    3 +
 src/LaTeXFeatures.cpp       |   14 +++++
 src/LaTeXFeatures.h         |    2 +
 src/Language.cpp            |    7 ++-
 src/Language.h              |    4 ++
 src/OutputParams.h          |    3 +
 src/insets/InsetTabular.cpp |  112 ++++++++++++++++++++++++-------------------
 src/insets/InsetTabular.h   |    6 +--
 9 files changed, 102 insertions(+), 55 deletions(-)

diff --git a/lib/languages b/lib/languages
index 54111cd..65e2d33 100644
--- a/lib/languages
+++ b/lib/languages
@@ -10,6 +10,7 @@
 #      BabelName          <babelname>
 #      PolyglossiaName    <polyglossianame>
 #      PolyglossiaOpts    "<language-specific options>"
+#      ActiveChars        <activated characters>
 #      QuoteStyle         <british|danish|english|french|frenchin|
 #                           german|polish|russian|swedish|swedishg|swiss|plain>
 #      DateFormats        "<long>|<medium>|<short>"
@@ -119,6 +120,9 @@
 # * Provides lists features that are provided by specific Babel languages,
 #   but are available globally if this language is used (not only for this
 #   language. Examples are \textgreek (Greek) and \textcyrillic (Russian).
+# * ActiveChars provides a string of the characters that are made active
+#   by the language. We record particularly those characters that have to 
+#   be de-activated in some contexts (such as - or =).
 #
 ##########################################################################
 
@@ -562,6 +566,7 @@ Language czech
        BabelName        czech
        PolyglossiaName  czech
        QuoteStyle       german
+       ActiveChars      -
        Encoding         iso8859-2
        FontEncoding     T1|OT1
        DateFormats      "d. MMMM yyyy|d. MMM. yyyy|d.M.yyyy"
@@ -1331,6 +1336,7 @@ Language slovak
        BabelName        slovak
        PolyglossiaName  slovak
        QuoteStyle       german
+       ActiveChars      -
        Encoding         iso8859-2
        FontEncoding     T1|OT1
        DateFormats      "d. MMMM yyyy|d. MMM yyyy|d.M.yyyy"
diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index b6d09a9..4f770f1 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -1968,6 +1968,9 @@ Buffer::ExportStatus Buffer::writeLaTeXSource(otexstream 
& os,
                runparams.use_babel = params().writeLaTeX(os, features,
                                                          
d->filename.onlyPath());
 
+               // Active characters
+               runparams.active_chars = features.getActiveChars();
+
                // Biblatex bibliographies are loaded here
                if (params().useBiblatex()) {
                        vector<pair<docstring, string>> const bibfiles =
diff --git a/src/LaTeXFeatures.cpp b/src/LaTeXFeatures.cpp
index cd9db06..7a74291 100644
--- a/src/LaTeXFeatures.cpp
+++ b/src/LaTeXFeatures.cpp
@@ -885,6 +885,20 @@ set<string> LaTeXFeatures::getPolyglossiaLanguages() const
 }
 
 
+string LaTeXFeatures::getActiveChars() const
+{
+       string res;
+       // first the main language
+       res += params_.language->activeChars();
+       // now the secondary languages
+       LanguageList::const_iterator const begin = UsedLanguages_.begin();
+       for (LanguageList::const_iterator cit = begin;
+            cit != UsedLanguages_.end(); ++cit)
+               res += ((*cit)->activeChars());
+       return res;
+}
+
+
 set<string> LaTeXFeatures::getEncodingSet(string const & doc_encoding) const
 {
        // This does only find encodings of languages supported by babel, but
diff --git a/src/LaTeXFeatures.h b/src/LaTeXFeatures.h
index a902c4a..235f4df 100644
--- a/src/LaTeXFeatures.h
+++ b/src/LaTeXFeatures.h
@@ -134,6 +134,8 @@ public:
        ///
        std::set<std::string> getPolyglossiaLanguages() const;
        ///
+       std::string getActiveChars() const;
+       ///
        std::set<std::string> getEncodingSet(std::string const & doc_encoding) 
const;
        ///
        void getFontEncodings(std::vector<std::string> & encodings,
diff --git a/src/Language.cpp b/src/Language.cpp
index 799abca..97a1788 100644
--- a/src/Language.cpp
+++ b/src/Language.cpp
@@ -146,11 +146,13 @@ bool Language::readLanguage(Lexer & lex)
                LA_REQUIRES,
                LA_QUOTESTYLE,
                LA_RTL,
-               LA_WORDWRAP
+               LA_WORDWRAP,
+               LA_ACTIVECHARS
        };
 
        // Keep these sorted alphabetically!
        LexerKeyword languageTags[] = {
+               { "activechars",          LA_ACTIVECHARS },
                { "babelname",            LA_BABELNAME },
                { "dateformats",          LA_DATEFORMATS },
                { "encoding",             LA_ENCODING },
@@ -207,6 +209,9 @@ bool Language::readLanguage(Lexer & lex)
                case LA_QUOTESTYLE:
                        lex >> quote_style_;
                        break;
+               case LA_ACTIVECHARS:
+                       lex >> active_chars_;
+                       break;
                case LA_ENCODING:
                        lex >> encodingStr_;
                        break;
diff --git a/src/Language.h b/src/Language.h
index 0445503..6876828 100644
--- a/src/Language.h
+++ b/src/Language.h
@@ -52,6 +52,8 @@ public:
        bool isBabelExclusive() const;
        /// quotation marks style
        std::string const quoteStyle() const { return quote_style_; }
+       /// active characters
+       std::string const activeChars() const { return active_chars_; }
        /// requirement (package, function)
        std::string const requires() const { return requires_; }
        /// provides feature
@@ -117,6 +119,8 @@ private:
        ///
        trivstring quote_style_;
        ///
+       trivstring active_chars_;
+       ///
        trivstring requires_;
        ///
        trivstring provides_;
diff --git a/src/OutputParams.h b/src/OutputParams.h
index fb8cea3..201d091 100644
--- a/src/OutputParams.h
+++ b/src/OutputParams.h
@@ -134,6 +134,9 @@ public:
         */
        mutable Language const * master_language;
 
+       /// Active characters
+       std::string active_chars;
+
        /** Current stream encoding. Only used for LaTeX.
            This must be set to the document encoding (via the constructor)
            before output starts. Afterwards it must be kept up to date for
diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp
index c6be423..11fc934 100644
--- a/src/insets/InsetTabular.cpp
+++ b/src/insets/InsetTabular.cpp
@@ -2382,8 +2382,7 @@ bool Tabular::isPartOfMultiRow(row_type row, col_type 
column) const
 }
 
 
-void Tabular::TeXTopHLine(otexstream & os, row_type row, string const & lang,
-                         list<col_type> columns) const
+void Tabular::TeXTopHLine(otexstream & os, row_type row, list<col_type> 
columns) const
 {
        // we only output complete row lines and the 1st row here, the rest
        // is done in Tabular::TeXBottomHLine(...)
@@ -2474,20 +2473,10 @@ void Tabular::TeXTopHLine(otexstream & os, row_type 
row, string const & lang,
                                    && toprtrims.find(c)->second)
                                        trim += "r";
 
-                               //babel makes the "-" character an active one, 
so we have to suppress this here
-                               //see 
http://groups.google.com/group/comp.text.tex/browse_thread/thread/af769424a4a0f289#
-                               if (lang == "slovak" || lang == "czech") {
-                                       os << "\\expandafter" << cline;
-                                       if (!trim.empty())
-                                               os << "(" << trim << ")";
-                                       os << "\\expandafter{\\expandafter" << 
firstcol << "\\string-";
-                               } else {
-                                       os << cline;
-                                       if (!trim.empty())
-                                               os << "(" << trim << ")";
-                                       os << "{" << firstcol << '-';
-                               }
-                               os << lastcol << "}";
+                               os << cline;
+                               if (!trim.empty())
+                                       os << "(" << trim << ")";
+                               os << "{" << firstcol << '-' << lastcol << "}";
                                if (c == ncols() - 1)
                                        break;
                                ++c;
@@ -2498,8 +2487,7 @@ void Tabular::TeXTopHLine(otexstream & os, row_type row, 
string const & lang,
 }
 
 
-void Tabular::TeXBottomHLine(otexstream & os, row_type row, string const & 
lang,
-                            list<col_type> columns) const
+void Tabular::TeXBottomHLine(otexstream & os, row_type row, list<col_type> 
columns) const
 {
        // we output bottomlines of row r and the toplines of row r+1
        // if the latter do not span the whole tabular
@@ -2610,20 +2598,10 @@ void Tabular::TeXBottomHLine(otexstream & os, row_type 
row, string const & lang,
                                    && bottomrtrims.find(c)->second)
                                        trim += "r";
 
-                               //babel makes the "-" character an active one, 
so we have to suppress this here
-                               //see 
http://groups.google.com/group/comp.text.tex/browse_thread/thread/af769424a4a0f289#
-                               if (lang == "slovak" || lang == "czech") {
-                                       os << "\\expandafter" << cline;
-                                       if (!trim.empty())
-                                               os << "(" << trim << ")";
-                                       os << "\\expandafter{\\expandafter" << 
firstcol << "\\string-";
-                               } else {
-                                       os << cline;
-                                       if (!trim.empty())
-                                               os << "(" << trim << ")";
-                                       os << "{" << firstcol << '-';
-                               }
-                               os << lastcol << "}";
+                               os << cline;
+                               if (!trim.empty())
+                                       os << "(" << trim << ")";
+                               os << "{" << firstcol << '-' << lastcol << "}";
                                if (c == ncols() - 1)
                                        break;
                                ++c;
@@ -2917,12 +2895,9 @@ void Tabular::TeXRow(otexstream & os, row_type row,
                     list<col_type> columns) const
 {
        idx_type cell = cellIndex(row, 0);
-       InsetTableCell const * cinset = cellInset(cell);
-       Paragraph const & cpar = cinset->paragraphs().front();
-       string const clang = cpar.getParLanguage(buffer().params())->lang();
 
        //output the top line
-       TeXTopHLine(os, row, clang, columns);
+       TeXTopHLine(os, row, columns);
 
        if (row_info[row].top_space_default) {
                if (use_booktabs)
@@ -3070,7 +3045,7 @@ void Tabular::TeXRow(otexstream & os, row_type row,
        os << '\n';
 
        //output the bottom line
-       TeXBottomHLine(os, row, clang, columns);
+       TeXBottomHLine(os, row, columns);
 
        if (row_info[row].interline_space_default) {
                if (use_booktabs)
@@ -3113,6 +3088,52 @@ void Tabular::latex(otexstream & os, OutputParams const 
& runparams) const
                        os << "\\begin{turn}{" << convert<string>(rotate) << 
"}\n";
        }
 
+       // The bidi package (loaded by polyglossia with XeTeX) swaps the column
+       // order for RTL (#9686). Thus we use this list.
+       bool const bidi_rtl =
+               runparams.local_font->isRightToLeft()
+               && runparams.useBidiPackage();
+       list<col_type> columns;
+       for (col_type cl = 0; cl < ncols(); ++cl) {
+               if (bidi_rtl)
+                       columns.push_front(cl);
+               else
+                       columns.push_back(cl);
+       }
+
+       // If we use \cline or \cmidrule, we need to locally de-activate
+       // the - character when using languages that activate it (e.g., Czech, 
Slovak).
+       bool deactivate_chars = false;
+       if ((runparams.use_babel || runparams.use_polyglossia)
+           && contains(runparams.active_chars, '-')) {
+               bool have_clines = false;
+               // Check if we use \cline or \cmidrule
+               for (row_type row = 0; row < nrows(); ++row) {
+                       col_type bset = 0, tset = 0;
+                       for (auto const & c : columns) {
+                               idx_type const idx = cellIndex(row, c);
+                               if (bottomLineTrim(idx).first || 
bottomLineTrim(idx).second
+                                   || topLineTrim(idx).first || 
topLineTrim(idx).second) {
+                                       have_clines = true;
+                                       break;
+                               }
+                               if (bottomLine(cellIndex(row, c)))
+                                       ++bset;
+                               if (topLine(cellIndex(row, c)))
+                                       ++tset;
+                       }
+                       if ((bset > 0 && bset < ncols()) || (tset > 0 && tset < 
ncols())) {
+                               have_clines = true;
+                               break;
+                       }
+               }
+               if (have_clines) {
+                       deactivate_chars = true;
+                       os << "\\begingroup\n"
+                          << "\\catcode`\\-=12\n";
+               }
+       }
+
        if (is_long_tabular) {
                if (is_xltabular)
                        os << "\\begin{xltabular}";
@@ -3163,19 +3184,6 @@ void Tabular::latex(otexstream & os, OutputParams const 
& runparams) const
        if (is_tabular_star)
                os << "@{\\extracolsep{\\fill}}";
 
-       // The bidi package (loaded by polyglossia with XeTeX) swaps the column
-       // order for RTL (#9686). Thus we use this list.
-       bool const bidi_rtl =
-               runparams.local_font->isRightToLeft()
-               && runparams.useBidiPackage();
-       list<col_type> columns;
-       for (col_type cl = 0; cl < ncols(); ++cl) {
-               if (bidi_rtl)
-                       columns.push_front(cl);
-               else
-                       columns.push_back(cl);
-       }
-
        for (auto const & c : columns) {
                if ((bidi_rtl && columnRightLine(c)) || (!bidi_rtl && 
columnLeftLine(c)))
                        os << '|';
@@ -3337,6 +3345,10 @@ void Tabular::latex(otexstream & os, OutputParams const 
& runparams) const
                        os << "\\end{tabular}";
        }
 
+       if (deactivate_chars)
+               // close the group
+               os << "\n\\endgroup\n";
+
        if (rotate != 0) {
                if (is_long_tabular)
                        os << breakln << "\\end{landscape}";
diff --git a/src/insets/InsetTabular.h b/src/insets/InsetTabular.h
index fac2660..17e05d7 100644
--- a/src/insets/InsetTabular.h
+++ b/src/insets/InsetTabular.h
@@ -865,11 +865,9 @@ public:
        ///
        // helper function for Latex
        ///
-       void TeXTopHLine(otexstream &, row_type row, std::string const & lang,
-                        std::list<col_type>) const;
+       void TeXTopHLine(otexstream &, row_type row, std::list<col_type>) const;
        ///
-       void TeXBottomHLine(otexstream &, row_type row, std::string const & 
lang,
-                           std::list<col_type>) const;
+       void TeXBottomHLine(otexstream &, row_type row, std::list<col_type>) 
const;
        ///
        void TeXCellPreamble(otexstream &, idx_type cell, bool & ismulticol, 
bool & ismultirow,
                             bool const bidi) const;

Reply via email to