X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FBufferParams.cpp;h=451736e6dedc96afac842a6a8c7280951d19c457;hb=6780a3040958c937d6441c32f333c5ee55f64e3c;hp=08c7e0de400f8fdfafb8939be0925d4b8664eed1;hpb=6d4cde435d32d71475c4eb1e12877b11a53ce975;p=lyx.git diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 08c7e0de40..451736e6de 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -20,6 +20,7 @@ #include "Author.h" #include "LayoutFile.h" #include "BranchList.h" +#include "Buffer.h" #include "buffer_funcs.h" #include "Bullet.h" #include "Color.h" @@ -52,6 +53,7 @@ #include "support/filetools.h" #include "support/gettext.h" #include "support/Messages.h" +#include "support/mutex.h" #include "support/Translator.h" #include "support/lstrings.h" @@ -87,11 +89,6 @@ static char const * const string_orientation[] = { }; -static char const * const string_footnotekinds[] = { - "footnote", "margin", "fig", "tab", "alg", "wide-fig", "wide-tab", "" -}; - - static char const * const tex_graphics[] = { "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx", "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex", @@ -122,7 +119,8 @@ ParSepTranslator const init_parseptranslator() ParSepTranslator const & parseptranslator() { - static ParSepTranslator translator = init_parseptranslator(); + static ParSepTranslator const translator = + init_parseptranslator(); return translator; } @@ -146,7 +144,8 @@ QuotesLangTranslator const init_quoteslangtranslator() QuotesLangTranslator const & quoteslangtranslator() { - static QuotesLangTranslator translator = init_quoteslangtranslator(); + static QuotesLangTranslator const translator = + init_quoteslangtranslator(); return translator; } @@ -196,7 +195,8 @@ static PaperSizeTranslator initPaperSizeTranslator() PaperSizeTranslator const & papersizetranslator() { - static PaperSizeTranslator translator = initPaperSizeTranslator(); + static PaperSizeTranslator const translator = + initPaperSizeTranslator(); return translator; } @@ -215,7 +215,8 @@ PaperOrientationTranslator const init_paperorientationtranslator() PaperOrientationTranslator const & paperorientationtranslator() { - static PaperOrientationTranslator translator = init_paperorientationtranslator(); + static PaperOrientationTranslator const translator = + init_paperorientationtranslator(); return translator; } @@ -234,7 +235,7 @@ SidesTranslator const init_sidestranslator() SidesTranslator const & sidestranslator() { - static SidesTranslator translator = init_sidestranslator(); + static SidesTranslator const translator = init_sidestranslator(); return translator; } @@ -254,7 +255,8 @@ PackageTranslator const init_packagetranslator() PackageTranslator const & packagetranslator() { - static PackageTranslator translator = init_packagetranslator(); + static PackageTranslator const translator = + init_packagetranslator(); return translator; } @@ -267,13 +269,15 @@ CiteEngineTypeTranslator const init_citeenginetypetranslator() { CiteEngineTypeTranslator translator("authoryear", ENGINE_TYPE_AUTHORYEAR); translator.addPair("numerical", ENGINE_TYPE_NUMERICAL); + translator.addPair("default", ENGINE_TYPE_DEFAULT); return translator; } CiteEngineTypeTranslator const & citeenginetypetranslator() { - static CiteEngineTypeTranslator translator = init_citeenginetypetranslator(); + static CiteEngineTypeTranslator const translator = + init_citeenginetypetranslator(); return translator; } @@ -295,7 +299,7 @@ SpaceTranslator const init_spacetranslator() SpaceTranslator const & spacetranslator() { - static SpaceTranslator translator = init_spacetranslator(); + static SpaceTranslator const translator = init_spacetranslator(); return translator; } @@ -335,8 +339,7 @@ BufferParams::Impl::Impl() BufferParams::Impl * BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr) { - LASSERT(ptr, /**/); - + LBUFERR(ptr); return new BufferParams::Impl(*ptr); } @@ -361,12 +364,12 @@ BufferParams::BufferParams() orientation = ORIENTATION_PORTRAIT; use_geometry = false; cite_engine_.push_back("basic"); - cite_engine_type_ = ENGINE_TYPE_NUMERICAL; + cite_engine_type_ = ENGINE_TYPE_DEFAULT; biblio_style = "plain"; use_bibtopic = false; use_indices = false; - trackChanges = false; - outputChanges = false; + track_changes = false; + output_changes = false; use_default_options = true; maintain_unincluded_children = false; secnumdepth = 3; @@ -415,6 +418,7 @@ BufferParams::BufferParams() html_math_output = MathML; html_math_img_scale = 1.0; html_css_as_file = false; + display_pixel_ratio = 1.0; output_sync = false; use_refstyle = true; @@ -423,7 +427,7 @@ BufferParams::BufferParams() docstring BufferParams::B_(string const & l10n) const { - LASSERT(language, /**/); + LASSERT(language, return from_utf8(l10n)); return getMessages(language->code()).get(l10n); } @@ -447,6 +451,14 @@ map const & BufferParams::auto_packages() { static map packages; if (packages.empty()) { + // We could have a race condition here that two threads + // discover an empty map at the same time and want to fill + // it, but that is no problem, since the same contents is + // filled in twice then. Having the locker inside the + // packages.empty() condition has the advantage that we + // don't need the mutex overhead for simple reading. + static Mutex mutex; + Mutex::Locker locker(&mutex); // adding a package here implies a file format change! packages["amsmath"] = N_("The LaTeX package amsmath is only used if AMS formula types or symbols from the AMS math toolbars are inserted into formulas"); @@ -511,28 +523,28 @@ IndicesList const & BufferParams::indiceslist() const Bullet & BufferParams::temp_bullet(lyx::size_type const index) { - LASSERT(index < 4, /**/); + LASSERT(index < 4, return pimpl_->temp_bullets[0]); return pimpl_->temp_bullets[index]; } Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const { - LASSERT(index < 4, /**/); + LASSERT(index < 4, return pimpl_->temp_bullets[0]); return pimpl_->temp_bullets[index]; } Bullet & BufferParams::user_defined_bullet(lyx::size_type const index) { - LASSERT(index < 4, /**/); + LASSERT(index < 4, return pimpl_->temp_bullets[0]); return pimpl_->user_defined_bullets[index]; } Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const { - LASSERT(index < 4, /**/); + LASSERT(index < 4, return pimpl_->temp_bullets[0]); return pimpl_->user_defined_bullets[index]; } @@ -590,6 +602,8 @@ void BufferParams::setDefSkip(VSpace const & vs) string BufferParams::readToken(Lexer & lex, string const & token, FileName const & filepath) { + string result; + if (token == "\\textclass") { lex.next(); string const classname = lex.getString(); @@ -598,12 +612,31 @@ string BufferParams::readToken(Lexer & lex, string const & token, // be available. string tcp; LayoutFileList & bcl = LayoutFileList::get(); - if (tcp.empty() && !filepath.empty()) - tcp = bcl.addLocalLayout(classname, filepath.absFileName()); - if (!tcp.empty()) - setBaseClass(tcp); - else - setBaseClass(classname); + if (!filepath.empty()) { + // If classname is an absolute path, the document is + // using a local layout file which could not be accessed + // by a relative path. In this case the path is correct + // even if the document was moved to a different + // location. However, we will have a problem if the + // document was generated on a different platform. + bool isabsolute = FileName::isAbsolute(classname); + string const classpath = onlyPath(classname); + string const path = isabsolute ? classpath + : FileName(addPath(filepath.absFileName(), + classpath)).realPath(); + string const oldpath = isabsolute ? string() + : FileName(addPath(origin, classpath)).realPath(); + tcp = bcl.addLocalLayout(onlyFileName(classname), path, oldpath); + } + // that returns non-empty if a "local" layout file is found. + if (!tcp.empty()) { + result = to_utf8(makeRelPath(from_utf8(onlyPath(tcp)), + from_utf8(filepath.absFileName()))); + if (result.empty()) + result = "."; + setBaseClass(onlyFileName(tcp)); + } else + setBaseClass(onlyFileName(classname)); // We assume that a tex class exists for local or unknown // layouts so this warning, will only be given for system layouts. if (!baseClass()->isTeXClassAvailable()) { @@ -622,12 +655,17 @@ string BufferParams::readToken(Lexer & lex, string const & token, "See section 3.1.2.2 (Class Availability) of the\n" "User's Guide for more information."), desc, prereqs); frontend::Alert::warning(_("Document class not available"), - msg); + msg, true); } + } else if (token == "\\origin") { + lex.eatLine(); + origin = lex.getString(); } else if (token == "\\begin_preamble") { readPreamble(lex); } else if (token == "\\begin_local_layout") { - readLocalLayout(lex); + readLocalLayout(lex, false); + } else if (token == "\\begin_forced_local_layout") { + readLocalLayout(lex, true); } else if (token == "\\begin_modules") { readModules(lex); } else if (token == "\\begin_removed_modules") { @@ -741,9 +779,9 @@ string BufferParams::readToken(Lexer & lex, string const & token, } else if (token == "\\use_indices") { lex >> use_indices; } else if (token == "\\tracking_changes") { - lex >> trackChanges; + lex >> track_changes; } else if (token == "\\output_changes") { - lex >> outputChanges; + lex >> output_changes; } else if (token == "\\branch") { lex.eatLine(); docstring branch = lex.getDocString(); @@ -922,17 +960,22 @@ string BufferParams::readToken(Lexer & lex, string const & token, return token; } - return string(); + return result; } -void BufferParams::writeFile(ostream & os) const +void BufferParams::writeFile(ostream & os, Buffer const * buf) const { // The top of the file is written by the buffer. // Prints out the buffer info into the .lyx file given by file + // the document directory + os << "\\origin " << buf->filePath() << '\n'; + // the textclass - os << "\\textclass " << baseClass()->name() << '\n'; + os << "\\textclass " << buf->includedFilePath(addName(buf->layoutPos(), + baseClass()->name()), "layout") + << '\n'; // then the preamble if (!preamble.empty()) { @@ -990,6 +1033,7 @@ void BufferParams::writeFile(ostream & os) const << convert(maintain_unincluded_children) << '\n'; // local layout information + string const local_layout = getLocalLayout(false); if (!local_layout.empty()) { // remove '\n' from the end string const tmplocal = rtrim(local_layout, "\n"); @@ -997,6 +1041,14 @@ void BufferParams::writeFile(ostream & os) const << tmplocal << "\n\\end_local_layout\n"; } + string const forced_local_layout = getLocalLayout(true); + if (!forced_local_layout.empty()) { + // remove '\n' from the end + string const tmplocal = rtrim(forced_local_layout, "\n"); + os << "\\begin_forced_local_layout\n" + << tmplocal + << "\n\\end_forced_local_layout\n"; + } // then the text parameters if (language != ignore_language) @@ -1158,8 +1210,8 @@ void BufferParams::writeFile(ostream & os) const } } - os << "\\tracking_changes " << convert(trackChanges) << '\n' - << "\\output_changes " << convert(outputChanges) << '\n' + os << "\\tracking_changes " << convert(track_changes) << '\n' + << "\\output_changes " << convert(output_changes) << '\n' << "\\html_math_output " << html_math_output << '\n' << "\\html_css_as_file " << html_css_as_file << '\n' << "\\html_be_strict " << convert(html_be_strict) << '\n'; @@ -1182,7 +1234,7 @@ void BufferParams::validate(LaTeXFeatures & features) const if (columns > 1 && language->rightToLeft()) features.require("rtloutputdblcol"); - if (outputChanges) { + if (output_changes) { bool dvipost = LaTeXFeatures::isAvailable("dvipost"); bool xcolorulem = LaTeXFeatures::isAvailable("ulem") && LaTeXFeatures::isAvailable("xcolor"); @@ -1268,6 +1320,15 @@ void BufferParams::validate(LaTeXFeatures & features) const if (pdfoptions().colorlinks) features.require("color"); } + if (!listings_params.empty()) { + // do not test validity because listings_params is + // supposed to be valid + string par = + InsetListingsParams(listings_params).separatedParams(true); + // we can't support all packages, but we should load the color package + if (par.find("\\color", 0) != string::npos) + features.require("color"); + } // some languages are only available via polyglossia if (features.runparams().flavor == OutputParams::XETEX @@ -1294,6 +1355,11 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, // are doing! if (features.mustProvide("fix-cm")) os << "\\RequirePackage{fix-cm}\n"; + // Likewise for fixltx2e. If other packages conflict with this policy, + // treat it as a package bug (and report it!) + // See http://www.latex-project.org/cgi-bin/ltxbugs2html?pr=latex/4407 + if (features.mustProvide("fixltx2e")) + os << "\\RequirePackage{fixltx2e}\n"; os << "\\documentclass"; @@ -1433,9 +1499,13 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, os << '{' << from_ascii(tclass.latexname()) << "}\n"; // end of \documentclass defs - // if we use fontspec, we have to load the AMS packages here + // if we use fontspec or newtxmath, we have to load the AMS packages here string const ams = features.loadAMSPackages(); - if (useNonTeXFonts && !ams.empty()) + bool const ot1 = (font_encoding() == "default" || font_encoding() == "OT1"); + bool const use_newtxmath = + theLaTeXFonts().getLaTeXFont(from_ascii(fonts_math)).getUsedPackage( + ot1, false, false) == "newtxmath"; + if ((useNonTeXFonts || use_newtxmath) && !ams.empty()) os << from_ascii(ams); if (useNonTeXFonts) { @@ -1455,32 +1525,16 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, << from_ascii(fonts_default_family) << "}\n"; // set font encoding - // for arabic_arabi and farsi we also need to load the LAE and - // LFE encoding - // XeTeX and LuaTeX (with OS fonts) work without fontenc - if (font_encoding() != "default" && language->lang() != "japanese" - && !useNonTeXFonts && !features.isProvided("fontenc")) { - docstring extra_encoding; - if (features.mustProvide("textgreek")) - extra_encoding += from_ascii("LGR"); - if (features.mustProvide("textcyr")) { - if (!extra_encoding.empty()) - extra_encoding.push_back(','); - extra_encoding += from_ascii("T2A"); - } - if (!extra_encoding.empty() && !font_encoding().empty()) - extra_encoding.push_back(','); - size_t fars = language_options.str().find("farsi"); - size_t arab = language_options.str().find("arabic"); - if (language->lang() == "arabic_arabi" - || language->lang() == "farsi" || fars != string::npos - || arab != string::npos) { - os << "\\usepackage[" << extra_encoding - << from_ascii(font_encoding()) - << ",LFE,LAE]{fontenc}\n"; - } else { - os << "\\usepackage[" << extra_encoding - << from_ascii(font_encoding()) + // XeTeX and LuaTeX (with OS fonts) do not need fontenc + if (!useNonTeXFonts && !features.isProvided("fontenc") + && font_encoding() != "default") { + // get main font encodings + vector fontencs = font_encodings(); + // get font encodings of secondary languages + features.getFontEncodings(fontencs); + if (!fontencs.empty()) { + os << "\\usepackage[" + << from_ascii(getStringFromVector(fontencs)) << "]{fontenc}\n"; } } @@ -1514,21 +1568,6 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, os << "}\n"; } - if (!listings_params.empty() || features.isRequired("listings")) - os << "\\usepackage{listings}\n"; - - if (!listings_params.empty()) { - os << "\\lstset{"; - // do not test validity because listings_params is - // supposed to be valid - string par = - InsetListingsParams(listings_params).separatedParams(true); - // we can't support all packages, but we should load the color package - if (par.find("\\color", 0) != string::npos) - features.require("color"); - os << from_utf8(par) - << "}\n"; - } if (!features.isProvided("geometry") && (use_geometry || nonstandard_papersize)) { odocstringstream ods; @@ -1755,6 +1794,9 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, lyxpreamble += "\\synctex=-1\n"; } + // The package options (via \PassOptionsToPackage) + lyxpreamble += from_ascii(features.getPackageOptions()); + // due to interferences with babel and hyperref, the color package has to // be loaded (when it is not already loaded) before babel when hyperref // is used with the colorlinks option, see @@ -1871,6 +1913,13 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, "User specified LaTeX commands.\n" + from_utf8(preamble) + '\n'; + // footmisc must be loaded after setspace + // Load it here to avoid clashes with footmisc loaded in the user + // preamble. For that reason we also pass the options via + // \PassOptionsToPackage in getPreamble() and not here. + if (features.mustProvide("footmisc")) + atlyxpreamble += "\\usepackage{footmisc}\n"; + // subfig loads internally the LaTeX package "caption". As // caption is a very popular package, users will load it in // the preamble. Therefore we must load subfig behind the @@ -1927,7 +1976,8 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, + atlyxpreamble + "\\makeatother\n\n"; // We try to load babel late, in case it interferes with other packages. - // Jurabib, hyperref and varioref have to be called after babel, though. + // Jurabib, hyperref, varioref, bicaption and listings (bug 8995) have to be + // called after babel, though. if (use_babel && !features.isRequired("jurabib") && !features.isRequired("hyperref") && !features.isRequired("varioref") @@ -1939,10 +1989,24 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, features.needBabelLangOptions())) + '\n'; lyxpreamble += from_utf8(features.getBabelPostsettings()); } + if (features.isRequired("bicaption")) + lyxpreamble += "\\usepackage{bicaption}\n"; + if (!listings_params.empty() || features.isRequired("listings")) + lyxpreamble += "\\usepackage{listings}\n"; + if (!listings_params.empty()) { + lyxpreamble += "\\lstset{"; + // do not test validity because listings_params is + // supposed to be valid + string par = + InsetListingsParams(listings_params).separatedParams(true); + lyxpreamble += from_utf8(par); + lyxpreamble += "}\n"; + } // xunicode needs to be loaded at least after amsmath, amssymb, // esint and the other packages that provide special glyphs - if (features.runparams().flavor == OutputParams::XETEX) + if (features.runparams().flavor == OutputParams::XETEX + && useNonTeXFonts) lyxpreamble += "\\usepackage{xunicode}\n"; // Polyglossia must be loaded last @@ -2084,7 +2148,7 @@ LayoutFileIndex const & BufferParams::baseClassID() const } -void BufferParams::makeDocumentClass() +void BufferParams::makeDocumentClass(bool const clone) { if (!baseClass()) return; @@ -2100,15 +2164,17 @@ void BufferParams::makeDocumentClass() for (; it != en; ++it) mods.push_back(*it); - doc_class_ = getDocumentClass(*baseClass(), mods); + doc_class_ = getDocumentClass(*baseClass(), mods, clone); - if (!local_layout.empty()) { - TextClass::ReturnValues success = - doc_class_->read(local_layout, TextClass::MODULE); - if (success != TextClass::OK && success != TextClass::OK_OLDFORMAT) { - docstring const msg = _("Error reading internal layout information"); - frontend::Alert::warning(_("Read Error"), msg); - } + TextClass::ReturnValues success = TextClass::OK; + if (!forced_local_layout_.empty()) + success = doc_class_->read(forced_local_layout_, TextClass::MODULE); + if (!local_layout_.empty() && + (success == TextClass::OK || success == TextClass::OK_OLDFORMAT)) + success = doc_class_->read(local_layout_, TextClass::MODULE); + if (success != TextClass::OK && success != TextClass::OK_OLDFORMAT) { + docstring const msg = _("Error reading internal layout information"); + frontend::Alert::warning(_("Read Error"), msg); } } @@ -2125,6 +2191,24 @@ bool BufferParams::citationModuleCanBeAdded(string const & modName) const } +std::string BufferParams::getLocalLayout(bool forced) const +{ + if (forced) + return doc_class_->forcedLayouts(); + else + return local_layout_; +} + + +void BufferParams::setLocalLayout(string const & layout, bool forced) +{ + if (forced) + forced_local_layout_ = layout; + else + local_layout_ = layout; +} + + bool BufferParams::addLayoutModule(string const & modName) { LayoutModuleList::const_iterator it = layout_modules_.begin(); @@ -2227,7 +2311,7 @@ vector BufferParams::backends() const } -OutputParams::FLAVOR BufferParams::getOutputFlavor(string const format) const +OutputParams::FLAVOR BufferParams::getOutputFlavor(string const & format) const { string const dformat = (format.empty() || format == "default") ? getDefaultOutputFormat() : format; @@ -2284,7 +2368,6 @@ string BufferParams::getDefaultOutputFormat() const && default_output_format != "default") return default_output_format; if (isDocBook() - || useNonTeXFonts || encoding().package() == Encoding::japanese) { vector const formats = exportableFormats(true); if (formats.empty()) @@ -2292,6 +2375,8 @@ string BufferParams::getDefaultOutputFormat() const // return the first we find return formats.front()->name(); } + if (useNonTeXFonts) + return lyxrc.default_otf_view_format; return lyxrc.default_view_format; } @@ -2308,7 +2393,7 @@ Font const BufferParams::getFont() const } -InsetQuotes::QuoteLanguage BufferParams::getQuoteStyle(string const qs) const +InsetQuotes::QuoteLanguage BufferParams::getQuoteStyle(string const & qs) const { return quoteslangtranslator().find(qs); } @@ -2342,13 +2427,19 @@ void BufferParams::readPreamble(Lexer & lex) } -void BufferParams::readLocalLayout(Lexer & lex) +void BufferParams::readLocalLayout(Lexer & lex, bool forced) { - if (lex.getString() != "\\begin_local_layout") + string const expected = forced ? "\\begin_forced_local_layout" : + "\\begin_local_layout"; + if (lex.getString() != expected) lyxerr << "Error (BufferParams::readLocalLayout):" "consistency check failed." << endl; - local_layout = lex.getLongString("\\end_local_layout"); + if (forced) + forced_local_layout_ = + lex.getLongString("\\end_forced_local_layout"); + else + local_layout_ = lex.getLongString("\\end_local_layout"); } @@ -2690,7 +2781,31 @@ string const BufferParams::dvips_options() const string const BufferParams::font_encoding() const { - return (fontenc == "global") ? lyxrc.fontenc : fontenc; + return font_encodings().empty() ? "default" : font_encodings().back(); +} + + +vector const BufferParams::font_encodings() const +{ + string doc_fontenc = (fontenc == "global") ? lyxrc.fontenc : fontenc; + + vector fontencs; + + // "default" means "no explicit font encoding" + if (doc_fontenc != "default") { + fontencs = getVectorFromString(doc_fontenc); + if (!language->fontenc().empty() + && ascii_lowercase(language->fontenc()) != "none") { + vector fencs = getVectorFromString(language->fontenc()); + vector::const_iterator fit = fencs.begin(); + for (; fit != fencs.end(); ++fit) { + if (find(fontencs.begin(), fontencs.end(), *fit) == fontencs.end()) + fontencs.push_back(*fit); + } + } + } + + return fontencs; } @@ -2760,7 +2875,8 @@ void BufferParams::writeEncodingPreamble(otexstream & os, // inputenc must be omitted. // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html if ((!encodings.empty() || package == Encoding::inputenc) - && !features.isRequired("japanese")) { + && !features.isRequired("japanese") + && !features.isProvided("inputenc")) { os << "\\usepackage["; set::const_iterator it = encodings.begin(); set::const_iterator const end = encodings.end(); @@ -2791,7 +2907,9 @@ void BufferParams::writeEncodingPreamble(otexstream & os, break; case Encoding::inputenc: // do not load inputenc if japanese is used - if (features.isRequired("japanese")) + // or if the class provides inputenc + if (features.isRequired("japanese") + || features.isProvided("inputenc")) break; os << "\\usepackage[" << from_ascii(encoding().latexName()) << "]{inputenc}\n"; @@ -2804,6 +2922,15 @@ void BufferParams::writeEncodingPreamble(otexstream & os, os << "\\usepackage{CJK}\n"; break; } + // Load the CJK package if needed by a secondary language. + // If the main encoding is some variant of UTF8, use CJKutf8. + if (encoding().package() != Encoding::CJK && features.mustProvide("CJK")) { + if (encoding().iconvName() == "UTF-8" + && LaTeXFeatures::isAvailable("CJKutf8")) + os << "\\usepackage{CJKutf8}\n"; + else + os << "\\usepackage{CJK}\n"; + } } } @@ -2918,7 +3045,8 @@ Encoding const & BufferParams::encoding() const // FIXME: actually, we should check for the flavor // or runparams.isFullyUnicode() here: // This check will not work with XeTeX/LuaTeX and tex fonts. - // Thus we have to reset the encoding in Buffer::makeLaTeXFile. + // Thus we have to reset the encoding in Buffer::makeLaTeXFile + // (for export) and Buffer::writeLaTeXSource (for preview). if (useNonTeXFonts) return *(encodings.fromLyXName("utf8-plain")); if (inputenc == "auto" || inputenc == "default")