X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferParams.cpp;h=51c3d410af64471cbaa0e65079368f07c9977df7;hb=df7f2a074fe062de0033d0ba16bd05e4a4b79eb0;hp=2c97acef6b199ae668cb4ec2a45e159f6514386c;hpb=1e947e3a18f3676c527684affa96cd41aa61345c;p=lyx.git diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 2c97acef6b..51c3d410af 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -30,6 +30,7 @@ #include "IndicesList.h" #include "Language.h" #include "LaTeXFeatures.h" +#include "LaTeXFonts.h" #include "ModuleList.h" #include "Font.h" #include "Lexer.h" @@ -375,6 +376,7 @@ BufferParams::BufferParams() fonts_roman = "default"; fonts_sans = "default"; fonts_typewriter = "default"; + fonts_math = "auto"; fonts_default_family = "default"; useNonTeXFonts = false; fonts_expert_sc = false; @@ -447,6 +449,7 @@ vector const & BufferParams::auto_packages() if (packages.empty()) { // adding a package here implies a file format change! packages.push_back("amsmath"); + packages.push_back("amssymb"); packages.push_back("esint"); packages.push_back("mathdots"); packages.push_back("mathtools"); @@ -661,6 +664,9 @@ string BufferParams::readToken(Lexer & lex, string const & token, } else if (token == "\\font_typewriter") { lex.eatLine(); fonts_typewriter = lex.getString(); + } else if (token == "\\font_math") { + lex.eatLine(); + fonts_math = lex.getString(); } else if (token == "\\font_default_family") { lex >> fonts_default_family; } else if (token == "\\use_non_tex_fonts") { @@ -809,10 +815,12 @@ string BufferParams::readToken(Lexer & lex, string const & token, lex.eatLine(); string color = lex.getString(); notefontcolor = lyx::rgbFromHexName(color); + lcolor.setColor("notefontcolor", color); } else if (token == "\\boxbgcolor") { lex.eatLine(); string color = lex.getString(); boxbgcolor = lyx::rgbFromHexName(color); + lcolor.setColor("boxbgcolor", color); } else if (token == "\\paperwidth") { lex >> paperwidth; } else if (token == "\\paperheight") { @@ -941,7 +949,7 @@ void BufferParams::writeFile(ostream & os) const os << "\\begin_removed_modules" << '\n'; list::const_iterator it = removed_modules_.begin(); list::const_iterator en = removed_modules_.end(); - for (; it != en; it++) + for (; it != en; ++it) os << *it << '\n'; os << "\\end_removed_modules" << '\n'; } @@ -951,7 +959,7 @@ void BufferParams::writeFile(ostream & os) const os << "\\begin_modules" << '\n'; LayoutModuleList::const_iterator it = layout_modules_.begin(); LayoutModuleList::const_iterator en = layout_modules_.end(); - for (; it != en; it++) + for (; it != en; ++it) os << *it << '\n'; os << "\\end_modules" << '\n'; } @@ -961,7 +969,7 @@ void BufferParams::writeFile(ostream & os) const os << "\\begin_includeonly" << '\n'; list::const_iterator it = included_children_.begin(); list::const_iterator en = included_children_.end(); - for (; it != en; it++) + for (; it != en; ++it) os << *it << '\n'; os << "\\end_includeonly" << '\n'; } @@ -986,6 +994,7 @@ void BufferParams::writeFile(ostream & os) const << "\n\\font_roman " << fonts_roman << "\n\\font_sans " << fonts_sans << "\n\\font_typewriter " << fonts_typewriter + << "\n\\font_math " << fonts_math << "\n\\font_default_family " << fonts_default_family << "\n\\use_non_tex_fonts " << convert(useNonTeXFonts) << "\n\\font_sc " << convert(fonts_expert_sc) @@ -996,7 +1005,7 @@ void BufferParams::writeFile(ostream & os) const if (!fonts_cjk.empty()) { os << "\\font_cjk " << fonts_cjk << '\n'; } - os << "\n\\graphics " << graphics_driver << '\n'; + os << "\\graphics " << graphics_driver << '\n'; os << "\\default_output_format " << default_output_format << '\n'; os << "\\output_sync " << output_sync << '\n'; if (!output_sync_macro.empty()) @@ -1156,6 +1165,9 @@ void BufferParams::validate(LaTeXFeatures & features) const { features.require(documentClass().requires()); + if (columns > 1 && language->rightToLeft()) + features.require("rtloutputdblcol"); + if (outputChanges) { bool dvipost = LaTeXFeatures::isAvailable("dvipost"); bool xcolorulem = LaTeXFeatures::isAvailable("ulem") && @@ -1202,7 +1214,7 @@ void BufferParams::validate(LaTeXFeatures & features) const if (it->first == "amsmath") { // AMS Style is at document level if (it->second == package_on || - documentClass().provides("amsmath")) + features.isProvided("amsmath")) features.require(it->first); } else if (it->second == package_on) features.require(it->first); @@ -1243,14 +1255,17 @@ void BufferParams::validate(LaTeXFeatures & features) const features.require("color"); } + // some languages are only available via polyglossia if (features.runparams().flavor == OutputParams::XETEX - && useNonTeXFonts) + && (features.hasPolyglossiaExclusiveLanguages() + || useNonTeXFonts)) features.require("polyglossia"); - if (language->lang() == "vietnamese") - features.require("vietnamese"); - else if (language->lang() == "japanese") - features.require("japanese"); + if (useNonTeXFonts && fonts_math != "auto") + features.require("unicode-math"); + + if (!language->requires().empty()) + features.require(language->requires()); } @@ -1370,17 +1385,18 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, features.useLanguage(default_language); ostringstream language_options; - bool const use_babel = features.useBabel() && !tclass.provides("babel"); + 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)) { - language_options << features.getLanguages(); + language_options << features.getBabelLanguages(); if (!language->babel().empty()) { if (!language_options.str().empty()) language_options << ','; language_options << language->babel(); } - if (global && !features.needBabelLangOptions()) + if (global && !features.needBabelLangOptions() + && !language_options.str().empty()) clsoptions << language_options.str() << ','; } @@ -1408,15 +1424,15 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, if (useNonTeXFonts && !ams.empty()) os << from_ascii(ams); - if (useNonTeXFonts) + if (useNonTeXFonts) { os << "\\usepackage{fontspec}\n"; + if (features.mustProvide("unicode-math") + && features.isAvailable("unicode-math")) + os << "\\usepackage{unicode-math}\n"; + } // font selection must be done before loading fontenc.sty - string const fonts = - loadFonts(fonts_roman, fonts_sans, fonts_typewriter, - fonts_expert_sc, fonts_old_figures, - fonts_sans_scale, fonts_typewriter_scale, - useNonTeXFonts, features); + string const fonts = loadFonts(features); if (!fonts.empty()) os << from_utf8(fonts); @@ -1429,7 +1445,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, // LFE encoding // XeTeX and LuaTeX (with OS fonts) work without fontenc if (font_encoding() != "default" && language->lang() != "japanese" - && !useNonTeXFonts && !tclass.provides("fontenc")) { + && !useNonTeXFonts && !features.isProvided("fontenc")) { size_t fars = language_options.str().find("farsi"); size_t arab = language_options.str().find("arabic"); if (language->lang() == "arabic_arabi" @@ -1487,7 +1503,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, os << from_utf8(par) << "}\n"; } - if (!tclass.provides("geometry") + if (!features.isProvided("geometry") && (use_geometry || nonstandard_papersize)) { odocstringstream ods; if (!getGraphicsDriver("geometry").empty()) @@ -1742,16 +1758,27 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, IndicesList::const_iterator iit = indiceslist().begin(); IndicesList::const_iterator iend = indiceslist().end(); for (; iit != iend; ++iit) { + pair indexname_latex = + features.runparams().encoding->latexString(iit->index(), + features.runparams().dryrun); + if (!indexname_latex.second.empty()) { + // issue a warning about omitted characters + // FIXME: should be passed to the error dialog + frontend::Alert::warning(_("Uncodable characters"), + bformat(_("The following characters that are used in an index name are not\n" + "representable in the current encoding and therefore have been omitted:\n%1$s."), + indexname_latex.second)); + } lyxpreamble += "\\newindex["; - lyxpreamble += iit->index(); + lyxpreamble += indexname_latex.first; lyxpreamble += "]{"; - lyxpreamble += iit->shortcut(); + lyxpreamble += escape(iit->shortcut()); lyxpreamble += "}\n"; } } // Line spacing - lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace"))); + lyxpreamble += from_utf8(spacing().writePreamble(features.isProvided("SetSpace"))); // PDF support. // * Hyperref manual: "Make sure it comes last of your loaded @@ -1769,7 +1796,7 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, OutputParams tmp_params = features.runparams(); pdfoptions().writeLaTeX(tmp_params, os, - documentClass().provides("hyperref")); + features.isProvided("hyperref")); // set back for the rest lyxpreamble.clear(); // correctly break URLs with hyperref and dvi output @@ -1780,6 +1807,11 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, // hyperref loads this automatically lyxpreamble += "\\usepackage{nameref}\n"; + // bibtopic needs to be loaded after hyperref. + // the dot provides the aux file naming which LyX can detect. + if (features.mustProvide("bibtopic")) + lyxpreamble += "\\usepackage[dot]{bibtopic}\n"; + // Will be surrounded by \makeatletter and \makeatother when not empty docstring atlyxpreamble; @@ -1905,6 +1937,15 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, } } + // Load custom language package here + if (features.langPackage() == LaTeXFeatures::LANG_PACK_CUSTOM) { + if (lang_package == "default") + lyxpreamble += from_utf8(lyxrc.language_custom_package); + else + lyxpreamble += from_utf8(lang_package); + lyxpreamble += '\n'; + } + docstring const i18npreamble = features.getTClassI18nPreamble(use_babel, use_polyglossia); if (!i18npreamble.empty()) @@ -1947,20 +1988,20 @@ bool BufferParams::hasClassDefaults() const DocumentClass const & BufferParams::documentClass() const { - return *doc_class_; + return *doc_class_.get(); } -DocumentClass const * BufferParams::documentClassPtr() const +DocumentClassConstPtr BufferParams::documentClassPtr() const { return doc_class_; } -void BufferParams::setDocumentClass(DocumentClass const * const tc) +void BufferParams::setDocumentClass(DocumentClassConstPtr tc) { // evil, but this function is evil - doc_class_ = const_cast(tc); + doc_class_ = const_pointer_cast(tc); } @@ -2025,13 +2066,13 @@ void BufferParams::makeDocumentClass() it = layout_modules_.begin(); en = layout_modules_.end(); - for (; it != en; it++) + for (; it != en; ++it) mods.push_back(*it); it = cite_engine_.begin(); en = cite_engine_.end(); - for (; it != en; it++) + for (; it != en; ++it) mods.push_back(*it); - doc_class_ = &(DocumentClassBundle::get().makeDocumentClass(*baseClass(), mods)); + doc_class_ = getDocumentClass(*baseClass(), mods); if (!local_layout.empty()) { TextClass::ReturnValues success = @@ -2055,7 +2096,7 @@ bool BufferParams::addLayoutModule(string const & modName) { LayoutModuleList::const_iterator it = layout_modules_.begin(); LayoutModuleList::const_iterator end = layout_modules_.end(); - for (; it != end; it++) + for (; it != end; ++it) if (*it == modName) return false; layout_modules_.push_back(modName); @@ -2088,9 +2129,12 @@ bool BufferParams::isExportable(string const & format) const namespace { -bool formatSorter(Format const * lhs, Format const * rhs) { + +bool formatSorter(Format const * lhs, Format const * rhs) +{ return _(lhs->prettyname()) < _(rhs->prettyname()); } + } @@ -2133,17 +2177,24 @@ bool BufferParams::isExportableFormat(string const & format) const vector BufferParams::backends() const { vector v; - v.push_back(bufferFormat()); + string const buffmt = bufferFormat(); + // FIXME: Don't hardcode format names here, but use a flag - if (v.back() == "latex") { - v.push_back("pdflatex"); + if (buffmt == "latex") { + if (!useNonTeXFonts) { + v.push_back("pdflatex"); + v.push_back("latex"); + } v.push_back("luatex"); v.push_back("dviluatex"); v.push_back("xetex"); - } else if (v.back() == "xetex") { + } else if (buffmt == "xetex") { + v.push_back("xetex"); v.push_back("luatex"); v.push_back("dviluatex"); - } + } else + v.push_back(buffmt); + v.push_back("xhtml"); v.push_back("text"); v.push_back("lyx"); @@ -2163,8 +2214,22 @@ OutputParams::FLAVOR BufferParams::getOutputFlavor(string const format) const OutputParams::FLAVOR result = OutputParams::LATEX; + // FIXME It'd be better not to hardcode this, but to do + // something with formats. if (dformat == "xhtml") result = OutputParams::HTML; + else if (dformat == "text") + result = OutputParams::TEXT; + else if (dformat == "lyx") + result = OutputParams::LYX; + else if (dformat == "pdflatex") + result = OutputParams::PDFLATEX; + else if (dformat == "xetex") + result = OutputParams::XETEX; + else if (dformat == "luatex") + result = OutputParams::LUATEX; + else if (dformat == "dviluatex") + result = OutputParams::DVILUATEX; else { // Try to determine flavor of default output format vector backs = backends(); @@ -2218,6 +2283,12 @@ Font const BufferParams::getFont() const } +InsetQuotes::QuoteLanguage BufferParams::getQuoteStyle(string const qs) const +{ + return quoteslangtranslator().find(qs); +} + + bool BufferParams::isLatex() const { return documentClass().outputType() == LATEX; @@ -2381,7 +2452,7 @@ void BufferParams::readRemovedModules(Lexer & lex) // start of the read. list::const_iterator rit = removed_modules_.begin(); list::const_iterator const ren = removed_modules_.end(); - for (; rit != ren; rit++) { + for (; rit != ren; ++rit) { LayoutModuleList::iterator const mit = layout_modules_.begin(); LayoutModuleList::iterator const men = layout_modules_.end(); LayoutModuleList::iterator found = find(mit, men, *rit); @@ -2600,11 +2671,6 @@ 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 // for the document language in the lib/languages file and if no // other languages are used (lang_opts is then empty) @@ -2668,9 +2734,6 @@ void BufferParams::writeEncodingPreamble(otexstream & os, // If the "japanese" package (i.e. pLaTeX) is used, // inputenc must be omitted. // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html - if (package == Encoding::japanese) - features.require("japanese"); - if ((!encodings.empty() || package == Encoding::inputenc) && !features.isRequired("japanese")) { os << "\\usepackage["; @@ -2717,12 +2780,6 @@ void BufferParams::writeEncodingPreamble(otexstream & os, break; } } - - // The encoding "armscii8" (for Armenian) is only available when - // the package "armtex" is loaded. - if (language->encoding()->latexName() == "armscii8" - || inputenc == "armscii8") - os << "\\usepackage{armtex}\n"; } @@ -2737,26 +2794,11 @@ string const BufferParams::parseFontName(string const & name) const } -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 & 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 - be installed on every system. We have to take care for that - (see psnfss.pdf). We try to support all psnfss fonts as well - as the fonts that have become de facto standard in the LaTeX - world (e.g. Latin Modern). We do not support obsolete fonts - (like PSLatex). In general, it should be possible to mix any - rm font with any sf or tt font, respectively. (JSpitzm) - TODO: - -- separate math fonts. - */ - - if (rm == "default" && sf == "default" && tt == "default") +string const BufferParams::loadFonts(LaTeXFeatures & features) const +{ + if (fonts_roman == "default" && fonts_sans == "default" + && fonts_typewriter == "default" + && (fonts_math == "default" || fonts_math == "auto")) //nothing to do return string(); @@ -2772,7 +2814,7 @@ string const BufferParams::loadFonts(string const & rm, * -- 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")) { + if (useNonTeXFonts && 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" @@ -2785,28 +2827,28 @@ string const BufferParams::loadFonts(string const & rm, string const texmapping = (features.runparams().flavor == OutputParams::XETEX) ? "Mapping=tex-text" : "Ligatures=TeX"; - if (rm != "default") { + if (fonts_roman != "default") { os << "\\setmainfont[" << texmapping; - if (osf) + if (fonts_old_figures) os << ",Numbers=OldStyle"; - os << "]{" << parseFontName(rm) << "}\n"; + os << "]{" << parseFontName(fonts_roman) << "}\n"; } - if (sf != "default") { - string const sans = parseFontName(sf); - if (sfscale != 100) + if (fonts_sans != "default") { + string const sans = parseFontName(fonts_sans); + if (fonts_sans_scale != 100) os << "\\setsansfont[Scale=" - << float(sfscale) / 100 + << float(fonts_sans_scale) / 100 << "," << texmapping << "]{" << sans << "}\n"; else os << "\\setsansfont[" << texmapping << "]{" << sans << "}\n"; } - if (tt != "default") { - string const mono = parseFontName(tt); - if (ttscale != 100) + if (fonts_typewriter != "default") { + string const mono = parseFontName(fonts_typewriter); + if (fonts_typewriter_scale != 100) os << "\\setmonofont[Scale=" - << float(ttscale) / 100 + << float(fonts_typewriter_scale) / 100 << "]{" << mono << "}\n"; else @@ -2816,115 +2858,31 @@ string const BufferParams::loadFonts(string const & rm, return os.str(); } + // Tex Fonts + bool const ot1 = (font_encoding() == "default" || font_encoding() == "OT1"); + bool const dryrun = features.runparams().dryrun; + bool const complete = (fonts_sans == "default" && fonts_typewriter == "default"); + bool const nomath = (fonts_math == "default"); + // ROMAN FONTS - // Computer Modern (must be explicitly selectable -- there might be classes - // that define a different default font! - if (rm == "cmr") { - os << "\\renewcommand{\\rmdefault}{cmr}\n"; - // osf for Computer Modern needs eco.sty - if (osf) - os << "\\usepackage{eco}\n"; - } - // Latin Modern Roman - else if (rm == "lmodern") - os << "\\usepackage{lmodern}\n"; - // AE - else if (rm == "ae") { - // not needed when using OT1 font encoding. - if (font_encoding() != "default") - os << "\\usepackage{ae,aecompl}\n"; - } - // Times - else if (rm == "times") { - // try to load the best available package - if (LaTeXFeatures::isAvailable("mathptmx")) - os << "\\usepackage{mathptmx}\n"; - else if (LaTeXFeatures::isAvailable("mathptm")) - os << "\\usepackage{mathptm}\n"; - else - os << "\\usepackage{times}\n"; - } - // Palatino - else if (rm == "palatino") { - // try to load the best available package - if (LaTeXFeatures::isAvailable("mathpazo")) { - os << "\\usepackage"; - if (osf || sc) { - os << '['; - if (!osf) - os << "sc"; - else - // "osf" includes "sc"! - os << "osf"; - os << ']'; - } - os << "{mathpazo}\n"; - } - else if (LaTeXFeatures::isAvailable("mathpple")) - os << "\\usepackage{mathpple}\n"; - else - os << "\\usepackage{palatino}\n"; - } - // Utopia - else if (rm == "utopia") { - // fourier supersedes utopia.sty, but does - // not work with OT1 encoding. - if (LaTeXFeatures::isAvailable("fourier") - && font_encoding() != "default") { - os << "\\usepackage"; - if (osf || sc) { - os << '['; - if (sc) - os << "expert"; - if (osf && sc) - os << ','; - if (osf) - os << "oldstyle"; - os << ']'; - } - os << "{fourier}\n"; - } - else - os << "\\usepackage{utopia}\n"; - } - // Bera (complete fontset) - else if (rm == "bera" && sf == "default" && tt == "default") - os << "\\usepackage{bera}\n"; - // everything else - else if (rm != "default") - os << "\\usepackage" << "{" << rm << "}\n"; + os << theLaTeXFonts().getLaTeXFont(from_ascii(fonts_roman)).getLaTeXCode( + dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures, + nomath); // SANS SERIF - // Helvetica, Bera Sans - if (sf == "helvet" || sf == "berasans") { - if (sfscale != 100) - os << "\\usepackage[scaled=" << float(sfscale) / 100 - << "]{" << sf << "}\n"; - else - os << "\\usepackage{" << sf << "}\n"; - } - // Avant Garde - else if (sf == "avant") - os << "\\usepackage{" << sf << "}\n"; - // Computer Modern, Latin Modern, CM Bright - else if (sf != "default") - os << "\\renewcommand{\\sfdefault}{" << sf << "}\n"; - - // monospaced/typewriter - // Courier, LuxiMono - if (tt == "luximono" || tt == "beramono") { - if (ttscale != 100) - os << "\\usepackage[scaled=" << float(ttscale) / 100 - << "]{" << tt << "}\n"; - else - os << "\\usepackage{" << tt << "}\n"; - } - // Courier - else if (tt == "courier" ) - os << "\\usepackage{" << tt << "}\n"; - // Computer Modern, Latin Modern, CM Bright - else if (tt != "default") - os << "\\renewcommand{\\ttdefault}{" << tt << "}\n"; + os << theLaTeXFonts().getLaTeXFont(from_ascii(fonts_sans)).getLaTeXCode( + dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures, + nomath, fonts_sans_scale); + + // MONOSPACED/TYPEWRITER + os << theLaTeXFonts().getLaTeXFont(from_ascii(fonts_typewriter)).getLaTeXCode( + dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures, + nomath, fonts_typewriter_scale); + + // MATH + os << theLaTeXFonts().getLaTeXFont(from_ascii(fonts_math)).getLaTeXCode( + dryrun, ot1, complete, fonts_expert_sc, fonts_old_figures, + nomath); return os.str(); }