Fix bug #7800 (Lyx cannot create dvi with Russian)

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@39820 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Enrico Forestieri 2011-10-08 22:13:38 +00:00
parent dfd8a97bff
commit 33c5f6d628
4 changed files with 78 additions and 26 deletions

View File

@ -1162,11 +1162,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,
Language const * buflang, bool const polyglossia)
{
docstring const language = polyglossia ? from_ascii(lang->polyglossia())
: from_ascii(lang->babel());
docstring const enc = from_ascii(lang->encoding()->iconvName());
docstring const texenc = from_ascii(lang->encoding()->latexName());
docstring const bufenc = from_ascii(buflang->encoding()->iconvName());
docstring const translated = (enc == bufenc) ? name
: from_ascii("\\inputencoding{") + texenc + from_ascii("}")
+ docstring(1, 0xF0000) + enc + docstring(1, 0xF0001)
+ translated
+ docstring(1, 0xF0000) + bufenc + docstring(1, 0xF0001);
odocstringstream os;
os << "\\addto\\captions" << lang
<< "{\\renewcommand{\\" << type << "name}{" << name << "}}\n";
os << "\\addto\\captions" << language
<< "{\\renewcommand{\\" << type << "name}{" << translated << "}}\n";
return os.str();
}
}
@ -1189,10 +1202,15 @@ docstring const LaTeXFeatures::getTClassI18nPreamble(bool use_babel, bool use_po
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().language(),
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().language(),
use_polyglossia));
}
}
if ((use_babel || use_polyglossia) && !UsedLanguages_.empty()) {
@ -1209,14 +1227,10 @@ 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)
if (flname != name)
snippets.insert(getFloatI18nPreamble(
type, name,
from_ascii(buffer().language()->polyglossia())));
else if (flname != name)
snippets.insert(getFloatI18nPreamble(
type, name,
from_ascii(buffer().language()->babel())));
type, name, buffer().language(),
buffer().language(), use_polyglossia));
for (lang_it lit = lbeg; lit != lend; ++lit) {
string const code = (*lit)->code();
name = (*lit)->translateLayout(fl.name());
@ -1227,14 +1241,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)
if (have_translation)
snippets.insert(getFloatI18nPreamble(
type, name,
from_ascii((*lit)->polyglossia())));
else if (have_translation)
snippets.insert(getFloatI18nPreamble(
type, name,
from_ascii((*lit)->babel())));
type, name, *lit,
buffer().language(),
use_polyglossia));
}
}
}

View File

@ -13,6 +13,7 @@
#include <config.h>
#include "Layout.h"
#include "Encoding.h"
#include "FontInfo.h"
#include "Language.h"
#include "Lexer.h"
@ -860,7 +861,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, Language const * buflang,
docstring const & templ, bool const polyglossia)
{
if (templ.empty())
return templ;
@ -873,6 +875,12 @@ docstring const i18npreamble(Language const * lang, docstring const & templ, boo
// tex2lyx does not have getMessages()
LASSERT(false, /**/);
#else
string const enc = lang->encoding()->iconvName();
string const texenc = lang->encoding()->latexName();
string const bufenc = buflang->encoding()->iconvName();
// First and second character of plane 15 (Private Use Area)
char const s1[5] = {0xf3, 0xb0, 0x80, 0x80, 0x00}; // U+F0000
char const s2[5] = {0xf3, 0xb0, 0x80, 0x81, 0x00}; // U+F0001
// FIXME UNICODE
// lyx::regex is not unicode-safe.
// Should use QRegExp or (boost::u32regex, but that requires ICU)
@ -881,6 +889,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 (enc != bufenc)
translated = "\\inputencoding{" + texenc + "}"
+ string(s1) + enc + string(s2) + translated
+ string(s1) + bufenc + string(s2);
preamble = subst(preamble, sub.str(), translated);
}
#endif
@ -892,13 +904,14 @@ docstring const i18npreamble(Language const * lang, docstring const & templ, boo
docstring const Layout::langpreamble(Language const * lang, bool const polyglossia) const
{
return i18npreamble(lang, langpreamble_, polyglossia);
return i18npreamble(lang, lang, langpreamble_, polyglossia);
}
docstring const Layout::babelpreamble(Language const * lang, bool const polyglossia) const
docstring const Layout::babelpreamble(Language const * lang,
Language const * buflang, bool const polyglossia) const
{
return i18npreamble(lang, babelpreamble_, polyglossia);
return i18npreamble(lang, buflang, babelpreamble_, polyglossia);
}

View File

@ -98,7 +98,7 @@ public:
docstring const langpreamble(Language const * lang, 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, Language const * buflang, bool const polyglossia) const;
///
std::set<std::string> const & requires() const { return requires_; }
///

View 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_utf8(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');