From: Enrico Forestieri Date: Sun, 30 Oct 2011 22:40:03 +0000 (+0000) Subject: Fix bug #7800 (Lyx cannot create dvi with Russian) X-Git-Tag: 2.0.2~81 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=3f691d1f55f214b57098c2e267fb5fc744e3a1bc;p=features.git Fix bug #7800 (Lyx cannot create dvi with Russian) git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_2_0_X@40107 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/LaTeXFeatures.cpp b/src/LaTeXFeatures.cpp index 2cfc1ce6e2..da17de0d41 100644 --- a/src/LaTeXFeatures.cpp +++ b/src/LaTeXFeatures.cpp @@ -1159,11 +1159,24 @@ docstring const LaTeXFeatures::getTClassHTMLStyles() const { namespace { -docstring const getFloatI18nPreamble(docstring const & type, docstring const & name, docstring const & lang) +docstring const getFloatI18nPreamble(docstring const & type, + docstring const & name, Language const * lang, + Encoding const & enc, bool const polyglossia) { + docstring const language = polyglossia ? from_ascii(lang->polyglossia()) + : from_ascii(lang->babel()); + docstring const langenc = from_ascii(lang->encoding()->iconvName()); + docstring const texenc = from_ascii(lang->encoding()->latexName()); + docstring const bufenc = from_ascii(enc.iconvName()); + docstring const s1 = docstring(1, 0xF0000); + docstring const s2 = docstring(1, 0xF0001); + docstring const translated = (langenc == bufenc) ? name + : from_ascii("\\inputencoding{") + texenc + from_ascii("}") + + s1 + langenc + s2 + translated + s1 + bufenc + s2; + odocstringstream os; - os << "\\addto\\captions" << lang - << "{\\renewcommand{\\" << type << "name}{" << name << "}}\n"; + os << "\\addto\\captions" << language + << "{\\renewcommand{\\" << type << "name}{" << translated << "}}\n"; return os.str(); } } @@ -1183,13 +1196,19 @@ docstring const LaTeXFeatures::getTClassI18nPreamble(bool use_babel, bool use_po for (; cit != end; ++cit) { // language dependent commands (once per document) snippets.insert(tclass[*cit].langpreamble(buffer().language(), - use_polyglossia)); + buffer().params().encoding(), + use_polyglossia)); // commands for language changing (for multilanguage documents) if ((use_babel || use_polyglossia) && !UsedLanguages_.empty()) { - snippets.insert(tclass[*cit].babelpreamble(buffer().language(), - use_polyglossia)); + snippets.insert(tclass[*cit].babelpreamble( + buffer().language(), + buffer().params().encoding(), + use_polyglossia)); for (lang_it lit = lbeg; lit != lend; ++lit) - snippets.insert(tclass[*cit].babelpreamble(*lit, use_polyglossia)); + snippets.insert(tclass[*cit].babelpreamble( + *lit, + buffer().params().encoding(), + use_polyglossia)); } } if ((use_babel || use_polyglossia) && !UsedLanguages_.empty()) { @@ -1206,14 +1225,11 @@ docstring const LaTeXFeatures::getTClassI18nPreamble(bool use_babel, bool use_po docstring name = buffer().language()->translateLayout(fl.name()); // only request translation if we have a real translation // (that differs from the source) - if (use_polyglossia && flname != name) - snippets.insert(getFloatI18nPreamble( - type, name, - from_ascii(buffer().language()->polyglossia()))); - else if (flname != name) + if (flname != name) snippets.insert(getFloatI18nPreamble( - type, name, - from_ascii(buffer().language()->babel()))); + type, name, buffer().language(), + buffer().params().encoding(), + use_polyglossia)); for (lang_it lit = lbeg; lit != lend; ++lit) { string const code = (*lit)->code(); name = (*lit)->translateLayout(fl.name()); @@ -1224,14 +1240,11 @@ docstring const LaTeXFeatures::getTClassI18nPreamble(bool use_babel, bool use_po // something different to the English source. bool const have_translation = (flname != name || contains(code, "en")); - if (use_polyglossia && have_translation) - snippets.insert(getFloatI18nPreamble( - type, name, - from_ascii((*lit)->polyglossia()))); - else if (have_translation) + if (have_translation) snippets.insert(getFloatI18nPreamble( - type, name, - from_ascii((*lit)->babel()))); + type, name, *lit, + buffer().params().encoding(), + use_polyglossia)); } } } diff --git a/src/Layout.cpp b/src/Layout.cpp index 983c53e7a3..2700752f52 100644 --- a/src/Layout.cpp +++ b/src/Layout.cpp @@ -13,6 +13,7 @@ #include #include "Layout.h" +#include "Encoding.h" #include "FontInfo.h" #include "Language.h" #include "Lexer.h" @@ -863,7 +864,8 @@ void Layout::readSpacing(Lexer & lex) namespace { -docstring const i18npreamble(Language const * lang, docstring const & templ, bool const polyglossia) +docstring const i18npreamble(Language const * lang, Encoding const & enc, + docstring const & templ, bool const polyglossia) { if (templ.empty()) return templ; @@ -876,6 +878,12 @@ docstring const i18npreamble(Language const * lang, docstring const & templ, boo // tex2lyx does not have getMessages() LASSERT(false, /**/); #else + string const langenc = lang->encoding()->iconvName(); + string const texenc = lang->encoding()->latexName(); + string const bufenc = enc.iconvName(); + // First and second character of plane 15 (Private Use Area) + string const s1 = "\xf3\xb0\x80\x80"; // U+F0000 + string const s2 = "\xf3\xb0\x80\x81"; // U+F0001 // FIXME UNICODE // lyx::regex is not unicode-safe. // Should use QRegExp or (boost::u32regex, but that requires ICU) @@ -884,6 +892,10 @@ docstring const i18npreamble(Language const * lang, docstring const & templ, boo while (regex_search(preamble, sub, reg)) { string const key = sub.str(1); string translated = to_utf8(lang->translateLayout(key)); + if (langenc != bufenc) + translated = "\\inputencoding{" + texenc + "}" + + s1 + langenc + s2 + translated + + s1 + bufenc + s2; preamble = subst(preamble, sub.str(), translated); } #endif @@ -893,15 +905,17 @@ docstring const i18npreamble(Language const * lang, docstring const & templ, boo } -docstring const Layout::langpreamble(Language const * lang, bool const polyglossia) const +docstring const Layout::langpreamble(Language const * lang, + Encoding const & enc, bool const polyglossia) const { - return i18npreamble(lang, langpreamble_, polyglossia); + return i18npreamble(lang, enc, langpreamble_, polyglossia); } -docstring const Layout::babelpreamble(Language const * lang, bool const polyglossia) const +docstring const Layout::babelpreamble(Language const * lang, + Encoding const & enc, bool const polyglossia) const { - return i18npreamble(lang, babelpreamble_, polyglossia); + return i18npreamble(lang, enc, babelpreamble_, polyglossia); } diff --git a/src/Layout.h b/src/Layout.h index f957f74730..1db9a23a38 100644 --- a/src/Layout.h +++ b/src/Layout.h @@ -14,6 +14,7 @@ #ifndef LAYOUT_H #define LAYOUT_H +#include "Encoding.h" #include "FontInfo.h" #include "LayoutEnums.h" #include "Spacing.h" @@ -95,10 +96,10 @@ public: docstring const & preamble() const { return preamble_; } /// Get language dependent macro definitions needed for this layout /// for language \p lang - docstring const langpreamble(Language const * lang, bool const polyglossia) const; + docstring const langpreamble(Language const * lang, Encoding const & enc, bool const polyglossia) const; /// Get language and babel dependent macro definitions needed for /// this layout for language \p lang - docstring const babelpreamble(Language const * lang, bool const polyglossia) const; + docstring const babelpreamble(Language const * lang, Encoding const & enc, bool const polyglossia) const; /// std::set const & requires() const { return requires_; } /// diff --git a/src/support/docstream.cpp b/src/support/docstream.cpp index a44c062272..e8839e07f6 100644 --- a/src/support/docstream.cpp +++ b/src/support/docstream.cpp @@ -11,6 +11,7 @@ #include #include "support/docstream.h" +#include "support/lstrings.h" #include "support/unicode.h" #include @@ -23,6 +24,8 @@ using namespace std; using lyx::ucs4_codeset; +using lyx::support::contains; +using lyx::support::split; #if defined(_MSC_VER) && (_MSC_VER >= 1600) @@ -474,7 +477,32 @@ otexstream & operator<<(otexstream & ots, docstring const & s) ots.os() << "{}"; ots.protectSpace(false); } - ots.os() << s; + + if (contains(s, 0xF0000)) { + // Some encoding changes for the underlying stream are embedded + // in the docstring. The encoding names to be used are enclosed + // between the code points 0xF0000 and 0xF0001, the first two + // characters of plane 15, which is a Private Use Area whose + // codepoints don't have any associated glyph. + docstring s1; + docstring s2 = split(s, s1, 0xF0000); + while (true) { + if (!s1.empty()) + ots.os() << s1; + if (s2.empty()) + break; + docstring enc; + docstring const s3 = split(s2, enc, 0xF0001); + if (!contains(s2, 0xF0001)) + s2 = split(enc, s1, 0xF0000); + else { + ots.os() << setEncoding(to_ascii(enc)); + s2 = split(s3, s1, 0xF0000); + } + } + } else + ots.os() << s; + ots.lastChar(s[len - 1]); ots.texrow().newlines(count(s.begin(), s.end(), '\n')); ots.canBreakLine(s[len - 1] != '\n'); @@ -484,28 +512,14 @@ otexstream & operator<<(otexstream & ots, docstring const & s) otexstream & operator<<(otexstream & ots, string const & s) { - ots << s.c_str(); + ots << from_utf8(s); return ots; } otexstream & operator<<(otexstream & ots, char const * s) { - size_t const len = strlen(s); - - // Check whether there's something to output - if (len == 0) - return ots; - - if (ots.protectSpace()) { - if (!ots.canBreakLine() && s[0] == ' ') - ots.os() << "{}"; - ots.protectSpace(false); - } - ots.os() << s; - ots.lastChar(s[len - 1]); - ots.texrow().newlines(count(s, s + len, '\n')); - ots.canBreakLine(s[len - 1] != '\n'); + ots << from_utf8(s); return ots; } diff --git a/status.20x b/status.20x index 1c0847a44a..830cd15419 100644 --- a/status.20x +++ b/status.20x @@ -154,6 +154,9 @@ What's new - Store the autosave files of unnamed buffers in the correct directory and make sure they are not left behind after saving (bug 7793). +- Fix latex export of multilingual documents containing theorem-like + environments (bug 7800). + * USER INTERFACE