X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferParams.cpp;h=5704940ecd30413daf0a78b3a04c54668100a0ca;hb=0b54650f0e7f1eae39f93444cac6c8525811975b;hp=8143556ade9d4419b9ccab58bfb23920c93206fd;hpb=26ea1e14966c092a7b87c75c19b83a369e79aeb8;p=lyx.git diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 8143556ade..5704940ecd 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -102,9 +102,20 @@ static char const * const tex_graphics[] = { }; - namespace lyx { +// XeTeX with TeX fonts: +// run in 8-bit emulation mode and trick `inputenc` into working with XeTeX +static docstring const xetex_pre_inputenc = from_ascii( + "\\XeTeXinputencoding \"bytes\" % current file\n" + "\\XeTeXdefaultencoding \"bytes\" % included files\n" + "\\makeatletter\n" + "\\let\\origUmathchar\\Umathchar\n" + "\\let\\Umathchar\\@undefined\n"); +static docstring const xetex_post_inputenc = from_ascii( + "\\let\\Umathchar\\origUmathchar\n" + "\\makeatother\n"); + // Local translators namespace { @@ -308,7 +319,7 @@ bool inSystemDir(FileName const & document_dir, string & system_dir) string dir = document_dir.absFileName(); - for (int i = 0; i < 2; ++i) { + for (int i = 0; i < 3; ++i) { dir = addPath(dir, ".."); if (!fileSearch(dir, "configure.py").empty() && !fileSearch(dir, "chkconfig.ltx").empty()) { @@ -380,7 +391,7 @@ BufferParams::BufferParams() : pimpl_(new Impl) { setBaseClass(defaultBaseclass()); - cite_engine_.push_back("basic"); + cite_engine_ = "basic"; cite_engine_type_ = ENGINE_TYPE_DEFAULT; makeDocumentClass(); paragraph_separation = ParagraphIndentSeparation; @@ -435,6 +446,7 @@ BufferParams::BufferParams() columns = 1; listings_params = string(); pagestyle = "default"; + tablestyle = "default"; suppress_date = false; justification = true; // no color is the default (white) @@ -901,8 +913,7 @@ string BufferParams::readToken(Lexer & lex, string const & token, use_package(package, packagetranslator().find(use)); } else if (token == "\\cite_engine") { lex.eatLine(); - vector engine = getVectorFromString(lex.getString()); - setCiteEngine(engine); + cite_engine_ = lex.getString(); } else if (token == "\\cite_engine_type") { string engine_type; lex >> engine_type; @@ -1053,6 +1064,8 @@ string BufferParams::readToken(Lexer & lex, string const & token, sides = sidestranslator().find(psides); } else if (token == "\\paperpagestyle") { lex >> pagestyle; + } else if (token == "\\tablestyle") { + lex >> tablestyle; } else if (token == "\\bullet") { readBullets(lex); } else if (token == "\\bulletLaTeX") { @@ -1071,6 +1084,8 @@ string BufferParams::readToken(Lexer & lex, string const & token, spacing().set(spacetranslator().find(nspacing), tmp_val); } else if (token == "\\float_placement") { lex >> float_placement; + } else if (token == "\\float_alignment") { + lex >> float_alignment; } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") { string toktmp = pdfoptions().readToken(lex, token); @@ -1261,9 +1276,10 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const os << "\\bibtex_command " << bibtex_command << '\n'; os << "\\index_command " << index_command << '\n'; - if (!float_placement.empty()) { + if (!float_placement.empty()) os << "\\float_placement " << float_placement << '\n'; - } + if (!float_alignment.empty()) + os << "\\float_alignment " << float_alignment << '\n'; os << "\\paperfontsize " << fontsize << '\n'; spacing().writeFile(os); @@ -1279,17 +1295,10 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const os << "\n\\cite_engine "; - if (!cite_engine_.empty()) { - LayoutModuleList::const_iterator be = cite_engine_.begin(); - LayoutModuleList::const_iterator en = cite_engine_.end(); - for (LayoutModuleList::const_iterator it = be; it != en; ++it) { - if (it != be) - os << ','; - os << *it; - } - } else { + if (!cite_engine_.empty()) + os << cite_engine_; + else os << "basic"; - } os << "\n\\cite_engine_type " << theCiteEnginesList.getTypeAsString(cite_engine_type_); @@ -1401,7 +1410,8 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const << "\n\\dynamic_quotes " << dynamic_quotes << "\n\\papercolumns " << columns << "\n\\papersides " << sides - << "\n\\paperpagestyle " << pagestyle << '\n'; + << "\n\\paperpagestyle " << pagestyle + << "\n\\tablestyle " << tablestyle << '\n'; if (!listings_params.empty()) os << "\\listings_params \"" << InsetListingsParams(listings_params).encodedString() << "\"\n"; @@ -1702,7 +1712,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, bool const use_babel = features.useBabel() && !features.isProvided("babel"); bool const use_polyglossia = features.usePolyglossia(); bool const global = lyxrc.language_global_options; - if (use_babel || (use_polyglossia && global)) { + if (features.useBabel() || (use_polyglossia && global)) { language_options << features.getBabelLanguages(); if (!language->babel().empty()) { if (!language_options.str().empty()) @@ -1750,6 +1760,16 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, os << "\\usepackage{unicode-math}\n"; } + // load CJK support package before font selection + // (see autotests/export/latex/CJK/micro-sign_utf8-cjk-libertine.lyx) + if (!useNonTeXFonts && encoding().package() != Encoding::none && inputenc != "utf8x" + && (encoding().package() == Encoding::CJK || features.mustProvide("CJK"))) { + if (inputenc == "utf8-cjk" || inputenc == "utf8") + os << "\\usepackage{CJKutf8}\n"; + else + os << "\\usepackage[encapsulated]{CJK}\n"; + } + // font selection must be done before loading fontenc.sty string const fonts = loadFonts(features); if (!fonts.empty()) @@ -1760,7 +1780,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, << from_ascii(fonts_default_family) << "}\n"; // set font encoding - // XeTeX and LuaTeX (with OS fonts) do not need fontenc + // non-TeX fonts use font encoding TU (set by fontspec) if (!useNonTeXFonts && !features.isProvided("fontenc") && main_font_encoding() != "default") { // get main font encodings @@ -1774,6 +1794,12 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, } } + // Load textcomp and pmboxdraw before (lua)inputenc (#11454) + if (features.mustProvide("textcomp")) + os << "\\usepackage{textcomp}\n"; + if (features.mustProvide("pmboxdraw")) + os << "\\usepackage{pmboxdraw}\n"; + // handle inputenc etc. writeEncodingPreamble(os, features); @@ -2247,8 +2273,8 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, << "\\makeatother\n\n"; // We try to load babel late, in case it interferes with other packages. - // Jurabib, hyperref, varioref, bicaption and listings (bug 8995) have to be - // called after babel, though. + // Jurabib, hyperref, varioref, bicaption, menukeys and listings (bug 8995) + // have to be called after babel, though. if (use_babel && !features.isRequired("jurabib") && !features.isRequired("hyperref") && !features.isRequired("varioref") @@ -2264,20 +2290,31 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, if (!listings_params.empty() || features.mustProvide("listings") || features.mustProvide("minted")) { - if (features.mustProvide("listings")) - os << "\\usepackage{listings}\n"; - else + if (use_minted) os << "\\usepackage{minted}\n"; - } - if (!listings_params.empty()) { - if (features.mustProvide("listings")) - os << "\\lstset{"; else + os << "\\usepackage{listings}\n"; + } + string lst_params = listings_params; + // If minted, do not output the language option (bug 11203) + if (use_minted && contains(lst_params, "language=")) { + vector opts = + getVectorFromString(lst_params, ",", false); + for (size_t i = 0; i < opts.size(); ++i) { + if (prefixIs(opts[i], "language=")) + opts.erase(opts.begin() + i--); + } + lst_params = getStringFromVector(opts, ","); + } + if (!lst_params.empty()) { + if (use_minted) os << "\\setminted{"; + else + os << "\\lstset{"; // do not test validity because listings_params is // supposed to be valid string par = - InsetListingsParams(listings_params).separatedParams(true); + InsetListingsParams(lst_params).separatedParams(true); os << from_utf8(par); os << "}\n"; } @@ -2288,8 +2325,8 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, // esint and the other packages that provide special glyphs if (features.mustProvide("tipa") && useNonTeXFonts && !features.isProvided("xunicode")) { - // The package officially only supports XeTeX, but also works - // with LuaTeX. Thus we work around its XeTeX test. + // The `xunicode` package officially only supports XeTeX, + // but also works with LuaTeX. We work around its XeTeX test. if (features.runparams().flavor != OutputParams::XETEX) { os << "% Pretend to xunicode that we are XeTeX\n" << "\\def\\XeTeXpicfile{}\n"; @@ -2297,6 +2334,10 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, os << "\\usepackage{xunicode}\n"; } + // covington must be loaded after beamerarticle + if (features.isRequired("covington")) + os << "\\usepackage{covington}\n"; + // Polyglossia must be loaded last ... if (use_polyglossia) { // call the package @@ -2322,19 +2363,25 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, } // ... but before biblatex (see #7065) - if (features.mustProvide("biblatex") + if ((features.mustProvide("biblatex") + || features.isRequired("biblatex-chicago")) + && !features.isProvided("biblatex-chicago") && !features.isProvided("biblatex-natbib") && !features.isProvided("natbib-internal") && !features.isProvided("natbib") && !features.isProvided("jurabib")) { + // The biblatex-chicago package has a differing interface + // it uses a wrapper package and loads styles via fixed options + bool const chicago = features.isRequired("biblatex-chicago"); string delim = ""; string opts; os << "\\usepackage"; if (!biblatex_bibstyle.empty() - && (biblatex_bibstyle == biblatex_citestyle)) { + && (biblatex_bibstyle == biblatex_citestyle) + && !chicago) { opts = "style=" + biblatex_bibstyle; delim = ","; - } else { + } else if (!chicago) { if (!biblatex_bibstyle.empty()) { opts = "bibstyle=" + biblatex_bibstyle; delim = ","; @@ -2357,11 +2404,19 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, opts += delim + "backend=bibtex"; delim = ","; } + if (!bib_encoding.empty() && encodings.fromLyXName(bib_encoding)) { + opts += delim + "bibencoding=" + + encodings.fromLyXName(bib_encoding)->latexName(); + delim = ","; + } if (!biblio_opts.empty()) opts += delim + biblio_opts; if (!opts.empty()) os << "[" << opts << "]"; - os << "{biblatex}\n"; + if (chicago) + os << "{biblatex-chicago}\n"; + else + os << "{biblatex}\n"; } @@ -2374,6 +2429,11 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, os << '\n'; } + // Since menukeys uses catoptions, which does some heavy changes on key-value options, + // it is recommended to load menukeys as the last package (even after hyperref) + if (features.isRequired("menukeys")) + os << "\\usepackage{menukeys}\n"; + docstring const i18npreamble = features.getTClassI18nPreamble(use_babel, use_polyglossia, use_minted); @@ -2391,6 +2451,7 @@ void BufferParams::useClassDefaults() sides = tclass.sides(); columns = tclass.columns(); pagestyle = tclass.pagestyle(); + tablestyle = tclass.tablestyle(); use_default_options = true; // Only if class has a ToC hierarchy if (tclass.hasTocLevels()) { @@ -2407,6 +2468,7 @@ bool BufferParams::hasClassDefaults() const return sides == tclass.sides() && columns == tclass.columns() && pagestyle == tclass.pagestyle() + && tablestyle == tclass.tablestyle() && use_default_options && secnumdepth == tclass.secnumdepth() && tocdepth == tclass.tocdepth(); @@ -2433,7 +2495,7 @@ void BufferParams::setDocumentClass(DocumentClassConstPtr tc) } -bool BufferParams::setBaseClass(string const & classname) +bool BufferParams::setBaseClass(string const & classname, string const & path) { LYXERR(Debug::TCLASS, "setBaseClass: " << classname); LayoutFileList & bcl = LayoutFileList::get(); @@ -2449,7 +2511,7 @@ bool BufferParams::setBaseClass(string const & classname) bcl.addEmptyClass(classname); } - bool const success = bcl[classname].load(); + bool const success = bcl[classname].load(path); if (!success) { docstring s = bformat(_("Due to some error in it, the layout file:\n" @@ -2490,18 +2552,12 @@ void BufferParams::makeDocumentClass(bool const clone) invalidateConverterCache(); LayoutModuleList mods; - LayoutModuleList ces; LayoutModuleList::iterator it = layout_modules_.begin(); LayoutModuleList::iterator en = layout_modules_.end(); for (; it != en; ++it) mods.push_back(*it); - it = cite_engine_.begin(); - en = cite_engine_.end(); - for (; it != en; ++it) - ces.push_back(*it); - - doc_class_ = getDocumentClass(*baseClass(), mods, ces, clone); + doc_class_ = getDocumentClass(*baseClass(), mods, cite_engine_, clone); TextClass::ReturnValues success = TextClass::OK; if (!forced_local_layout_.empty()) @@ -2523,12 +2579,6 @@ bool BufferParams::layoutModuleCanBeAdded(string const & modName) const } -bool BufferParams::citationModuleCanBeAdded(string const & modName) const -{ - return cite_engine_.moduleCanBeAdded(modName, baseClass()); -} - - docstring BufferParams::getLocalLayout(bool forced) const { if (forced) @@ -2592,13 +2642,17 @@ FormatList const & BufferParams::exportableFormats(bool only_viewable) const if (useNonTeXFonts) { excludes.insert("latex"); excludes.insert("pdflatex"); - } - FormatList result = - theConverters().getReachable(backs[0], only_viewable, true, excludes); + } else if (inputenc != "ascii" && inputenc != "utf8" + && inputenc != "utf8x" && inputenc != "utf8-plain") + // XeTeX with TeX fonts requires input encoding ascii or utf8 + // (https://www.tug.org/pipermail/xetex/2010-April/016452.html). + excludes.insert("xetex"); + FormatList result = theConverters().getReachable(backs[0], only_viewable, + true, excludes); for (vector::const_iterator it = backs.begin() + 1; it != backs.end(); ++it) { FormatList r = theConverters().getReachable(*it, only_viewable, - false, excludes); + false, excludes); result.insert(result.end(), r.begin(), r.end()); } sort(result.begin(), result.end(), Format::formatSorter); @@ -2622,7 +2676,9 @@ vector BufferParams::backends() const v.push_back("pdflatex"); v.push_back("latex"); } - v.push_back("xetex"); + if (useNonTeXFonts || inputenc == "ascii" || inputenc == "utf8" + || inputenc == "utf8x" || inputenc == "utf8-plain") + v.push_back("xetex"); v.push_back("luatex"); v.push_back("dviluatex"); } @@ -3114,7 +3170,12 @@ string const BufferParams::dvips_options() const string const BufferParams::main_font_encoding() const { - return font_encodings().empty() ? "default" : font_encodings().back(); + if (font_encodings().empty()) { + if (ascii_lowercase(language->fontenc(*this)) == "none") + return "none"; + return "default"; + } + return font_encodings().back(); } @@ -3180,12 +3241,8 @@ docstring BufferParams::getGraphicsDriver(string const & package) const void BufferParams::writeEncodingPreamble(otexstream & os, LaTeXFeatures & features) const { - // XeTeX/LuaTeX: (see also #9740) - // With Unicode fonts we use utf8-plain without encoding package. - // With TeX fonts, we cannot use utf8-plain, but "inputenc" fails. - // XeTeX must use ASCII encoding (see Buffer.cpp), - // for LuaTeX, we load "luainputenc" (see below). - if (useNonTeXFonts || features.runparams().flavor == OutputParams::XETEX) + // With no-TeX fonts we use utf8-plain without encoding package. + if (useNonTeXFonts) return; if (inputenc == "auto") { @@ -3197,7 +3254,8 @@ void BufferParams::writeEncodingPreamble(otexstream & os, // Create list of inputenc options: set encoding_set; // luainputenc fails with more than one encoding - if (!features.runparams().isFullUnicode()) // if we reach this point, this means LuaTeX with TeX fonts + if (features.runparams().flavor != OutputParams::LUATEX + && features.runparams().flavor != OutputParams::DVILUATEX) // list all input encodings used in the document encoding_set = features.getEncodingSet(doc_encoding); @@ -3227,17 +3285,16 @@ void BufferParams::writeEncodingPreamble(otexstream & os, else os << "]{inputenc}\n"; } - if (package == Encoding::CJK || features.mustProvide("CJK")) { - if (language->encoding()->name() == "utf8-cjk" - && LaTeXFeatures::isAvailable("CJKutf8")) - os << "\\usepackage{CJKutf8}\n"; - else - os << "\\usepackage{CJK}\n"; - } } else if (inputenc != "default") { switch (encoding().package()) { case Encoding::none: + case Encoding::CJK: case Encoding::japanese: + if (encoding().iconvName() != "UTF-8" + && !features.runparams().isFullUnicode()) + // don't default to [utf8]{inputenc} with TeXLive >= 18 + os << "\\ifdefined\\UseRawInputEncoding\n" + << " \\UseRawInputEncoding\\fi\n"; break; case Encoding::inputenc: // do not load inputenc if japanese is used @@ -3245,30 +3302,23 @@ void BufferParams::writeEncodingPreamble(otexstream & os, if (features.isRequired("japanese") || features.isProvided("inputenc")) break; + if (features.runparams().flavor == OutputParams::XETEX) + os << xetex_pre_inputenc; os << "\\usepackage[" << from_ascii(encoding().latexName()); if (features.runparams().flavor == OutputParams::LUATEX || features.runparams().flavor == OutputParams::DVILUATEX) os << "]{luainputenc}\n"; else os << "]{inputenc}\n"; - break; - case Encoding::CJK: - if (encoding().name() == "utf8-cjk" - && LaTeXFeatures::isAvailable("CJKutf8")) - os << "\\usepackage{CJKutf8}\n"; - else - os << "\\usepackage{CJK}\n"; + if (features.runparams().flavor == OutputParams::XETEX) + os << xetex_post_inputenc; 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"; - } + } + if (inputenc == "default" || features.isRequired("japanese")) { + // don't default to [utf8]{inputenc} with TeXLive >= 18 + os << "\\ifdefined\\UseRawInputEncoding\n"; + os << " \\UseRawInputEncoding\\fi\n"; } } @@ -3381,12 +3431,6 @@ string const BufferParams::loadFonts(LaTeXFeatures & features) const Encoding const & BufferParams::encoding() const { // Main encoding for LaTeX output. - // - // Exception: XeTeX with 8-bit TeX fonts requires ASCII (see #9740). - // As the "flavor" is only known once export started, this - // cannot be handled here. Instead, runparams.encoding is set - // to ASCII in Buffer::makeLaTeXFile (for export) - // and Buffer::writeLaTeXSource (for preview). if (useNonTeXFonts) return *(encodings.fromLyXName("utf8-plain")); if (inputenc == "auto" || inputenc == "default") @@ -3400,30 +3444,6 @@ Encoding const & BufferParams::encoding() const } -bool BufferParams::addCiteEngine(string const & engine) -{ - LayoutModuleList::const_iterator it = cite_engine_.begin(); - LayoutModuleList::const_iterator en = cite_engine_.end(); - for (; it != en; ++it) - if (*it == engine) - return false; - cite_engine_.push_back(engine); - return true; -} - - -bool BufferParams::addCiteEngine(vector const & engine) -{ - vector::const_iterator it = engine.begin(); - vector::const_iterator en = engine.end(); - bool ret = true; - for (; it != en; ++it) - if (!addCiteEngine(*it)) - ret = false; - return ret; -} - - string const & BufferParams::defaultBiblioStyle() const { if (!biblio_style.empty()) @@ -3458,20 +3478,6 @@ string BufferParams::getCiteAlias(string const & s) const } -void BufferParams::setCiteEngine(string const & engine) -{ - clearCiteEngine(); - addCiteEngine(engine); -} - - -void BufferParams::setCiteEngine(vector const & engine) -{ - clearCiteEngine(); - addCiteEngine(engine); -} - - vector BufferParams::citeCommands() const { static CitationStyle const default_style; @@ -3535,8 +3541,7 @@ string const BufferParams::bibtexCommand() const bool BufferParams::useBiblatex() const { - return theCiteEnginesList[citeEngine().list().front()] - ->getCiteFramework() == "biblatex"; + return theCiteEnginesList[citeEngine()]->getCiteFramework() == "biblatex"; } @@ -3546,4 +3551,32 @@ void BufferParams::invalidateConverterCache() const pimpl_->isViewCacheValid = false; } + +// We shouldn't need to reset the params here, since anything +// we need will be recopied. +void BufferParams::copyForAdvFR(const BufferParams & bp) +{ + string const & lang = bp.language->lang(); + setLanguage(lang); + layout_modules_ = bp.layout_modules_; + string const & doc_class = bp.documentClass().name(); + setBaseClass(doc_class); +} + + +void BufferParams::setBibFileEncoding(string const & file, string const & enc) +{ + bib_encodings[file] = enc; +} + + +string const BufferParams::bibFileEncoding(string const & file) const +{ + if (bib_encodings.find(file) == bib_encodings.end()) + return string(); + return bib_encodings.find(file)->second; +} + + + } // namespace lyx