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();
}
}
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()) {
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());
// 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));
}
}
}
#include <config.h>
#include "Layout.h"
+#include "Encoding.h"
#include "FontInfo.h"
#include "Language.h"
#include "Lexer.h"
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;
// 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)
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
}
-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);
}
#ifndef LAYOUT_H
#define LAYOUT_H
+#include "Encoding.h"
#include "FontInfo.h"
#include "LayoutEnums.h"
#include "Spacing.h"
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_; }
///
#include <config.h>
#include "support/docstream.h"
+#include "support/lstrings.h"
#include "support/unicode.h"
#include <algorithm>
using namespace std;
using lyx::ucs4_codeset;
+using lyx::support::contains;
+using lyx::support::split;
#if defined(_MSC_VER) && (_MSC_VER >= 1600)
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');
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;
}
- 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