diff --git a/src/encoding.C b/src/encoding.C index b1a41fd396..2bfb4a8a2f 100644 --- a/src/encoding.C +++ b/src/encoding.C @@ -179,11 +179,8 @@ docstring const Encoding::latexChar(char_type c) const } -void Encoding::validate(char_type c, LaTeXFeatures & features) const +void Encodings::validate(char_type c, LaTeXFeatures & features) { - // Add the preamble stuff even if c can be encoded in this encoding, - // since the inputenc package only maps the code point c to a command, - // it does not make this command available. CharInfoMap::const_iterator const it = unicodesymbols.find(c); if (it != unicodesymbols.end() && !it->second.preamble.empty()) { if (it->second.feature) diff --git a/src/encoding.h b/src/encoding.h index f07fb645a4..61ee7c6811 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -48,9 +48,6 @@ public: * character is returned. */ docstring const latexChar(char_type c) const; - /// Add the preamble snippet needed for the output of latexChar(c) - /// to \p features. - void validate(char_type c, LaTeXFeatures & features) const; private: /// std::string Name_; @@ -123,6 +120,14 @@ public: static char_type transformChar(char_type c, Letter_Form form); /// Is this a combining char? static bool isCombiningChar(char_type c); + /** + * Add the preamble snippet needed for the output of \p c to + * \p features. + * This does not depend on the used encoding, since the inputenc + * package only maps the code point \p c to a command, it does not + * make this command available. + */ + static void validate(char_type c, LaTeXFeatures & features); private: /// diff --git a/src/output_latex.C b/src/output_latex.C index 138d560e2c..f1f43f48a5 100644 --- a/src/output_latex.C +++ b/src/output_latex.C @@ -292,6 +292,33 @@ TeXOnePar(Buffer const & buf, } } + // Switch file encoding if necessary + if (bparams.inputenc == "auto") { + // Look ahead for future encoding changes. + // We try to output them at the beginning of the paragraph, + // since the \inputencoding command is not allowed e.g. in + // sections. + for (pos_type i = 0; i < pit->size(); ++i) { + char_type const c = pit->getChar(i); + if (c < 0x80) + continue; + if (pit->isInset(i)) + break; + // All characters before c are in the ASCII range, and + // c is non-ASCII (but no inset), so change the + // encoding to that required by the language of c. + Encoding const * const encoding = + pit->getFontSettings(bparams, i).language()->encoding(); + if (switchEncoding(os, bparams, false, + *(runparams.encoding), *encoding) > 0) { + runparams.encoding = encoding; + os << '\n'; + texrow.newline(); + } + break; + } + } + // In an inset with unlimited length (all in one row), // don't allow any special options in the paragraph if (!pit->forceDefaultParagraphs()) { @@ -563,13 +590,17 @@ void latexParagraphs(Buffer const & buf, int switchEncoding(odocstream & os, BufferParams const & bparams, - Encoding const & oldEnc, Encoding const & newEnc) + bool moving_arg, Encoding const & oldEnc, + Encoding const & newEnc) { // FIXME thailatex does not support the inputenc package, so we // ignore switches from/to tis620-0 encoding here. This does of // course only work as long as the non-thai text contains ASCII // only, but it is the best we can do. - if ((bparams.inputenc == "auto" || bparams.inputenc == "default") && + // Since the \inputencoding command does not work inside sections + // we ignore the encoding switch also in moving arguments. + if (((bparams.inputenc == "auto" && !moving_arg) || + bparams.inputenc == "default") && oldEnc.name() != newEnc.name() && oldEnc.name() != "ascii" && newEnc.name() != "ascii" && oldEnc.name() != "tis620-0" && newEnc.name() != "tis620-0") { diff --git a/src/output_latex.h b/src/output_latex.h index ca6618c7a7..ef18a081f3 100644 --- a/src/output_latex.h +++ b/src/output_latex.h @@ -45,7 +45,8 @@ void latexParagraphs(Buffer const & buf, /// Switch the encoding of \p os from \p oldEnc to \p newEnc if needed. /// \return the number of characters written to \p os. int switchEncoding(odocstream & os, BufferParams const & bparams, - Encoding const & oldEnc, Encoding const & newEnc); + bool moving_arg, Encoding const & oldEnc, + Encoding const & newEnc); } // namespace lyx diff --git a/src/paragraph.C b/src/paragraph.C index 0e3cb22475..22626a73a5 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -1007,9 +1007,6 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, runparams.moving_arg); } - // Computed only once per paragraph since bparams.encoding() is expensive - Encoding const & doc_encoding = bparams.encoding(); - for (pos_type i = 0; i < size(); ++i) { // First char in paragraph or after label? if (i == body_pos) { @@ -1076,7 +1073,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, // Switch file encoding if necessary int const count = switchEncoding(os, bparams, - *(runparams.encoding), + runparams.moving_arg, *(runparams.encoding), *(font.language()->encoding())); if (count > 0) { column += count; @@ -1101,7 +1098,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, // style->pass_thru is false. if (i != body_pos - 1) { if (pimpl_->simpleTeXBlanks(bparams, - doc_encoding, os, texrow, + *(runparams.encoding), os, texrow, i, column, font, *style)) // A surrogate pair was output. We // must not call simpleTeXSpecialChars @@ -1117,7 +1114,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, rp.free_spacing = style->free_spacing; rp.local_font = &font; rp.intitle = style->intitle; - pimpl_->simpleTeXSpecialChars(buf, bparams, doc_encoding, os, + pimpl_->simpleTeXSpecialChars(buf, bparams, os, texrow, rp, running_font, basefont, outerfont, open_font, runningChangeType, *style, i, column, c); diff --git a/src/paragraph_pimpl.C b/src/paragraph_pimpl.C index 5512635377..70b21edfe6 100644 --- a/src/paragraph_pimpl.C +++ b/src/paragraph_pimpl.C @@ -58,18 +58,6 @@ special_phrase const special_phrases[] = { size_t const phrases_nr = sizeof(special_phrases)/sizeof(special_phrase); - -/// Get the real encoding of a character with font \p font. -/// doc_encoding == bparams.encoding(), but we use a precomputed variable -/// since bparams.encoding() is expensive -inline Encoding const & getEncoding(BufferParams const & bparams, - Encoding const & doc_encoding, LyXFont const & font) -{ - if (bparams.inputenc == "auto" || bparams.inputenc == "default") - return *(font.language()->encoding()); - return doc_encoding; -} - } // namespace anon @@ -398,7 +386,7 @@ int Paragraph::Pimpl::latexSurrogatePair(odocstream & os, value_type c, bool Paragraph::Pimpl::simpleTeXBlanks(BufferParams const & bparams, - Encoding const & doc_encoding, + Encoding const & encoding, odocstream & os, TexRow & texrow, pos_type & i, unsigned int & column, @@ -412,7 +400,6 @@ bool Paragraph::Pimpl::simpleTeXBlanks(BufferParams const & bparams, char_type next = getChar(i + 1); if (Encodings::isCombiningChar(next)) { // This space has an accent, so we must always output it. - Encoding const & encoding = getEncoding(bparams, doc_encoding, font); column += latexSurrogatePair(os, ' ', next, encoding) - 1; ++i; return true; @@ -478,7 +465,6 @@ bool Paragraph::Pimpl::isTextAt(string const & str, pos_type pos) const void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf, BufferParams const & bparams, - Encoding const & doc_encoding, odocstream & os, TexRow & texrow, OutputParams const & runparams, @@ -738,8 +724,7 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf, } if (pnr == phrases_nr && c != '\0') { - Encoding const & encoding = - getEncoding(bparams, doc_encoding, running_font); + Encoding const & encoding = *(runparams.encoding); if (i < size() - 1) { char_type next = getChar(i + 1); if (Encodings::isCombiningChar(next)) { @@ -837,7 +822,6 @@ void Paragraph::Pimpl::validate(LaTeXFeatures & features, } // then the contents - Encoding const & doc_encoding = bparams.encoding(); for (pos_type i = 0; i < size() ; ++i) { for (size_t pnr = 0; pnr < phrases_nr; ++pnr) { if (!special_phrases[pnr].builtin @@ -846,12 +830,7 @@ void Paragraph::Pimpl::validate(LaTeXFeatures & features, break; } } - // We do not need the completely realized font, since we are - // only interested in the language, and that is never inherited. - // Therefore we can use getFontSettings instead of getFont. - LyXFont const & font = owner_->getFontSettings(bparams, i); - Encoding const & encoding = getEncoding(bparams, doc_encoding, font); - encoding.validate(getChar(i), features); + Encodings::validate(getChar(i), features); } } diff --git a/src/paragraph_pimpl.h b/src/paragraph_pimpl.h index df899b695d..7d4aba0c58 100644 --- a/src/paragraph_pimpl.h +++ b/src/paragraph_pimpl.h @@ -139,7 +139,7 @@ public: LyXLayout const & style); /// void simpleTeXSpecialChars(Buffer const &, BufferParams const &, - Encoding const &, odocstream &, + odocstream &, TexRow & texrow, OutputParams const &, LyXFont & running_font, LyXFont & basefont,