X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLaTeXFeatures.cpp;h=8b7287e5307e2cc384f75d02c69a6839245539ad;hb=0c7bd9a57f2a308bb9659200eda3b7e45f8d5d3c;hp=dca1b6cf66704c5d934da66b223a751c3b39988a;hpb=5d6351d4763ce9ec209b491d7a507cf00d819288;p=lyx.git diff --git a/src/LaTeXFeatures.cpp b/src/LaTeXFeatures.cpp index dca1b6cf66..8b7287e530 100644 --- a/src/LaTeXFeatures.cpp +++ b/src/LaTeXFeatures.cpp @@ -66,7 +66,7 @@ static docstring const lyx_def = from_ascii( static docstring const lyx_hyperref_def = from_ascii( "\\providecommand{\\LyX}{\\texorpdfstring%\n" " {L\\kern-.1667em\\lower.25em\\hbox{Y}\\kern-.125emX\\@}\n" - " {LyX}}"); + " {LyX}}"); static docstring const noun_def = from_ascii( "\\newcommand{\\noun}[1]{\\textsc{#1}}"); @@ -134,6 +134,24 @@ static docstring const paragraphleftindent_def = from_ascii( "}\n" "{\\end{list}}\n"); +static docstring const floatingfootnote_def = from_ascii( + "%% Special footnote code from the package 'stblftnt.sty'\n" + "%% Author: Robin Fairbairns -- Last revised Dec 13 1996\n" + "\\let\\SF@@footnote\\footnote\n" + "\\def\\footnote{\\ifx\\protect\\@typeset@protect\n" + " \\expandafter\\SF@@footnote\n" + " \\else\n" + " \\expandafter\\SF@gobble@opt\n" + " \\fi\n" + "}\n" + "\\expandafter\\def\\csname SF@gobble@opt \\endcsname{\\@ifnextchar[%]\n" + " \\SF@gobble@twobracket\n" + " \\@gobble\n" + "}\n" + "\\edef\\SF@gobble@opt{\\noexpand\\protect\n" + " \\expandafter\\noexpand\\csname SF@gobble@opt \\endcsname}\n" + "\\def\\SF@gobble@twobracket[#1]#2{}\n"); + static docstring const binom_def = from_ascii( "%% Binom macro for standard LaTeX users\n" "\\newcommand{\\binom}[2]{{#1 \\choose #2}}\n"); @@ -184,18 +202,21 @@ static docstring const changetracking_none_def = from_ascii( "\\newcommand{\\lyxadded}[3]{#3}\n" "\\newcommand{\\lyxdeleted}[3]{}\n"); +static docstring const textgreek_LGR_def = from_ascii( + "\\DeclareFontEncoding{LGR}{}{}\n"); static docstring const textgreek_def = from_ascii( "\\DeclareRobustCommand{\\greektext}{%\n" " \\fontencoding{LGR}\\selectfont\\def\\encodingdefault{LGR}}\n" "\\DeclareRobustCommand{\\textgreek}[1]{\\leavevmode{\\greektext #1}}\n" - "\\DeclareFontEncoding{LGR}{}{}\n" - "\\DeclareTextSymbol{\\~}{LGR}{126}"); + "\\ProvideTextCommand{\\~}{LGR}[1]{\\char126#1}\n"); +static docstring const textcyr_T2A_def = from_ascii( + "\\InputIfFileExists{t2aenc.def}{}{%\n" + " \\errmessage{File `t2aenc.def' not found: Cyrillic script not supported}}\n"); static docstring const textcyr_def = from_ascii( "\\DeclareRobustCommand{\\cyrtext}{%\n" " \\fontencoding{T2A}\\selectfont\\def\\encodingdefault{T2A}}\n" - "\\DeclareRobustCommand{\\textcyr}[1]{\\leavevmode{\\cyrtext #1}}\n" - "\\AtBeginDocument{\\DeclareFontEncoding{T2A}{}{}}\n"); + "\\DeclareRobustCommand{\\textcyr}[1]{\\leavevmode{\\cyrtext #1}}\n"); static docstring const lyxmathsym_def = from_ascii( "\\newcommand{\\lyxmathsym}[1]{\\ifmmode\\begingroup\\def\\b@ld{bold}\n" @@ -208,6 +229,13 @@ static docstring const papersizepdf_def = from_ascii( "\\pdfpageheight\\paperheight\n" "\\pdfpagewidth\\paperwidth\n"); +static docstring const papersizepdflua_def = from_ascii( + "% Backwards compatibility for LuaTeX < 0.90\n" + "\\@ifundefined{pageheight}{\\let\\pageheight\\pdfpageheight}\n" + "\\@ifundefined{pagewidth}{\\let\\pagewidth\\pdfpagewidth}\n" + "\\pageheight\\paperheight\n" + "\\pagewidth\\paperwidth\n"); + static docstring const cedilla_def = from_ascii( "\\newcommand{\\docedilla}[2]{\\underaccent{#1\\mathchar'30}{#2}}\n" "\\newcommand{\\cedilla}[1]{\\mathpalette\\docedilla{#1}}\n"); @@ -248,15 +276,51 @@ static docstring const ogonek_def = from_ascii( " \\mathchar\"0\\hexnumber@\\symtipasymb0C}{#2}}\n" "\\newcommand{\\ogonek}[1]{\\mathpalette\\doogonek{#1}}\n"); +static docstring const lyxaccent_def = from_ascii( + "%% custom text accent \\LyxTextAccent[]{}{}\n" + "\\newcommand*{\\LyxTextAccent}[3][0ex]{%\n" + " \\hmode@bgroup\\ooalign{\\null#3\\crcr\\hidewidth\n" + " \\raise#1\\hbox{#2}\\hidewidth}\\egroup}\n" + "%% select a font size smaller than the current font size:\n" + "\\newcommand{\\LyxAccentSize}[1][\\sf@size]{%\n" + " \\check@mathfonts\\fontsize#1\\z@\\math@fontsfalse\\selectfont\n" + "}\n"); + +static docstring const textcommabelow_def = from_ascii( + "\\ProvideTextCommandDefault{\\textcommabelow}[1]{%%\n" + " \\LyxTextAccent[-.31ex]{\\LyxAccentSize,}{#1}}\n"); + +static docstring const textcommaabove_def = from_ascii( + "\\ProvideTextCommandDefault{\\textcommaabove}[1]{%%\n" + " \\LyxTextAccent[.5ex]{\\LyxAccentSize`}{#1}}\n"); + +static docstring const textcommaaboveright_def = from_ascii( + "\\ProvideTextCommandDefault{\\textcommaaboveright}[1]{%%\n" + " \\LyxTextAccent[.5ex]{\\LyxAccentSize\\ `}{#1}}\n"); + +// Baltic languages use a comma-accent instead of a cedilla +static docstring const textbaltic_def = from_ascii( + "%% use comma accent instead of cedilla for these characters:\n" + "\\DeclareTextCompositeCommand{\\c}{T1}{g}{\\textcommaabove{g}}\n" + "\\DeclareTextCompositeCommand{\\c}{T1}{G}{\\textcommabelow{G}}\n" + "\\DeclareTextCompositeCommand{\\c}{T1}{k}{\\textcommabelow{k}}\n" + "\\DeclareTextCompositeCommand{\\c}{T1}{K}{\\textcommabelow{K}}\n" + "\\DeclareTextCompositeCommand{\\c}{T1}{l}{\\textcommabelow{l}}\n" + "\\DeclareTextCompositeCommand{\\c}{T1}{L}{\\textcommabelow{L}}\n" + "\\DeclareTextCompositeCommand{\\c}{T1}{n}{\\textcommabelow{n}}\n" + "\\DeclareTextCompositeCommand{\\c}{T1}{N}{\\textcommabelow{N}}\n" + "\\DeclareTextCompositeCommand{\\c}{T1}{r}{\\textcommabelow{r}}\n" + "\\DeclareTextCompositeCommand{\\c}{T1}{R}{\\textcommabelow{R}}\n"); + static docstring const lyxref_def = from_ascii( - "\\RS@ifundefined{subref}\n" - " {\\def\\RSsubtxt{section~}\\newref{sub}{name = \\RSsubtxt}}\n" + "\\RS@ifundefined{subsecref}\n" + " {\\newref{subsec}{name = \\RSsectxt}}\n" " {}\n" "\\RS@ifundefined{thmref}\n" " {\\def\\RSthmtxt{theorem~}\\newref{thm}{name = \\RSthmtxt}}\n" " {}\n" "\\RS@ifundefined{lemref}\n" - " {\\def\\RSlemtxt{lemma~}\\newref{lem}{name = \\RSlemtxt}}\n" + " {\\def\\RSlemtxt{lemma~}\\newref{lem}{name = \\RSlemtxt}}\n" " {}\n"); // Make sure the columns are also outputed as rtl @@ -304,15 +368,15 @@ static docstring const rtloutputdblcol_def = from_ascii( static docstring const lyxnoun_style = from_ascii( "dfn.lyxnoun {\n" - " font-variant: small-caps;\n" - "}\n"); + " font-variant: small-caps;\n" + "}\n"); // this is how it normally renders, but it might not always do so. static docstring const lyxstrikeout_style = from_ascii( "del.strikeout {\n" - " text-decoration: line-through;\n" - "}\n"); + " text-decoration: line-through;\n" + "}\n"); ///////////////////////////////////////////////////////////////////// @@ -343,18 +407,18 @@ LaTeXFeatures::LangPackage LaTeXFeatures::langPackage() const if (local_lp == "none") return LANG_PACK_NONE; - /* If "auto" is selected, we load polyglossia if required, + /* If "auto" is selected, we load polyglossia with non-TeX fonts, * else we select babel. * If babel is selected (either directly or via the "auto" * mechanism), we really do only require it if we have * a language that needs it. */ bool const polyglossia_required = - isRequired("polyglossia") + params_.useNonTeXFonts && isAvailable("polyglossia") && !isProvided("babel") && this->hasOnlyPolyglossiaLanguages(); - bool const babel_required = + bool const babel_required = !bufferParams().language->babel().empty() || !this->getBabelLanguages().empty(); @@ -477,26 +541,29 @@ bool LaTeXFeatures::isProvided(string const & name) const bool const ot1 = (params_.font_encoding() == "default" || params_.font_encoding() == "OT1"); - bool const complete = (params_.fonts_sans == "default") - && (params_.fonts_typewriter == "default"); - bool const nomath = (params_.fonts_math == "default"); + bool const complete = (params_.fontsSans() == "default" + && params_.fontsTypewriter() == "default"); + bool const nomath = (params_.fontsMath() == "default"); return params_.documentClass().provides(name) || theLaTeXFonts().getLaTeXFont( - from_ascii(params_.fonts_roman)).provides(name, ot1, + from_ascii(params_.fontsRoman())).provides(name, ot1, complete, nomath) || theLaTeXFonts().getLaTeXFont( - from_ascii(params_.fonts_sans)).provides(name, ot1, + from_ascii(params_.fontsSans())).provides(name, ot1, complete, nomath) || theLaTeXFonts().getLaTeXFont( - from_ascii(params_.fonts_typewriter)).provides(name, ot1, + from_ascii(params_.fontsTypewriter())).provides(name, ot1, complete, nomath) || theLaTeXFonts().getLaTeXFont( - from_ascii(params_.fonts_math)).provides(name, ot1, + from_ascii(params_.fontsMath())).provides(name, ot1, complete, nomath); + // TODO: "textbaltic" provided, if the font-encoding is "L7x" + // "textgreek" provided, if a language with font-encoding LGR is used in the document + // "textcyr" provided, if a language with font-encoding T2A is used in the document } @@ -519,11 +586,12 @@ bool LaTeXFeatures::isAvailable(string const & name) } -void LaTeXFeatures::addPreambleSnippet(string const & preamble) +void LaTeXFeatures::addPreambleSnippet(string const & preamble, + bool allowdupes) { SnippetList::const_iterator begin = preamble_snippets_.begin(); SnippetList::const_iterator end = preamble_snippets_.end(); - if (find(begin, end, preamble) == end) + if (allowdupes || find(begin, end, preamble) == end) preamble_snippets_.push_back(preamble); } @@ -666,6 +734,31 @@ set LaTeXFeatures::getEncodingSet(string const & doc_encoding) const return encodings; } + +void LaTeXFeatures::getFontEncodings(vector & encodings) const +{ + // these must be loaded if glyphs of this script are used + // unless a language providing them is used in the document + // FIXME: currently the option is written twice in this case + if (mustProvide("textgreek")) + encodings.insert(encodings.begin(), "LGR"); + if (mustProvide("textcyr")) + encodings.insert(encodings.begin(), "T2A"); + + LanguageList::const_iterator it = UsedLanguages_.begin(); + LanguageList::const_iterator end = UsedLanguages_.end(); + for (; it != end; ++it) + if (!(*it)->fontenc().empty() + && ascii_lowercase((*it)->fontenc()) != "none") { + vector extraencs = getVectorFromString((*it)->fontenc()); + vector::const_iterator fit = extraencs.begin(); + for (; fit != extraencs.end(); ++fit) { + if (find(encodings.begin(), encodings.end(), *fit) == encodings.end()) + encodings.insert(encodings.begin(), *fit); + } + } +} + namespace { char const * simplefeatures[] = { @@ -698,7 +791,6 @@ char const * simplefeatures[] = { "pmboxdraw", "bbding", "ifsym", - "marvosym", "txfonts", "pxfonts", "mathdesign", @@ -724,12 +816,15 @@ char const * simplefeatures[] = { "tfrupee", "shapepar", "rsphrase", + "hpstatement", "algorithm2e", "sectionbox", "tcolorbox", "pdfcomment", "fixme", - "todonotes" + "todonotes", + "forest", + "varwidth" }; char const * bibliofeatures[] = { @@ -866,22 +961,23 @@ string const LaTeXFeatures::getPackages() const string const amsPackages = loadAMSPackages(); bool const ot1 = (params_.font_encoding() == "default" || params_.font_encoding() == "OT1"); bool const use_newtxmath = - theLaTeXFonts().getLaTeXFont(from_ascii(params_.fonts_math)).getUsedPackage( + theLaTeXFonts().getLaTeXFont(from_ascii(params_.fontsMath())).getUsedPackage( ot1, false, false) == "newtxmath"; - + if (!params_.useNonTeXFonts && !use_newtxmath && !amsPackages.empty()) packages << amsPackages; - // fixltx2e must be loaded after amsthm, since amsthm produces an error with - // the redefined \[ command (bug 7233). Load it as early as possible, since - // other packages might profit from it. - if (mustProvide("fixltx2e")) - packages << "\\usepackage{fixltx2e}\n"; - if (mustProvide("cancel") && params_.use_package("cancel") != BufferParams::package_off) packages << "\\usepackage{cancel}\n"; - + + // marvosym and bbding both define the \Cross macro + if (mustProvide("marvosym")) { + if (mustProvide("bbding")) + packages << "\\let\\Cross\\relax\n"; + packages << "\\usepackage{marvosym}\n"; + } + // accents must be loaded after amsmath if (mustProvide("accents") && params_.use_package("accents") != BufferParams::package_off) @@ -1044,6 +1140,10 @@ string const LaTeXFeatures::getPackages() const if (mustProvide("footmisc")) packages << "\\PassOptionsToPackage{stable}{footmisc}\n"; + if (mustProvide("microtype")){ + packages << "\\usepackage{microtype}\n"; + } + return packages.str(); } @@ -1080,8 +1180,11 @@ docstring const LaTeXFeatures::getMacros() const } if (mustProvide("papersize")) { - if (runparams_.flavor == OutputParams::LATEX) + if (runparams_.flavor == OutputParams::LATEX + || runparams_.flavor == OutputParams::DVILUATEX) macros << papersizedvi_def << '\n'; + else if (runparams_.flavor == OutputParams::LUATEX) + macros << papersizepdflua_def << '\n'; else macros << papersizepdf_def << '\n'; } @@ -1100,21 +1203,35 @@ docstring const LaTeXFeatures::getMacros() const macros << lyxarrow_def << '\n'; if (!usePolyglossia() && mustProvide("textgreek")) { - // Avoid a LaTeX error if times fonts are used and the grtimes - // package is installed but actual fonts are not (bug 6469). - if (params_.fonts_roman == "times") - macros << subst(textgreek_def, - from_ascii("\\greektext #1"), - from_ascii("%\n \\IfFileExists" - "{grtm10.tfm}{}{\\fontfamily" - "{cmr}}\\greektext #1")) - << '\n'; - else - macros << textgreek_def << '\n'; + // ensure LGR font encoding is defined also if fontenc is not loaded by LyX + if (params_.font_encoding() == "default") + macros << textgreek_LGR_def; + macros << textgreek_def << '\n'; } - if (!usePolyglossia() && mustProvide("textcyr")) + if (!usePolyglossia() && mustProvide("textcyr")) { + // ensure T2A font encoding is set up also if fontenc is not loaded by LyX + if (params_.font_encoding() == "default") + macros << textcyr_T2A_def; macros << textcyr_def << '\n'; + } + + // non-standard text accents: + if (mustProvide("textcommaabove") || mustProvide("textcommaaboveright") || + mustProvide("textcommabelow") || mustProvide("textbaltic")) + macros << lyxaccent_def; + + if (mustProvide("textcommabelow") || mustProvide("textbaltic")) + macros << textcommabelow_def << '\n'; + + if (mustProvide("textcommaabove") || mustProvide("textbaltic")) + macros << textcommaabove_def << '\n'; + + if (mustProvide("textcommaaboveright")) + macros << textcommaaboveright_def << '\n'; + + if (mustProvide("textbaltic")) + macros << textbaltic_def << '\n'; if (mustProvide("lyxmathsym")) macros << lyxmathsym_def << '\n'; @@ -1172,6 +1289,8 @@ docstring const LaTeXFeatures::getMacros() const // other if (mustProvide("ParagraphLeftIndent")) macros << paragraphleftindent_def; + if (mustProvide("NeedLyXFootnoteCode")) + macros << floatingfootnote_def; // some problems with tex->html converters if (mustProvide("NeedTabularnewline")) @@ -1281,8 +1400,6 @@ bool LaTeXFeatures::needBabelLangOptions() const string const LaTeXFeatures::loadAMSPackages() const { ostringstream tmp; - if (mustProvide("amsthm")) - tmp << "\\usepackage{amsthm}\n"; if (mustProvide("amsmath") && params_.use_package("amsmath") != BufferParams::package_off) { @@ -1295,6 +1412,9 @@ string const LaTeXFeatures::loadAMSPackages() const tmp << "\\usepackage{amstext}\n"; } + if (mustProvide("amsthm")) + tmp << "\\usepackage{amsthm}\n"; + if (mustProvide("amssymb") && params_.use_package("amssymb") != BufferParams::package_off) tmp << "\\usepackage{amssymb}\n"; @@ -1569,11 +1689,8 @@ docstring const LaTeXFeatures::getTClassI18nPreamble(bool use_babel, bool use_po // need to force a fixed width encoding for // \lstlistlistingname and \lstlistingname (bug 9382). // This needs to be consistent with InsetListings::latex(). - docstring const ilname = it->second.name(); bool const need_fixedwidth = !runparams_.isFullUnicode() && - (ilname == "Listings" || - ilname == "Include:Listings" || - ilname == "TOC:Listings"); + it->second.fixedwidthpreambleencoding(); // language dependent commands (once per document) snippets.insert(i18npreamble(it->second.langpreamble(), buffer().language(), @@ -1739,10 +1856,23 @@ void LaTeXFeatures::resolveAlternatives() vector const alternatives = getVectorFromString(*it, "|"); vector::const_iterator const end = alternatives.end(); vector::const_iterator ita = alternatives.begin(); + // Is any alternative already required? => use that for (; ita != end; ++ita) { if (isRequired(*ita)) break; } + // Is any alternative available? => use the first one + // (bug 9498) + if (ita == end) { + for (ita = alternatives.begin(); ita != end; ++ita) { + if (isAvailable(*ita)) { + require(*ita); + break; + } + } + } + // This will not work, but not requiring something + // would be more confusing if (ita == end) require(alternatives.front()); features_.erase(it);