X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferParams.cpp;h=fd3c7e4411ab32693055fbb6d3320fc97d1ba60a;hb=0bff66b8a5a8a289dfb36bfb339e9586b3a02d51;hp=640f3544d6d0fb3a5c96225881295404eae6b5f5;hpb=7cbeed2e40691570b5572c58ce51222d487400e6;p=lyx.git diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 640f3544d6..fd3c7e4411 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -24,6 +24,7 @@ #include "Bullet.h" #include "Color.h" #include "ColorSet.h" +#include "Converter.h" #include "Encoding.h" #include "HSpace.h" #include "IndicesList.h" @@ -364,6 +365,7 @@ BufferParams::BufferParams() use_esint = package_auto; use_mhchem = package_auto; use_mathdots = package_auto; + use_undertilde = package_auto; cite_engine_ = ENGINE_BASIC; use_bibtopic = false; use_indices = false; @@ -375,18 +377,19 @@ BufferParams::BufferParams() tocdepth = 3; language = default_language; fontenc = "global"; - fontsRoman = "default"; - fontsSans = "default"; - fontsTypewriter = "default"; - fontsDefaultFamily = "default"; - useXetex = false; - fontsSC = false; - fontsOSF = false; - fontsSansScale = 100; - fontsTypewriterScale = 100; + fonts_roman = "default"; + fonts_sans = "default"; + fonts_typewriter = "default"; + fonts_default_family = "default"; + useNonTeXFonts = false; + fonts_expert_sc = false; + fonts_old_figures = false; + fonts_sans_scale = 100; + fonts_typewriter_scale = 100; inputenc = "auto"; - graphicsDriver = "default"; - defaultOutputFormat = "default"; + lang_package = "default"; + graphics_driver = "default"; + default_output_format = "default"; bibtex_command = "default"; index_command = "default"; sides = OneSide; @@ -413,6 +416,7 @@ BufferParams::BufferParams() html_be_strict = false; html_math_output = MathML; html_math_img_scale = 1.0; + html_css_as_file = false; output_sync = false; use_refstyle = true; @@ -572,8 +576,8 @@ string BufferParams::readToken(Lexer & lex, string const & token, "document cannot be compiled until the following\n" "prerequisites are installed:\n" "\t%2$s\n" - "See section 3.1.2.2 of the User's Guide for\n" - "more information."), desc, prereqs); + "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); } @@ -601,12 +605,15 @@ string BufferParams::readToken(Lexer & lex, string const & token, lex >> suppress_date; } else if (token == "\\language") { readLanguage(lex); + } else if (token == "\\language_package") { + lex.eatLine(); + lang_package = lex.getString(); } else if (token == "\\inputencoding") { lex >> inputenc; } else if (token == "\\graphics") { readGraphicsDriver(lex); } else if (token == "\\default_output_format") { - lex >> defaultOutputFormat; + lex >> default_output_format; } else if (token == "\\bibtex_command") { lex.eatLine(); bibtex_command = lex.getString(); @@ -618,27 +625,27 @@ string BufferParams::readToken(Lexer & lex, string const & token, fontenc = lex.getString(); } else if (token == "\\font_roman") { lex.eatLine(); - fontsRoman = lex.getString(); + fonts_roman = lex.getString(); } else if (token == "\\font_sans") { lex.eatLine(); - fontsSans = lex.getString(); + fonts_sans = lex.getString(); } else if (token == "\\font_typewriter") { lex.eatLine(); - fontsTypewriter = lex.getString(); + fonts_typewriter = lex.getString(); } else if (token == "\\font_default_family") { - lex >> fontsDefaultFamily; - } else if (token == "\\use_xetex") { - lex >> useXetex; + lex >> fonts_default_family; + } else if (token == "\\use_non_tex_fonts") { + lex >> useNonTeXFonts; } else if (token == "\\font_sc") { - lex >> fontsSC; + lex >> fonts_expert_sc; } else if (token == "\\font_osf") { - lex >> fontsOSF; + lex >> fonts_old_figures; } else if (token == "\\font_sf_scale") { - lex >> fontsSansScale; + lex >> fonts_sans_scale; } else if (token == "\\font_tt_scale") { - lex >> fontsTypewriterScale; + lex >> fonts_typewriter_scale; } else if (token == "\\font_cjk") { - lex >> fontsCJK; + lex >> fonts_cjk; } else if (token == "\\paragraph_separation") { string parsep; lex >> parsep; @@ -680,6 +687,10 @@ string BufferParams::readToken(Lexer & lex, string const & token, int usemathdots; lex >> usemathdots; use_mathdots = packagetranslator().find(usemathdots); + } else if (token == "\\use_undertilde") { + int useundertilde; + lex >> useundertilde; + use_undertilde = packagetranslator().find(useundertilde); } else if (token == "\\cite_engine") { string engine; lex >> engine; @@ -846,6 +857,8 @@ string BufferParams::readToken(Lexer & lex, string const & token, html_math_output = static_cast(temp); } else if (token == "\\html_be_strict") { lex >> html_be_strict; + } else if (token == "\\html_css_as_file") { + lex >> html_css_as_file; } else if (token == "\\html_math_img_scale") { lex >> html_math_img_scale; } else if (token == "\\html_latex_start") { @@ -902,30 +915,30 @@ void BufferParams::writeFile(ostream & os) const } // removed modules - if (!removedModules_.empty()) { + if (!removed_modules_.empty()) { os << "\\begin_removed_modules" << '\n'; - list::const_iterator it = removedModules_.begin(); - list::const_iterator en = removedModules_.end(); + list::const_iterator it = removed_modules_.begin(); + list::const_iterator en = removed_modules_.end(); for (; it != en; it++) os << *it << '\n'; os << "\\end_removed_modules" << '\n'; } // the modules - if (!layoutModules_.empty()) { + if (!layout_modules_.empty()) { os << "\\begin_modules" << '\n'; - LayoutModuleList::const_iterator it = layoutModules_.begin(); - LayoutModuleList::const_iterator en = layoutModules_.end(); + LayoutModuleList::const_iterator it = layout_modules_.begin(); + LayoutModuleList::const_iterator en = layout_modules_.end(); for (; it != en; it++) os << *it << '\n'; os << "\\end_modules" << '\n'; } // includeonly - if (!includedChildren_.empty()) { + if (!included_children_.empty()) { os << "\\begin_includeonly" << '\n'; - list::const_iterator it = includedChildren_.begin(); - list::const_iterator en = includedChildren_.end(); + list::const_iterator it = included_children_.begin(); + list::const_iterator en = included_children_.end(); for (; it != en; it++) os << *it << '\n'; os << "\\end_includeonly" << '\n'; @@ -945,23 +958,24 @@ void BufferParams::writeFile(ostream & os) const // then the text parameters if (language != ignore_language) os << "\\language " << language->lang() << '\n'; - os << "\\inputencoding " << inputenc + os << "\\language_package " << lang_package + << "\n\\inputencoding " << inputenc << "\n\\fontencoding " << fontenc - << "\n\\font_roman " << fontsRoman - << "\n\\font_sans " << fontsSans - << "\n\\font_typewriter " << fontsTypewriter - << "\n\\font_default_family " << fontsDefaultFamily - << "\n\\use_xetex " << convert(useXetex) - << "\n\\font_sc " << convert(fontsSC) - << "\n\\font_osf " << convert(fontsOSF) - << "\n\\font_sf_scale " << fontsSansScale - << "\n\\font_tt_scale " << fontsTypewriterScale + << "\n\\font_roman " << fonts_roman + << "\n\\font_sans " << fonts_sans + << "\n\\font_typewriter " << fonts_typewriter + << "\n\\font_default_family " << fonts_default_family + << "\n\\use_non_tex_fonts " << convert(useNonTeXFonts) + << "\n\\font_sc " << convert(fonts_expert_sc) + << "\n\\font_osf " << convert(fonts_old_figures) + << "\n\\font_sf_scale " << fonts_sans_scale + << "\n\\font_tt_scale " << fonts_typewriter_scale << '\n'; - if (!fontsCJK.empty()) { - os << "\\font_cjk " << fontsCJK << '\n'; + if (!fonts_cjk.empty()) { + os << "\\font_cjk " << fonts_cjk << '\n'; } - os << "\n\\graphics " << graphicsDriver << '\n'; - os << "\\default_output_format " << defaultOutputFormat << '\n'; + os << "\n\\graphics " << graphics_driver << '\n'; + os << "\\default_output_format " << default_output_format << '\n'; os << "\\output_sync " << output_sync << '\n'; if (!output_sync_macro.empty()) os << "\\output_sync_macro \"" << output_sync_macro << "\"\n"; @@ -982,6 +996,7 @@ void BufferParams::writeFile(ostream & os) const << "\n\\use_esint " << use_esint << "\n\\use_mhchem " << use_mhchem << "\n\\use_mathdots " << use_mathdots + << "\n\\use_undertilde " << use_undertilde << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_) << "\n\\use_bibtopic " << convert(use_bibtopic) << "\n\\use_indices " << convert(use_indices) @@ -1083,9 +1098,10 @@ void BufferParams::writeFile(ostream & os) const } os << "\\tracking_changes " << convert(trackChanges) << '\n' - << "\\output_changes " << convert(outputChanges) << '\n' - << "\\html_math_output " << html_math_output << '\n' - << "\\html_be_strict " << convert(html_be_strict) << '\n'; + << "\\output_changes " << convert(outputChanges) << '\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'; if (html_math_img_scale != 1.0) os << "\\html_math_img_scale " << convert(html_math_img_scale) << '\n'; @@ -1109,6 +1125,7 @@ void BufferParams::validate(LaTeXFeatures & features) const switch (features.runparams().flavor) { case OutputParams::LATEX: + case OutputParams::DVILUATEX: if (dvipost) { features.require("ct-dvipost"); features.require("dvipost"); @@ -1120,6 +1137,7 @@ void BufferParams::validate(LaTeXFeatures & features) const features.require("ct-none"); } break; + case OutputParams::LUATEX: case OutputParams::PDFLATEX: case OutputParams::XETEX: if (xcolorulem) { @@ -1151,6 +1169,8 @@ void BufferParams::validate(LaTeXFeatures & features) const features.require("mhchem"); if (use_mathdots == package_on) features.require("mathdots"); + if (use_undertilde == package_on) + features.require("undertilde"); // Document-level line spacing if (spacing().getSpace() != Spacing::Single && !spacing().isDefault()) @@ -1187,8 +1207,9 @@ void BufferParams::validate(LaTeXFeatures & features) const features.require("color"); } - if (useXetex) - features.require("xetex"); + if (features.runparams().flavor == OutputParams::XETEX + && useNonTeXFonts) + features.require("polyglossia"); if (language->lang() == "vietnamese") features.require("vietnamese"); @@ -1197,9 +1218,18 @@ void BufferParams::validate(LaTeXFeatures & features) const } -bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, - TexRow & texrow, FileName const & filepath) const +bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, + FileName const & filepath) const { + // http://www.tug.org/texmf-dist/doc/latex/base/fixltx2e.pdf + // !! To use the Fix-cm package, load it before \documentclass, and use the command + // \RequirePackage to do so, rather than the normal \usepackage + // Do not try to load any other package before the document class, unless you + // have a thorough understanding of the LATEX internals and know exactly what you + // are doing! + if (features.mustProvide("fix-cm")) + os << "\\RequirePackage{fix-cm}\n"; + os << "\\documentclass"; DocumentClass const & tclass = documentClass(); @@ -1335,33 +1365,35 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, } os << '{' << from_ascii(tclass.latexname()) << "}\n"; - texrow.newline(); // end of \documentclass defs - if (useXetex) { + // if we use fontspec, we have to load the AMS packages here + string const ams = features.loadAMSPackages(); + if (useNonTeXFonts && !ams.empty()) + os << from_ascii(ams); + + if (useNonTeXFonts) os << "\\usepackage{fontspec}\n"; - texrow.newline(); - } // font selection must be done before loading fontenc.sty string const fonts = - loadFonts(fontsRoman, fontsSans, - fontsTypewriter, fontsSC, fontsOSF, - fontsSansScale, fontsTypewriterScale, useXetex); - if (!fonts.empty()) { - os << from_ascii(fonts); - texrow.newline(); - } - if (fontsDefaultFamily != "default") + loadFonts(fonts_roman, fonts_sans, fonts_typewriter, + fonts_expert_sc, fonts_old_figures, + fonts_sans_scale, fonts_typewriter_scale, + useNonTeXFonts, features); + if (!fonts.empty()) + os << from_utf8(fonts); + + if (fonts_default_family != "default") os << "\\renewcommand{\\familydefault}{\\" - << from_ascii(fontsDefaultFamily) << "}\n"; + << 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 works without fontenc + // XeTeX and LuaTeX (with OS fonts) work without fontenc if (font_encoding() != "default" && language->lang() != "japanese" - && !useXetex && !tclass.provides("fontenc")) { + && !useNonTeXFonts && !tclass.provides("fontenc")) { size_t fars = language_options.str().find("farsi"); size_t arab = language_options.str().find("arabic"); if (language->lang() == "arabic_arabi" @@ -1369,23 +1401,22 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, || arab != string::npos) { os << "\\usepackage[" << from_ascii(font_encoding()) << ",LFE,LAE]{fontenc}\n"; - texrow.newline(); } else { os << "\\usepackage[" << from_ascii(font_encoding()) << "]{fontenc}\n"; - texrow.newline(); } } // handle inputenc etc. - writeEncodingPreamble(os, features, texrow); + writeEncodingPreamble(os, features); // includeonly - if (!features.runparams().includeall && !includedChildren_.empty()) { + if (!features.runparams().includeall && !included_children_.empty()) { os << "\\includeonly{"; - list::const_iterator it = includedChildren_.begin(); + list::const_iterator it = included_children_.begin(); + list::const_iterator en = included_children_.end(); bool first = true; - for (; it != includedChildren_.end() ; ++it) { + for (; it != en; ++it) { string incfile = *it; FileName inc = makeAbsPath(incfile, filepath.absFileName()); string mangled = DocFileName(changeExtension(inc.absFileName(), ".tex")). @@ -1405,10 +1436,9 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, os << "}\n"; } - if (!listings_params.empty() || features.isRequired("listings")) { + if (!listings_params.empty() || features.isRequired("listings")) os << "\\usepackage{listings}\n"; - texrow.newline(); - } + if (!listings_params.empty()) { os << "\\lstset{"; // do not test validity because listings_params is @@ -1418,13 +1448,8 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, // 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); - // count the number of newlines - for (size_t i = 0; i < par.size(); ++i) - if (par[i] == '\n') - texrow.newline(); - os << "}\n"; - texrow.newline(); + os << from_utf8(par) + << "}\n"; } if (!tclass.provides("geometry") && (use_geometry || nonstandard_papersize)) { @@ -1539,6 +1564,7 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, // default papersize ie PAPER_DEFAULT switch (lyxrc.default_papersize) { case PAPER_DEFAULT: // keep compiler happy + break; case PAPER_USLETTER: ods << ",letterpaper"; break; @@ -1593,7 +1619,6 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, if (!g_options.empty()) os << '[' << g_options << ']'; os << "{geometry}\n"; - texrow.newline(); // output this only if use_geometry is true if (use_geometry) { os << "\\geometry{verbose"; @@ -1614,21 +1639,16 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, if (!columnsep.empty()) os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString()); os << "}\n"; - texrow.newline(); } } else if (orientation == ORIENTATION_LANDSCAPE || papersize != PAPER_DEFAULT) { features.require("papersize"); } - if (tokenPos(tclass.opt_pagestyle(), - '|', pagestyle) >= 0) { - if (pagestyle == "fancy") { + if (tokenPos(tclass.opt_pagestyle(), '|', pagestyle) >= 0) { + if (pagestyle == "fancy") os << "\\usepackage{fancyhdr}\n"; - texrow.newline(); - } os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n"; - texrow.newline(); } // only output when the background color is not default @@ -1655,13 +1675,11 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, os << "\\setcounter{secnumdepth}{" << secnumdepth << "}\n"; - texrow.newline(); } if (tocdepth != tclass.tocdepth()) { os << "\\setcounter{tocdepth}{" << tocdepth << "}\n"; - texrow.newline(); } } @@ -1686,22 +1704,20 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, os << "\\setlength{\\parskip}{\\medskipamount}\n"; break; } - texrow.newline(); os << "\\setlength{\\parindent}{0pt}\n"; - texrow.newline(); } else { // when separation by indentation // only output something when a width is given if (getIndentation().asLyXCommand() != "default") { os << "\\setlength{\\parindent}{" - << from_utf8(getIndentation().asLatexCommand()) + << from_utf8(getIndentation().asLatexCommand()) << "}\n"; - texrow.newline(); } } // Now insert the LyX specific LaTeX commands... docstring lyxpreamble; + features.resolveAlternatives(); if (output_sync) { if (!output_sync_macro.empty()) @@ -1766,15 +1782,15 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, // to access the stream itself in PDFOptions. os << lyxpreamble; - int lines = - int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n')); - OutputParams tmp_params = features.runparams(); - lines += pdfoptions().writeLaTeX(tmp_params, os, + pdfoptions().writeLaTeX(tmp_params, os, documentClass().provides("hyperref")); - texrow.newlines(lines); // set back for the rest lyxpreamble.clear(); + // correctly break URLs with hyperref and dvi output + if (features.runparams().flavor == OutputParams::LATEX + && features.isAvailable("breakurl")) + lyxpreamble += "\\usepackage{breakurl}\n"; } else if (features.isRequired("nameref")) // hyperref loads this automatically lyxpreamble += "\\usepackage{nameref}\n"; @@ -1878,49 +1894,39 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, lyxpreamble += from_utf8(features.getBabelPostsettings()); } - // FIXME Polyglossia? - docstring const i18npreamble = features.getTClassI18nPreamble(use_babel); - if (!i18npreamble.empty()) - lyxpreamble += i18npreamble + '\n'; - - int const nlines = - int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n')); - texrow.newlines(nlines); - - os << lyxpreamble; + // 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) + lyxpreamble += "\\usepackage{xunicode}\n"; - // these packages (xunicode, for that matter) need to be loaded at least - // after amsmath, amssymb, esint and the other packages that provide - // special glyphs - if (useXetex) { - os << "\\usepackage{xunicode}\n"; - texrow.newline(); - os << "\\usepackage{xltxtra}\n"; - texrow.newline(); - } - // Polyglossia must be loaded after xltxtra + // Polyglossia must be loaded last if (use_polyglossia) { // call the package - os << "\\usepackage{polyglossia}\n"; - texrow.newline(); + lyxpreamble += "\\usepackage{polyglossia}\n"; // set the main language - os << "\\setdefaultlanguage"; + lyxpreamble += "\\setdefaultlanguage"; if (!language->polyglossiaOpts().empty()) - os << "[" << from_ascii(language->polyglossiaOpts()) << "]"; - os << "{" + from_ascii(language->polyglossia()) + "}\n"; - texrow.newline(); + lyxpreamble += "[" + from_ascii(language->polyglossiaOpts()) + "]"; + lyxpreamble += "{" + from_ascii(language->polyglossia()) + "}\n"; // now setup the other languages std::map const polylangs = features.getPolyglossiaLanguages(); for (std::map::const_iterator mit = polylangs.begin(); mit != polylangs.end() ; ++mit) { - os << "\\setotherlanguage"; + lyxpreamble += "\\setotherlanguage"; if (!mit->second.empty()) - os << "[" << from_ascii(mit->second) << "]"; - os << "{" << from_ascii(mit->first) << "}\n"; - texrow.newline(); + lyxpreamble += "[" + from_ascii(mit->second) + "]"; + lyxpreamble += "{" + from_ascii(mit->first) + "}\n"; } } + + docstring const i18npreamble = + features.getTClassI18nPreamble(use_babel, use_polyglossia); + if (!i18npreamble.empty()) + lyxpreamble += i18npreamble + '\n'; + + os << lyxpreamble; + return use_babel; } @@ -2003,7 +2009,7 @@ bool BufferParams::setBaseClass(string const & classname) } pimpl_->baseClass_ = classname; - layoutModules_.adaptToBaseClass(baseClass(), removedModules_); + layout_modules_.adaptToBaseClass(baseClass(), removed_modules_); return true; } @@ -2028,10 +2034,12 @@ void BufferParams::makeDocumentClass() if (!baseClass()) return; - doc_class_ = &(DocumentClassBundle::get().makeDocumentClass(*baseClass(), layoutModules_)); + doc_class_ = &(DocumentClassBundle::get().makeDocumentClass(*baseClass(), layout_modules_)); if (!local_layout.empty()) { - if (!doc_class_->read(local_layout, TextClass::MODULE)) { + 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); } @@ -2041,35 +2049,187 @@ void BufferParams::makeDocumentClass() bool BufferParams::moduleCanBeAdded(string const & modName) const { - return layoutModules_.moduleCanBeAdded(modName, baseClass()); + return layout_modules_.moduleCanBeAdded(modName, baseClass()); } bool BufferParams::addLayoutModule(string const & modName) { - LayoutModuleList::const_iterator it = layoutModules_.begin(); - LayoutModuleList::const_iterator end = layoutModules_.end(); + LayoutModuleList::const_iterator it = layout_modules_.begin(); + LayoutModuleList::const_iterator end = layout_modules_.end(); for (; it != end; it++) if (*it == modName) return false; - layoutModules_.push_back(modName); + layout_modules_.push_back(modName); return true; } +string BufferParams::bufferFormat() const +{ + string format = documentClass().outputFormat(); + if (format == "latex") { + if (useNonTeXFonts) + return "xetex"; + if (encoding().package() == Encoding::japanese) + return "platex"; + } + return format; +} + + +bool BufferParams::isExportable(string const & format) const +{ + vector backs = backends(); + for (vector::const_iterator it = backs.begin(); + it != backs.end(); ++it) + if (theConverters().isReachable(*it, format)) + return true; + return false; +} + + +vector BufferParams::exportableFormats(bool only_viewable) const +{ + vector const backs = backends(); + set excludes; + if (useNonTeXFonts) { + excludes.insert("latex"); + excludes.insert("pdflatex"); + } + vector result = + theConverters().getReachable(backs[0], only_viewable, true, excludes); + for (vector::const_iterator it = backs.begin() + 1; + it != backs.end(); ++it) { + vector r = + theConverters().getReachable(*it, only_viewable, false, excludes); + result.insert(result.end(), r.begin(), r.end()); + } + return result; +} + + +bool BufferParams::isExportableFormat(string const & format) const +{ + typedef vector Formats; + Formats formats; + formats = exportableFormats(true); + Formats::const_iterator fit = formats.begin(); + Formats::const_iterator end = formats.end(); + for (; fit != end ; ++fit) { + if ((*fit)->name() == format) + return true; + } + return false; +} + + +vector BufferParams::backends() const +{ + vector v; + v.push_back(bufferFormat()); + // FIXME: Don't hardcode format names here, but use a flag + if (v.back() == "latex") { + v.push_back("pdflatex"); + v.push_back("luatex"); + v.push_back("dviluatex"); + v.push_back("xetex"); + } else if (v.back() == "xetex") { + v.push_back("luatex"); + v.push_back("dviluatex"); + } + v.push_back("xhtml"); + v.push_back("text"); + v.push_back("lyx"); + return v; +} + + +OutputParams::FLAVOR BufferParams::getOutputFlavor(string const format) const +{ + string const dformat = (format.empty() || format == "default") ? + getDefaultOutputFormat() : format; + DefaultFlavorCache::const_iterator it = + default_flavors_.find(dformat); + + if (it != default_flavors_.end()) + return it->second; + + OutputParams::FLAVOR result = OutputParams::LATEX; + + if (dformat == "xhtml") + result = OutputParams::HTML; + else { + // Try to determine flavor of default output format + vector backs = backends(); + if (find(backs.begin(), backs.end(), dformat) == backs.end()) { + // Get shortest path to format + Graph::EdgePath path; + for (vector::const_iterator it = backs.begin(); + it != backs.end(); ++it) { + Graph::EdgePath p = theConverters().getPath(*it, dformat); + if (!p.empty() && (path.empty() || p.size() < path.size())) { + path = p; + } + } + if (!path.empty()) + result = theConverters().getFlavor(path); + } + } + // cache this flavor + default_flavors_[dformat] = result; + return result; +} + + +string BufferParams::getDefaultOutputFormat() const +{ + if (!default_output_format.empty() + && default_output_format != "default") + return default_output_format; + if (isDocBook() + || useNonTeXFonts + || encoding().package() == Encoding::japanese) { + vector const formats = exportableFormats(true); + if (formats.empty()) + return string(); + // return the first we find + return formats.front()->name(); + } + return lyxrc.default_view_format; +} + Font const BufferParams::getFont() const { FontInfo f = documentClass().defaultfont(); - if (fontsDefaultFamily == "rmdefault") + if (fonts_default_family == "rmdefault") f.setFamily(ROMAN_FAMILY); - else if (fontsDefaultFamily == "sfdefault") + else if (fonts_default_family == "sfdefault") f.setFamily(SANS_FAMILY); - else if (fontsDefaultFamily == "ttdefault") + else if (fonts_default_family == "ttdefault") f.setFamily(TYPEWRITER_FAMILY); return Font(f, language); } +bool BufferParams::isLatex() const +{ + return documentClass().outputType() == LATEX; +} + + +bool BufferParams::isLiterate() const +{ + return documentClass().outputType() == LITERATE; +} + + +bool BufferParams::isDocBook() const +{ + return documentClass().outputType() == DOCBOOK; +} + + void BufferParams::readPreamble(Lexer & lex) { if (lex.getString() != "\\begin_preamble") @@ -2090,6 +2250,18 @@ void BufferParams::readLocalLayout(Lexer & lex) } +bool BufferParams::setLanguage(string const & lang) +{ + Language const *new_language = languages.getLanguage(lang); + if (!new_language) { + // Language lang was not found + return false; + } + language = new_language; + return true; +} + + void BufferParams::readLanguage(Lexer & lex) { if (!lex.next()) return; @@ -2097,8 +2269,7 @@ void BufferParams::readLanguage(Lexer & lex) string const tmptok = lex.getString(); // check if tmptok is part of tex_babel in tex-defs.h - language = languages.getLanguage(tmptok); - if (!language) { + if (!setLanguage(tmptok)) { // Language tmptok was not found language = default_language; lyxerr << "Warning: Setting language `" @@ -2120,14 +2291,14 @@ void BufferParams::readGraphicsDriver(Lexer & lex) string const test = tex_graphics[n++]; if (test == tmptok) { - graphicsDriver = tmptok; + graphics_driver = tmptok; break; } if (test.empty()) { lex.printError( "Warning: graphics driver `$$Token' not recognized!\n" " Setting graphics driver to `default'.\n"); - graphicsDriver = "default"; + graphics_driver = "default"; break; } } @@ -2195,22 +2366,22 @@ void BufferParams::readRemovedModules(Lexer & lex) string mod = lex.getString(); if (mod == "\\end_removed_modules") break; - removedModules_.push_back(mod); + removed_modules_.push_back(mod); lex.eatLine(); } // now we want to remove any removed modules that were previously // added. normally, that will be because default modules were added in // setBaseClass(), which gets called when \textclass is read at the // start of the read. - list::const_iterator rit = removedModules_.begin(); - list::const_iterator const ren = removedModules_.end(); + list::const_iterator rit = removed_modules_.begin(); + list::const_iterator const ren = removed_modules_.end(); for (; rit != ren; rit++) { - LayoutModuleList::iterator const mit = layoutModules_.begin(); - LayoutModuleList::iterator const men = layoutModules_.end(); + LayoutModuleList::iterator const mit = layout_modules_.begin(); + LayoutModuleList::iterator const men = layout_modules_.end(); LayoutModuleList::iterator found = find(mit, men, *rit); if (found == men) continue; - layoutModules_.erase(found); + layout_modules_.erase(found); } } @@ -2226,7 +2397,7 @@ void BufferParams::readIncludeonly(Lexer & lex) string child = lex.getString(); if (child == "\\end_includeonly") break; - includedChildren_.push_back(child); + included_children_.push_back(child); lex.eatLine(); } } @@ -2419,6 +2590,9 @@ string const BufferParams::font_encoding() const string BufferParams::babelCall(string const & lang_opts, bool const langoptions) const { + if (lang_package != "auto" && lang_package != "babel" + && lang_package != "default" && lang_package != "none") + return lang_package; if (lyxrc.language_package_selection == LyXRC::LP_CUSTOM) return lyxrc.language_custom_package; // suppress the babel call if there is no BabelName defined @@ -2440,12 +2614,12 @@ docstring BufferParams::getGraphicsDriver(string const & package) const docstring result; if (package == "geometry") { - if (graphicsDriver == "dvips" - || graphicsDriver == "dvipdfm" - || graphicsDriver == "pdftex" - || graphicsDriver == "vtex") - result = from_ascii(graphicsDriver); - else if (graphicsDriver == "dvipdfmx") + if (graphics_driver == "dvips" + || graphics_driver == "dvipdfm" + || graphics_driver == "pdftex" + || graphics_driver == "vtex") + result = from_ascii(graphics_driver); + else if (graphics_driver == "dvipdfmx") result = from_ascii("dvipdfm"); } @@ -2453,11 +2627,23 @@ docstring BufferParams::getGraphicsDriver(string const & package) const } -void BufferParams::writeEncodingPreamble(odocstream & os, - LaTeXFeatures & features, TexRow & texrow) const +void BufferParams::writeEncodingPreamble(otexstream & os, + LaTeXFeatures & features) const { - if (useXetex) + // XeTeX does not need this + if (features.runparams().flavor == OutputParams::XETEX) return; + // LuaTeX neither, but with tex fonts, we need to load + // the luainputenc package. + if (features.runparams().flavor == OutputParams::LUATEX + || features.runparams().flavor == OutputParams::DVILUATEX) { + if (!useNonTeXFonts && inputenc != "default" + && ((inputenc == "auto" && language->encoding()->package() == Encoding::inputenc) + || (inputenc != "auto" && encoding().package() == Encoding::inputenc))) { + os << "\\usepackage[utf8]{luainputenc}\n"; + } + return; + } if (inputenc == "auto") { string const doc_encoding = language->encoding()->latexName(); @@ -2492,7 +2678,6 @@ void BufferParams::writeEncodingPreamble(odocstream & os, os << from_ascii(doc_encoding); } os << "]{inputenc}\n"; - texrow.newline(); } if (package == Encoding::CJK || features.mustProvide("CJK")) { if (language->encoding()->name() == "utf8-cjk" @@ -2500,7 +2685,6 @@ void BufferParams::writeEncodingPreamble(odocstream & os, os << "\\usepackage{CJKutf8}\n"; else os << "\\usepackage{CJK}\n"; - texrow.newline(); } } else if (inputenc != "default") { switch (encoding().package()) { @@ -2513,7 +2697,6 @@ void BufferParams::writeEncodingPreamble(odocstream & os, break; os << "\\usepackage[" << from_ascii(inputenc) << "]{inputenc}\n"; - texrow.newline(); break; case Encoding::CJK: if (encoding().name() == "utf8-cjk" @@ -2521,7 +2704,6 @@ void BufferParams::writeEncodingPreamble(odocstream & os, os << "\\usepackage{CJKutf8}\n"; else os << "\\usepackage{CJK}\n"; - texrow.newline(); break; } } @@ -2529,10 +2711,8 @@ void BufferParams::writeEncodingPreamble(odocstream & os, // The encoding "armscii8" (for Armenian) is only available when // the package "armtex" is loaded. if (language->encoding()->latexName() == "armscii8" - || inputenc == "armscii8") { + || inputenc == "armscii8") os << "\\usepackage{armtex}\n"; - texrow.newline(); - } } @@ -2551,7 +2731,8 @@ string const BufferParams::loadFonts(string const & rm, string const & sf, string const & tt, bool const & sc, bool const & osf, int const & sfscale, int const & ttscale, - bool const & xetex) const + bool const & use_systemfonts, + LaTeXFeatures & features) const { /* The LaTeX font world is in a flux. In the PSNFSS font interface, several packages have been replaced by others, that might not @@ -2571,9 +2752,31 @@ string const BufferParams::loadFonts(string const & rm, ostringstream os; - if (xetex) { + /* Fontspec (XeTeX, LuaTeX): we provide GUI support for oldstyle + * numbers (Numbers=OldStyle) and sf/tt scaling. The Ligatures=TeX/ + * Mapping=tex-text option assures TeX ligatures (such as "--") + * are resolved. Note that tt does not use these ligatures. + * TODO: + * -- add more GUI options? + * -- add more fonts (fonts for other scripts) + * -- if there's a way to find out if a font really supports + * OldStyle, enable/disable the widget accordingly. + */ + if (use_systemfonts && features.isAvailable("fontspec")) { + // "Mapping=tex-text" and "Ligatures=TeX" are equivalent. + // However, until v.2 (2010/07/11) fontspec only knew + // Mapping=tex-text (for XeTeX only); then "Ligatures=TeX" + // was introduced for both XeTeX and LuaTeX (LuaTeX + // didn't understand "Mapping=tex-text", while XeTeX + // understood both. With most recent versions, both + // variants are understood by both engines. However, + // we want to provide support for at least TeXLive 2009 + // (for XeTeX; LuaTeX is only supported as of v.2) + string const texmapping = + (features.runparams().flavor == OutputParams::XETEX) ? + "Mapping=tex-text" : "Ligatures=TeX"; if (rm != "default") { - os << "\\setmainfont[Mapping=tex-text"; + os << "\\setmainfont[" << texmapping; if (osf) os << ",Numbers=OldStyle"; os << "]{" << parseFontName(rm) << "}\n"; @@ -2583,21 +2786,21 @@ string const BufferParams::loadFonts(string const & rm, if (sfscale != 100) os << "\\setsansfont[Scale=" << float(sfscale) / 100 - << ",Mapping=tex-text]{" + << "," << texmapping << "]{" << sans << "}\n"; else - os << "\\setsansfont[Mapping=tex-text]{" + os << "\\setsansfont[" << texmapping << "]{" << sans << "}\n"; } if (tt != "default") { string const mono = parseFontName(tt); if (ttscale != 100) os << "\\setmonofont[Scale=" - << float(sfscale) / 100 + << float(ttscale) / 100 << "]{" << mono << "}\n"; else - os << "\\setmonofont[Mapping=tex-text]{" + os << "\\setmonofont{" << mono << "}\n"; } return os.str(); @@ -2719,7 +2922,11 @@ string const BufferParams::loadFonts(string const & rm, Encoding const & BufferParams::encoding() const { - if (useXetex) + // 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. + if (useNonTeXFonts) return *(encodings.fromLaTeXName("utf8-plain")); if (inputenc == "auto" || inputenc == "default") return *language->encoding();