X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLaTeXFeatures.cpp;h=a9ad21ca2c6e028674dfb95189fa677b7e76b879;hb=e41c790f9156e3b889e4b4f48653380c7a5c737d;hp=8b7287e5307e2cc384f75d02c69a6839245539ad;hpb=97b9e81ceef7aaedcdbe012fba5f4972727d29ea;p=lyx.git diff --git a/src/LaTeXFeatures.cpp b/src/LaTeXFeatures.cpp index 8b7287e530..a9ad21ca2c 100644 --- a/src/LaTeXFeatures.cpp +++ b/src/LaTeXFeatures.cpp @@ -30,6 +30,8 @@ #include "Lexer.h" #include "LyXRC.h" #include "TextClass.h" +#include "TexRow.h" +#include "texstream.h" #include "insets/InsetLayout.h" @@ -63,6 +65,10 @@ namespace lyx { static docstring const lyx_def = from_ascii( "\\providecommand{\\LyX}{L\\kern-.1667em\\lower.25em\\hbox{Y}\\kern-.125emX\\@}"); +static docstring const lyx_rtl_def = from_ascii( + "\\let\\@@LyX\\LyX\n" + "\\def\\LyX{\\@ensure@LTR{\\@@LyX}}"); + static docstring const lyx_hyperref_def = from_ascii( "\\providecommand{\\LyX}{\\texorpdfstring%\n" " {L\\kern-.1667em\\lower.25em\\hbox{Y}\\kern-.125emX\\@}\n" @@ -77,6 +83,15 @@ static docstring const lyxarrow_def = from_ascii( "{\\leavevmode\\,$\\triangleleft$\\,\\allowbreak}\n" "{\\leavevmode\\,$\\triangleright$\\,\\allowbreak}}"); +// ZERO WIDTH SPACE (ZWSP) is actually not a space character +// but marks a line break opportunity. Several commands provide a +// line break opportunity. They differ in side-effects: +// \allowbreak prevents hyphenation after hyphen or dash + ZWSP +// \linebreak[] takes an optional argument denoting "urgency". +// The \LyXZeroWidthSpace wrapper allows customization in the preamble. +static docstring const lyxZWSP_def = from_ascii( + "\\newcommand*\\LyXZeroWidthSpace{\\hspace{0pt}}"); + // for quotes without babel. This does not give perfect results, but // anybody serious about non-english quotes should use babel (JMarc). @@ -116,6 +131,25 @@ static docstring const guilsinglright_def = from_ascii( " {\\usefont{U}{lasy}{m}{n}\\char'51}%\n" "}"); +static docstring const textquotedbl_def = from_ascii( + "\\DeclareTextSymbolDefault{\\textquotedbl}{T1}"); + +static docstring const textquotedblp_xetex_def = from_ascii( + "\\providecommand\\textquotedblplain{%\n" + " \\bgroup\\addfontfeatures{Mapping=}\\char34\\egroup}"); + +static docstring const textquotedblp_luatex_def = from_ascii( + "\\providecommand\\textquotedblplain{%\n" + " \\bgroup\\addfontfeatures{RawFeature=-tlig}\\char34\\egroup}"); + +static docstring const textquotesinglep_xetex_def = from_ascii( + "\\providecommand\\textquotesingleplain{%\n" + " \\bgroup\\addfontfeatures{Mapping=}\\char39\\egroup}"); + +static docstring const textquotesinglep_luatex_def = from_ascii( + "\\providecommand\\textquotesingleplain{%\n" + " \\bgroup\\addfontfeatures{RawFeature=-tlig}\\char39\\egroup}"); + static docstring const paragraphleftindent_def = from_ascii( "\\newenvironment{LyXParagraphLeftIndent}[1]%\n" "{\n" @@ -170,6 +204,39 @@ static docstring const lyxgreyedout_def = from_ascii( " {\\textcolor{note_fontcolor}\\bgroup\\ignorespaces}\n" " {\\ignorespacesafterend\\egroup}\n"); +static docstring const lyxgreyedout_rtl_def = from_ascii( + "%% The greyedout annotation environment (with RTL support)\n" + "\\NewEnviron{lyxgreyedout}{%\n" + "\\if@rl%\n" + "\\everypar{\\textcolor{note_fontcolor}\\beginL\\ignorespaces}%\n" + "\\BODY\\everypar{\\ignorespacesafterend\\endL}\n" + "\\else%\n" + "\\textcolor{note_fontcolor}\\bgroup\\ignorespaces%\n" + "\\BODY\\ignorespacesafterend\\egroup\n" + "\\fi}\n"); + +static docstring const lyxgreyedout_luartl_def = from_ascii( + "%% The greyedout annotation environment (with RTL support)\n" + "\\NewEnviron{lyxgreyedout}{%\n" + "\\if@RTL%\n" + "\\everypar{\\color{note_fontcolor}\\pardir TRT \\textdir TRT\\ignorespaces}%\n" + "\\BODY\\everypar{\\ignorespacesafterend}\n" + "\\else%\n" + "\\textcolor{note_fontcolor}\\bgroup\\ignorespaces%\n" + "\\BODY\\ignorespacesafterend\\egroup\n" + "\\fi}\n"); + +static docstring const lyxgreyedout_luartl_babel_def = from_ascii( + "%% The greyedout annotation environment (with RTL support)\n" + "\\NewEnviron{lyxgreyedout}{%\n" + "\\if@rl%\n" + "\\everypar{\\color{note_fontcolor}\\pardir TRT \\textdir TRT\\ignorespaces}%\n" + "\\BODY\\everypar{\\ignorespacesafterend}\n" + "\\else%\n" + "\\textcolor{note_fontcolor}\\bgroup\\ignorespaces%\n" + "\\BODY\\ignorespacesafterend\\egroup\n" + "\\fi}\n"); + // We want to omit the file extension for includegraphics, but this does not // work when the filename contains other dots. // Idea from http://www.tex.ac.uk/cgi-bin/texfaq2html?label=unkgrfextn @@ -191,12 +258,25 @@ static docstring const changetracking_dvipost_def = from_ascii( static docstring const changetracking_xcolor_ulem_def = from_ascii( "%% Change tracking with ulem\n" "\\DeclareRobustCommand{\\lyxadded}[3]{{\\color{lyxadded}{}#3}}\n" - "\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\color{lyxdeleted}\\sout{#3}}}\n"); + "\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\color{lyxdeleted}\\lyxsout{#3}}}\n" + "\\DeclareRobustCommand{\\lyxsout}[1]{\\ifx\\\\#1\\else\\sout{#1}\\fi}\n"); static docstring const changetracking_xcolor_ulem_hyperref_def = from_ascii( "%% Change tracking with ulem\n" "\\DeclareRobustCommand{\\lyxadded}[3]{{\\texorpdfstring{\\color{lyxadded}{}}{}#3}}\n" - "\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\texorpdfstring{\\color{lyxdeleted}\\sout{#3}}{}}}\n"); + "\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\texorpdfstring{\\color{lyxdeleted}\\lyxsout{#3}}{}}}\n" + "\\DeclareRobustCommand{\\lyxsout}[1]{\\ifx\\\\#1\\else\\sout{#1}\\fi}\n"); + +static docstring const changetracking_tikz_math_sout_def = from_ascii( + "%% Strike out display math with tikz\n" + "\\usepackage{tikz}\n" + "\\usetikzlibrary{calc}\n" + "\\newcommand{\\lyxmathsout}[1]{%\n" + " \\tikz[baseline=(math.base)]{\n" + " \\node[inner sep=0pt,outer sep=0pt](math){#1};\n" + " \\draw($(math.south west)+(2em,.5em)$)--($(math.north east)-(2em,.5em)$);\n" + " }\n" + "}\n"); static docstring const changetracking_none_def = from_ascii( "\\newcommand{\\lyxadded}[3]{#3}\n" @@ -231,8 +311,8 @@ static docstring const papersizepdf_def = from_ascii( 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" + "\\@ifundefined{pageheight}{\\let\\pageheight\\pdfpageheight}{}\n" + "\\@ifundefined{pagewidth}{\\let\\pagewidth\\pdfpagewidth}{}\n" "\\pageheight\\paperheight\n" "\\pagewidth\\paperwidth\n"); @@ -296,7 +376,7 @@ static docstring const textcommaabove_def = from_ascii( static docstring const textcommaaboveright_def = from_ascii( "\\ProvideTextCommandDefault{\\textcommaaboveright}[1]{%%\n" - " \\LyxTextAccent[.5ex]{\\LyxAccentSize\\ `}{#1}}\n"); + " \\LyxTextAccent[.5ex]{\\LyxAccentSize\\ '}{#1}}\n"); // Baltic languages use a comma-accent instead of a cedilla static docstring const textbaltic_def = from_ascii( @@ -312,6 +392,23 @@ static docstring const textbaltic_def = from_ascii( "\\DeclareTextCompositeCommand{\\c}{T1}{r}{\\textcommabelow{r}}\n" "\\DeclareTextCompositeCommand{\\c}{T1}{R}{\\textcommabelow{R}}\n"); +// split-level fractions +static docstring const xfrac_def = from_ascii( + "\\usepackage{xfrac}\n"); +static docstring const smallLetterFrac_def = from_ascii( + "\\DeclareCollectionInstance{smallLetterFrac}{xfrac}{default}{text}\n" + " {phantom=c, scale-factor=1.0, slash-left-kern=-.05em}\n" + "\\DeclareCollectionInstance{smallLetterFrac}{xfrac}{lmr}{text}\n" + " {slash-symbol-font=ptm, phantom=c, scale-factor=1, slash-left-kern=-.05em}\n" + "\\DeclareCollectionInstance{smallLetterFrac}{xfrac}{lmss}{text}\n" + " {slash-symbol-font=ptm, phantom=c, scale-factor=1, slash-left-kern=-.05em}\n" + "\\DeclareCollectionInstance{smallLetterFrac}{xfrac}{cmr}{text}\n" + " {slash-symbol-font=ptm, phantom=c, scale-factor=1, slash-left-kern=-.05em}\n" + "\\DeclareCollectionInstance{smallLetterFrac}{xfrac}{cmss}{text}\n" + " {slash-symbol-font=ptm, phantom=c, scale-factor=1, slash-left-kern=-.05em}\n" + "\\newcommand{\\smallLetterFrac}[2]{%\n" + " {\\UseCollection{xfrac}{smallLetterFrac}\\sfrac{#1}{#2}}}\n"); + static docstring const lyxref_def = from_ascii( "\\RS@ifundefined{subsecref}\n" " {\\newref{subsec}{name = \\RSsectxt}}\n" @@ -359,6 +456,19 @@ static docstring const rtloutputdblcol_def = from_ascii( "}\n" "\\@mparswitchtrue\n"); +static docstring const lyxmintcaption_def = from_ascii( + "\\long\\def\\lyxmintcaption[#1]#2{%\n" + " \\ifx#1t\\vskip\\baselineskip\\fi%\n" + " \\refstepcounter{listing}\\noindent%\n" + " \\addcontentsline{lol}{listing}%\n" + " {\\protect\\numberline{\\thelisting}{\\ignorespaces #2}}%\n" + " \\setbox\\@tempboxa\\hbox{\\listingscaption~\\thelisting: #2}%\n" + " \\ifdim \\wd\\@tempboxa >\\linewidth%\n" + " \\parbox[t]{\\linewidth}{\\unhbox\\@tempboxa}\\else%\n" + " \\hbox to\\linewidth{\\hfil\\box\\@tempboxa\\hfil}\\fi%\n" + " \\ifx#1b\\vskip\\baselineskip\\fi\n" + "}\n"); + ///////////////////////////////////////////////////////////////////// // @@ -388,7 +498,8 @@ static docstring const lyxstrikeout_style = from_ascii( LaTeXFeatures::LaTeXFeatures(Buffer const & b, BufferParams const & p, OutputParams const & r) - : buffer_(&b), params_(p), runparams_(r), in_float_(false) + : buffer_(&b), params_(p), runparams_(r), in_float_(false), + in_deleted_inset_(false) {} @@ -539,8 +650,8 @@ bool LaTeXFeatures::isProvided(string const & name) const if (params_.useNonTeXFonts) return params_.documentClass().provides(name); - bool const ot1 = (params_.font_encoding() == "default" - || params_.font_encoding() == "OT1"); + bool const ot1 = (params_.main_font_encoding() == "default" + || params_.main_font_encoding() == "OT1"); bool const complete = (params_.fontsSans() == "default" && params_.fontsTypewriter() == "default"); bool const nomath = (params_.fontsMath() == "default"); @@ -586,25 +697,62 @@ bool LaTeXFeatures::isAvailable(string const & name) } -void LaTeXFeatures::addPreambleSnippet(string const & preamble, - bool allowdupes) +namespace { + +void addSnippet(std::list & list, TexString ts, bool allow_dupes) { - SnippetList::const_iterator begin = preamble_snippets_.begin(); - SnippetList::const_iterator end = preamble_snippets_.end(); - if (allowdupes || find(begin, end, preamble) == end) - preamble_snippets_.push_back(preamble); + if (allow_dupes || + // test the absense of duplicates, i.e. elements with same str + none_of(list.begin(), list.end(), [&](TexString const & ts2){ + return ts.str == ts2.str; + }) + ) + list.push_back(move(ts)); +} + + +TexString getSnippets(std::list const & list) +{ + otexstringstream snip; + for (TexString const & ts : list) + snip << TexString(ts) << '\n'; + return snip.release(); +} + +} // namespace + + +void LaTeXFeatures::addPreambleSnippet(TexString ts, bool allow_dupes) +{ + addSnippet(preamble_snippets_, move(ts), allow_dupes); +} + + +void LaTeXFeatures::addPreambleSnippet(docstring const & str, bool allow_dupes) +{ + addSnippet(preamble_snippets_, TexString(str), allow_dupes); } void LaTeXFeatures::addCSSSnippet(std::string const & snippet) { - SnippetList::const_iterator begin = css_snippets_.begin(); - SnippetList::const_iterator end = css_snippets_.end(); - if (find(begin, end, snippet) == end) - css_snippets_.push_back(snippet); + addSnippet(css_snippets_, TexString(from_ascii(snippet)), false); } +TexString LaTeXFeatures::getPreambleSnippets() const +{ + return getSnippets(preamble_snippets_); +} + + +docstring LaTeXFeatures::getCSSSnippets() const +{ + return getSnippets(css_snippets_).str; +} + + + void LaTeXFeatures::useFloat(string const & name, bool subfloat) { if (!usedFloats_[name]) @@ -683,6 +831,42 @@ bool LaTeXFeatures::hasPolyglossiaExclusiveLanguages() const } +vector LaTeXFeatures::getPolyglossiaExclusiveLanguages() const +{ + vector result; + // first the main language + if (params_.language->isPolyglossiaExclusive()) + result.push_back(params_.language->display()); + // now the secondary languages + LanguageList::const_iterator const begin = UsedLanguages_.begin(); + for (LanguageList::const_iterator cit = begin; + cit != UsedLanguages_.end(); + ++cit) { + if ((*cit)->isPolyglossiaExclusive()) + result.push_back((*cit)->display()); + } + return result; +} + + +vector LaTeXFeatures::getBabelExclusiveLanguages() const +{ + vector result; + // first the main language + if (params_.language->isBabelExclusive()) + result.push_back(params_.language->display()); + // now the secondary languages + LanguageList::const_iterator const begin = UsedLanguages_.begin(); + for (LanguageList::const_iterator cit = begin; + cit != UsedLanguages_.end(); + ++cit) { + if ((*cit)->isBabelExclusive()) + result.push_back((*cit)->display()); + } + return result; +} + + string LaTeXFeatures::getBabelLanguages() const { ostringstream languages; @@ -704,15 +888,16 @@ string LaTeXFeatures::getBabelLanguages() const } -std::map LaTeXFeatures::getPolyglossiaLanguages() const +set LaTeXFeatures::getPolyglossiaLanguages() const { - std::map languages; + set languages; LanguageList::const_iterator const begin = UsedLanguages_.begin(); for (LanguageList::const_iterator cit = begin; cit != UsedLanguages_.end(); ++cit) { - languages[(*cit)->polyglossia()] = (*cit)->polyglossiaOpts(); + // We do not need the variants here + languages.insert((*cit)->polyglossia()); } return languages; } @@ -739,10 +924,11 @@ 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")) + if (mustProvide("textgreek") + && find(encodings.begin(), encodings.end(), "LGR") == encodings.end()) encodings.insert(encodings.begin(), "LGR"); - if (mustProvide("textcyr")) + if (mustProvide("textcyr") + && find(encodings.begin(), encodings.end(), "T2A") == encodings.end()) encodings.insert(encodings.begin(), "T2A"); LanguageList::const_iterator it = UsedLanguages_.begin(); @@ -759,6 +945,17 @@ void LaTeXFeatures::getFontEncodings(vector & encodings) const } } + +bool LaTeXFeatures::hasRTLLanguage() const +{ + if (params_.language->rightToLeft()) + return true; + for (auto const & lang : UsedLanguages_) + if (lang->rightToLeft()) + return true; + return false; +} + namespace { char const * simplefeatures[] = { @@ -766,7 +963,6 @@ char const * simplefeatures[] = { "array", "verbatim", "longtable", - "rotating", "latexsym", "pifont", // subfig is handled in BufferParams.cpp @@ -778,7 +974,6 @@ char const * simplefeatures[] = { the `float' package. See the caption package documentation for explanation.*/ "float", - "rotfloat", "wrapfig", "booktabs", "dvipost", @@ -788,6 +983,7 @@ char const * simplefeatures[] = { "framed", "soul", "textcomp", + "dingbat", "pmboxdraw", "bbding", "ifsym", @@ -800,7 +996,6 @@ char const * simplefeatures[] = { // "cancel", "ascii", "url", - "covington", "csquotes", "enumitem", "endnotes", @@ -824,7 +1019,8 @@ char const * simplefeatures[] = { "fixme", "todonotes", "forest", - "varwidth" + "varwidth", + "environ" }; char const * bibliofeatures[] = { @@ -836,6 +1032,7 @@ char const * bibliofeatures[] = { "authordate1-4", "babelbib", "bibgerm", + "chapterbib", "chicago", "chscite", "harvard", @@ -847,7 +1044,7 @@ int const nb_bibliofeatures = sizeof(bibliofeatures) / sizeof(char const *); int const nb_simplefeatures = sizeof(simplefeatures) / sizeof(char const *); -} +} // namespace string const LaTeXFeatures::getColorOptions() const @@ -946,6 +1143,22 @@ string const LaTeXFeatures::getPackages() const // The rest of these packages are somewhat more complicated // than those above. + if (mustProvide("footnote")) { + if (isRequired("hyperref")) + packages << "\\usepackage{footnotehyper}\n"; + else + packages << "\\usepackage{footnote}\n"; + } + + // [pdf]lscape is used to rotate longtables + if (mustProvide("lscape")) { + if (runparams_.flavor == OutputParams::LATEX + || runparams_.flavor == OutputParams::DVILUATEX) + packages << "\\usepackage{lscape}\n"; + else + packages << "\\usepackage{pdflscape}\n"; + } + // The tipa package and its extensions (tipx, tone) must not // be loaded with non-TeX fonts, since fontspec includes the // respective macros @@ -953,13 +1166,16 @@ string const LaTeXFeatures::getPackages() const packages << "\\usepackage{tipa}\n"; if (mustProvide("tipx") && !params_.useNonTeXFonts) packages << "\\usepackage{tipx}\n"; + if (mustProvide("extraipa") && !params_.useNonTeXFonts) + packages << "\\usepackage{extraipa}\n"; if (mustProvide("tone") && !params_.useNonTeXFonts) packages << "\\usepackage{tone}\n"; // if fontspec or newtxmath is used, AMS packages have to be loaded // before fontspec (in BufferParams) string const amsPackages = loadAMSPackages(); - bool const ot1 = (params_.font_encoding() == "default" || params_.font_encoding() == "OT1"); + bool const ot1 = (params_.main_font_encoding() == "default" + || params_.main_font_encoding() == "OT1"); bool const use_newtxmath = theLaTeXFonts().getLaTeXFont(from_ascii(params_.fontsMath())).getUsedPackage( ot1, false, false) == "newtxmath"; @@ -1027,6 +1243,16 @@ string const LaTeXFeatures::getPackages() const << "]{graphicx}\n"; } + // These must be loaded after graphicx, since they try + // to load graphicx without options + if (mustProvide("rotating")) + packages << "\\usepackage{rotating}\n"; + if (mustProvide("rotfloat")) + packages << "\\usepackage{rotfloat}\n"; + // and this must be loaded after rotating + if (mustProvide("tablefootnote")) + packages << "\\usepackage{tablefootnote}\n"; + // lyxskak.sty --- newer chess support based on skak.sty if (mustProvide("chess")) packages << "\\usepackage[ps,mover]{lyxskak}\n"; @@ -1077,12 +1303,18 @@ string const LaTeXFeatures::getPackages() const // Some classes load natbib themselves, but still allow (or even require) // plain numeric citations (ReVTeX is such a case, see bug 5182). // This special case is indicated by the "natbib-internal" key. - if (mustProvide("natbib") && !isProvided("natbib-internal")) { + if (mustProvide("natbib") + && !isProvided("natbib-internal") + && !isProvided("biblatex") + && !isProvided("biblatex-natbib") + && !isProvided("jurabib")) { packages << "\\usepackage["; if (params_.citeEngineType() == ENGINE_TYPE_NUMERICAL) packages << "numbers"; else packages << "authoryear"; + if (!params_.biblio_opts.empty()) + packages << ',' << params_.biblio_opts; packages << "]{natbib}\n"; } @@ -1094,8 +1326,16 @@ string const LaTeXFeatures::getPackages() const } // jurabib -- we need version 0.6 at least. - if (mustProvide("jurabib")) - packages << "\\usepackage{jurabib}[2004/01/25]\n"; + if (mustProvide("jurabib") + && !isProvided("natbib-internal") + && !isProvided("natbib") + && !isProvided("biblatex") + && !isProvided("biblatex-natbib")) { + packages << "\\usepackage"; + if (!params_.biblio_opts.empty()) + packages << '[' << params_.biblio_opts << ']'; + packages << "{jurabib}[2004/01/25]\n"; + } // opcit -- we pass custombst as we output \bibliographystyle ourselves if (mustProvide("opcit")) { @@ -1148,37 +1388,18 @@ string const LaTeXFeatures::getPackages() const } -string LaTeXFeatures::getPreambleSnippets() const +TexString LaTeXFeatures::getMacros() const { - ostringstream snip; - SnippetList::const_iterator pit = preamble_snippets_.begin(); - SnippetList::const_iterator pend = preamble_snippets_.end(); - for (; pit != pend; ++pit) - snip << *pit << '\n'; - return snip.str(); -} - - -std::string LaTeXFeatures::getCSSSnippets() const -{ - ostringstream snip; - SnippetList::const_iterator pit = css_snippets_.begin(); - SnippetList::const_iterator pend = css_snippets_.end(); - for (; pit != pend; ++pit) - snip << *pit << '\n'; - return snip.str(); -} - - -docstring const LaTeXFeatures::getMacros() const -{ - odocstringstream macros; + otexstringstream macros; if (!preamble_snippets_.empty()) { macros << '\n'; - macros << from_utf8(getPreambleSnippets()); + macros << getPreambleSnippets(); } + if (mustProvide("xetexdashbreakstate")) + macros << "\\XeTeXdashbreakstate 0" << '\n'; + if (mustProvide("papersize")) { if (runparams_.flavor == OutputParams::LATEX || runparams_.flavor == OutputParams::DVILUATEX) @@ -1194,6 +1415,8 @@ docstring const LaTeXFeatures::getMacros() const macros << lyx_hyperref_def << '\n'; else macros << lyx_def << '\n'; + if (runparams_.use_polyglossia && hasRTLLanguage()) + macros << lyx_rtl_def << '\n'; } if (mustProvide("noun")) @@ -1202,21 +1425,24 @@ docstring const LaTeXFeatures::getMacros() const if (mustProvide("lyxarrow")) macros << lyxarrow_def << '\n'; + if (mustProvide("lyxzerowidthspace")) + macros << lyxZWSP_def << '\n'; + if (!usePolyglossia() && mustProvide("textgreek")) { - // ensure LGR font encoding is defined also if fontenc is not loaded by LyX - if (params_.font_encoding() == "default") + // ensure LGR font encoding is defined also if fontenc is not loaded by LyX + if (params_.main_font_encoding() == "default") macros << textgreek_LGR_def; macros << textgreek_def << '\n'; } if (!usePolyglossia() && mustProvide("textcyr")) { // ensure T2A font encoding is set up also if fontenc is not loaded by LyX - if (params_.font_encoding() == "default") + if (params_.main_font_encoding() == "default") macros << textcyr_T2A_def; macros << textcyr_def << '\n'; } - // non-standard text accents: + // non-standard text accents: if (mustProvide("textcommaabove") || mustProvide("textcommaaboveright") || mustProvide("textcommabelow") || mustProvide("textbaltic")) macros << lyxaccent_def; @@ -1233,6 +1459,13 @@ docstring const LaTeXFeatures::getMacros() const if (mustProvide("textbaltic")) macros << textbaltic_def << '\n'; + // split-level fractions + if (mustProvide("xfrac") || mustProvide("smallLetterFrac")) + macros << xfrac_def << '\n'; + + if (mustProvide("smallLetterFrac")) + macros << smallLetterFrac_def << '\n'; + if (mustProvide("lyxmathsym")) macros << lyxmathsym_def << '\n'; @@ -1279,6 +1512,20 @@ docstring const LaTeXFeatures::getMacros() const macros << guillemotleft_def << '\n'; if (mustProvide("guillemotright")) macros << guillemotright_def << '\n'; + if (mustProvide("textquotedbl")) + macros << textquotedbl_def << '\n'; + if (mustProvide("textquotesinglep")) { + if (runparams_.flavor == OutputParams::XETEX) + macros << textquotesinglep_xetex_def << '\n'; + else + macros << textquotesinglep_luatex_def << '\n'; + } + if (mustProvide("textquotedblp")) { + if (runparams_.flavor == OutputParams::XETEX) + macros << textquotedblp_xetex_def << '\n'; + else + macros << textquotedblp_luatex_def << '\n'; + } // Math mode if (mustProvide("binom") && !isRequired("amsmath")) @@ -1299,8 +1546,19 @@ docstring const LaTeXFeatures::getMacros() const // greyed-out environment (note inset) // the color is specified in the routine // getColorOptions() to avoid LaTeX-package clashes - if (mustProvide("lyxgreyedout")) - macros << lyxgreyedout_def; + if (mustProvide("lyxgreyedout")) { + // We need different version for RTL (#8647) + if (hasRTLLanguage()) { + if (runparams_.flavor == OutputParams::LUATEX) + if (useBabel()) + macros << lyxgreyedout_luartl_babel_def; + else + macros << lyxgreyedout_luartl_def; + else + macros << lyxgreyedout_rtl_def; + } else + macros << lyxgreyedout_def; + } if (mustProvide("lyxdot")) macros << lyxdot_def << '\n'; @@ -1316,7 +1574,7 @@ docstring const LaTeXFeatures::getMacros() const macros << changetracking_dvipost_def; if (mustProvide("ct-xcolor-ulem")) { - streamsize const prec = macros.precision(2); + streamsize const prec = macros.os().precision(2); RGBColor cadd = rgbFromHexName(lcolor.getX11Name(Color_addedtext)); macros << "\\providecolor{lyxadded}{rgb}{" @@ -1326,7 +1584,7 @@ docstring const LaTeXFeatures::getMacros() const macros << "\\providecolor{lyxdeleted}{rgb}{" << cdel.r / 255.0 << ',' << cdel.g / 255.0 << ',' << cdel.b / 255.0 << "}\n"; - macros.precision(prec); + macros.os().precision(prec); if (isRequired("hyperref")) macros << changetracking_xcolor_ulem_hyperref_def; @@ -1334,25 +1592,29 @@ docstring const LaTeXFeatures::getMacros() const macros << changetracking_xcolor_ulem_def; } + if (mustProvide("ct-tikz-math-sout")) + macros << changetracking_tikz_math_sout_def; + if (mustProvide("ct-none")) macros << changetracking_none_def; if (mustProvide("rtloutputdblcol")) macros << rtloutputdblcol_def; - return macros.str(); + if (mustProvide("lyxmintcaption")) + macros << lyxmintcaption_def; + + return macros.release(); } -string const LaTeXFeatures::getBabelPresettings() const +docstring const LaTeXFeatures::getBabelPresettings() const { - ostringstream tmp; + odocstringstream tmp; - LanguageList::const_iterator it = UsedLanguages_.begin(); - LanguageList::const_iterator end = UsedLanguages_.end(); - for (; it != end; ++it) - if (!(*it)->babel_presettings().empty()) - tmp << (*it)->babel_presettings() << '\n'; + for (Language const * lang : UsedLanguages_) + if (!lang->babel_presettings().empty()) + tmp << lang->babel_presettings() << '\n'; if (!params_.language->babel_presettings().empty()) tmp << params_.language->babel_presettings() << '\n'; @@ -1363,15 +1625,13 @@ string const LaTeXFeatures::getBabelPresettings() const } -string const LaTeXFeatures::getBabelPostsettings() const +docstring const LaTeXFeatures::getBabelPostsettings() const { - ostringstream tmp; + odocstringstream tmp; - LanguageList::const_iterator it = UsedLanguages_.begin(); - LanguageList::const_iterator end = UsedLanguages_.end(); - for (; it != end; ++it) - if (!(*it)->babel_postsettings().empty()) - tmp << (*it)->babel_postsettings() << '\n'; + for (Language const * lang : UsedLanguages_) + if (!lang->babel_postsettings().empty()) + tmp << lang->babel_postsettings() << '\n'; if (!params_.language->babel_postsettings().empty()) tmp << params_.language->babel_postsettings() << '\n'; @@ -1434,7 +1694,10 @@ docstring const LaTeXFeatures::getTClassPreamble() const list::const_iterator cit = usedLayouts_.begin(); list::const_iterator end = usedLayouts_.end(); for (; cit != end; ++cit) - tcpreamble << tclass[*cit].preamble(); + // For InPreamble layouts, we output the preamble stuff earlier + // (before the layouts). See Paragraph::Private::validate. + if (!tclass[*cit].inpreamble) + tcpreamble << tclass[*cit].preamble(); cit = usedInsetLayouts_.begin(); end = usedInsetLayouts_.end(); @@ -1604,10 +1867,11 @@ docstring const i18npreamble(docstring const & templ, Language const * lang, return from_utf8(preamble); } -} +} // namespace -docstring const LaTeXFeatures::getTClassI18nPreamble(bool use_babel, bool use_polyglossia) const +docstring const LaTeXFeatures::getTClassI18nPreamble(bool use_babel, + bool use_polyglossia, bool use_minted) const { DocumentClass const & tclass = params_.documentClass(); // collect preamble snippets in a set to prevent multiple identical @@ -1689,8 +1953,9 @@ 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(). - bool const need_fixedwidth = !runparams_.isFullUnicode() && - it->second.fixedwidthpreambleencoding(); + bool const need_fixedwidth = !use_minted && + !runparams_.isFullUnicode() && + it->second.fixedwidthpreambleencoding(); // language dependent commands (once per document) snippets.insert(i18npreamble(it->second.langpreamble(), buffer().language(), @@ -1756,7 +2021,7 @@ void LaTeXFeatures::showStruct() const { lyxerr << "LyX needs the following commands when LaTeXing:" << "\n***** Packages:" << getPackages() - << "\n***** Macros:" << to_utf8(getMacros()) + << "\n***** Macros:" << to_utf8(getMacros().str) << "\n***** Textclass stuff:" << to_utf8(getTClassPreamble()) << "\n***** done." << endl; } @@ -1780,7 +2045,7 @@ BufferParams const & LaTeXFeatures::bufferParams() const } -void LaTeXFeatures::getFloatDefinitions(odocstream & os) const +void LaTeXFeatures::getFloatDefinitions(otexstream & os) const { FloatList const & floats = params_.documentClass().floats(); @@ -1883,4 +2148,24 @@ void LaTeXFeatures::resolveAlternatives() } +void LaTeXFeatures::expandMultiples() +{ + for (Features::iterator it = features_.begin(); it != features_.end();) { + if (contains(*it, ',')) { + vector const multiples = getVectorFromString(*it, ","); + vector::const_iterator const end = multiples.end(); + vector::const_iterator itm = multiples.begin(); + // Do nothing if any multiple is already required + for (; itm != end; ++itm) { + if (!isRequired(*itm)) + require(*itm); + } + features_.erase(it); + it = features_.begin(); + } else + ++it; + } +} + + } // namespace lyx