]> git.lyx.org Git - features.git/commitdiff
Fix bug #7800 (Lyx cannot create dvi with Russian)
authorEnrico Forestieri <forenr@lyx.org>
Sun, 30 Oct 2011 22:40:03 +0000 (22:40 +0000)
committerEnrico Forestieri <forenr@lyx.org>
Sun, 30 Oct 2011 22:40:03 +0000 (22:40 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_2_0_X@40107 a592a061-630c-0410-9148-cb99ea01b6c8

src/LaTeXFeatures.cpp
src/Layout.cpp
src/Layout.h
src/support/docstream.cpp
status.20x

index 2cfc1ce6e2275940c4cb69f7f97f0eb3b11634f9..da17de0d4190f4f46656275f9683cef8fdfac675 100644 (file)
@@ -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));
                        }
                }
        }
index 983c53e7a3922783a3f8e9b9739311f9dac1d2f1..2700752f524d998f69479aaba4eea661ab6484ec 100644 (file)
@@ -13,6 +13,7 @@
 #include <config.h>
 
 #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);
 }
 
 
index f957f747304a85425b1142d2a701c54b3162c831..1db9a23a386896ac0248fb08df98c33a34506154 100644 (file)
@@ -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<std::string> const & requires() const { return requires_; }
        ///
index a44c062272e6ec5058fd81b776830828ae61b23c..e8839e07f61420104c3ff49826f7dc4997123ce6 100644 (file)
@@ -11,6 +11,7 @@
 #include <config.h>
 
 #include "support/docstream.h"
+#include "support/lstrings.h"
 #include "support/unicode.h"
 
 #include <algorithm>
@@ -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;
 }
 
index 1c0847a44a99a1f68aaf6e2943a22944a8b179a3..830cd15419bac20755890e974447fcbfa9ce6278 100644 (file)
@@ -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