From d08f3a6456dcbf699d8ee5bfb17c0a3ed0c25463 Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Wed, 14 Aug 2019 13:10:42 +0200 Subject: [PATCH] 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 54111cd706..65e2d33b5d 100644 --- a/lib/languages +++ b/lib/languages @@ -10,6 +10,7 @@ # BabelName # PolyglossiaName # PolyglossiaOpts "" +# ActiveChars # QuoteStyle # DateFormats "||" @@ -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 b6d09a954c..4f770f18a4 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> const bibfiles = diff --git a/src/LaTeXFeatures.cpp b/src/LaTeXFeatures.cpp index cd9db06930..7a74291b75 100644 --- a/src/LaTeXFeatures.cpp +++ b/src/LaTeXFeatures.cpp @@ -885,6 +885,20 @@ set 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 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 a902c4a7b2..235f4df8c4 100644 --- a/src/LaTeXFeatures.h +++ b/src/LaTeXFeatures.h @@ -134,6 +134,8 @@ public: /// std::set getPolyglossiaLanguages() const; /// + std::string getActiveChars() const; + /// std::set getEncodingSet(std::string const & doc_encoding) const; /// void getFontEncodings(std::vector & encodings, diff --git a/src/Language.cpp b/src/Language.cpp index 799abca1ba..97a17880c1 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 0445503d9a..687682821a 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 fb8cea3831..201d0915a9 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 c6be423648..11fc934a45 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 columns) const +void Tabular::TeXTopHLine(otexstream & os, row_type row, list 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 columns) const +void Tabular::TeXBottomHLine(otexstream & os, row_type row, list 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 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(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 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 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 fac2660fe6..17e05d75dd 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) const; + void TeXTopHLine(otexstream &, row_type row, std::list) const; /// - void TeXBottomHLine(otexstream &, row_type row, std::string const & lang, - std::list) const; + void TeXBottomHLine(otexstream &, row_type row, std::list) const; /// void TeXCellPreamble(otexstream &, idx_type cell, bool & ismulticol, bool & ismultirow, bool const bidi) const; -- 2.39.5