]> git.lyx.org Git - lyx.git/blob - src/LaTeXFeatures.cpp
Provide proper fallback if a bibliography processor is not found
[lyx.git] / src / LaTeXFeatures.cpp
1 /**
2  * \file LaTeXFeatures.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author José Matos
7  * \author Lars Gullik Bjønnes
8  * \author Jean-Marc Lasgouttes
9  * \author Jürgen Vigna
10  * \author André Pönitz
11  *
12  * Full author contact details are available in file CREDITS.
13  */
14
15 #include <config.h>
16
17 #include "LaTeXFeatures.h"
18
19 #include "Buffer.h"
20 #include "BufferParams.h"
21 #include "ColorSet.h"
22 #include "Converter.h"
23 #include "Encoding.h"
24 #include "Floating.h"
25 #include "FloatList.h"
26 #include "Language.h"
27 #include "LaTeXFonts.h"
28 #include "LaTeXPackages.h"
29 #include "Layout.h"
30 #include "Lexer.h"
31 #include "LyXRC.h"
32 #include "TextClass.h"
33 #include "TexRow.h"
34 #include "texstream.h"
35
36 #include "insets/InsetLayout.h"
37
38 #include "support/debug.h"
39 #include "support/docstream.h"
40 #include "support/FileName.h"
41 #include "support/filetools.h"
42 #include "support/gettext.h"
43 #include "support/lstrings.h"
44 #include "support/regex.h"
45
46 #include <algorithm>
47
48
49 using namespace std;
50 using namespace lyx::support;
51
52
53 namespace lyx {
54
55 /////////////////////////////////////////////////////////////////////
56 //
57 // Strings
58 //
59 /////////////////////////////////////////////////////////////////////
60
61 //\NeedsTeXFormat{LaTeX2e}
62 //\ProvidesPackage{lyx}[1996/01/11 LLE v0.2 (LyX LaTeX Extensions)]
63 //\message{LyX LaTeX Extensions (LLE v0.2) of 11-Jan-1996.}
64
65 static docstring const lyx_def = from_ascii(
66         "\\providecommand{\\LyX}{L\\kern-.1667em\\lower.25em\\hbox{Y}\\kern-.125emX\\@}");
67
68 static docstring const lyx_rtl_def = from_ascii(
69         "\\let\\@@LyX\\LyX\n"
70         "\\def\\LyX{\\@ensure@LTR{\\@@LyX}}");
71
72 static docstring const lyx_hyperref_def = from_ascii(
73         "\\providecommand{\\LyX}{\\texorpdfstring%\n"
74         "  {L\\kern-.1667em\\lower.25em\\hbox{Y}\\kern-.125emX\\@}\n"
75         "  {LyX}}");
76
77 static docstring const noun_def = from_ascii(
78         "\\newcommand{\\noun}[1]{\\textsc{#1}}");
79
80 static docstring const lyxarrow_def = from_ascii(
81         "\\DeclareRobustCommand*{\\lyxarrow}{%\n"
82         "\\@ifstar\n"
83         "{\\leavevmode\\,$\\triangleleft$\\,\\allowbreak}\n"
84         "{\\leavevmode\\,$\\triangleright$\\,\\allowbreak}}");
85
86 // ZERO WIDTH SPACE (ZWSP) is actually not a space character
87 // but marks a line break opportunity. Several commands provide a
88 // line break opportunity. They differ in side-effects:
89 // \allowbreak prevents hyphenation after hyphen or dash + ZWSP
90 // \linebreak[<n>] takes an optional argument denoting "urgency".
91 // The \LyXZeroWidthSpace wrapper allows customization in the preamble.
92 static docstring const lyxZWSP_def = from_ascii(
93         "\\newcommand*\\LyXZeroWidthSpace{\\hspace{0pt}}");
94
95 // for quotes without babel. This does not give perfect results, but
96 // anybody serious about non-english quotes should use babel (JMarc).
97
98 static docstring const quotedblbase_def = from_ascii(
99         "\\ProvideTextCommandDefault{\\quotedblbase}{%\n"
100         "  \\raisebox{-1.4ex}[1ex][.5ex]{\\textquotedblright}%\n"
101         "  \\penalty10000\\hskip0em\\relax%\n"
102         "}");
103
104 static docstring const quotesinglbase_def = from_ascii(
105         "\\ProvideTextCommandDefault{\\quotesinglbase}{%\n"
106         "  \\raisebox{-1.4ex}[1ex][.5ex]{\\textquoteright}%\n"
107         "  \\penalty10000\\hskip0em\\relax%\n"
108         "}");
109
110 static docstring const guillemotleft_def = from_ascii(
111         "\\ProvideTextCommandDefault{\\guillemotleft}{%\n"
112         "  {\\usefont{U}{lasy}{m}{n}\\char'50\\kern-.15em\\char'50}%\n"
113         "\\penalty10000\\hskip0pt\\relax%\n"
114         "}");
115
116 static docstring const guillemotright_def = from_ascii(
117         "\\ProvideTextCommandDefault{\\guillemotright}{%\n"
118         "  \\penalty10000\\hskip0pt%\n"
119         "  {\\usefont{U}{lasy}{m}{n}\\char'51\\kern-.15em\\char'51}%\n"
120         "}");
121
122 static docstring const guilsinglleft_def = from_ascii(
123         "\\ProvideTextCommandDefault{\\guilsinglleft}{%\n"
124         "  {\\usefont{U}{lasy}{m}{n}\\char'50}%\n"
125         "  \\penalty10000\\hskip0pt\\relax%\n"
126         "}");
127
128 static docstring const guilsinglright_def = from_ascii(
129         "\\ProvideTextCommandDefault{\\guilsinglright}{%\n"
130         "  \\penalty10000\\hskip0pt%\n"
131         "  {\\usefont{U}{lasy}{m}{n}\\char'51}%\n"
132         "}");
133
134 static docstring const textquotedbl_def = from_ascii(
135         "\\DeclareTextSymbolDefault{\\textquotedbl}{T1}");
136
137 static docstring const textquotedblp_xetex_def = from_ascii(
138         "\\providecommand\\textquotedblplain{%\n"
139         "  \\bgroup\\addfontfeatures{Mapping=}\\char34\\egroup}");
140
141 static docstring const textquotedblp_luatex_def = from_ascii(
142         "\\providecommand\\textquotedblplain{%\n"
143         "  \\bgroup\\addfontfeatures{RawFeature=-tlig}\\char34\\egroup}");
144
145 static docstring const textquotesinglep_xetex_def = from_ascii(
146         "\\providecommand\\textquotesingleplain{%\n"
147         "  \\bgroup\\addfontfeatures{Mapping=}\\char39\\egroup}");
148
149 static docstring const textquotesinglep_luatex_def = from_ascii(
150         "\\providecommand\\textquotesingleplain{%\n"
151         "  \\bgroup\\addfontfeatures{RawFeature=-tlig}\\char39\\egroup}");
152
153 static docstring const paragraphleftindent_def = from_ascii(
154         "\\newenvironment{LyXParagraphLeftIndent}[1]%\n"
155         "{\n"
156         "  \\begin{list}{}{%\n"
157         "    \\setlength{\\topsep}{0pt}%\n"
158         "    \\addtolength{\\leftmargin}{#1}\n"
159 // ho hum, yet more things commented out with no hint as to why they
160 // weren't just removed
161 //      "%%    \\addtolength{\\leftmargin}{#1\\textwidth}\n"
162 //      "%%    \\setlength{\\textwidth}{#2\\textwidth}\n"
163 //      "%%    \\setlength\\listparindent\\parindent%\n"
164 //      "%%    \\setlength\\itemindent\\parindent%\n"
165         "    \\setlength{\\parsep}{0pt plus 1pt}%\n"
166         "  }\n"
167         "  \\item[]\n"
168         "}\n"
169         "{\\end{list}}\n");
170
171 static docstring const floatingfootnote_def = from_ascii(
172         "%% Special footnote code from the package 'stblftnt.sty'\n"
173         "%% Author: Robin Fairbairns -- Last revised Dec 13 1996\n"
174         "\\let\\SF@@footnote\\footnote\n"
175         "\\def\\footnote{\\ifx\\protect\\@typeset@protect\n"
176         "    \\expandafter\\SF@@footnote\n"
177         "  \\else\n"
178         "    \\expandafter\\SF@gobble@opt\n"
179         "  \\fi\n"
180         "}\n"
181         "\\expandafter\\def\\csname SF@gobble@opt \\endcsname{\\@ifnextchar[%]\n"
182         "  \\SF@gobble@twobracket\n"
183         "  \\@gobble\n"
184         "}\n"
185         "\\edef\\SF@gobble@opt{\\noexpand\\protect\n"
186         "  \\expandafter\\noexpand\\csname SF@gobble@opt \\endcsname}\n"
187         "\\def\\SF@gobble@twobracket[#1]#2{}\n");
188
189 static docstring const binom_def = from_ascii(
190         "%% Binom macro for standard LaTeX users\n"
191         "\\newcommand{\\binom}[2]{{#1 \\choose #2}}\n");
192
193 static docstring const mathcircumflex_def = from_ascii(
194         "%% For printing a cirumflex inside a formula\n"
195         "\\newcommand{\\mathcircumflex}[0]{\\mbox{\\^{}}}\n");
196
197 static docstring const tabularnewline_def = from_ascii(
198         "%% Because html converters don't know tabularnewline\n"
199         "\\providecommand{\\tabularnewline}{\\\\}\n");
200
201 static docstring const lyxgreyedout_def = from_ascii(
202         "%% The greyedout annotation environment\n"
203         "\\newenvironment{lyxgreyedout}\n"
204         "  {\\textcolor{note_fontcolor}\\bgroup\\ignorespaces}\n"
205         "  {\\ignorespacesafterend\\egroup}\n");
206
207 static docstring const lyxgreyedout_rtl_def = from_ascii(
208         "%% The greyedout annotation environment (with RTL support)\n"
209         "\\NewEnviron{lyxgreyedout}{%\n"
210         "\\if@rl%\n"
211         "\\everypar{\\textcolor{note_fontcolor}\\beginL\\ignorespaces}%\n"
212         "\\BODY\\everypar{\\ignorespacesafterend\\endL}\n"
213         "\\else%\n"
214         "\\textcolor{note_fontcolor}\\bgroup\\ignorespaces%\n"
215         "\\BODY\\ignorespacesafterend\\egroup\n"
216         "\\fi}\n");
217
218 static docstring const lyxgreyedout_luartl_def = from_ascii(
219         "%% The greyedout annotation environment (with RTL support)\n"
220         "\\NewEnviron{lyxgreyedout}{%\n"
221         "\\if@RTL%\n"
222         "\\everypar{\\color{note_fontcolor}\\pardir TRT \\textdir TRT\\ignorespaces}%\n"
223         "\\BODY\\everypar{\\ignorespacesafterend}\n"
224         "\\else%\n"
225         "\\textcolor{note_fontcolor}\\bgroup\\ignorespaces%\n"
226         "\\BODY\\ignorespacesafterend\\egroup\n"
227         "\\fi}\n");
228
229 static docstring const lyxgreyedout_luartl_babel_def = from_ascii(
230         "%% The greyedout annotation environment (with RTL support)\n"
231         "\\NewEnviron{lyxgreyedout}{%\n"
232         "\\if@rl%\n"
233         "\\everypar{\\color{note_fontcolor}\\pardir TRT \\textdir TRT\\ignorespaces}%\n"
234         "\\BODY\\everypar{\\ignorespacesafterend}\n"
235         "\\else%\n"
236         "\\textcolor{note_fontcolor}\\bgroup\\ignorespaces%\n"
237         "\\BODY\\ignorespacesafterend\\egroup\n"
238         "\\fi}\n");
239
240 // We want to omit the file extension for includegraphics, but this does not
241 // work when the filename contains other dots.
242 // Idea from http://www.tex.ac.uk/cgi-bin/texfaq2html?label=unkgrfextn
243 static docstring const lyxdot_def = from_ascii(
244         "%% A simple dot to overcome graphicx limitations\n"
245         "\\newcommand{\\lyxdot}{.}\n");
246
247 static docstring const changetracking_dvipost_def = from_ascii(
248         "%% Change tracking with dvipost\n"
249         "\\dvipostlayout\n"
250         "\\dvipost{osstart color push Red}\n"
251         "\\dvipost{osend color pop}\n"
252         "\\dvipost{cbstart color push Blue}\n"
253         "\\dvipost{cbend color pop}\n"
254         "\\DeclareRobustCommand{\\lyxadded}[3]{\\changestart#3\\changeend}\n"
255         "\\DeclareRobustCommand{\\lyxdeleted}[3]{%\n"
256         "\\changestart\\overstrikeon#3\\overstrikeoff\\changeend}\n");
257
258 static docstring const changetracking_xcolor_ulem_def = from_ascii(
259         "%% Change tracking with ulem\n"
260         "\\DeclareRobustCommand{\\lyxadded}[3]{{\\color{lyxadded}{}#3}}\n"
261         "\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\color{lyxdeleted}\\lyxsout{#3}}}\n"
262         "\\DeclareRobustCommand{\\lyxsout}[1]{\\ifx\\\\#1\\else\\sout{#1}\\fi}\n");
263
264 static docstring const changetracking_xcolor_ulem_hyperref_def = from_ascii(
265         "%% Change tracking with ulem\n"
266         "\\DeclareRobustCommand{\\lyxadded}[3]{{\\texorpdfstring{\\color{lyxadded}{}}{}#3}}\n"
267         "\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\texorpdfstring{\\color{lyxdeleted}\\lyxsout{#3}}{}}}\n"
268         "\\DeclareRobustCommand{\\lyxsout}[1]{\\ifx\\\\#1\\else\\sout{#1}\\fi}\n");
269
270 static docstring const changetracking_tikz_math_sout_def = from_ascii(
271         "%% Strike out display math with tikz\n"
272         "\\usepackage{tikz}\n"
273         "\\usetikzlibrary{calc}\n"
274         "\\newcommand{\\lyxmathsout}[1]{%\n"
275         "  \\tikz[baseline=(math.base)]{\n"
276         "    \\node[inner sep=0pt,outer sep=0pt](math){#1};\n"
277         "    \\draw($(math.south west)+(2em,.5em)$)--($(math.north east)-(2em,.5em)$);\n"
278         "  }\n"
279         "}\n");
280
281 static docstring const changetracking_none_def = from_ascii(
282         "\\newcommand{\\lyxadded}[3]{#3}\n"
283         "\\newcommand{\\lyxdeleted}[3]{}\n");
284
285 static docstring const textgreek_LGR_def = from_ascii(
286         "\\DeclareFontEncoding{LGR}{}{}\n");
287 static docstring const textgreek_def = from_ascii(
288         "\\DeclareRobustCommand{\\greektext}{%\n"
289         "  \\fontencoding{LGR}\\selectfont\\def\\encodingdefault{LGR}}\n"
290         "\\DeclareRobustCommand{\\textgreek}[1]{\\leavevmode{\\greektext #1}}\n"
291         "\\ProvideTextCommand{\\~}{LGR}[1]{\\char126#1}\n");
292
293 static docstring const textcyr_T2A_def = from_ascii(
294         "\\InputIfFileExists{t2aenc.def}{}{%\n"
295         "  \\errmessage{File `t2aenc.def' not found: Cyrillic script not supported}}\n");
296 static docstring const textcyr_def = from_ascii(
297         "\\DeclareRobustCommand{\\cyrtext}{%\n"
298         "  \\fontencoding{T2A}\\selectfont\\def\\encodingdefault{T2A}}\n"
299         "\\DeclareRobustCommand{\\textcyr}[1]{\\leavevmode{\\cyrtext #1}}\n");
300
301 static docstring const lyxmathsym_def = from_ascii(
302         "\\newcommand{\\lyxmathsym}[1]{\\ifmmode\\begingroup\\def\\b@ld{bold}\n"
303         "  \\text{\\ifx\\math@version\\b@ld\\bfseries\\fi#1}\\endgroup\\else#1\\fi}\n");
304
305 static docstring const papersizedvi_def = from_ascii(
306         "\\special{papersize=\\the\\paperwidth,\\the\\paperheight}\n");
307
308 static docstring const papersizepdf_def = from_ascii(
309         "\\pdfpageheight\\paperheight\n"
310         "\\pdfpagewidth\\paperwidth\n");
311
312 static docstring const papersizepdflua_def = from_ascii(
313         "% Backwards compatibility for LuaTeX < 0.90\n"
314         "\\@ifundefined{pageheight}{\\let\\pageheight\\pdfpageheight}{}\n"
315         "\\@ifundefined{pagewidth}{\\let\\pagewidth\\pdfpagewidth}{}\n"
316         "\\pageheight\\paperheight\n"
317         "\\pagewidth\\paperwidth\n");
318
319 static docstring const cedilla_def = from_ascii(
320         "\\newcommand{\\docedilla}[2]{\\underaccent{#1\\mathchar'30}{#2}}\n"
321         "\\newcommand{\\cedilla}[1]{\\mathpalette\\docedilla{#1}}\n");
322
323 static docstring const subring_def = from_ascii(
324         "\\newcommand{\\dosubring}[2]{\\underaccent{#1\\mathchar'27}{#2}}\n"
325         "\\newcommand{\\subring}[1]{\\mathpalette\\dosubring{#1}}\n");
326
327 static docstring const subdot_def = from_ascii(
328         "\\newcommand{\\dosubdot}[2]{\\underaccent{#1.}{#2}}\n"
329         "\\newcommand{\\subdot}[1]{\\mathpalette\\dosubdot{#1}}\n");
330
331 static docstring const subhat_def = from_ascii(
332         "\\newcommand{\\dosubhat}[2]{\\underaccent{#1\\mathchar'136}{#2}}\n"
333         "\\newcommand{\\subhat}[1]{\\mathpalette\\dosubhat{#1}}\n");
334
335 static docstring const subtilde_def = from_ascii(
336         "\\newcommand{\\dosubtilde}[2]{\\underaccent{#1\\mathchar'176}{#2}}\n"
337         "\\newcommand{\\subtilde}[1]{\\mathpalette\\dosubtilde{#1}}\n");
338
339 static docstring const dacute_def = from_ascii(
340         "\\DeclareMathAccent{\\dacute}{\\mathalpha}{operators}{'175}\n");
341
342 static docstring const tipasymb_def = from_ascii(
343         "\\DeclareFontEncoding{T3}{}{}\n"
344         "\\DeclareSymbolFont{tipasymb}{T3}{cmr}{m}{n}\n");
345
346 static docstring const dgrave_def = from_ascii(
347         "\\DeclareMathAccent{\\dgrave}{\\mathord}{tipasymb}{'15}\n");
348
349 static docstring const rcap_def = from_ascii(
350         "\\DeclareMathAccent{\\rcap}{\\mathord}{tipasymb}{'20}\n");
351
352 static docstring const ogonek_def = from_ascii(
353         "\\newcommand{\\doogonek}[2]{\\setbox0=\\hbox{$#1#2$}\\underaccent{#1\\mkern-6mu\n"
354         "  \\ifx#2O\\hskip0.5\\wd0\\else\\ifx#2U\\hskip0.5\\wd0\\else\\hskip\\wd0\\fi\\fi\n"
355         "  \\ifx#2o\\mkern-2mu\\else\\ifx#2e\\mkern-1mu\\fi\\fi\n"
356         "  \\mathchar\"0\\hexnumber@\\symtipasymb0C}{#2}}\n"
357         "\\newcommand{\\ogonek}[1]{\\mathpalette\\doogonek{#1}}\n");
358
359 static docstring const lyxaccent_def = from_ascii(
360         "%% custom text accent \\LyxTextAccent[<rise value (length)>]{<accent>}{<base>}\n"
361         "\\newcommand*{\\LyxTextAccent}[3][0ex]{%\n"
362         "  \\hmode@bgroup\\ooalign{\\null#3\\crcr\\hidewidth\n"
363         "  \\raise#1\\hbox{#2}\\hidewidth}\\egroup}\n"
364         "%% select a font size smaller than the current font size:\n"
365         "\\newcommand{\\LyxAccentSize}[1][\\sf@size]{%\n"
366         "  \\check@mathfonts\\fontsize#1\\z@\\math@fontsfalse\\selectfont\n"
367         "}\n");
368
369 static docstring const textcommabelow_def = from_ascii(
370         "\\ProvideTextCommandDefault{\\textcommabelow}[1]{%%\n"
371         "  \\LyxTextAccent[-.31ex]{\\LyxAccentSize,}{#1}}\n");
372
373 static docstring const textcommaabove_def = from_ascii(
374         "\\ProvideTextCommandDefault{\\textcommaabove}[1]{%%\n"
375         "  \\LyxTextAccent[.5ex]{\\LyxAccentSize`}{#1}}\n");
376
377 static docstring const textcommaaboveright_def = from_ascii(
378         "\\ProvideTextCommandDefault{\\textcommaaboveright}[1]{%%\n"
379         "  \\LyxTextAccent[.5ex]{\\LyxAccentSize\\ '}{#1}}\n");
380
381 // Baltic languages use a comma-accent instead of a cedilla
382 static docstring const textbaltic_def = from_ascii(
383         "%% use comma accent instead of cedilla for these characters:\n"
384         "\\DeclareTextCompositeCommand{\\c}{T1}{g}{\\textcommaabove{g}}\n"
385         "\\DeclareTextCompositeCommand{\\c}{T1}{G}{\\textcommabelow{G}}\n"
386         "\\DeclareTextCompositeCommand{\\c}{T1}{k}{\\textcommabelow{k}}\n"
387         "\\DeclareTextCompositeCommand{\\c}{T1}{K}{\\textcommabelow{K}}\n"
388         "\\DeclareTextCompositeCommand{\\c}{T1}{l}{\\textcommabelow{l}}\n"
389         "\\DeclareTextCompositeCommand{\\c}{T1}{L}{\\textcommabelow{L}}\n"
390         "\\DeclareTextCompositeCommand{\\c}{T1}{n}{\\textcommabelow{n}}\n"
391         "\\DeclareTextCompositeCommand{\\c}{T1}{N}{\\textcommabelow{N}}\n"
392         "\\DeclareTextCompositeCommand{\\c}{T1}{r}{\\textcommabelow{r}}\n"
393         "\\DeclareTextCompositeCommand{\\c}{T1}{R}{\\textcommabelow{R}}\n");
394
395 // split-level fractions
396 static docstring const xfrac_def = from_ascii(
397            "\\usepackage{xfrac}\n");
398 static docstring const smallLetterFrac_def = from_ascii(
399         "\\DeclareCollectionInstance{smallLetterFrac}{xfrac}{default}{text}\n"
400                 "  {phantom=c, scale-factor=1.0, slash-left-kern=-.05em}\n"
401                 "\\DeclareCollectionInstance{smallLetterFrac}{xfrac}{lmr}{text}\n"
402                 "  {slash-symbol-font=ptm, phantom=c, scale-factor=1, slash-left-kern=-.05em}\n"
403                 "\\DeclareCollectionInstance{smallLetterFrac}{xfrac}{lmss}{text}\n"
404                 "  {slash-symbol-font=ptm, phantom=c, scale-factor=1, slash-left-kern=-.05em}\n"
405                 "\\DeclareCollectionInstance{smallLetterFrac}{xfrac}{cmr}{text}\n"
406                 "  {slash-symbol-font=ptm, phantom=c, scale-factor=1, slash-left-kern=-.05em}\n"
407                 "\\DeclareCollectionInstance{smallLetterFrac}{xfrac}{cmss}{text}\n"
408                 "  {slash-symbol-font=ptm, phantom=c, scale-factor=1, slash-left-kern=-.05em}\n"
409                 "\\newcommand{\\smallLetterFrac}[2]{%\n"
410                 "  {\\UseCollection{xfrac}{smallLetterFrac}\\sfrac{#1}{#2}}}\n");
411
412 static docstring const lyxref_def = from_ascii(
413                 "\\RS@ifundefined{subsecref}\n"
414                 "  {\\newref{subsec}{name = \\RSsectxt}}\n"
415                 "  {}\n"
416                 "\\RS@ifundefined{thmref}\n"
417                 "  {\\def\\RSthmtxt{theorem~}\\newref{thm}{name = \\RSthmtxt}}\n"
418                 "  {}\n"
419                 "\\RS@ifundefined{lemref}\n"
420                 "  {\\def\\RSlemtxt{lemma~}\\newref{lem}{name = \\RSlemtxt}}\n"
421                 "  {}\n");
422
423 // Make sure the columns are also outputed as rtl
424 static docstring const rtloutputdblcol_def = from_ascii(
425         "\\def\\@outputdblcol{%\n"
426         "  \\if@firstcolumn\n"
427         "    \\global \\@firstcolumnfalse\n"
428         "    \\global \\setbox\\@leftcolumn \\box\\@outputbox\n"
429         "  \\else\n"
430         "    \\global \\@firstcolumntrue\n"
431         "    \\setbox\\@outputbox \\vbox {%\n"
432         "      \\hb@xt@\\textwidth {%\n"
433         "      \\kern\\textwidth \\kern-\\columnwidth %**\n"
434         "      \\hb@xt@\\columnwidth {%\n"
435         "         \\box\\@leftcolumn \\hss}%\n"
436         "      \\kern-\\textwidth %**\n"
437         "      \\hfil\n"
438         "      {\\normalcolor\\vrule \\@width\\columnseprule}%\n"
439         "      \\hfil\n"
440         "      \\kern-\\textwidth  %**\n"
441         "      \\hb@xt@\\columnwidth {%\n"
442         "         \\box\\@outputbox \\hss}%\n"
443         "      \\kern-\\columnwidth \\kern\\textwidth %**\n"
444         "    }%\n"
445         "  }%\n"
446         "  \\@combinedblfloats\n"
447         "  \\@outputpage\n"
448         "  \\begingroup\n"
449         "  \\@dblfloatplacement\n"
450         "  \\@startdblcolumn\n"
451         "  \\@whilesw\\if@fcolmade \\fi\n"
452         "  {\\@outputpage\n"
453         "    \\@startdblcolumn}%\n"
454         "  \\endgroup\n"
455         "  \\fi\n"
456         "}\n"
457         "\\@mparswitchtrue\n");
458
459 static docstring const lyxmintcaption_def = from_ascii(
460         "\\long\\def\\lyxmintcaption[#1]#2{%\n"
461         "  \\ifx#1t\\vskip\\baselineskip\\fi%\n"
462         "  \\refstepcounter{listing}\\noindent%\n"
463         "  \\addcontentsline{lol}{listing}%\n"
464         "  {\\protect\\numberline{\\thelisting}{\\ignorespaces #2}}%\n"
465         "  \\setbox\\@tempboxa\\hbox{\\listingscaption~\\thelisting: #2}%\n"
466         "  \\ifdim \\wd\\@tempboxa >\\linewidth%\n"
467         "  \\parbox[t]{\\linewidth}{\\unhbox\\@tempboxa}\\else%\n"
468         "  \\hbox to\\linewidth{\\hfil\\box\\@tempboxa\\hfil}\\fi%\n"
469         "  \\ifx#1b\\vskip\\baselineskip\\fi\n"
470         "}\n");
471
472
473 /////////////////////////////////////////////////////////////////////
474 //
475 // LyXHTML strings
476 //
477 /////////////////////////////////////////////////////////////////////
478
479 static docstring const lyxnoun_style = from_ascii(
480         "dfn.lyxnoun {\n"
481         "  font-variant: small-caps;\n"
482         "}\n");
483
484
485 // this is how it normally renders, but it might not always do so.
486 static docstring const lyxstrikeout_style = from_ascii(
487         "del.strikeout {\n"
488         "  text-decoration: line-through;\n"
489         "}\n");
490
491
492 /////////////////////////////////////////////////////////////////////
493 //
494 // LaTeXFeatures
495 //
496 /////////////////////////////////////////////////////////////////////
497
498
499 LaTeXFeatures::LaTeXFeatures(Buffer const & b, BufferParams const & p,
500                              OutputParams const & r)
501         : buffer_(&b), params_(p), runparams_(r), in_float_(false),
502           in_deleted_inset_(false)
503 {}
504
505
506 LaTeXFeatures::LangPackage LaTeXFeatures::langPackage() const
507 {
508         string const local_lp = bufferParams().lang_package;
509
510         // Locally, custom is just stored as a string
511         // in bufferParams().lang_package.
512         if (local_lp != "auto"
513             && local_lp != "babel"
514             && local_lp != "default"
515             && local_lp != "none")
516                  return LANG_PACK_CUSTOM;
517
518         if (local_lp == "none")
519                 return LANG_PACK_NONE;
520
521         /* If "auto" is selected, we load polyglossia with non-TeX fonts,
522          * else we select babel.
523          * If babel is selected (either directly or via the "auto"
524          * mechanism), we really do only require it if we have
525          * a language that needs it.
526          */
527         bool const polyglossia_required =
528                 params_.useNonTeXFonts
529                 && isAvailable("polyglossia")
530                 && !isProvided("babel")
531                 && this->hasOnlyPolyglossiaLanguages();
532         bool const babel_required =
533                 !bufferParams().language->babel().empty()
534                 || !this->getBabelLanguages().empty();
535
536         if (local_lp == "auto") {
537                 // polyglossia requirement has priority over babel
538                 if (polyglossia_required)
539                         return LANG_PACK_POLYGLOSSIA;
540                 else if (babel_required)
541                         return LANG_PACK_BABEL;
542         }
543
544         if (local_lp == "babel") {
545                 if (babel_required)
546                         return LANG_PACK_BABEL;
547         }
548
549         if (local_lp == "default") {
550                 switch (lyxrc.language_package_selection) {
551                 case LyXRC::LP_AUTO:
552                         // polyglossia requirement has priority over babel
553                         if (polyglossia_required)
554                                 return LANG_PACK_POLYGLOSSIA;
555                         else if (babel_required)
556                                 return LANG_PACK_BABEL;
557                         break;
558                 case LyXRC::LP_BABEL:
559                         if (babel_required)
560                                 return LANG_PACK_BABEL;
561                         break;
562                 case LyXRC::LP_CUSTOM:
563                         return LANG_PACK_CUSTOM;
564                 case LyXRC::LP_NONE:
565                         return LANG_PACK_NONE;
566                 }
567         }
568
569         return LANG_PACK_NONE;
570 }
571
572
573 void LaTeXFeatures::require(string const & name)
574 {
575         features_.insert(name);
576 }
577
578
579 void LaTeXFeatures::require(set<string> const & names)
580 {
581         features_.insert(names.begin(), names.end());
582 }
583
584
585 void LaTeXFeatures::useLayout(docstring const & layoutname)
586 {
587         useLayout(layoutname, 0);
588 }
589
590
591 void LaTeXFeatures::useLayout(docstring const & layoutname, int level)
592 {
593         // Some code to avoid loops in dependency definition
594         const int maxlevel = 30;
595         if (level > maxlevel) {
596                 lyxerr << "LaTeXFeatures::useLayout: maximum level of "
597                        << "recursion attained by layout "
598                        << to_utf8(layoutname) << endl;
599                 return;
600         }
601
602         DocumentClass const & tclass = params_.documentClass();
603         if (tclass.hasLayout(layoutname)) {
604                 // Is this layout already in usedLayouts?
605                 if (find(usedLayouts_.begin(), usedLayouts_.end(), layoutname)
606                     != usedLayouts_.end())
607                         return;
608
609                 Layout const & layout = tclass[layoutname];
610                 require(layout.requires());
611
612                 if (!layout.depends_on().empty()) {
613                         useLayout(layout.depends_on(), level + 1);
614                 }
615                 usedLayouts_.push_back(layoutname);
616         } else {
617                 lyxerr << "LaTeXFeatures::useLayout: layout `"
618                        << to_utf8(layoutname) << "' does not exist in this class"
619                        << endl;
620         }
621 }
622
623
624 void LaTeXFeatures::useInsetLayout(InsetLayout const & lay)
625 {
626         docstring const & lname = lay.name();
627         DocumentClass const & tclass = params_.documentClass();
628
629         // this is a default inset layout, nothing useful here
630         if (!tclass.hasInsetLayout(lname))
631                 return;
632         // Is this layout already in usedInsetLayouts?
633         if (find(usedInsetLayouts_.begin(), usedInsetLayouts_.end(), lname)
634                         != usedInsetLayouts_.end())
635                 return;
636
637         require(lay.requires());
638         usedInsetLayouts_.push_back(lname);
639 }
640
641
642 bool LaTeXFeatures::isRequired(string const & name) const
643 {
644         return features_.find(name) != features_.end();
645 }
646
647
648 bool LaTeXFeatures::isProvided(string const & name) const
649 {
650         if (params_.useNonTeXFonts)
651                 return params_.documentClass().provides(name);
652
653         bool const ot1 = (params_.main_font_encoding() == "default"
654                 || params_.main_font_encoding() == "OT1");
655         bool const complete = (params_.fontsSans() == "default"
656                 && params_.fontsTypewriter() == "default");
657         bool const nomath = (params_.fontsMath() == "default");
658         return params_.documentClass().provides(name)
659                 || theLaTeXFonts().getLaTeXFont(
660                         from_ascii(params_.fontsRoman())).provides(name, ot1,
661                                                                   complete,
662                                                                   nomath)
663                 || theLaTeXFonts().getLaTeXFont(
664                         from_ascii(params_.fontsSans())).provides(name, ot1,
665                                                                  complete,
666                                                                  nomath)
667                 || theLaTeXFonts().getLaTeXFont(
668                         from_ascii(params_.fontsTypewriter())).provides(name, ot1,
669                                                                        complete,
670                                                                        nomath)
671                 || theLaTeXFonts().getLaTeXFont(
672                         from_ascii(params_.fontsMath())).provides(name, ot1,
673                                                                        complete,
674                                                                        nomath);
675         // TODO: "textbaltic" provided, if the font-encoding is "L7x"
676         //       "textgreek" provided, if a language with font-encoding LGR is used in the document
677         //       "textcyr" provided, if a language with font-encoding T2A is used in the document
678 }
679
680
681 bool LaTeXFeatures::mustProvide(string const & name) const
682 {
683         return isRequired(name) && !isProvided(name);
684 }
685
686
687 bool LaTeXFeatures::isAvailable(string const & name)
688 {
689         string::size_type const i = name.find("->");
690         if (i != string::npos) {
691                 string const from = name.substr(0,i);
692                 string const to = name.substr(i+2);
693                 //LYXERR0("from=[" << from << "] to=[" << to << "]");
694                 return theConverters().isReachable(from, to);
695         }
696         return LaTeXPackages::isAvailable(name);
697 }
698
699
700 namespace {
701
702 void addSnippet(std::list<TexString> & list, TexString ts, bool allow_dupes)
703 {
704         if (allow_dupes ||
705             // test the absense of duplicates, i.e. elements with same str
706             none_of(list.begin(), list.end(), [&](TexString const & ts2){
707                             return ts.str == ts2.str;
708                     })
709             )
710                 list.push_back(move(ts));
711 }
712
713
714 TexString getSnippets(std::list<TexString> const & list)
715 {
716         otexstringstream snip;
717         for (TexString const & ts : list)
718                 snip << TexString(ts) << '\n';
719         return snip.release();
720 }
721
722 } // namespace
723
724
725 void LaTeXFeatures::addPreambleSnippet(TexString ts, bool allow_dupes)
726 {
727         addSnippet(preamble_snippets_, move(ts), allow_dupes);
728 }
729
730
731 void LaTeXFeatures::addPreambleSnippet(docstring const & str, bool allow_dupes)
732 {
733         addSnippet(preamble_snippets_, TexString(str), allow_dupes);
734 }
735
736
737 void LaTeXFeatures::addCSSSnippet(std::string const & snippet)
738 {
739         addSnippet(css_snippets_, TexString(from_ascii(snippet)), false);
740 }
741
742
743 TexString LaTeXFeatures::getPreambleSnippets() const
744 {
745         return getSnippets(preamble_snippets_);
746 }
747
748
749 docstring LaTeXFeatures::getCSSSnippets() const
750 {
751         return getSnippets(css_snippets_).str;
752 }
753
754
755
756 void LaTeXFeatures::useFloat(string const & name, bool subfloat)
757 {
758         if (!usedFloats_[name])
759                 usedFloats_[name] = subfloat;
760         if (subfloat)
761                 require("subfig");
762         // We only need float.sty if we use non builtin floats, or if we
763         // use the "H" modifier. This includes modified table and
764         // figure floats. (Lgb)
765         Floating const & fl = params_.documentClass().floats().getType(name);
766         if (!fl.floattype().empty() && fl.usesFloatPkg()) {
767                 require("float");
768         }
769 }
770
771
772 void LaTeXFeatures::useLanguage(Language const * lang)
773 {
774         if (!lang->babel().empty() || !lang->polyglossia().empty())
775                 UsedLanguages_.insert(lang);
776         if (!lang->requires().empty())
777                 require(lang->requires());
778         // CJK languages do not have a babel name.
779         // They use the CJK package
780         if (lang->encoding()->package() == Encoding::CJK)
781                 require("CJK");
782         // japanese package is special
783         if (lang->encoding()->package() == Encoding::japanese)
784                 require("japanese");
785 }
786
787
788 void LaTeXFeatures::includeFile(docstring const & key, string const & name)
789 {
790         IncludedFiles_[key] = name;
791 }
792
793
794 bool LaTeXFeatures::hasLanguages() const
795 {
796         return !UsedLanguages_.empty();
797 }
798
799
800 bool LaTeXFeatures::hasOnlyPolyglossiaLanguages() const
801 {
802         // first the main language
803         if (params_.language->polyglossia().empty())
804                 return false;
805         // now the secondary languages
806         LanguageList::const_iterator const begin = UsedLanguages_.begin();
807         for (LanguageList::const_iterator cit = begin;
808              cit != UsedLanguages_.end();
809              ++cit) {
810                 if ((*cit)->polyglossia().empty())
811                         return false;
812         }
813         return true;
814 }
815
816
817 bool LaTeXFeatures::hasPolyglossiaExclusiveLanguages() const
818 {
819         // first the main language
820         if (params_.language->isPolyglossiaExclusive())
821                 return true;
822         // now the secondary languages
823         LanguageList::const_iterator const begin = UsedLanguages_.begin();
824         for (LanguageList::const_iterator cit = begin;
825              cit != UsedLanguages_.end();
826              ++cit) {
827                 if ((*cit)->isPolyglossiaExclusive())
828                         return true;
829         }
830         return false;
831 }
832
833
834 vector<string> LaTeXFeatures::getPolyglossiaExclusiveLanguages() const
835 {
836         vector<string> result;
837         // first the main language
838         if (params_.language->isPolyglossiaExclusive())
839                 result.push_back(params_.language->display());
840         // now the secondary languages
841         LanguageList::const_iterator const begin = UsedLanguages_.begin();
842         for (LanguageList::const_iterator cit = begin;
843              cit != UsedLanguages_.end();
844              ++cit) {
845                 if ((*cit)->isPolyglossiaExclusive())
846                         result.push_back((*cit)->display());
847         }
848         return result;
849 }
850
851
852 vector<string> LaTeXFeatures::getBabelExclusiveLanguages() const
853 {
854         vector<string> result;
855         // first the main language
856         if (params_.language->isBabelExclusive())
857                 result.push_back(params_.language->display());
858         // now the secondary languages
859         LanguageList::const_iterator const begin = UsedLanguages_.begin();
860         for (LanguageList::const_iterator cit = begin;
861              cit != UsedLanguages_.end();
862              ++cit) {
863                 if ((*cit)->isBabelExclusive())
864                         result.push_back((*cit)->display());
865         }
866         return result;
867 }
868
869
870 string LaTeXFeatures::getBabelLanguages() const
871 {
872         ostringstream languages;
873
874         bool first = true;
875         LanguageList::const_iterator const begin = UsedLanguages_.begin();
876         for (LanguageList::const_iterator cit = begin;
877              cit != UsedLanguages_.end();
878              ++cit) {
879                 if ((*cit)->babel().empty())
880                         continue;
881                 if (!first)
882                         languages << ',';
883                 else
884                         first = false;
885                 languages << (*cit)->babel();
886         }
887         return languages.str();
888 }
889
890
891 set<string> LaTeXFeatures::getPolyglossiaLanguages() const
892 {
893         set<string> languages;
894
895         LanguageList::const_iterator const begin = UsedLanguages_.begin();
896         for (LanguageList::const_iterator cit = begin;
897              cit != UsedLanguages_.end();
898              ++cit) {
899                 // We do not need the variants here
900                 languages.insert((*cit)->polyglossia());
901         }
902         return languages;
903 }
904
905
906 set<string> LaTeXFeatures::getEncodingSet(string const & doc_encoding) const
907 {
908         // This does only find encodings of languages supported by babel, but
909         // that does not matter since we don't have a language with an
910         // encoding supported by inputenc but without babel support.
911         set<string> encodings;
912         LanguageList::const_iterator it  = UsedLanguages_.begin();
913         LanguageList::const_iterator end = UsedLanguages_.end();
914         for (; it != end; ++it)
915                 if ((*it)->encoding()->latexName() != doc_encoding &&
916                     ((*it)->encoding()->package() == Encoding::inputenc
917                      || (*it)->encoding()->package() == Encoding::japanese))
918                         encodings.insert((*it)->encoding()->latexName());
919         return encodings;
920 }
921
922
923 void LaTeXFeatures::getFontEncodings(vector<string> & encodings) const
924 {
925         // these must be loaded if glyphs of this script are used
926         // unless a language providing them is used in the document
927         if (mustProvide("textgreek")
928             && find(encodings.begin(), encodings.end(), "LGR") == encodings.end())
929                 encodings.insert(encodings.begin(), "LGR");
930         if (mustProvide("textcyr")
931             && find(encodings.begin(), encodings.end(), "T2A") == encodings.end())
932                 encodings.insert(encodings.begin(), "T2A");
933
934         LanguageList::const_iterator it  = UsedLanguages_.begin();
935         LanguageList::const_iterator end = UsedLanguages_.end();
936         for (; it != end; ++it)
937                 if (!(*it)->fontenc().empty()
938                     && ascii_lowercase((*it)->fontenc()) != "none") {
939                         vector<string> extraencs = getVectorFromString((*it)->fontenc());
940                         vector<string>::const_iterator fit = extraencs.begin();
941                         for (; fit != extraencs.end(); ++fit) {
942                                 if (find(encodings.begin(), encodings.end(), *fit) == encodings.end())
943                                         encodings.insert(encodings.begin(), *fit);
944                         }
945                 }
946 }
947
948
949 bool LaTeXFeatures::hasRTLLanguage() const
950 {
951         if (params_.language->rightToLeft())
952                 return true;
953         for (auto const & lang : UsedLanguages_)
954                 if (lang->rightToLeft())
955                         return true;
956         return false;
957 }
958
959 namespace {
960
961 char const * simplefeatures[] = {
962 // note that the package order here will be the same in the LaTeX-output
963         "array",
964         "verbatim",
965         "longtable",
966         "latexsym",
967         "pifont",
968         // subfig is handled in BufferParams.cpp
969         "varioref",
970         "prettyref",
971         "refstyle",
972         /*For a successful cooperation of the `wrapfig' package with the
973           `float' package you should load the `wrapfig' package *after*
974           the `float' package. See the caption package documentation
975           for explanation.*/
976         "float",
977         "wrapfig",
978         "booktabs",
979         "dvipost",
980         "fancybox",
981         "calc",
982         "units",
983         "framed",
984         "soul",
985         "textcomp",
986         "dingbat",
987         "pmboxdraw",
988         "bbding",
989         "ifsym",
990         "txfonts",
991         "pxfonts",
992         "mathdesign",
993         "mathrsfs",
994         "mathabx",
995         "mathtools",
996         // "cancel",
997         "ascii",
998         "url",
999         "csquotes",
1000         "enumitem",
1001         "endnotes",
1002         "hhline",
1003         "ifthen",
1004         // listings is handled in BufferParams.cpp
1005         "bm",
1006         "pdfpages",
1007         "amscd",
1008         "slashed",
1009         "multicol",
1010         "multirow",
1011         "tfrupee",
1012         "shapepar",
1013         "rsphrase",
1014         "hpstatement",
1015         "algorithm2e",
1016         "sectionbox",
1017         "tcolorbox",
1018         "pdfcomment",
1019         "fixme",
1020         "todonotes",
1021         "forest",
1022         "varwidth",
1023         "environ",
1024         "dsfont"
1025 };
1026
1027 char const * bibliofeatures[] = {
1028         // Known bibliography packages (will be loaded before natbib)
1029         "achicago",
1030         "apacite",
1031         "apalike",
1032         "astron",
1033         "authordate1-4",
1034         "babelbib",
1035         "bibgerm",
1036         "chapterbib",
1037         "chicago",
1038         "chscite",
1039         "harvard",
1040         "mslapa",
1041         "named"
1042 };
1043
1044 int const nb_bibliofeatures = sizeof(bibliofeatures) / sizeof(char const *);
1045
1046 int const nb_simplefeatures = sizeof(simplefeatures) / sizeof(char const *);
1047
1048 } // namespace
1049
1050
1051 string const LaTeXFeatures::getColorOptions() const
1052 {
1053         ostringstream colors;
1054
1055         // Handling the color packages separately is needed to be able to load them
1056         // before babel when hyperref is loaded with the colorlinks option
1057         // for more info see Bufferparams.cpp
1058
1059         // [x]color.sty
1060         if (mustProvide("color") || mustProvide("xcolor")) {
1061                 string const package =
1062                         (mustProvide("xcolor") ? "xcolor" : "color");
1063                 if (params_.graphics_driver == "default"
1064                         || params_.graphics_driver == "none")
1065                         colors << "\\usepackage{" << package << "}\n";
1066                 else
1067                         colors << "\\usepackage["
1068                                  << params_.graphics_driver
1069                                  << "]{" << package << "}\n";
1070         }
1071
1072         // pdfcolmk must be loaded after color
1073         if (mustProvide("pdfcolmk"))
1074                 colors << "\\usepackage{pdfcolmk}\n";
1075
1076         // the following 3 color commands must be set after color
1077         // is loaded and before pdfpages, therefore add the command
1078         // here define the set color
1079         if (mustProvide("pagecolor")) {
1080                 colors << "\\definecolor{page_backgroundcolor}{rgb}{";
1081                 colors << outputLaTeXColor(params_.backgroundcolor) << "}\n";
1082                 // set the page color
1083                 colors << "\\pagecolor{page_backgroundcolor}\n";
1084         }
1085
1086         if (mustProvide("fontcolor")) {
1087                 colors << "\\definecolor{document_fontcolor}{rgb}{";
1088                 colors << outputLaTeXColor(params_.fontcolor) << "}\n";
1089                 // set the color
1090                 colors << "\\color{document_fontcolor}\n";
1091         }
1092
1093         if (mustProvide("lyxgreyedout")) {
1094                 colors << "\\definecolor{note_fontcolor}{rgb}{";
1095                 colors << outputLaTeXColor(params_.notefontcolor) << "}\n";
1096                 // the color will be set together with the definition of
1097                 // the lyxgreyedout environment (see lyxgreyedout_def)
1098         }
1099
1100         // color for shaded boxes
1101         if (isRequired("framed") && mustProvide("color")) {
1102                 colors << "\\definecolor{shadecolor}{rgb}{";
1103                 colors << outputLaTeXColor(params_.boxbgcolor) << "}\n";
1104                 // this color is automatically used by the LaTeX-package "framed"
1105         }
1106
1107         return colors.str();
1108 }
1109
1110
1111 string const LaTeXFeatures::getPackageOptions() const
1112 {
1113         ostringstream packageopts;
1114         // Output all the package option stuff we have been asked to do.
1115         map<string, string>::const_iterator it =
1116                 params_.documentClass().packageOptions().begin();
1117         map<string, string>::const_iterator en =
1118                 params_.documentClass().packageOptions().end();
1119         for (; it != en; ++it)
1120                 if (mustProvide(it->first))
1121                         packageopts << "\\PassOptionsToPackage{" << it->second << "}"
1122                                  << "{" << it->first << "}\n";
1123         return packageopts.str();
1124 }
1125
1126
1127 string const LaTeXFeatures::getPackages() const
1128 {
1129         ostringstream packages;
1130
1131         // FIXME: currently, we can only load packages and macros known
1132         // to LyX.
1133         // However, with the Require tag of layouts/custom insets,
1134         // also unknown packages can be requested. They are silently
1135         // swallowed now. We should change this eventually.
1136
1137         //  These are all the 'simple' includes.  i.e
1138         //  packages which we just \usepackage{package}
1139         for (int i = 0; i < nb_simplefeatures; ++i) {
1140                 if (mustProvide(simplefeatures[i]))
1141                         packages << "\\usepackage{" << simplefeatures[i] << "}\n";
1142         }
1143
1144         // The rest of these packages are somewhat more complicated
1145         // than those above.
1146
1147         if (mustProvide("footnote")) {
1148                 if (isRequired("hyperref"))
1149                         packages << "\\usepackage{footnotehyper}\n";
1150                 else
1151                         packages << "\\usepackage{footnote}\n";
1152         }
1153
1154         // [pdf]lscape is used to rotate longtables
1155         if (mustProvide("lscape")) {
1156                 if (runparams_.flavor == OutputParams::LATEX
1157                     || runparams_.flavor == OutputParams::DVILUATEX)
1158                         packages << "\\usepackage{lscape}\n";
1159                 else
1160                         packages << "\\usepackage{pdflscape}\n";
1161         }
1162
1163         // The tipa package and its extensions (tipx, tone) must not
1164         // be loaded with non-TeX fonts, since fontspec includes the
1165         // respective macros
1166         if (mustProvide("tipa") && !params_.useNonTeXFonts)
1167                 packages << "\\usepackage{tipa}\n";
1168         if (mustProvide("tipx") && !params_.useNonTeXFonts)
1169                 packages << "\\usepackage{tipx}\n";
1170         if (mustProvide("extraipa") && !params_.useNonTeXFonts)
1171                 packages << "\\usepackage{extraipa}\n";
1172         if (mustProvide("tone") && !params_.useNonTeXFonts)
1173                 packages << "\\usepackage{tone}\n";
1174
1175         // if fontspec or newtxmath is used, AMS packages have to be loaded
1176         // before fontspec (in BufferParams)
1177         string const amsPackages = loadAMSPackages();
1178         bool const ot1 = (params_.main_font_encoding() == "default"
1179                           || params_.main_font_encoding() == "OT1");
1180         bool const use_newtxmath =
1181                 theLaTeXFonts().getLaTeXFont(from_ascii(params_.fontsMath())).getUsedPackage(
1182                         ot1, false, false) == "newtxmath";
1183
1184         if (!params_.useNonTeXFonts && !use_newtxmath && !amsPackages.empty())
1185                 packages << amsPackages;
1186
1187         if (mustProvide("cancel") &&
1188             params_.use_package("cancel") != BufferParams::package_off)
1189                 packages << "\\usepackage{cancel}\n";
1190
1191         // marvosym and bbding both define the \Cross macro
1192         if (mustProvide("marvosym")) {
1193             if (mustProvide("bbding"))
1194                 packages << "\\let\\Cross\\relax\n";
1195             packages << "\\usepackage{marvosym}\n";
1196         }
1197
1198         // accents must be loaded after amsmath
1199         if (mustProvide("accents") &&
1200             params_.use_package("accents") != BufferParams::package_off)
1201                 packages << "\\usepackage{accents}\n";
1202
1203         // mathdots must be loaded after amsmath
1204         if (mustProvide("mathdots") &&
1205                 params_.use_package("mathdots") != BufferParams::package_off)
1206                 packages << "\\usepackage{mathdots}\n";
1207
1208         // yhmath must be loaded after amsmath
1209         if (mustProvide("yhmath") &&
1210             params_.use_package("yhmath") != BufferParams::package_off)
1211                 packages << "\\usepackage{yhmath}\n";
1212
1213         // stmaryrd must be loaded after amsmath
1214         if (mustProvide("stmaryrd") &&
1215             params_.use_package("stmaryrd") != BufferParams::package_off)
1216                 packages << "\\usepackage{stmaryrd}\n";
1217
1218         if (mustProvide("stackrel") &&
1219             params_.use_package("stackrel") != BufferParams::package_off)
1220                 packages << "\\usepackage{stackrel}\n";
1221
1222         if (mustProvide("undertilde") &&
1223                 params_.use_package("undertilde") != BufferParams::package_off)
1224                 packages << "\\usepackage{undertilde}\n";
1225
1226         // [x]color and pdfcolmk are handled in getColorOptions() above
1227
1228         // makeidx.sty
1229         if (isRequired("makeidx") || isRequired("splitidx")) {
1230                 if (!isProvided("makeidx") && !isRequired("splitidx"))
1231                         packages << "\\usepackage{makeidx}\n";
1232                 if (mustProvide("splitidx"))
1233                         packages << "\\usepackage{splitidx}\n";
1234                 packages << "\\makeindex\n";
1235         }
1236
1237         // graphicx.sty
1238         if (mustProvide("graphicx") && params_.graphics_driver != "none") {
1239                 if (params_.graphics_driver == "default")
1240                         packages << "\\usepackage{graphicx}\n";
1241                 else
1242                         packages << "\\usepackage["
1243                                  << params_.graphics_driver
1244                                  << "]{graphicx}\n";
1245         }
1246
1247         // These must be loaded after graphicx, since they try
1248         // to load graphicx without options
1249         if (mustProvide("rotating"))
1250                 packages << "\\usepackage{rotating}\n";
1251         if (mustProvide("rotfloat"))
1252                 packages << "\\usepackage{rotfloat}\n";
1253         // and this must be loaded after rotating
1254         if (mustProvide("tablefootnote"))
1255                 packages << "\\usepackage{tablefootnote}\n";
1256
1257         // lyxskak.sty --- newer chess support based on skak.sty
1258         if (mustProvide("chess"))
1259                 packages << "\\usepackage[ps,mover]{lyxskak}\n";
1260
1261         // setspace.sty
1262         if (mustProvide("setspace") && !isProvided("SetSpace"))
1263                 packages << "\\usepackage{setspace}\n";
1264
1265         // we need to assure that mhchem is loaded before esint and every other
1266         // package that redefines command of amsmath because mhchem loads amlatex
1267         // (this info is from the author of mhchem from June 2013)
1268         if (mustProvide("mhchem") &&
1269             params_.use_package("mhchem") != BufferParams::package_off)
1270                 packages << "\\PassOptionsToPackage{version=3}{mhchem}\n"
1271                             "\\usepackage{mhchem}\n";
1272
1273         // wasysym is a simple feature, but it must be after amsmath if both
1274         // are used
1275         // wasysym redefines some integrals (e.g. iint) from amsmath. That
1276         // leads to inconsistent integrals. We only load this package if
1277         // the document does not contain integrals (then isRequired("esint")
1278         // is false) or if esint is used, since esint redefines all relevant
1279         // integral symbols from wasysym and amsmath.
1280         // See http://www.lyx.org/trac/ticket/1942
1281         if (mustProvide("wasysym") &&
1282             params_.use_package("wasysym") != BufferParams::package_off &&
1283             (params_.use_package("esint") != BufferParams::package_off || !isRequired("esint")))
1284                 packages << "\\usepackage{wasysym}\n";
1285
1286         // esint must be after amsmath (and packages requiring amsmath, like mhchem)
1287         // and wasysym, since it will redeclare inconsistent integral symbols
1288         if (mustProvide("esint") &&
1289             params_.use_package("esint") != BufferParams::package_off)
1290                 packages << "\\usepackage{esint}\n";
1291
1292         // Known bibliography packages (simple \usepackage{package})
1293         for (int i = 0; i < nb_bibliofeatures; ++i) {
1294                 if (mustProvide(bibliofeatures[i]))
1295                         packages << "\\usepackage{"
1296                                  << bibliofeatures[i] << "}\n";
1297         }
1298
1299         // Compatibility between achicago and natbib
1300         if (mustProvide("achicago") && mustProvide("natbib"))
1301                 packages << "\\let\\achicagobib\\thebibliography\n";
1302
1303         // natbib.sty
1304         // Some classes load natbib themselves, but still allow (or even require)
1305         // plain numeric citations (ReVTeX is such a case, see bug 5182).
1306         // This special case is indicated by the "natbib-internal" key.
1307         if (mustProvide("natbib")
1308             && !isProvided("natbib-internal")
1309             && !isProvided("biblatex")
1310             && !isProvided("biblatex-natbib")
1311             && !isProvided("jurabib")) {
1312                 packages << "\\usepackage[";
1313                 if (params_.citeEngineType() == ENGINE_TYPE_NUMERICAL)
1314                         packages << "numbers";
1315                 else
1316                         packages << "authoryear";
1317                 if (!params_.biblio_opts.empty())
1318                         packages << ',' << params_.biblio_opts;
1319                 packages << "]{natbib}\n";
1320         }
1321
1322         // Compatibility between achicago and natbib
1323         if (mustProvide("achicago") && mustProvide("natbib")) {
1324                 packages << "\\let\\thebibliography\\achicagobib\n";
1325                 packages << "\\let\\SCcite\\astroncite\n";
1326                 packages << "\\let\\UnexpandableProtect\\protect\n";
1327         }
1328
1329         // jurabib -- we need version 0.6 at least.
1330         if (mustProvide("jurabib")
1331             && !isProvided("natbib-internal")
1332             && !isProvided("natbib")
1333             && !isProvided("biblatex")
1334             && !isProvided("biblatex-natbib")) {
1335                 packages << "\\usepackage";
1336                 if (!params_.biblio_opts.empty())
1337                         packages << '[' << params_.biblio_opts << ']';
1338                 packages << "{jurabib}[2004/01/25]\n";
1339         }
1340
1341         // opcit -- we pass custombst as we output \bibliographystyle ourselves
1342         if (mustProvide("opcit")) {
1343                 if (isRequired("hyperref"))
1344                         packages << "\\usepackage[custombst,hyperref]{opcit}\n";
1345                 else
1346                         packages << "\\usepackage[custombst]{opcit}\n";
1347         }
1348
1349         // xargs -- we need version 1.09 at least
1350         if (mustProvide("xargs"))
1351                 packages << "\\usepackage{xargs}[2008/03/08]\n";
1352
1353         if (mustProvide("xy"))
1354                 packages << "\\usepackage[all]{xy}\n";
1355
1356         if (mustProvide("feyn"))
1357                 packages << "\\usepackage{feyn}\n"; //Diagram
1358
1359         if (mustProvide("ulem"))
1360                 packages << "\\PassOptionsToPackage{normalem}{ulem}\n"
1361                             "\\usepackage{ulem}\n";
1362
1363         if (mustProvide("nomencl")) {
1364                 // Make it work with the new and old version of the package,
1365                 // but don't use the compatibility option since it is
1366                 // incompatible to other packages.
1367                 packages << "\\usepackage{nomencl}\n"
1368                             "% the following is useful when we have the old nomencl.sty package\n"
1369                             "\\providecommand{\\printnomenclature}{\\printglossary}\n"
1370                             "\\providecommand{\\makenomenclature}{\\makeglossary}\n"
1371                             "\\makenomenclature\n";
1372         }
1373
1374         // fixltx2e provides subscript
1375         if (mustProvide("subscript") && !isRequired("fixltx2e"))
1376                 packages << "\\usepackage{subscript}\n";
1377
1378         // footmisc must be loaded after setspace
1379         // Set options here, load the package after the user preamble to
1380         // avoid problems with manual loaded footmisc.
1381         if (mustProvide("footmisc"))
1382                 packages << "\\PassOptionsToPackage{stable}{footmisc}\n";
1383
1384         if (mustProvide("microtype")){
1385                 packages << "\\usepackage{microtype}\n";
1386         }
1387
1388         return packages.str();
1389 }
1390
1391
1392 TexString LaTeXFeatures::getMacros() const
1393 {
1394         otexstringstream macros;
1395
1396         if (!preamble_snippets_.empty()) {
1397                 macros << '\n';
1398                 macros << getPreambleSnippets();
1399         }
1400
1401         if (mustProvide("xetexdashbreakstate"))
1402                 macros << "\\XeTeXdashbreakstate 0" << '\n';
1403
1404         if (mustProvide("papersize")) {
1405                 if (runparams_.flavor == OutputParams::LATEX
1406                     || runparams_.flavor == OutputParams::DVILUATEX)
1407                         macros << papersizedvi_def << '\n';
1408                 else if  (runparams_.flavor == OutputParams::LUATEX)
1409                         macros << papersizepdflua_def << '\n';
1410                 else
1411                         macros << papersizepdf_def << '\n';
1412         }
1413
1414         if (mustProvide("LyX")) {
1415                 if (isRequired("hyperref"))
1416                         macros << lyx_hyperref_def << '\n';
1417                 else
1418                         macros << lyx_def << '\n';
1419                 if (runparams_.use_polyglossia && hasRTLLanguage())
1420                         macros << lyx_rtl_def << '\n';
1421         }
1422
1423         if (mustProvide("noun"))
1424                 macros << noun_def << '\n';
1425
1426         if (mustProvide("lyxarrow"))
1427                 macros << lyxarrow_def << '\n';
1428
1429         if (mustProvide("lyxzerowidthspace"))
1430                 macros << lyxZWSP_def << '\n';
1431
1432         if (!usePolyglossia() && mustProvide("textgreek")) {
1433             // ensure LGR font encoding is defined also if fontenc is not loaded by LyX
1434                 if (params_.main_font_encoding() == "default")
1435                         macros << textgreek_LGR_def;
1436                 macros << textgreek_def << '\n';
1437         }
1438
1439         if (!usePolyglossia() && mustProvide("textcyr")) {
1440                 // ensure T2A font encoding is set up also if fontenc is not loaded by LyX
1441                 if (params_.main_font_encoding() == "default")
1442                         macros << textcyr_T2A_def;
1443                 macros << textcyr_def << '\n';
1444         }
1445
1446         // non-standard text accents:
1447         if (mustProvide("textcommaabove") || mustProvide("textcommaaboveright") ||
1448             mustProvide("textcommabelow") || mustProvide("textbaltic"))
1449                 macros << lyxaccent_def;
1450
1451         if (mustProvide("textcommabelow") || mustProvide("textbaltic"))
1452                 macros << textcommabelow_def << '\n';
1453
1454         if (mustProvide("textcommaabove") || mustProvide("textbaltic"))
1455                 macros << textcommaabove_def << '\n';
1456
1457         if (mustProvide("textcommaaboveright"))
1458                 macros << textcommaaboveright_def << '\n';
1459
1460         if (mustProvide("textbaltic"))
1461                 macros << textbaltic_def << '\n';
1462
1463         // split-level fractions
1464         if (mustProvide("xfrac") || mustProvide("smallLetterFrac"))
1465                 macros << xfrac_def << '\n';
1466
1467         if (mustProvide("smallLetterFrac"))
1468                 macros << smallLetterFrac_def << '\n';
1469
1470         if (mustProvide("lyxmathsym"))
1471                 macros << lyxmathsym_def << '\n';
1472
1473         if (mustProvide("cedilla"))
1474                 macros << cedilla_def << '\n';
1475
1476         if (mustProvide("subring"))
1477                 macros << subring_def << '\n';
1478
1479         if (mustProvide("subdot"))
1480                 macros << subdot_def << '\n';
1481
1482         if (mustProvide("subhat"))
1483                 macros << subhat_def << '\n';
1484
1485         if (mustProvide("subtilde"))
1486                 macros << subtilde_def << '\n';
1487
1488         if (mustProvide("dacute"))
1489                 macros << dacute_def << '\n';
1490
1491         if (mustProvide("tipasymb"))
1492                 macros << tipasymb_def << '\n';
1493
1494         if (mustProvide("dgrave"))
1495                 macros << dgrave_def << '\n';
1496
1497         if (mustProvide("rcap"))
1498                 macros << rcap_def << '\n';
1499
1500         if (mustProvide("ogonek"))
1501                 macros << ogonek_def << '\n';
1502
1503         // quotes.
1504         if (mustProvide("quotesinglbase"))
1505                 macros << quotesinglbase_def << '\n';
1506         if (mustProvide("quotedblbase"))
1507                 macros << quotedblbase_def << '\n';
1508         if (mustProvide("guilsinglleft"))
1509                 macros << guilsinglleft_def << '\n';
1510         if (mustProvide("guilsinglright"))
1511                 macros << guilsinglright_def << '\n';
1512         if (mustProvide("guillemotleft"))
1513                 macros << guillemotleft_def << '\n';
1514         if (mustProvide("guillemotright"))
1515                 macros << guillemotright_def << '\n';
1516         if (mustProvide("textquotedbl"))
1517                 macros << textquotedbl_def << '\n';
1518         if (mustProvide("textquotesinglep")) {
1519                 if (runparams_.flavor == OutputParams::XETEX)
1520                         macros << textquotesinglep_xetex_def << '\n';
1521                 else
1522                         macros << textquotesinglep_luatex_def << '\n';
1523         }
1524         if (mustProvide("textquotedblp")) {
1525                 if (runparams_.flavor == OutputParams::XETEX)
1526                         macros << textquotedblp_xetex_def << '\n';
1527                 else
1528                         macros << textquotedblp_luatex_def << '\n';
1529         }
1530
1531         // Math mode
1532         if (mustProvide("binom") && !isRequired("amsmath"))
1533                 macros << binom_def << '\n';
1534         if (mustProvide("mathcircumflex"))
1535                 macros << mathcircumflex_def << '\n';
1536
1537         // other
1538         if (mustProvide("ParagraphLeftIndent"))
1539                 macros << paragraphleftindent_def;
1540         if (mustProvide("NeedLyXFootnoteCode"))
1541                 macros << floatingfootnote_def;
1542
1543         // some problems with tex->html converters
1544         if (mustProvide("NeedTabularnewline"))
1545                 macros << tabularnewline_def;
1546
1547         // greyed-out environment (note inset)
1548         // the color is specified in the routine
1549         // getColorOptions() to avoid LaTeX-package clashes
1550         if (mustProvide("lyxgreyedout")) {
1551                 // We need different version for RTL (#8647)
1552                 if (hasRTLLanguage()) {
1553                         if (runparams_.flavor == OutputParams::LUATEX)
1554                                 if (useBabel())
1555                                         macros << lyxgreyedout_luartl_babel_def;
1556                                 else
1557                                         macros << lyxgreyedout_luartl_def;
1558                         else
1559                                 macros << lyxgreyedout_rtl_def;
1560                 } else
1561                         macros << lyxgreyedout_def;
1562         }
1563
1564         if (mustProvide("lyxdot"))
1565                 macros << lyxdot_def << '\n';
1566
1567         // floats
1568         getFloatDefinitions(macros);
1569
1570         if (mustProvide("refstyle"))
1571                 macros << lyxref_def << '\n';
1572
1573         // change tracking
1574         if (mustProvide("ct-dvipost"))
1575                 macros << changetracking_dvipost_def;
1576
1577         if (mustProvide("ct-xcolor-ulem")) {
1578                 streamsize const prec = macros.os().precision(2);
1579
1580                 RGBColor cadd = rgbFromHexName(lcolor.getX11Name(Color_addedtext));
1581                 macros << "\\providecolor{lyxadded}{rgb}{"
1582                        << cadd.r / 255.0 << ',' << cadd.g / 255.0 << ',' << cadd.b / 255.0 << "}\n";
1583
1584                 RGBColor cdel = rgbFromHexName(lcolor.getX11Name(Color_deletedtext));
1585                 macros << "\\providecolor{lyxdeleted}{rgb}{"
1586                        << cdel.r / 255.0 << ',' << cdel.g / 255.0 << ',' << cdel.b / 255.0 << "}\n";
1587
1588                 macros.os().precision(prec);
1589
1590                 if (isRequired("hyperref"))
1591                         macros << changetracking_xcolor_ulem_hyperref_def;
1592                 else
1593                         macros << changetracking_xcolor_ulem_def;
1594         }
1595
1596         if (mustProvide("ct-tikz-math-sout"))
1597                         macros << changetracking_tikz_math_sout_def;
1598
1599         if (mustProvide("ct-none"))
1600                 macros << changetracking_none_def;
1601
1602         if (mustProvide("rtloutputdblcol"))
1603                 macros << rtloutputdblcol_def;
1604
1605         if (mustProvide("lyxmintcaption"))
1606                 macros << lyxmintcaption_def;
1607
1608         return macros.release();
1609 }
1610
1611
1612 docstring const LaTeXFeatures::getBabelPresettings() const
1613 {
1614         odocstringstream tmp;
1615
1616         for (Language const * lang : UsedLanguages_)
1617                 if (!lang->babel_presettings().empty())
1618                         tmp << lang->babel_presettings() << '\n';
1619         if (!params_.language->babel_presettings().empty())
1620                 tmp << params_.language->babel_presettings() << '\n';
1621
1622         if (!contains(tmp.str(), '@'))
1623                 return tmp.str();
1624
1625         return "\\makeatletter\n" + tmp.str() + "\\makeatother\n";
1626 }
1627
1628
1629 docstring const LaTeXFeatures::getBabelPostsettings() const
1630 {
1631         odocstringstream tmp;
1632
1633         for (Language const * lang : UsedLanguages_)
1634                 if (!lang->babel_postsettings().empty())
1635                         tmp << lang->babel_postsettings() << '\n';
1636         if (!params_.language->babel_postsettings().empty())
1637                 tmp << params_.language->babel_postsettings() << '\n';
1638
1639         if (!contains(tmp.str(), '@'))
1640                 return tmp.str();
1641
1642         return "\\makeatletter\n" + tmp.str() + "\\makeatother\n";
1643 }
1644
1645
1646 bool LaTeXFeatures::needBabelLangOptions() const
1647 {
1648         if (!lyxrc.language_global_options || params_.language->asBabelOptions())
1649                 return true;
1650
1651         LanguageList::const_iterator it  = UsedLanguages_.begin();
1652         LanguageList::const_iterator end = UsedLanguages_.end();
1653         for (; it != end; ++it)
1654                 if ((*it)->asBabelOptions())
1655                         return true;
1656
1657         return false;
1658 }
1659
1660
1661 string const LaTeXFeatures::loadAMSPackages() const
1662 {
1663         ostringstream tmp;
1664
1665         if (mustProvide("amsmath")
1666             && params_.use_package("amsmath") != BufferParams::package_off) {
1667                 tmp << "\\usepackage{amsmath}\n";
1668         } else {
1669                 // amsbsy and amstext are already provided by amsmath
1670                 if (mustProvide("amsbsy"))
1671                         tmp << "\\usepackage{amsbsy}\n";
1672                 if (mustProvide("amstext"))
1673                         tmp << "\\usepackage{amstext}\n";
1674         }
1675
1676         if (mustProvide("amsthm"))
1677                 tmp << "\\usepackage{amsthm}\n";
1678
1679         if (mustProvide("amssymb")
1680             && params_.use_package("amssymb") != BufferParams::package_off)
1681                 tmp << "\\usepackage{amssymb}\n";
1682
1683         return tmp.str();
1684 }
1685
1686
1687 docstring const LaTeXFeatures::getTClassPreamble() const
1688 {
1689         // the text class specific preamble
1690         DocumentClass const & tclass = params_.documentClass();
1691         odocstringstream tcpreamble;
1692
1693         tcpreamble << tclass.preamble();
1694
1695         list<docstring>::const_iterator cit = usedLayouts_.begin();
1696         list<docstring>::const_iterator end = usedLayouts_.end();
1697         for (; cit != end; ++cit)
1698                 // For InPreamble layouts, we output the preamble stuff earlier
1699                 // (before the layouts). See Paragraph::Private::validate.
1700                 if (!tclass[*cit].inpreamble)
1701                         tcpreamble << tclass[*cit].preamble();
1702
1703         cit = usedInsetLayouts_.begin();
1704         end = usedInsetLayouts_.end();
1705         TextClass::InsetLayouts const & ils = tclass.insetLayouts();
1706         for (; cit != end; ++cit) {
1707                 TextClass::InsetLayouts::const_iterator it = ils.find(*cit);
1708                 if (it == ils.end())
1709                         continue;
1710                 tcpreamble << it->second.preamble();
1711         }
1712
1713         return tcpreamble.str();
1714 }
1715
1716
1717 docstring const LaTeXFeatures::getTClassHTMLPreamble() const
1718 {
1719         DocumentClass const & tclass = params_.documentClass();
1720         odocstringstream tcpreamble;
1721
1722         tcpreamble << tclass.htmlpreamble();
1723
1724         list<docstring>::const_iterator cit = usedLayouts_.begin();
1725         list<docstring>::const_iterator end = usedLayouts_.end();
1726         for (; cit != end; ++cit)
1727                 tcpreamble << tclass[*cit].htmlpreamble();
1728
1729         cit = usedInsetLayouts_.begin();
1730         end = usedInsetLayouts_.end();
1731         TextClass::InsetLayouts const & ils = tclass.insetLayouts();
1732         for (; cit != end; ++cit) {
1733                 TextClass::InsetLayouts::const_iterator it = ils.find(*cit);
1734                 if (it == ils.end())
1735                         continue;
1736                 tcpreamble << it->second.htmlpreamble();
1737         }
1738
1739         return tcpreamble.str();
1740 }
1741
1742
1743 docstring const LaTeXFeatures::getTClassHTMLStyles() const
1744 {
1745         DocumentClass const & tclass = params_.documentClass();
1746         odocstringstream tcpreamble;
1747
1748         if (mustProvide("noun"))
1749                 tcpreamble << lyxnoun_style;
1750         // this isn't exact, but it won't hurt that much if it
1751         // wasn't for this.
1752         if (mustProvide("ulem"))
1753                 tcpreamble << lyxstrikeout_style;
1754
1755         tcpreamble << tclass.htmlstyles();
1756
1757         list<docstring>::const_iterator cit = usedLayouts_.begin();
1758         list<docstring>::const_iterator end = usedLayouts_.end();
1759         for (; cit != end; ++cit)
1760                 tcpreamble << tclass[*cit].htmlstyle();
1761
1762         cit = usedInsetLayouts_.begin();
1763         end = usedInsetLayouts_.end();
1764         TextClass::InsetLayouts const & ils = tclass.insetLayouts();
1765         for (; cit != end; ++cit) {
1766                 TextClass::InsetLayouts::const_iterator it = ils.find(*cit);
1767                 if (it == ils.end())
1768                         continue;
1769                 tcpreamble << it->second.htmlstyle();
1770         }
1771
1772         return tcpreamble.str();
1773 }
1774
1775
1776 namespace {
1777
1778 docstring const getFloatI18nPreamble(docstring const & type,
1779                         docstring const & name, Language const * lang,
1780                         Encoding const & enc, bool const polyglossia)
1781 {
1782         // Check whether name can be encoded in the buffer encoding
1783         bool encodable = true;
1784         for (size_t i = 0; i < name.size(); ++i) {
1785                 if (!enc.encodable(name[i])) {
1786                         encodable = false;
1787                         break;
1788                 }
1789         }
1790
1791         docstring const language = polyglossia ? from_ascii(lang->polyglossia())
1792                                                : from_ascii(lang->babel());
1793         docstring const langenc = from_ascii(lang->encoding()->iconvName());
1794         docstring const texenc = from_ascii(lang->encoding()->latexName());
1795         docstring const bufenc = from_ascii(enc.iconvName());
1796         docstring const s1 = docstring(1, 0xF0000);
1797         docstring const s2 = docstring(1, 0xF0001);
1798         docstring const translated = encodable ? name
1799                 : from_ascii("\\inputencoding{") + texenc + from_ascii("}")
1800                         + s1 + langenc + s2 + name + s1 + bufenc + s2;
1801
1802         odocstringstream os;
1803         os << "\\addto\\captions" << language
1804            << "{\\renewcommand{\\" << type << "name}{" << translated << "}}\n";
1805         return os.str();
1806 }
1807
1808
1809 docstring const i18npreamble(docstring const & templ, Language const * lang,
1810                              Encoding const & enc, bool const polyglossia,
1811                              bool const need_fixedwidth)
1812 {
1813         if (templ.empty())
1814                 return templ;
1815
1816         string preamble = polyglossia ?
1817                 subst(to_utf8(templ), "$$lang", lang->polyglossia()) :
1818                 subst(to_utf8(templ), "$$lang", lang->babel());
1819
1820         string const langenc = lang->encoding()->iconvName();
1821         string const texenc = lang->encoding()->latexName();
1822         string const bufenc = enc.iconvName();
1823         Encoding const * testenc(&enc);
1824         bool lang_fallback = false;
1825         bool ascii_fallback = false;
1826         if (need_fixedwidth && !enc.hasFixedWidth()) {
1827                 if (lang->encoding()->hasFixedWidth()) {
1828                         testenc = lang->encoding();
1829                         lang_fallback = true;
1830                 } else {
1831                         // We need a fixed width encoding, but both the buffer
1832                         // encoding and the language encoding are variable
1833                         // width. As a last fallback, try to convert to pure
1834                         // ASCII using the LaTeX commands defined in unicodesymbols.
1835                         testenc = encodings.fromLyXName("ascii");
1836                         if (!testenc)
1837                                 return docstring();
1838                         ascii_fallback = true;
1839                 }
1840         }
1841         // First and second character of plane 15 (Private Use Area)
1842         string const s1 = "\xf3\xb0\x80\x80"; // U+F0000
1843         string const s2 = "\xf3\xb0\x80\x81"; // U+F0001
1844         // FIXME UNICODE
1845         // lyx::regex is not unicode-safe.
1846         // Should use QRegExp or (boost::u32regex, but that requires ICU)
1847         static regex const reg("_\\(([^\\)]+)\\)");
1848         smatch sub;
1849         while (regex_search(preamble, sub, reg)) {
1850                 string const key = sub.str(1);
1851                 docstring const name = lang->translateLayout(key);
1852                 // Check whether name can be encoded in the buffer encoding
1853                 bool encodable = true;
1854                 for (size_t i = 0; i < name.size() && encodable; ++i)
1855                         if (!testenc->encodable(name[i]))
1856                                 encodable = false;
1857                 string translated;
1858                 if (encodable && !lang_fallback)
1859                         translated = to_utf8(name);
1860                 else if (ascii_fallback)
1861                         translated = to_ascii(testenc->latexString(name).first);
1862                 else
1863                         translated = "\\inputencoding{" + texenc + "}"
1864                                 + s1 + langenc + s2 + to_utf8(name)
1865                                 + s1 + bufenc + s2;
1866                 preamble = subst(preamble, sub.str(), translated);
1867         }
1868         return from_utf8(preamble);
1869 }
1870
1871 } // namespace
1872
1873
1874 docstring const LaTeXFeatures::getTClassI18nPreamble(bool use_babel,
1875                                 bool use_polyglossia, bool use_minted) const
1876 {
1877         DocumentClass const & tclass = params_.documentClass();
1878         // collect preamble snippets in a set to prevent multiple identical
1879         // commands (would happen if e.g. both theorem and theorem* are used)
1880         set<docstring> snippets;
1881         typedef LanguageList::const_iterator lang_it;
1882         lang_it const lbeg = UsedLanguages_.begin();
1883         lang_it const lend =  UsedLanguages_.end();
1884         list<docstring>::const_iterator cit = usedLayouts_.begin();
1885         list<docstring>::const_iterator end = usedLayouts_.end();
1886         for (; cit != end; ++cit) {
1887                 // language dependent commands (once per document)
1888                 snippets.insert(i18npreamble(tclass[*cit].langpreamble(),
1889                                                 buffer().language(),
1890                                                 buffer().params().encoding(),
1891                                                 use_polyglossia, false));
1892                 // commands for language changing (for multilanguage documents)
1893                 if ((use_babel || use_polyglossia) && !UsedLanguages_.empty()) {
1894                         snippets.insert(i18npreamble(
1895                                                 tclass[*cit].babelpreamble(),
1896                                                 buffer().language(),
1897                                                 buffer().params().encoding(),
1898                                                 use_polyglossia, false));
1899                         for (lang_it lit = lbeg; lit != lend; ++lit)
1900                                 snippets.insert(i18npreamble(
1901                                                 tclass[*cit].babelpreamble(),
1902                                                 *lit,
1903                                                 buffer().params().encoding(),
1904                                                 use_polyglossia, false));
1905                 }
1906         }
1907         if ((use_babel || use_polyglossia) && !UsedLanguages_.empty()) {
1908                 FloatList const & floats = params_.documentClass().floats();
1909                 UsedFloats::const_iterator fit = usedFloats_.begin();
1910                 UsedFloats::const_iterator fend = usedFloats_.end();
1911                 for (; fit != fend; ++fit) {
1912                         Floating const & fl = floats.getType(fit->first);
1913                         // we assume builtin floats are translated
1914                         if (fl.isPredefined())
1915                                 continue;
1916                         docstring const type = from_ascii(fl.floattype());
1917                         docstring const flname = from_utf8(fl.name());
1918                         docstring name = buffer().language()->translateLayout(fl.name());
1919                         // only request translation if we have a real translation
1920                         // (that differs from the source)
1921                         if (flname != name)
1922                                 snippets.insert(getFloatI18nPreamble(
1923                                                 type, name, buffer().language(),
1924                                                 buffer().params().encoding(),
1925                                                 use_polyglossia));
1926                         for (lang_it lit = lbeg; lit != lend; ++lit) {
1927                                 string const code = (*lit)->code();
1928                                 name = (*lit)->translateLayout(fl.name());
1929                                 // we assume we have a suitable translation if
1930                                 // either the language is English (we need to
1931                                 // translate into English if English is a secondary
1932                                 // language) or if translateIfPossible returns
1933                                 // something different to the English source.
1934                                 bool const have_translation =
1935                                         (flname != name || contains(code, "en"));
1936                                 if (have_translation)
1937                                         snippets.insert(getFloatI18nPreamble(
1938                                                 type, name, *lit,
1939                                                 buffer().params().encoding(),
1940                                                 use_polyglossia));
1941                         }
1942                 }
1943         }
1944
1945         cit = usedInsetLayouts_.begin();
1946         end = usedInsetLayouts_.end();
1947         TextClass::InsetLayouts const & ils = tclass.insetLayouts();
1948         for (; cit != end; ++cit) {
1949                 TextClass::InsetLayouts::const_iterator it = ils.find(*cit);
1950                 if (it == ils.end())
1951                         continue;
1952                 // The listings package does not work with variable width
1953                 // encodings, only with fixed width encodings. Therefore we
1954                 // need to force a fixed width encoding for
1955                 // \lstlistlistingname and \lstlistingname (bug 9382).
1956                 // This needs to be consistent with InsetListings::latex().
1957                 bool const need_fixedwidth = !use_minted &&
1958                                         !runparams_.isFullUnicode() &&
1959                                         it->second.fixedwidthpreambleencoding();
1960                 // language dependent commands (once per document)
1961                 snippets.insert(i18npreamble(it->second.langpreamble(),
1962                                                 buffer().language(),
1963                                                 buffer().params().encoding(),
1964                                                 use_polyglossia, need_fixedwidth));
1965                 // commands for language changing (for multilanguage documents)
1966                 if ((use_babel || use_polyglossia) && !UsedLanguages_.empty()) {
1967                         snippets.insert(i18npreamble(
1968                                                 it->second.babelpreamble(),
1969                                                 buffer().language(),
1970                                                 buffer().params().encoding(),
1971                                                 use_polyglossia, need_fixedwidth));
1972                         for (lang_it lit = lbeg; lit != lend; ++lit)
1973                                 snippets.insert(i18npreamble(
1974                                                 it->second.babelpreamble(),
1975                                                 *lit,
1976                                                 buffer().params().encoding(),
1977                                                 use_polyglossia, need_fixedwidth));
1978                 }
1979         }
1980
1981         odocstringstream tcpreamble;
1982         set<docstring>::const_iterator const send = snippets.end();
1983         set<docstring>::const_iterator it = snippets.begin();
1984         for (; it != send; ++it)
1985                 tcpreamble << *it;
1986         return tcpreamble.str();
1987 }
1988
1989
1990 docstring const LaTeXFeatures::getLyXSGMLEntities() const
1991 {
1992         // Definition of entities used in the document that are LyX related.
1993         odocstringstream entities;
1994
1995         if (mustProvide("lyxarrow")) {
1996                 entities << "<!ENTITY lyxarrow \"-&gt;\">" << '\n';
1997         }
1998
1999         return entities.str();
2000 }
2001
2002
2003 docstring const LaTeXFeatures::getIncludedFiles(string const & fname) const
2004 {
2005         odocstringstream sgmlpreamble;
2006         // FIXME UNICODE
2007         docstring const basename(from_utf8(onlyPath(fname)));
2008
2009         FileMap::const_iterator end = IncludedFiles_.end();
2010         for (FileMap::const_iterator fi = IncludedFiles_.begin();
2011              fi != end; ++fi)
2012                 // FIXME UNICODE
2013                 sgmlpreamble << "\n<!ENTITY " << fi->first
2014                              << (isSGMLFileName(fi->second) ? " SYSTEM \"" : " \"")
2015                              << makeRelPath(from_utf8(fi->second), basename) << "\">";
2016
2017         return sgmlpreamble.str();
2018 }
2019
2020
2021 void LaTeXFeatures::showStruct() const
2022 {
2023         lyxerr << "LyX needs the following commands when LaTeXing:"
2024                << "\n***** Packages:" << getPackages()
2025                << "\n***** Macros:" << to_utf8(getMacros().str)
2026                << "\n***** Textclass stuff:" << to_utf8(getTClassPreamble())
2027                << "\n***** done." << endl;
2028 }
2029
2030
2031 Buffer const & LaTeXFeatures::buffer() const
2032 {
2033         return *buffer_;
2034 }
2035
2036
2037 void LaTeXFeatures::setBuffer(Buffer const & buffer)
2038 {
2039         buffer_ = &buffer;
2040 }
2041
2042
2043 BufferParams const & LaTeXFeatures::bufferParams() const
2044 {
2045         return params_;
2046 }
2047
2048
2049 void LaTeXFeatures::getFloatDefinitions(otexstream & os) const
2050 {
2051         FloatList const & floats = params_.documentClass().floats();
2052
2053         // Here we will output the code to create the needed float styles.
2054         // We will try to do this as minimal as possible.
2055         // \floatstyle{ruled}
2056         // \newfloat{algorithm}{htbp}{loa}
2057         // \providecommand{\algorithmname}{Algorithm}
2058         // \floatname{algorithm}{\protect\algorithmname}
2059         UsedFloats::const_iterator cit = usedFloats_.begin();
2060         UsedFloats::const_iterator end = usedFloats_.end();
2061         for (; cit != end; ++cit) {
2062                 Floating const & fl = floats.getType(cit->first);
2063
2064                 // For builtin floats we do nothing.
2065                 if (fl.isPredefined())
2066                         continue;
2067
2068                 // We have to special case "table" and "figure"
2069                 if (fl.floattype() == "tabular" || fl.floattype() == "figure") {
2070                         // Output code to modify "table" or "figure"
2071                         // but only if builtin == false
2072                         // and that have to be true at this point in the
2073                         // function.
2074                         docstring const type = from_ascii(fl.floattype());
2075                         docstring const placement = from_ascii(fl.placement());
2076                         docstring const style = from_ascii(fl.style());
2077                         if (!style.empty()) {
2078                                 os << "\\floatstyle{" << style << "}\n"
2079                                    << "\\restylefloat{" << type << "}\n";
2080                         }
2081                         if (!placement.empty()) {
2082                                 os << "\\floatplacement{" << type << "}{"
2083                                    << placement << "}\n";
2084                         }
2085                 } else {
2086                         // The other non builtin floats.
2087
2088                         docstring const type = from_ascii(fl.floattype());
2089                         docstring const placement = from_ascii(fl.placement());
2090                         docstring const ext = from_ascii(fl.ext());
2091                         docstring const within = from_ascii(fl.within());
2092                         docstring const style = from_ascii(fl.style());
2093                         docstring const name =
2094                                 buffer().language()->translateLayout(fl.name());
2095                         os << "\\floatstyle{" << style << "}\n"
2096                            << "\\newfloat{" << type << "}{" << placement
2097                            << "}{" << ext << '}';
2098                         if (!within.empty())
2099                                 os << '[' << within << ']';
2100                         os << '\n'
2101                            << "\\providecommand{\\" << type << "name}{"
2102                            << name << "}\n"
2103                            << "\\floatname{" << type << "}{\\protect\\"
2104                            << type << "name}\n";
2105
2106                         // What missing here is to code to minimalize the code
2107                         // output so that the same floatstyle will not be
2108                         // used several times, when the same style is still in
2109                         // effect. (Lgb)
2110                 }
2111                 if (cit->second)
2112                         // The subfig package is loaded later
2113                         os << "\n\\AtBeginDocument{\\newsubfloat{" << from_ascii(fl.floattype()) << "}}\n";
2114         }
2115 }
2116
2117
2118 void LaTeXFeatures::resolveAlternatives()
2119 {
2120         for (Features::iterator it = features_.begin(); it != features_.end();) {
2121                 if (contains(*it, '|')) {
2122                         vector<string> const alternatives = getVectorFromString(*it, "|");
2123                         vector<string>::const_iterator const end = alternatives.end();
2124                         vector<string>::const_iterator ita = alternatives.begin();
2125                         // Is any alternative already required? => use that
2126                         for (; ita != end; ++ita) {
2127                                 if (isRequired(*ita))
2128                                         break;
2129                         }
2130                         // Is any alternative available? => use the first one
2131                         // (bug 9498)
2132                         if (ita == end) {
2133                                 for (ita = alternatives.begin(); ita != end; ++ita) {
2134                                         if (isAvailable(*ita)) {
2135                                                 require(*ita);
2136                                                 break;
2137                                         }
2138                                 }
2139                         }
2140                         // This will not work, but not requiring something
2141                         // would be more confusing
2142                         if (ita == end)
2143                                 require(alternatives.front());
2144                         features_.erase(it);
2145                         it = features_.begin();
2146                 } else
2147                         ++it;
2148         }
2149 }
2150
2151
2152 void LaTeXFeatures::expandMultiples()
2153 {
2154         for (Features::iterator it = features_.begin(); it != features_.end();) {
2155                 if (contains(*it, ',')) {
2156                         vector<string> const multiples = getVectorFromString(*it, ",");
2157                         vector<string>::const_iterator const end = multiples.end();
2158                         vector<string>::const_iterator itm = multiples.begin();
2159                         // Do nothing if any multiple is already required
2160                         for (; itm != end; ++itm) {
2161                                 if (!isRequired(*itm))
2162                                         require(*itm);
2163                         }
2164                         features_.erase(it);
2165                         it = features_.begin();
2166                 } else
2167                         ++it;
2168         }
2169 }
2170
2171
2172 } // namespace lyx