* Introduce polyglossia support (bug 6576).

Please test this.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@36433 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jürgen Spitzmüller 2010-11-22 12:10:16 +00:00
parent 3ffbab3bca
commit 7cbeed2e40
13 changed files with 288 additions and 85 deletions

View File

@ -284,6 +284,7 @@
\TestPackage{nicefrac} \TestPackage{nicefrac}
\TestPackage{nomencl} \TestPackage{nomencl}
\TestPackage{pdfcolmk} \TestPackage{pdfcolmk}
\TestPackage{polyglossia}
\TestPackage{pdfpages} \TestPackage{pdfpages}
\TestPackage{prettyref} \TestPackage{prettyref}
\TestPackage{preview} \TestPackage{preview}

View File

@ -1,5 +1,5 @@
#LyX 2.0.0svn created this file. For more info see http://www.lyx.org/ #LyX 2.0.0svn created this file. For more info see http://www.lyx.org/
\lyxformat 401 \lyxformat 408
\begin_document \begin_document
\begin_header \begin_header
\textclass article \textclass article
@ -37,6 +37,7 @@
\use_indices false \use_indices false
\paperorientation portrait \paperorientation portrait
\suppress_date false \suppress_date false
\use_refstyle 0
\index Index \index Index
\shortcut idx \shortcut idx
\color #008000 \color #008000
@ -4276,6 +4277,48 @@ mongolian-babel
Mongolian. Mongolian.
\end_layout \end_layout
\begin_layout Subsection
polyglossia
\end_layout
\begin_layout Description
Found:
\begin_inset Info
type "package"
arg "polyglossia"
\end_inset
\end_layout
\begin_layout Description
CTAN:
\family typewriter
macros/xetex/latex/polyglossia/
\end_layout
\begin_layout Description
Notes: The package
\family sans
polyglossia
\family default
provides a language interface specifically for XeTeX.
It aims to supersede the
\family sans
babel
\family default
package by using XeTeX's mutlilingual and multiscript facilities.
If installed,
\family sans
polyglossia
\family default
will by used for language handling instead of
\family sans
babel
\family default
when XeTeX is used as output format.
\end_layout
\begin_layout Subsection \begin_layout Subsection
turkmen turkmen
\end_layout \end_layout

View File

@ -1386,6 +1386,7 @@ void Buffer::writeLaTeXSource(odocstream & os,
MacroSet parentMacros; MacroSet parentMacros;
listParentMacros(parentMacros, features); listParentMacros(parentMacros, features);
runparams.use_polyglossia = features.usePolyglossia();
// Write the preamble // Write the preamble
runparams.use_babel = params().writeLaTeX(os, features, runparams.use_babel = params().writeLaTeX(os, features,
d->texrow, d->texrow,

View File

@ -1305,15 +1305,16 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
ostringstream language_options; ostringstream language_options;
bool const use_babel = features.useBabel() && !tclass.provides("babel"); bool const use_babel = features.useBabel() && !tclass.provides("babel");
if (use_babel) { bool const use_polyglossia = features.usePolyglossia();
bool const global = lyxrc.language_global_options;
if (use_babel || (use_polyglossia && global)) {
language_options << features.getLanguages(); language_options << features.getLanguages();
if (!language->babel().empty()) { if (!language->babel().empty()) {
if (!language_options.str().empty()) if (!language_options.str().empty())
language_options << ','; language_options << ',';
language_options << language->babel(); language_options << language->babel();
} }
if (lyxrc.language_global_options if (global && !features.needBabelLangOptions())
&& !features.needBabelLangOptions())
clsoptions << language_options.str() << ','; clsoptions << language_options.str() << ',';
} }
@ -1721,15 +1722,15 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
// If we use hyperref, jurabib, japanese, or vietnamese, we have to call babel before them. // If we use hyperref, jurabib, japanese, or vietnamese, we have to call babel before them.
if (use_babel if (use_babel
&& (features.isRequired("jurabib") && (features.isRequired("jurabib")
|| features.isRequired("hyperref") || features.isRequired("hyperref")
|| features.isRequired("vietnamese") || features.isRequired("vietnamese")
|| features.isRequired("japanese") ) ) { || features.isRequired("japanese"))) {
// FIXME UNICODE // FIXME UNICODE
lyxpreamble += from_utf8(features.getBabelPresettings()); lyxpreamble += from_utf8(features.getBabelPresettings());
lyxpreamble += from_utf8(babelCall(language_options.str(), lyxpreamble += from_utf8(babelCall(language_options.str(),
features.needBabelLangOptions())) + '\n'; features.needBabelLangOptions())) + '\n';
lyxpreamble += from_utf8(features.getBabelPostsettings()); lyxpreamble += from_utf8(features.getBabelPostsettings());
} }
// The optional packages; // The optional packages;
@ -1877,6 +1878,7 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
lyxpreamble += from_utf8(features.getBabelPostsettings()); lyxpreamble += from_utf8(features.getBabelPostsettings());
} }
// FIXME Polyglossia?
docstring const i18npreamble = features.getTClassI18nPreamble(use_babel); docstring const i18npreamble = features.getTClassI18nPreamble(use_babel);
if (!i18npreamble.empty()) if (!i18npreamble.empty())
lyxpreamble += i18npreamble + '\n'; lyxpreamble += i18npreamble + '\n';
@ -1896,6 +1898,29 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
os << "\\usepackage{xltxtra}\n"; os << "\\usepackage{xltxtra}\n";
texrow.newline(); texrow.newline();
} }
// Polyglossia must be loaded after xltxtra
if (use_polyglossia) {
// call the package
os << "\\usepackage{polyglossia}\n";
texrow.newline();
// set the main language
os << "\\setdefaultlanguage";
if (!language->polyglossiaOpts().empty())
os << "[" << from_ascii(language->polyglossiaOpts()) << "]";
os << "{" + from_ascii(language->polyglossia()) + "}\n";
texrow.newline();
// now setup the other languages
std::map<std::string, std::string> const polylangs =
features.getPolyglossiaLanguages();
for (std::map<std::string, std::string>::const_iterator mit = polylangs.begin();
mit != polylangs.end() ; ++mit) {
os << "\\setotherlanguage";
if (!mit->second.empty())
os << "[" << from_ascii(mit->second) << "]";
os << "{" << from_ascii(mit->first) << "}\n";
texrow.newline();
}
}
return use_babel; return use_babel;
} }

View File

@ -272,7 +272,18 @@ int Font::latexWriteStartChanges(odocstream & os, BufferParams const & bparams,
bool env = false; bool env = false;
int count = 0; int count = 0;
if (language()->babel() != base.language()->babel() &&
// polyglossia or babel?
if (runparams.use_polyglossia) {
if (!language()->polyglossia().empty()) {
string tmp = "\\text" + language()->polyglossia();
if (!language()->polyglossiaOpts().empty())
tmp += "[" + language()->polyglossiaOpts() + "]";
tmp += "{";
os << from_ascii(tmp);
count += tmp.length();
}
} else if (language()->babel() != base.language()->babel() &&
language() != prev.language()) { language() != prev.language()) {
if (language()->lang() == "farsi") { if (language()->lang() == "farsi") {
os << "\\textFR{"; os << "\\textFR{";

View File

@ -285,10 +285,23 @@ LaTeXFeatures::LaTeXFeatures(Buffer const & b, BufferParams const & p,
bool LaTeXFeatures::useBabel() const bool LaTeXFeatures::useBabel() const
{ {
return (lyxrc.language_package_selection != LyXRC::LP_NONE) && return (lyxrc.language_package_selection != LyXRC::LP_NONE)
((bufferParams().language->lang() != lyxrc.default_language && && !usePolyglossia()
!bufferParams().language->babel().empty()) || && ((bufferParams().language->lang() != lyxrc.default_language
this->hasLanguages()); && !bufferParams().language->babel().empty())
|| this->hasLanguages());
}
bool LaTeXFeatures::usePolyglossia() const
{
return (lyxrc.language_package_selection == LyXRC::LP_AUTO)
&& isRequired("xetex")
&& isAvailable("polyglossia")
&& ((bufferParams().language->lang() != lyxrc.default_language
&& !bufferParams().language->polyglossia().empty())
|| this->hasLanguages())
&& this->hasPolyglossiaLanguages();
} }
@ -474,6 +487,19 @@ bool LaTeXFeatures::hasLanguages() const
} }
bool LaTeXFeatures::hasPolyglossiaLanguages() const
{
LanguageList::const_iterator const begin = UsedLanguages_.begin();
for (LanguageList::const_iterator cit = begin;
cit != UsedLanguages_.end();
++cit) {
if ((*cit)->polyglossia().empty())
return false;
}
return true;
}
string LaTeXFeatures::getLanguages() const string LaTeXFeatures::getLanguages() const
{ {
ostringstream languages; ostringstream languages;
@ -490,6 +516,20 @@ string LaTeXFeatures::getLanguages() const
} }
std::map<std::string, std::string> LaTeXFeatures::getPolyglossiaLanguages() const
{
std::map<std::string, std::string> languages;
LanguageList::const_iterator const begin = UsedLanguages_.begin();
for (LanguageList::const_iterator cit = begin;
cit != UsedLanguages_.end();
++cit) {
languages[(*cit)->polyglossia()] = (*cit)->polyglossiaOpts();
}
return languages;
}
set<string> LaTeXFeatures::getEncodingSet(string const & doc_encoding) const set<string> LaTeXFeatures::getEncodingSet(string const & doc_encoding) const
{ {
// This does only find encodings of languages supported by babel, but // This does only find encodings of languages supported by babel, but
@ -825,7 +865,7 @@ docstring const LaTeXFeatures::getMacros() const
if (mustProvide("lyxarrow")) if (mustProvide("lyxarrow"))
macros << lyxarrow_def << '\n'; macros << lyxarrow_def << '\n';
if (mustProvide("textgreek")) { if (!usePolyglossia() && mustProvide("textgreek")) {
// Avoid a LaTeX error if times fonts are used and the grtimes // Avoid a LaTeX error if times fonts are used and the grtimes
// package is installed but actual fonts are not (bug 6469). // package is installed but actual fonts are not (bug 6469).
if (params_.fontsRoman == "times") if (params_.fontsRoman == "times")
@ -839,7 +879,7 @@ docstring const LaTeXFeatures::getMacros() const
macros << textgreek_def << '\n'; macros << textgreek_def << '\n';
} }
if (mustProvide("textcyr")) if (!usePolyglossia() && mustProvide("textcyr"))
macros << textcyr_def << '\n'; macros << textcyr_def << '\n';
if (mustProvide("lyxmathsym")) if (mustProvide("lyxmathsym"))

View File

@ -101,9 +101,13 @@ public:
void useLanguage(Language const *); void useLanguage(Language const *);
/// ///
bool hasLanguages() const; bool hasLanguages() const;
/// check if all used languages are supported by polyglossia
bool hasPolyglossiaLanguages() const;
/// ///
std::string getLanguages() const; std::string getLanguages() const;
/// ///
std::map<std::string, std::string> getPolyglossiaLanguages() const;
///
std::set<std::string> getEncodingSet(std::string const & doc_encoding) const; std::set<std::string> getEncodingSet(std::string const & doc_encoding) const;
/// ///
void useLayout(docstring const & lyt); void useLayout(docstring const & lyt);
@ -117,6 +121,8 @@ public:
BufferParams const & bufferParams() const; BufferParams const & bufferParams() const;
/// the return value is dependent upon both LyXRC and LaTeXFeatures. /// the return value is dependent upon both LyXRC and LaTeXFeatures.
bool useBabel() const; bool useBabel() const;
///
bool usePolyglossia() const;
/// are we in a float? /// are we in a float?
bool inFloat() const { return in_float_; } bool inFloat() const { return in_float_; }
/// are we in a float? /// are we in a float?

View File

@ -21,7 +21,7 @@ namespace lyx {
OutputParams::OutputParams(Encoding const * enc) OutputParams::OutputParams(Encoding const * enc)
: flavor(LATEX), math_flavor(NotApplicable), nice(false), moving_arg(false), : flavor(LATEX), math_flavor(NotApplicable), nice(false), moving_arg(false),
inulemcmd(false), local_font(0), master_language(0), encoding(enc), inulemcmd(false), local_font(0), master_language(0), encoding(enc),
free_spacing(false), use_babel(false), free_spacing(false), use_babel(false), use_polyglossia(false),
use_indices(false), use_japanese(false), linelen(0), depth(0), use_indices(false), use_japanese(false), linelen(0), depth(0),
exportdata(new ExportData), exportdata(new ExportData),
inComment(false), inTableCell(NO), inFloat(NONFLOAT), inComment(false), inTableCell(NO), inFloat(NONFLOAT),

View File

@ -136,6 +136,10 @@ public:
*/ */
bool use_babel; bool use_babel;
/** Do we use polyglossia (instead of babel)?
*/
bool use_polyglossia;
/** Are we generating multiple indices? /** Are we generating multiple indices?
*/ */
bool use_indices; bool use_indices;

View File

@ -2369,12 +2369,16 @@ void Paragraph::latex(BufferParams const & bparams,
open_font = false; open_font = false;
} }
string const running_lang = runparams.use_polyglossia ?
running_font.language()->polyglossia() : running_font.language()->babel();
// close babel's font environment before opening CJK. // close babel's font environment before opening CJK.
if (!running_font.language()->babel().empty() && string const lang_end_command = runparams.use_polyglossia ?
"\\end{$$lang}" : lyxrc.language_command_end;
if (!running_lang.empty() &&
font.language()->encoding()->package() == Encoding::CJK) { font.language()->encoding()->package() == Encoding::CJK) {
string end_tag = subst(lyxrc.language_command_end, string end_tag = subst(lang_end_command,
"$$lang", "$$lang",
running_font.language()->babel()); running_lang);
os << from_ascii(end_tag); os << from_ascii(end_tag);
column += end_tag.length(); column += end_tag.length();
} }

View File

@ -234,7 +234,7 @@ int ParagraphMetrics::singleWidth(pos_type pos, Font const & font) const
c = par_->transformChar(c, pos); c = par_->transformChar(c, pos);
} else if (language->lang() == "hebrew" && } else if (language->lang() == "hebrew" &&
Encodings::isHebrewComposeChar(c)) { Encodings::isHebrewComposeChar(c)) {
return 0; return 0;
} }
} }
return theFontMetrics(font).width(c); return theFontMetrics(font).width(c);

View File

@ -267,18 +267,20 @@ int InsetQuotes::latex(odocstream & os, OutputParams const & runparams) const
string qstr; string qstr;
if (language_ == FrenchQuotes && times_ == DoubleQuotes if (language_ == FrenchQuotes && times_ == DoubleQuotes
&& prefixIs(runparams.local_font->language()->code(), "fr")) { && prefixIs(runparams.local_font->language()->code(), "fr")
&& !runparams.use_polyglossia) {
if (side_ == LeftQuote) if (side_ == LeftQuote)
qstr = "\\og "; //the spaces are important here qstr = "\\og "; //the spaces are important here
else else
qstr = " \\fg{}"; //and here qstr = " \\fg{}"; //and here
} else if (lyxrc.fontenc == "T1") { } else if (lyxrc.fontenc == "T1" && !runparams.use_polyglossia) {
qstr = latex_quote_t1[times_][quoteind]; qstr = latex_quote_t1[times_][quoteind];
#ifdef DO_USE_DEFAULT_LANGUAGE #ifdef DO_USE_DEFAULT_LANGUAGE
} else if (doclang == "default") { } else if (doclang == "default") {
#else #else
} else if (!runparams.use_babel) { } else if (!runparams.use_babel) {
#endif #endif
// these are also used by polyglossia
qstr = latex_quote_ot1[times_][quoteind]; qstr = latex_quote_ot1[times_][quoteind];
} else { } else {
qstr = latex_quote_babel[times_][quoteind]; qstr = latex_quote_babel[times_][quoteind];

View File

@ -97,6 +97,16 @@ TeXDeeper(Buffer const & buf,
} }
string const getPolyglossiaEnvName(Language const * lang)
{
string result = lang->polyglossia();
if (result == "arabic")
// exceptional spelling; see polyglossia docs.
result = "Arabic";
return result;
}
ParagraphList::const_iterator ParagraphList::const_iterator
TeXEnvironment(Buffer const & buf, TeXEnvironment(Buffer const & buf,
Text const & text, Text const & text,
@ -131,29 +141,47 @@ TeXEnvironment(Buffer const & buf,
? (use_prev_env_language ? prev_env_language_ ? (use_prev_env_language ? prev_env_language_
: priorpit->getParLanguage(bparams)) : priorpit->getParLanguage(bparams))
: doc_language; : doc_language;
if (par_language->babel() != prev_par_language->babel()) { string par_lang = par_language->babel();
string prev_par_lang = prev_par_language->babel();
string doc_lang = doc_language->babel();
string lang_begin_command = lyxrc.language_command_begin;
string lang_end_command = lyxrc.language_command_end;
if (!lyxrc.language_command_end.empty() && if (runparams.use_polyglossia) {
prev_par_language->babel() != doc_language->babel() && par_lang = getPolyglossiaEnvName(par_language);
!prev_par_language->babel().empty()) { prev_par_lang = getPolyglossiaEnvName(prev_par_language);
doc_lang = getPolyglossiaEnvName(doc_language);
lang_begin_command = "\\begin{$$lang}";
lang_end_command = "\\end{$$lang}";
}
if (par_lang != prev_par_lang) {
if (!lang_end_command.empty() &&
prev_par_lang != doc_lang &&
!prev_par_lang.empty()) {
os << from_ascii(subst( os << from_ascii(subst(
lyxrc.language_command_end, lang_end_command,
"$$lang", "$$lang",
prev_par_language->babel())) prev_par_lang))
// the '%' is necessary to prevent unwanted whitespace // the '%' is necessary to prevent unwanted whitespace
<< "%\n"; << "%\n";
texrow.newline(); texrow.newline();
} }
if ((lyxrc.language_command_end.empty() || if ((lyxrc.language_command_end.empty() ||
par_language->babel() != doc_language->babel()) && par_lang != doc_lang) &&
!par_language->babel().empty()) { !par_lang.empty()) {
os << from_ascii(subst( os << from_ascii(subst(
lyxrc.language_command_begin, lang_begin_command,
"$$lang", "$$lang",
par_language->babel())) par_lang));
// the '%' is necessary to prevent unwanted whitespace if (runparams.use_polyglossia
<< "%\n"; && !par_language->polyglossiaOpts().empty())
os << "["
<< from_ascii(par_language->polyglossiaOpts())
<< "]";
// the '%' is necessary to prevent unwanted whitespace
os << "%\n";
texrow.newline(); texrow.newline();
} }
} }
@ -441,7 +469,22 @@ ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
: priorpit->getParLanguage(bparams)) : priorpit->getParLanguage(bparams))
: outer_language; : outer_language;
if (par_language->babel() != prev_language->babel() string par_lang = par_language->babel();
string prev_lang = prev_language->babel();
string doc_lang = doc_language->babel();
string outer_lang = outer_language->babel();
string lang_begin_command = lyxrc.language_command_begin;
string lang_end_command = lyxrc.language_command_end;
if (runparams.use_polyglossia) {
par_lang = getPolyglossiaEnvName(par_language);
prev_lang = getPolyglossiaEnvName(prev_language);
doc_lang = getPolyglossiaEnvName(doc_language);
outer_lang = getPolyglossiaEnvName(outer_language);
lang_begin_command = "\\begin{$$lang}";
lang_end_command = "\\end{$$lang}";
}
if (par_lang != prev_lang
// check if we already put language command in TeXEnvironment() // check if we already put language command in TeXEnvironment()
&& !(style.isEnvironment() && !(style.isEnvironment()
&& (pit == paragraphs.begin() || && (pit == paragraphs.begin() ||
@ -449,13 +492,13 @@ ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
priorpit->getDepth() <= pit->getDepth()) priorpit->getDepth() <= pit->getDepth())
|| priorpit->getDepth() < pit->getDepth()))) || priorpit->getDepth() < pit->getDepth())))
{ {
if (!lyxrc.language_command_end.empty() && if (!lang_end_command.empty() &&
prev_language->babel() != outer_language->babel() && prev_lang != outer_lang &&
!prev_language->babel().empty()) !prev_lang.empty())
{ {
os << from_ascii(subst(lyxrc.language_command_end, os << from_ascii(subst(lang_end_command,
"$$lang", "$$lang",
prev_language->babel())) prev_lang))
// the '%' is necessary to prevent unwanted whitespace // the '%' is necessary to prevent unwanted whitespace
<< "%\n"; << "%\n";
texrow.newline(); texrow.newline();
@ -466,29 +509,30 @@ ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
// the previous one, if the current language is different than the // the previous one, if the current language is different than the
// outer_language (which is currently in effect once the previous one // outer_language (which is currently in effect once the previous one
// is closed). // is closed).
if ((lyxrc.language_command_end.empty() || if ((lang_end_command.empty() ||
par_language->babel() != outer_language->babel()) && par_lang != outer_lang) &&
!par_language->babel().empty()) { !par_lang.empty()) {
// If we're inside an inset, and that inset is within an \L or \R // If we're inside an inset, and that inset is within an \L or \R
// (or equivalents), then within the inset, too, any opposite // (or equivalents), then within the inset, too, any opposite
// language paragraph should appear within an \L or \R (in addition // language paragraph should appear within an \L or \R (in addition
// to, outside of, the normal language switch commands). // to, outside of, the normal language switch commands).
// This behavior is not correct for ArabTeX, though. // This behavior is not correct for ArabTeX, though.
if ( // not for ArabTeX if (!runparams.use_polyglossia &&
(par_language->lang() != "arabic_arabtex" && // not for ArabTeX
outer_language->lang() != "arabic_arabtex") && (par_language->lang() != "arabic_arabtex" &&
// are we in an inset? outer_language->lang() != "arabic_arabtex") &&
runparams.local_font != 0 && // are we in an inset?
// is the inset within an \L or \R? runparams.local_font != 0 &&
// // is the inset within an \L or \R?
// FIXME: currently, we don't check this; this means that //
// we'll have unnnecessary \L and \R commands, but that // FIXME: currently, we don't check this; this means that
// doesn't seem to hurt (though latex will complain) // we'll have unnnecessary \L and \R commands, but that
// // doesn't seem to hurt (though latex will complain)
// is this paragraph in the opposite direction? //
runparams.local_font->isRightToLeft() != // is this paragraph in the opposite direction?
par_language->rightToLeft() runparams.local_font->isRightToLeft() !=
) { par_language->rightToLeft()
) {
// FIXME: I don't have a working copy of the Arabi package, so // FIXME: I don't have a working copy of the Arabi package, so
// I'm not sure if the farsi and arabic_arabi stuff is correct // I'm not sure if the farsi and arabic_arabi stuff is correct
// or not... // or not...
@ -509,11 +553,16 @@ ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
// With CJK, the CJK tag has to be closed first (see below) // With CJK, the CJK tag has to be closed first (see below)
if (runparams.encoding->package() != Encoding::CJK) { if (runparams.encoding->package() != Encoding::CJK) {
os << from_ascii(subst( os << from_ascii(subst(
lyxrc.language_command_begin, lang_begin_command,
"$$lang", "$$lang",
par_language->babel())) par_lang));
if (runparams.use_polyglossia
&& !par_language->polyglossiaOpts().empty())
os << "["
<< from_ascii(par_language->polyglossiaOpts())
<< "]";
// the '%' is necessary to prevent unwanted whitespace // the '%' is necessary to prevent unwanted whitespace
<< "%\n"; os << "%\n";
texrow.newline(); texrow.newline();
} }
} }
@ -566,9 +615,9 @@ ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
// With CJK, the CJK tag had to be closed first (see above) // With CJK, the CJK tag had to be closed first (see above)
if (runparams.encoding->package() == Encoding::CJK) { if (runparams.encoding->package() == Encoding::CJK) {
os << from_ascii(subst( os << from_ascii(subst(
lyxrc.language_command_begin, lang_begin_command,
"$$lang", "$$lang",
par_language->babel())) par_lang))
// the '%' is necessary to prevent unwanted whitespace // the '%' is necessary to prevent unwanted whitespace
<< "%\n"; << "%\n";
texrow.newline(); texrow.newline();
@ -709,6 +758,7 @@ ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
// needed if we're within an \L or \R that we may have opened above (not // needed if we're within an \L or \R that we may have opened above (not
// necessarily in this paragraph) and are about to close. // necessarily in this paragraph) and are about to close.
bool closing_rtl_ltr_environment = bool closing_rtl_ltr_environment =
!runparams.use_polyglossia &&
// not for ArabTeX // not for ArabTeX
(par_language->lang() != "arabic_arabtex" && (par_language->lang() != "arabic_arabtex" &&
outer_language->lang() != "arabic_arabtex") && outer_language->lang() != "arabic_arabtex") &&
@ -734,7 +784,7 @@ ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
} }
// when the paragraph uses CJK, the language has to be closed earlier // when the paragraph uses CJK, the language has to be closed earlier
if (font.language()->encoding()->package() != Encoding::CJK) { if (font.language()->encoding()->package() != Encoding::CJK) {
if (lyxrc.language_command_end.empty()) { if (lang_end_command.empty()) {
// If this is a child, we should restore the // If this is a child, we should restore the
// master language after the last paragraph. // master language after the last paragraph.
Language const * const current_language = Language const * const current_language =
@ -742,18 +792,21 @@ ParagraphList::const_iterator TeXOnePar(Buffer const & buf,
&& runparams.master_language) && runparams.master_language)
? runparams.master_language ? runparams.master_language
: outer_language; : outer_language;
if (!current_language->babel().empty()) { string const current_lang = runparams.use_polyglossia ?
getPolyglossiaEnvName(current_language)
: current_language->babel();
if (!current_lang.empty()) {
os << from_ascii(subst( os << from_ascii(subst(
lyxrc.language_command_begin, lang_begin_command,
"$$lang", "$$lang",
current_language->babel())); current_lang));
pending_newline = true; pending_newline = true;
} }
} else if (!par_language->babel().empty()) { } else if (!par_lang.empty()) {
os << from_ascii(subst( os << from_ascii(subst(
lyxrc.language_command_end, lang_end_command,
"$$lang", "$$lang",
par_language->babel())); par_lang));
pending_newline = true; pending_newline = true;
} }
} }
@ -895,14 +948,25 @@ void latexParagraphs(Buffer const & buf,
} }
// if "auto begin" is switched off, explicitly switch the // if "auto begin" is switched off, explicitly switch the
// language on at start // language on at start
string const mainlang = runparams.use_polyglossia ?
getPolyglossiaEnvName(bparams.language)
: bparams.language->babel();
string const lang_begin_command = runparams.use_polyglossia ?
"\\begin{$$lang}" : lyxrc.language_command_begin;
if (maintext && !lyxrc.language_auto_begin && if (maintext && !lyxrc.language_auto_begin &&
!bparams.language->babel().empty()) { !mainlang.empty()) {
// FIXME UNICODE // FIXME UNICODE
os << from_utf8(subst(lyxrc.language_command_begin, os << from_utf8(subst(lang_begin_command,
"$$lang", "$$lang",
bparams.language->babel())) mainlang));
<< '\n'; if (runparams.use_polyglossia
texrow.newline(); && !bparams.language->polyglossiaOpts().empty())
os << "["
<< from_ascii(bparams.language->polyglossiaOpts())
<< "]";
os << '\n';
texrow.newline();
} }
ParagraphList::const_iterator lastpar; ParagraphList::const_iterator lastpar;
@ -969,11 +1033,13 @@ void latexParagraphs(Buffer const & buf,
// if "auto end" is switched off, explicitly close the language at the end // if "auto end" is switched off, explicitly close the language at the end
// but only if the last par is in a babel language // but only if the last par is in a babel language
if (maintext && !lyxrc.language_auto_end && !bparams.language->babel().empty() && string const lang_end_command = runparams.use_polyglossia ?
"\\end{$$lang}" : lyxrc.language_command_end;
if (maintext && !lyxrc.language_auto_end && !mainlang.empty() &&
lastpar->getParLanguage(bparams)->encoding()->package() != Encoding::CJK) { lastpar->getParLanguage(bparams)->encoding()->package() != Encoding::CJK) {
os << from_utf8(subst(lyxrc.language_command_end, os << from_utf8(subst(lang_end_command,
"$$lang", "$$lang",
bparams.language->babel())) mainlang))
<< '\n'; << '\n';
texrow.newline(); texrow.newline();
} }