]> git.lyx.org Git - lyx.git/blob - src/LaTeXFeatures.cpp
Fix tablefootnote loading order (#11841)
[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 };
1025
1026 char const * bibliofeatures[] = {
1027         // Known bibliography packages (will be loaded before natbib)
1028         "achicago",
1029         "apacite",
1030         "apalike",
1031         "astron",
1032         "authordate1-4",
1033         "babelbib",
1034         "bibgerm",
1035         "chapterbib",
1036         "chicago",
1037         "chscite",
1038         "harvard",
1039         "mslapa",
1040         "named"
1041 };
1042
1043 int const nb_bibliofeatures = sizeof(bibliofeatures) / sizeof(char const *);
1044
1045 int const nb_simplefeatures = sizeof(simplefeatures) / sizeof(char const *);
1046
1047 } // namespace
1048
1049
1050 string const LaTeXFeatures::getColorOptions() const
1051 {
1052         ostringstream colors;
1053
1054         // Handling the color packages separately is needed to be able to load them
1055         // before babel when hyperref is loaded with the colorlinks option
1056         // for more info see Bufferparams.cpp
1057
1058         // [x]color.sty
1059         if (mustProvide("color") || mustProvide("xcolor")) {
1060                 string const package =
1061                         (mustProvide("xcolor") ? "xcolor" : "color");
1062                 if (params_.graphics_driver == "default"
1063                         || params_.graphics_driver == "none")
1064                         colors << "\\usepackage{" << package << "}\n";
1065                 else
1066                         colors << "\\usepackage["
1067                                  << params_.graphics_driver
1068                                  << "]{" << package << "}\n";
1069         }
1070
1071         // pdfcolmk must be loaded after color
1072         if (mustProvide("pdfcolmk"))
1073                 colors << "\\usepackage{pdfcolmk}\n";
1074
1075         // the following 3 color commands must be set after color
1076         // is loaded and before pdfpages, therefore add the command
1077         // here define the set color
1078         if (mustProvide("pagecolor")) {
1079                 colors << "\\definecolor{page_backgroundcolor}{rgb}{";
1080                 colors << outputLaTeXColor(params_.backgroundcolor) << "}\n";
1081                 // set the page color
1082                 colors << "\\pagecolor{page_backgroundcolor}\n";
1083         }
1084
1085         if (mustProvide("fontcolor")) {
1086                 colors << "\\definecolor{document_fontcolor}{rgb}{";
1087                 colors << outputLaTeXColor(params_.fontcolor) << "}\n";
1088                 // set the color
1089                 colors << "\\color{document_fontcolor}\n";
1090         }
1091
1092         if (mustProvide("lyxgreyedout")) {
1093                 colors << "\\definecolor{note_fontcolor}{rgb}{";
1094                 colors << outputLaTeXColor(params_.notefontcolor) << "}\n";
1095                 // the color will be set together with the definition of
1096                 // the lyxgreyedout environment (see lyxgreyedout_def)
1097         }
1098
1099         // color for shaded boxes
1100         if (isRequired("framed") && mustProvide("color")) {
1101                 colors << "\\definecolor{shadecolor}{rgb}{";
1102                 colors << outputLaTeXColor(params_.boxbgcolor) << "}\n";
1103                 // this color is automatically used by the LaTeX-package "framed"
1104         }
1105
1106         return colors.str();
1107 }
1108
1109
1110 string const LaTeXFeatures::getPackageOptions() const
1111 {
1112         ostringstream packageopts;
1113         // Output all the package option stuff we have been asked to do.
1114         map<string, string>::const_iterator it =
1115                 params_.documentClass().packageOptions().begin();
1116         map<string, string>::const_iterator en =
1117                 params_.documentClass().packageOptions().end();
1118         for (; it != en; ++it)
1119                 if (mustProvide(it->first))
1120                         packageopts << "\\PassOptionsToPackage{" << it->second << "}"
1121                                  << "{" << it->first << "}\n";
1122         return packageopts.str();
1123 }
1124
1125
1126 string const LaTeXFeatures::getPackages() const
1127 {
1128         ostringstream packages;
1129
1130         // FIXME: currently, we can only load packages and macros known
1131         // to LyX.
1132         // However, with the Require tag of layouts/custom insets,
1133         // also unknown packages can be requested. They are silently
1134         // swallowed now. We should change this eventually.
1135
1136         //  These are all the 'simple' includes.  i.e
1137         //  packages which we just \usepackage{package}
1138         for (int i = 0; i < nb_simplefeatures; ++i) {
1139                 if (mustProvide(simplefeatures[i]))
1140                         packages << "\\usepackage{" << simplefeatures[i] << "}\n";
1141         }
1142
1143         // The rest of these packages are somewhat more complicated
1144         // than those above.
1145
1146         if (mustProvide("footnote")) {
1147                 if (isRequired("hyperref"))
1148                         packages << "\\usepackage{footnotehyper}\n";
1149                 else
1150                         packages << "\\usepackage{footnote}\n";
1151         }
1152
1153         // [pdf]lscape is used to rotate longtables
1154         if (mustProvide("lscape")) {
1155                 if (runparams_.flavor == OutputParams::LATEX
1156                     || runparams_.flavor == OutputParams::DVILUATEX)
1157                         packages << "\\usepackage{lscape}\n";
1158                 else
1159                         packages << "\\usepackage{pdflscape}\n";
1160         }
1161
1162         // The tipa package and its extensions (tipx, tone) must not
1163         // be loaded with non-TeX fonts, since fontspec includes the
1164         // respective macros
1165         if (mustProvide("tipa") && !params_.useNonTeXFonts)
1166                 packages << "\\usepackage{tipa}\n";
1167         if (mustProvide("tipx") && !params_.useNonTeXFonts)
1168                 packages << "\\usepackage{tipx}\n";
1169         if (mustProvide("extraipa") && !params_.useNonTeXFonts)
1170                 packages << "\\usepackage{extraipa}\n";
1171         if (mustProvide("tone") && !params_.useNonTeXFonts)
1172                 packages << "\\usepackage{tone}\n";
1173
1174         // if fontspec or newtxmath is used, AMS packages have to be loaded
1175         // before fontspec (in BufferParams)
1176         string const amsPackages = loadAMSPackages();
1177         bool const ot1 = (params_.main_font_encoding() == "default"
1178                           || params_.main_font_encoding() == "OT1");
1179         bool const use_newtxmath =
1180                 theLaTeXFonts().getLaTeXFont(from_ascii(params_.fontsMath())).getUsedPackage(
1181                         ot1, false, false) == "newtxmath";
1182
1183         if (!params_.useNonTeXFonts && !use_newtxmath && !amsPackages.empty())
1184                 packages << amsPackages;
1185
1186         if (mustProvide("cancel") &&
1187             params_.use_package("cancel") != BufferParams::package_off)
1188                 packages << "\\usepackage{cancel}\n";
1189
1190         // marvosym and bbding both define the \Cross macro
1191         if (mustProvide("marvosym")) {
1192             if (mustProvide("bbding"))
1193                 packages << "\\let\\Cross\\relax\n";
1194             packages << "\\usepackage{marvosym}\n";
1195         }
1196
1197         // accents must be loaded after amsmath
1198         if (mustProvide("accents") &&
1199             params_.use_package("accents") != BufferParams::package_off)
1200                 packages << "\\usepackage{accents}\n";
1201
1202         // mathdots must be loaded after amsmath
1203         if (mustProvide("mathdots") &&
1204                 params_.use_package("mathdots") != BufferParams::package_off)
1205                 packages << "\\usepackage{mathdots}\n";
1206
1207         // yhmath must be loaded after amsmath
1208         if (mustProvide("yhmath") &&
1209             params_.use_package("yhmath") != BufferParams::package_off)
1210                 packages << "\\usepackage{yhmath}\n";
1211
1212         // stmaryrd must be loaded after amsmath
1213         if (mustProvide("stmaryrd") &&
1214             params_.use_package("stmaryrd") != BufferParams::package_off)
1215                 packages << "\\usepackage{stmaryrd}\n";
1216
1217         if (mustProvide("stackrel") &&
1218             params_.use_package("stackrel") != BufferParams::package_off)
1219                 packages << "\\usepackage{stackrel}\n";
1220
1221         if (mustProvide("undertilde") &&
1222                 params_.use_package("undertilde") != BufferParams::package_off)
1223                 packages << "\\usepackage{undertilde}\n";
1224
1225         // [x]color and pdfcolmk are handled in getColorOptions() above
1226
1227         // makeidx.sty
1228         if (isRequired("makeidx") || isRequired("splitidx")) {
1229                 if (!isProvided("makeidx") && !isRequired("splitidx"))
1230                         packages << "\\usepackage{makeidx}\n";
1231                 if (mustProvide("splitidx"))
1232                         packages << "\\usepackage{splitidx}\n";
1233                 packages << "\\makeindex\n";
1234         }
1235
1236         // graphicx.sty
1237         if (mustProvide("graphicx") && params_.graphics_driver != "none") {
1238                 if (params_.graphics_driver == "default")
1239                         packages << "\\usepackage{graphicx}\n";
1240                 else
1241                         packages << "\\usepackage["
1242                                  << params_.graphics_driver
1243                                  << "]{graphicx}\n";
1244         }
1245
1246         // These must be loaded after graphicx, since they try
1247         // to load graphicx without options
1248         if (mustProvide("rotating"))
1249                 packages << "\\usepackage{rotating}\n";
1250         if (mustProvide("rotfloat"))
1251                 packages << "\\usepackage{rotfloat}\n";
1252         // and this must be loaded after rotating
1253         if (mustProvide("tablefootnote"))
1254                 packages << "\\usepackage{tablefootnote}\n";
1255
1256         // lyxskak.sty --- newer chess support based on skak.sty
1257         if (mustProvide("chess"))
1258                 packages << "\\usepackage[ps,mover]{lyxskak}\n";
1259
1260         // setspace.sty
1261         if (mustProvide("setspace") && !isProvided("SetSpace"))
1262                 packages << "\\usepackage{setspace}\n";
1263
1264         // we need to assure that mhchem is loaded before esint and every other
1265         // package that redefines command of amsmath because mhchem loads amlatex
1266         // (this info is from the author of mhchem from June 2013)
1267         if (mustProvide("mhchem") &&
1268             params_.use_package("mhchem") != BufferParams::package_off)
1269                 packages << "\\PassOptionsToPackage{version=3}{mhchem}\n"
1270                             "\\usepackage{mhchem}\n";
1271
1272         // wasysym is a simple feature, but it must be after amsmath if both
1273         // are used
1274         // wasysym redefines some integrals (e.g. iint) from amsmath. That
1275         // leads to inconsistent integrals. We only load this package if
1276         // the document does not contain integrals (then isRequired("esint")
1277         // is false) or if esint is used, since esint redefines all relevant
1278         // integral symbols from wasysym and amsmath.
1279         // See http://www.lyx.org/trac/ticket/1942
1280         if (mustProvide("wasysym") &&
1281             params_.use_package("wasysym") != BufferParams::package_off &&
1282             (params_.use_package("esint") != BufferParams::package_off || !isRequired("esint")))
1283                 packages << "\\usepackage{wasysym}\n";
1284
1285         // esint must be after amsmath (and packages requiring amsmath, like mhchem)
1286         // and wasysym, since it will redeclare inconsistent integral symbols
1287         if (mustProvide("esint") &&
1288             params_.use_package("esint") != BufferParams::package_off)
1289                 packages << "\\usepackage{esint}\n";
1290
1291         // Known bibliography packages (simple \usepackage{package})
1292         for (int i = 0; i < nb_bibliofeatures; ++i) {
1293                 if (mustProvide(bibliofeatures[i]))
1294                         packages << "\\usepackage{"
1295                                  << bibliofeatures[i] << "}\n";
1296         }
1297
1298         // Compatibility between achicago and natbib
1299         if (mustProvide("achicago") && mustProvide("natbib"))
1300                 packages << "\\let\\achicagobib\\thebibliography\n";
1301
1302         // natbib.sty
1303         // Some classes load natbib themselves, but still allow (or even require)
1304         // plain numeric citations (ReVTeX is such a case, see bug 5182).
1305         // This special case is indicated by the "natbib-internal" key.
1306         if (mustProvide("natbib")
1307             && !isProvided("natbib-internal")
1308             && !isProvided("biblatex")
1309             && !isProvided("biblatex-natbib")
1310             && !isProvided("jurabib")) {
1311                 packages << "\\usepackage[";
1312                 if (params_.citeEngineType() == ENGINE_TYPE_NUMERICAL)
1313                         packages << "numbers";
1314                 else
1315                         packages << "authoryear";
1316                 if (!params_.biblio_opts.empty())
1317                         packages << ',' << params_.biblio_opts;
1318                 packages << "]{natbib}\n";
1319         }
1320
1321         // Compatibility between achicago and natbib
1322         if (mustProvide("achicago") && mustProvide("natbib")) {
1323                 packages << "\\let\\thebibliography\\achicagobib\n";
1324                 packages << "\\let\\SCcite\\astroncite\n";
1325                 packages << "\\let\\UnexpandableProtect\\protect\n";
1326         }
1327
1328         // jurabib -- we need version 0.6 at least.
1329         if (mustProvide("jurabib")
1330             && !isProvided("natbib-internal")
1331             && !isProvided("natbib")
1332             && !isProvided("biblatex")
1333             && !isProvided("biblatex-natbib")) {
1334                 packages << "\\usepackage";
1335                 if (!params_.biblio_opts.empty())
1336                         packages << '[' << params_.biblio_opts << ']';
1337                 packages << "{jurabib}[2004/01/25]\n";
1338         }
1339
1340         // opcit -- we pass custombst as we output \bibliographystyle ourselves
1341         if (mustProvide("opcit")) {
1342                 if (isRequired("hyperref"))
1343                         packages << "\\usepackage[custombst,hyperref]{opcit}\n";
1344                 else
1345                         packages << "\\usepackage[custombst]{opcit}\n";
1346         }
1347
1348         // xargs -- we need version 1.09 at least
1349         if (mustProvide("xargs"))
1350                 packages << "\\usepackage{xargs}[2008/03/08]\n";
1351
1352         if (mustProvide("xy"))
1353                 packages << "\\usepackage[all]{xy}\n";
1354
1355         if (mustProvide("feyn"))
1356                 packages << "\\usepackage{feyn}\n"; //Diagram
1357
1358         if (mustProvide("ulem"))
1359                 packages << "\\PassOptionsToPackage{normalem}{ulem}\n"
1360                             "\\usepackage{ulem}\n";
1361
1362         if (mustProvide("nomencl")) {
1363                 // Make it work with the new and old version of the package,
1364                 // but don't use the compatibility option since it is
1365                 // incompatible to other packages.
1366                 packages << "\\usepackage{nomencl}\n"
1367                             "% the following is useful when we have the old nomencl.sty package\n"
1368                             "\\providecommand{\\printnomenclature}{\\printglossary}\n"
1369                             "\\providecommand{\\makenomenclature}{\\makeglossary}\n"
1370                             "\\makenomenclature\n";
1371         }
1372
1373         // fixltx2e provides subscript
1374         if (mustProvide("subscript") && !isRequired("fixltx2e"))
1375                 packages << "\\usepackage{subscript}\n";
1376
1377         // footmisc must be loaded after setspace
1378         // Set options here, load the package after the user preamble to
1379         // avoid problems with manual loaded footmisc.
1380         if (mustProvide("footmisc"))
1381                 packages << "\\PassOptionsToPackage{stable}{footmisc}\n";
1382
1383         if (mustProvide("microtype")){
1384                 packages << "\\usepackage{microtype}\n";
1385         }
1386
1387         return packages.str();
1388 }
1389
1390
1391 TexString LaTeXFeatures::getMacros() const
1392 {
1393         otexstringstream macros;
1394
1395         if (!preamble_snippets_.empty()) {
1396                 macros << '\n';
1397                 macros << getPreambleSnippets();
1398         }
1399
1400         if (mustProvide("xetexdashbreakstate"))
1401                 macros << "\\XeTeXdashbreakstate 0" << '\n';
1402
1403         if (mustProvide("papersize")) {
1404                 if (runparams_.flavor == OutputParams::LATEX
1405                     || runparams_.flavor == OutputParams::DVILUATEX)
1406                         macros << papersizedvi_def << '\n';
1407                 else if  (runparams_.flavor == OutputParams::LUATEX)
1408                         macros << papersizepdflua_def << '\n';
1409                 else
1410                         macros << papersizepdf_def << '\n';
1411         }
1412
1413         if (mustProvide("LyX")) {
1414                 if (isRequired("hyperref"))
1415                         macros << lyx_hyperref_def << '\n';
1416                 else
1417                         macros << lyx_def << '\n';
1418                 if (runparams_.use_polyglossia && hasRTLLanguage())
1419                         macros << lyx_rtl_def << '\n';
1420         }
1421
1422         if (mustProvide("noun"))
1423                 macros << noun_def << '\n';
1424
1425         if (mustProvide("lyxarrow"))
1426                 macros << lyxarrow_def << '\n';
1427
1428         if (mustProvide("lyxzerowidthspace"))
1429                 macros << lyxZWSP_def << '\n';
1430
1431         if (!usePolyglossia() && mustProvide("textgreek")) {
1432             // ensure LGR font encoding is defined also if fontenc is not loaded by LyX
1433                 if (params_.main_font_encoding() == "default")
1434                         macros << textgreek_LGR_def;
1435                 macros << textgreek_def << '\n';
1436         }
1437
1438         if (!usePolyglossia() && mustProvide("textcyr")) {
1439                 // ensure T2A font encoding is set up also if fontenc is not loaded by LyX
1440                 if (params_.main_font_encoding() == "default")
1441                         macros << textcyr_T2A_def;
1442                 macros << textcyr_def << '\n';
1443         }
1444
1445         // non-standard text accents:
1446         if (mustProvide("textcommaabove") || mustProvide("textcommaaboveright") ||
1447             mustProvide("textcommabelow") || mustProvide("textbaltic"))
1448                 macros << lyxaccent_def;
1449
1450         if (mustProvide("textcommabelow") || mustProvide("textbaltic"))
1451                 macros << textcommabelow_def << '\n';
1452
1453         if (mustProvide("textcommaabove") || mustProvide("textbaltic"))
1454                 macros << textcommaabove_def << '\n';
1455
1456         if (mustProvide("textcommaaboveright"))
1457                 macros << textcommaaboveright_def << '\n';
1458
1459         if (mustProvide("textbaltic"))
1460                 macros << textbaltic_def << '\n';
1461
1462         // split-level fractions
1463         if (mustProvide("xfrac") || mustProvide("smallLetterFrac"))
1464                 macros << xfrac_def << '\n';
1465
1466         if (mustProvide("smallLetterFrac"))
1467                 macros << smallLetterFrac_def << '\n';
1468
1469         if (mustProvide("lyxmathsym"))
1470                 macros << lyxmathsym_def << '\n';
1471
1472         if (mustProvide("cedilla"))
1473                 macros << cedilla_def << '\n';
1474
1475         if (mustProvide("subring"))
1476                 macros << subring_def << '\n';
1477
1478         if (mustProvide("subdot"))
1479                 macros << subdot_def << '\n';
1480
1481         if (mustProvide("subhat"))
1482                 macros << subhat_def << '\n';
1483
1484         if (mustProvide("subtilde"))
1485                 macros << subtilde_def << '\n';
1486
1487         if (mustProvide("dacute"))
1488                 macros << dacute_def << '\n';
1489
1490         if (mustProvide("tipasymb"))
1491                 macros << tipasymb_def << '\n';
1492
1493         if (mustProvide("dgrave"))
1494                 macros << dgrave_def << '\n';
1495
1496         if (mustProvide("rcap"))
1497                 macros << rcap_def << '\n';
1498
1499         if (mustProvide("ogonek"))
1500                 macros << ogonek_def << '\n';
1501
1502         // quotes.
1503         if (mustProvide("quotesinglbase"))
1504                 macros << quotesinglbase_def << '\n';
1505         if (mustProvide("quotedblbase"))
1506                 macros << quotedblbase_def << '\n';
1507         if (mustProvide("guilsinglleft"))
1508                 macros << guilsinglleft_def << '\n';
1509         if (mustProvide("guilsinglright"))
1510                 macros << guilsinglright_def << '\n';
1511         if (mustProvide("guillemotleft"))
1512                 macros << guillemotleft_def << '\n';
1513         if (mustProvide("guillemotright"))
1514                 macros << guillemotright_def << '\n';
1515         if (mustProvide("textquotedbl"))
1516                 macros << textquotedbl_def << '\n';
1517         if (mustProvide("textquotesinglep")) {
1518                 if (runparams_.flavor == OutputParams::XETEX)
1519                         macros << textquotesinglep_xetex_def << '\n';
1520                 else
1521                         macros << textquotesinglep_luatex_def << '\n';
1522         }
1523         if (mustProvide("textquotedblp")) {
1524                 if (runparams_.flavor == OutputParams::XETEX)
1525                         macros << textquotedblp_xetex_def << '\n';
1526                 else
1527                         macros << textquotedblp_luatex_def << '\n';
1528         }
1529
1530         // Math mode
1531         if (mustProvide("binom") && !isRequired("amsmath"))
1532                 macros << binom_def << '\n';
1533         if (mustProvide("mathcircumflex"))
1534                 macros << mathcircumflex_def << '\n';
1535
1536         // other
1537         if (mustProvide("ParagraphLeftIndent"))
1538                 macros << paragraphleftindent_def;
1539         if (mustProvide("NeedLyXFootnoteCode"))
1540                 macros << floatingfootnote_def;
1541
1542         // some problems with tex->html converters
1543         if (mustProvide("NeedTabularnewline"))
1544                 macros << tabularnewline_def;
1545
1546         // greyed-out environment (note inset)
1547         // the color is specified in the routine
1548         // getColorOptions() to avoid LaTeX-package clashes
1549         if (mustProvide("lyxgreyedout")) {
1550                 // We need different version for RTL (#8647)
1551                 if (hasRTLLanguage()) {
1552                         if (runparams_.flavor == OutputParams::LUATEX)
1553                                 if (useBabel())
1554                                         macros << lyxgreyedout_luartl_babel_def;
1555                                 else
1556                                         macros << lyxgreyedout_luartl_def;
1557                         else
1558                                 macros << lyxgreyedout_rtl_def;
1559                 } else
1560                         macros << lyxgreyedout_def;
1561         }
1562
1563         if (mustProvide("lyxdot"))
1564                 macros << lyxdot_def << '\n';
1565
1566         // floats
1567         getFloatDefinitions(macros);
1568
1569         if (mustProvide("refstyle"))
1570                 macros << lyxref_def << '\n';
1571
1572         // change tracking
1573         if (mustProvide("ct-dvipost"))
1574                 macros << changetracking_dvipost_def;
1575
1576         if (mustProvide("ct-xcolor-ulem")) {
1577                 streamsize const prec = macros.os().precision(2);
1578
1579                 RGBColor cadd = rgbFromHexName(lcolor.getX11Name(Color_addedtext));
1580                 macros << "\\providecolor{lyxadded}{rgb}{"
1581                        << cadd.r / 255.0 << ',' << cadd.g / 255.0 << ',' << cadd.b / 255.0 << "}\n";
1582
1583                 RGBColor cdel = rgbFromHexName(lcolor.getX11Name(Color_deletedtext));
1584                 macros << "\\providecolor{lyxdeleted}{rgb}{"
1585                        << cdel.r / 255.0 << ',' << cdel.g / 255.0 << ',' << cdel.b / 255.0 << "}\n";
1586
1587                 macros.os().precision(prec);
1588
1589                 if (isRequired("hyperref"))
1590                         macros << changetracking_xcolor_ulem_hyperref_def;
1591                 else
1592                         macros << changetracking_xcolor_ulem_def;
1593         }
1594
1595         if (mustProvide("ct-tikz-math-sout"))
1596                         macros << changetracking_tikz_math_sout_def;
1597
1598         if (mustProvide("ct-none"))
1599                 macros << changetracking_none_def;
1600
1601         if (mustProvide("rtloutputdblcol"))
1602                 macros << rtloutputdblcol_def;
1603
1604         if (mustProvide("lyxmintcaption"))
1605                 macros << lyxmintcaption_def;
1606
1607         return macros.release();
1608 }
1609
1610
1611 docstring const LaTeXFeatures::getBabelPresettings() const
1612 {
1613         odocstringstream tmp;
1614
1615         for (Language const * lang : UsedLanguages_)
1616                 if (!lang->babel_presettings().empty())
1617                         tmp << lang->babel_presettings() << '\n';
1618         if (!params_.language->babel_presettings().empty())
1619                 tmp << params_.language->babel_presettings() << '\n';
1620
1621         if (!contains(tmp.str(), '@'))
1622                 return tmp.str();
1623
1624         return "\\makeatletter\n" + tmp.str() + "\\makeatother\n";
1625 }
1626
1627
1628 docstring const LaTeXFeatures::getBabelPostsettings() const
1629 {
1630         odocstringstream tmp;
1631
1632         for (Language const * lang : UsedLanguages_)
1633                 if (!lang->babel_postsettings().empty())
1634                         tmp << lang->babel_postsettings() << '\n';
1635         if (!params_.language->babel_postsettings().empty())
1636                 tmp << params_.language->babel_postsettings() << '\n';
1637
1638         if (!contains(tmp.str(), '@'))
1639                 return tmp.str();
1640
1641         return "\\makeatletter\n" + tmp.str() + "\\makeatother\n";
1642 }
1643
1644
1645 bool LaTeXFeatures::needBabelLangOptions() const
1646 {
1647         if (!lyxrc.language_global_options || params_.language->asBabelOptions())
1648                 return true;
1649
1650         LanguageList::const_iterator it  = UsedLanguages_.begin();
1651         LanguageList::const_iterator end = UsedLanguages_.end();
1652         for (; it != end; ++it)
1653                 if ((*it)->asBabelOptions())
1654                         return true;
1655
1656         return false;
1657 }
1658
1659
1660 string const LaTeXFeatures::loadAMSPackages() const
1661 {
1662         ostringstream tmp;
1663
1664         if (mustProvide("amsmath")
1665             && params_.use_package("amsmath") != BufferParams::package_off) {
1666                 tmp << "\\usepackage{amsmath}\n";
1667         } else {
1668                 // amsbsy and amstext are already provided by amsmath
1669                 if (mustProvide("amsbsy"))
1670                         tmp << "\\usepackage{amsbsy}\n";
1671                 if (mustProvide("amstext"))
1672                         tmp << "\\usepackage{amstext}\n";
1673         }
1674
1675         if (mustProvide("amsthm"))
1676                 tmp << "\\usepackage{amsthm}\n";
1677
1678         if (mustProvide("amssymb")
1679             && params_.use_package("amssymb") != BufferParams::package_off)
1680                 tmp << "\\usepackage{amssymb}\n";
1681
1682         return tmp.str();
1683 }
1684
1685
1686 docstring const LaTeXFeatures::getTClassPreamble() const
1687 {
1688         // the text class specific preamble
1689         DocumentClass const & tclass = params_.documentClass();
1690         odocstringstream tcpreamble;
1691
1692         tcpreamble << tclass.preamble();
1693
1694         list<docstring>::const_iterator cit = usedLayouts_.begin();
1695         list<docstring>::const_iterator end = usedLayouts_.end();
1696         for (; cit != end; ++cit)
1697                 // For InPreamble layouts, we output the preamble stuff earlier
1698                 // (before the layouts). See Paragraph::Private::validate.
1699                 if (!tclass[*cit].inpreamble)
1700                         tcpreamble << tclass[*cit].preamble();
1701
1702         cit = usedInsetLayouts_.begin();
1703         end = usedInsetLayouts_.end();
1704         TextClass::InsetLayouts const & ils = tclass.insetLayouts();
1705         for (; cit != end; ++cit) {
1706                 TextClass::InsetLayouts::const_iterator it = ils.find(*cit);
1707                 if (it == ils.end())
1708                         continue;
1709                 tcpreamble << it->second.preamble();
1710         }
1711
1712         return tcpreamble.str();
1713 }
1714
1715
1716 docstring const LaTeXFeatures::getTClassHTMLPreamble() const
1717 {
1718         DocumentClass const & tclass = params_.documentClass();
1719         odocstringstream tcpreamble;
1720
1721         tcpreamble << tclass.htmlpreamble();
1722
1723         list<docstring>::const_iterator cit = usedLayouts_.begin();
1724         list<docstring>::const_iterator end = usedLayouts_.end();
1725         for (; cit != end; ++cit)
1726                 tcpreamble << tclass[*cit].htmlpreamble();
1727
1728         cit = usedInsetLayouts_.begin();
1729         end = usedInsetLayouts_.end();
1730         TextClass::InsetLayouts const & ils = tclass.insetLayouts();
1731         for (; cit != end; ++cit) {
1732                 TextClass::InsetLayouts::const_iterator it = ils.find(*cit);
1733                 if (it == ils.end())
1734                         continue;
1735                 tcpreamble << it->second.htmlpreamble();
1736         }
1737
1738         return tcpreamble.str();
1739 }
1740
1741
1742 docstring const LaTeXFeatures::getTClassHTMLStyles() const
1743 {
1744         DocumentClass const & tclass = params_.documentClass();
1745         odocstringstream tcpreamble;
1746
1747         if (mustProvide("noun"))
1748                 tcpreamble << lyxnoun_style;
1749         // this isn't exact, but it won't hurt that much if it
1750         // wasn't for this.
1751         if (mustProvide("ulem"))
1752                 tcpreamble << lyxstrikeout_style;
1753
1754         tcpreamble << tclass.htmlstyles();
1755
1756         list<docstring>::const_iterator cit = usedLayouts_.begin();
1757         list<docstring>::const_iterator end = usedLayouts_.end();
1758         for (; cit != end; ++cit)
1759                 tcpreamble << tclass[*cit].htmlstyle();
1760
1761         cit = usedInsetLayouts_.begin();
1762         end = usedInsetLayouts_.end();
1763         TextClass::InsetLayouts const & ils = tclass.insetLayouts();
1764         for (; cit != end; ++cit) {
1765                 TextClass::InsetLayouts::const_iterator it = ils.find(*cit);
1766                 if (it == ils.end())
1767                         continue;
1768                 tcpreamble << it->second.htmlstyle();
1769         }
1770
1771         return tcpreamble.str();
1772 }
1773
1774
1775 namespace {
1776
1777 docstring const getFloatI18nPreamble(docstring const & type,
1778                         docstring const & name, Language const * lang,
1779                         Encoding const & enc, bool const polyglossia)
1780 {
1781         // Check whether name can be encoded in the buffer encoding
1782         bool encodable = true;
1783         for (size_t i = 0; i < name.size(); ++i) {
1784                 if (!enc.encodable(name[i])) {
1785                         encodable = false;
1786                         break;
1787                 }
1788         }
1789
1790         docstring const language = polyglossia ? from_ascii(lang->polyglossia())
1791                                                : from_ascii(lang->babel());
1792         docstring const langenc = from_ascii(lang->encoding()->iconvName());
1793         docstring const texenc = from_ascii(lang->encoding()->latexName());
1794         docstring const bufenc = from_ascii(enc.iconvName());
1795         docstring const s1 = docstring(1, 0xF0000);
1796         docstring const s2 = docstring(1, 0xF0001);
1797         docstring const translated = encodable ? name
1798                 : from_ascii("\\inputencoding{") + texenc + from_ascii("}")
1799                         + s1 + langenc + s2 + name + s1 + bufenc + s2;
1800
1801         odocstringstream os;
1802         os << "\\addto\\captions" << language
1803            << "{\\renewcommand{\\" << type << "name}{" << translated << "}}\n";
1804         return os.str();
1805 }
1806
1807
1808 docstring const i18npreamble(docstring const & templ, Language const * lang,
1809                              Encoding const & enc, bool const polyglossia,
1810                              bool const need_fixedwidth)
1811 {
1812         if (templ.empty())
1813                 return templ;
1814
1815         string preamble = polyglossia ?
1816                 subst(to_utf8(templ), "$$lang", lang->polyglossia()) :
1817                 subst(to_utf8(templ), "$$lang", lang->babel());
1818
1819         string const langenc = lang->encoding()->iconvName();
1820         string const texenc = lang->encoding()->latexName();
1821         string const bufenc = enc.iconvName();
1822         Encoding const * testenc(&enc);
1823         bool lang_fallback = false;
1824         bool ascii_fallback = false;
1825         if (need_fixedwidth && !enc.hasFixedWidth()) {
1826                 if (lang->encoding()->hasFixedWidth()) {
1827                         testenc = lang->encoding();
1828                         lang_fallback = true;
1829                 } else {
1830                         // We need a fixed width encoding, but both the buffer
1831                         // encoding and the language encoding are variable
1832                         // width. As a last fallback, try to convert to pure
1833                         // ASCII using the LaTeX commands defined in unicodesymbols.
1834                         testenc = encodings.fromLyXName("ascii");
1835                         if (!testenc)
1836                                 return docstring();
1837                         ascii_fallback = true;
1838                 }
1839         }
1840         // First and second character of plane 15 (Private Use Area)
1841         string const s1 = "\xf3\xb0\x80\x80"; // U+F0000
1842         string const s2 = "\xf3\xb0\x80\x81"; // U+F0001
1843         // FIXME UNICODE
1844         // lyx::regex is not unicode-safe.
1845         // Should use QRegExp or (boost::u32regex, but that requires ICU)
1846         static regex const reg("_\\(([^\\)]+)\\)");
1847         smatch sub;
1848         while (regex_search(preamble, sub, reg)) {
1849                 string const key = sub.str(1);
1850                 docstring const name = lang->translateLayout(key);
1851                 // Check whether name can be encoded in the buffer encoding
1852                 bool encodable = true;
1853                 for (size_t i = 0; i < name.size() && encodable; ++i)
1854                         if (!testenc->encodable(name[i]))
1855                                 encodable = false;
1856                 string translated;
1857                 if (encodable && !lang_fallback)
1858                         translated = to_utf8(name);
1859                 else if (ascii_fallback)
1860                         translated = to_ascii(testenc->latexString(name).first);
1861                 else
1862                         translated = "\\inputencoding{" + texenc + "}"
1863                                 + s1 + langenc + s2 + to_utf8(name)
1864                                 + s1 + bufenc + s2;
1865                 preamble = subst(preamble, sub.str(), translated);
1866         }
1867         return from_utf8(preamble);
1868 }
1869
1870 } // namespace
1871
1872
1873 docstring const LaTeXFeatures::getTClassI18nPreamble(bool use_babel,
1874                                 bool use_polyglossia, bool use_minted) const
1875 {
1876         DocumentClass const & tclass = params_.documentClass();
1877         // collect preamble snippets in a set to prevent multiple identical
1878         // commands (would happen if e.g. both theorem and theorem* are used)
1879         set<docstring> snippets;
1880         typedef LanguageList::const_iterator lang_it;
1881         lang_it const lbeg = UsedLanguages_.begin();
1882         lang_it const lend =  UsedLanguages_.end();
1883         list<docstring>::const_iterator cit = usedLayouts_.begin();
1884         list<docstring>::const_iterator end = usedLayouts_.end();
1885         for (; cit != end; ++cit) {
1886                 // language dependent commands (once per document)
1887                 snippets.insert(i18npreamble(tclass[*cit].langpreamble(),
1888                                                 buffer().language(),
1889                                                 buffer().params().encoding(),
1890                                                 use_polyglossia, false));
1891                 // commands for language changing (for multilanguage documents)
1892                 if ((use_babel || use_polyglossia) && !UsedLanguages_.empty()) {
1893                         snippets.insert(i18npreamble(
1894                                                 tclass[*cit].babelpreamble(),
1895                                                 buffer().language(),
1896                                                 buffer().params().encoding(),
1897                                                 use_polyglossia, false));
1898                         for (lang_it lit = lbeg; lit != lend; ++lit)
1899                                 snippets.insert(i18npreamble(
1900                                                 tclass[*cit].babelpreamble(),
1901                                                 *lit,
1902                                                 buffer().params().encoding(),
1903                                                 use_polyglossia, false));
1904                 }
1905         }
1906         if ((use_babel || use_polyglossia) && !UsedLanguages_.empty()) {
1907                 FloatList const & floats = params_.documentClass().floats();
1908                 UsedFloats::const_iterator fit = usedFloats_.begin();
1909                 UsedFloats::const_iterator fend = usedFloats_.end();
1910                 for (; fit != fend; ++fit) {
1911                         Floating const & fl = floats.getType(fit->first);
1912                         // we assume builtin floats are translated
1913                         if (fl.isPredefined())
1914                                 continue;
1915                         docstring const type = from_ascii(fl.floattype());
1916                         docstring const flname = from_utf8(fl.name());
1917                         docstring name = buffer().language()->translateLayout(fl.name());
1918                         // only request translation if we have a real translation
1919                         // (that differs from the source)
1920                         if (flname != name)
1921                                 snippets.insert(getFloatI18nPreamble(
1922                                                 type, name, buffer().language(),
1923                                                 buffer().params().encoding(),
1924                                                 use_polyglossia));
1925                         for (lang_it lit = lbeg; lit != lend; ++lit) {
1926                                 string const code = (*lit)->code();
1927                                 name = (*lit)->translateLayout(fl.name());
1928                                 // we assume we have a suitable translation if
1929                                 // either the language is English (we need to
1930                                 // translate into English if English is a secondary
1931                                 // language) or if translateIfPossible returns
1932                                 // something different to the English source.
1933                                 bool const have_translation =
1934                                         (flname != name || contains(code, "en"));
1935                                 if (have_translation)
1936                                         snippets.insert(getFloatI18nPreamble(
1937                                                 type, name, *lit,
1938                                                 buffer().params().encoding(),
1939                                                 use_polyglossia));
1940                         }
1941                 }
1942         }
1943
1944         cit = usedInsetLayouts_.begin();
1945         end = usedInsetLayouts_.end();
1946         TextClass::InsetLayouts const & ils = tclass.insetLayouts();
1947         for (; cit != end; ++cit) {
1948                 TextClass::InsetLayouts::const_iterator it = ils.find(*cit);
1949                 if (it == ils.end())
1950                         continue;
1951                 // The listings package does not work with variable width
1952                 // encodings, only with fixed width encodings. Therefore we
1953                 // need to force a fixed width encoding for
1954                 // \lstlistlistingname and \lstlistingname (bug 9382).
1955                 // This needs to be consistent with InsetListings::latex().
1956                 bool const need_fixedwidth = !use_minted &&
1957                                         !runparams_.isFullUnicode() &&
1958                                         it->second.fixedwidthpreambleencoding();
1959                 // language dependent commands (once per document)
1960                 snippets.insert(i18npreamble(it->second.langpreamble(),
1961                                                 buffer().language(),
1962                                                 buffer().params().encoding(),
1963                                                 use_polyglossia, need_fixedwidth));
1964                 // commands for language changing (for multilanguage documents)
1965                 if ((use_babel || use_polyglossia) && !UsedLanguages_.empty()) {
1966                         snippets.insert(i18npreamble(
1967                                                 it->second.babelpreamble(),
1968                                                 buffer().language(),
1969                                                 buffer().params().encoding(),
1970                                                 use_polyglossia, need_fixedwidth));
1971                         for (lang_it lit = lbeg; lit != lend; ++lit)
1972                                 snippets.insert(i18npreamble(
1973                                                 it->second.babelpreamble(),
1974                                                 *lit,
1975                                                 buffer().params().encoding(),
1976                                                 use_polyglossia, need_fixedwidth));
1977                 }
1978         }
1979
1980         odocstringstream tcpreamble;
1981         set<docstring>::const_iterator const send = snippets.end();
1982         set<docstring>::const_iterator it = snippets.begin();
1983         for (; it != send; ++it)
1984                 tcpreamble << *it;
1985         return tcpreamble.str();
1986 }
1987
1988
1989 docstring const LaTeXFeatures::getLyXSGMLEntities() const
1990 {
1991         // Definition of entities used in the document that are LyX related.
1992         odocstringstream entities;
1993
1994         if (mustProvide("lyxarrow")) {
1995                 entities << "<!ENTITY lyxarrow \"-&gt;\">" << '\n';
1996         }
1997
1998         return entities.str();
1999 }
2000
2001
2002 docstring const LaTeXFeatures::getIncludedFiles(string const & fname) const
2003 {
2004         odocstringstream sgmlpreamble;
2005         // FIXME UNICODE
2006         docstring const basename(from_utf8(onlyPath(fname)));
2007
2008         FileMap::const_iterator end = IncludedFiles_.end();
2009         for (FileMap::const_iterator fi = IncludedFiles_.begin();
2010              fi != end; ++fi)
2011                 // FIXME UNICODE
2012                 sgmlpreamble << "\n<!ENTITY " << fi->first
2013                              << (isSGMLFileName(fi->second) ? " SYSTEM \"" : " \"")
2014                              << makeRelPath(from_utf8(fi->second), basename) << "\">";
2015
2016         return sgmlpreamble.str();
2017 }
2018
2019
2020 void LaTeXFeatures::showStruct() const
2021 {
2022         lyxerr << "LyX needs the following commands when LaTeXing:"
2023                << "\n***** Packages:" << getPackages()
2024                << "\n***** Macros:" << to_utf8(getMacros().str)
2025                << "\n***** Textclass stuff:" << to_utf8(getTClassPreamble())
2026                << "\n***** done." << endl;
2027 }
2028
2029
2030 Buffer const & LaTeXFeatures::buffer() const
2031 {
2032         return *buffer_;
2033 }
2034
2035
2036 void LaTeXFeatures::setBuffer(Buffer const & buffer)
2037 {
2038         buffer_ = &buffer;
2039 }
2040
2041
2042 BufferParams const & LaTeXFeatures::bufferParams() const
2043 {
2044         return params_;
2045 }
2046
2047
2048 void LaTeXFeatures::getFloatDefinitions(otexstream & os) const
2049 {
2050         FloatList const & floats = params_.documentClass().floats();
2051
2052         // Here we will output the code to create the needed float styles.
2053         // We will try to do this as minimal as possible.
2054         // \floatstyle{ruled}
2055         // \newfloat{algorithm}{htbp}{loa}
2056         // \providecommand{\algorithmname}{Algorithm}
2057         // \floatname{algorithm}{\protect\algorithmname}
2058         UsedFloats::const_iterator cit = usedFloats_.begin();
2059         UsedFloats::const_iterator end = usedFloats_.end();
2060         for (; cit != end; ++cit) {
2061                 Floating const & fl = floats.getType(cit->first);
2062
2063                 // For builtin floats we do nothing.
2064                 if (fl.isPredefined())
2065                         continue;
2066
2067                 // We have to special case "table" and "figure"
2068                 if (fl.floattype() == "tabular" || fl.floattype() == "figure") {
2069                         // Output code to modify "table" or "figure"
2070                         // but only if builtin == false
2071                         // and that have to be true at this point in the
2072                         // function.
2073                         docstring const type = from_ascii(fl.floattype());
2074                         docstring const placement = from_ascii(fl.placement());
2075                         docstring const style = from_ascii(fl.style());
2076                         if (!style.empty()) {
2077                                 os << "\\floatstyle{" << style << "}\n"
2078                                    << "\\restylefloat{" << type << "}\n";
2079                         }
2080                         if (!placement.empty()) {
2081                                 os << "\\floatplacement{" << type << "}{"
2082                                    << placement << "}\n";
2083                         }
2084                 } else {
2085                         // The other non builtin floats.
2086
2087                         docstring const type = from_ascii(fl.floattype());
2088                         docstring const placement = from_ascii(fl.placement());
2089                         docstring const ext = from_ascii(fl.ext());
2090                         docstring const within = from_ascii(fl.within());
2091                         docstring const style = from_ascii(fl.style());
2092                         docstring const name =
2093                                 buffer().language()->translateLayout(fl.name());
2094                         os << "\\floatstyle{" << style << "}\n"
2095                            << "\\newfloat{" << type << "}{" << placement
2096                            << "}{" << ext << '}';
2097                         if (!within.empty())
2098                                 os << '[' << within << ']';
2099                         os << '\n'
2100                            << "\\providecommand{\\" << type << "name}{"
2101                            << name << "}\n"
2102                            << "\\floatname{" << type << "}{\\protect\\"
2103                            << type << "name}\n";
2104
2105                         // What missing here is to code to minimalize the code
2106                         // output so that the same floatstyle will not be
2107                         // used several times, when the same style is still in
2108                         // effect. (Lgb)
2109                 }
2110                 if (cit->second)
2111                         // The subfig package is loaded later
2112                         os << "\n\\AtBeginDocument{\\newsubfloat{" << from_ascii(fl.floattype()) << "}}\n";
2113         }
2114 }
2115
2116
2117 void LaTeXFeatures::resolveAlternatives()
2118 {
2119         for (Features::iterator it = features_.begin(); it != features_.end();) {
2120                 if (contains(*it, '|')) {
2121                         vector<string> const alternatives = getVectorFromString(*it, "|");
2122                         vector<string>::const_iterator const end = alternatives.end();
2123                         vector<string>::const_iterator ita = alternatives.begin();
2124                         // Is any alternative already required? => use that
2125                         for (; ita != end; ++ita) {
2126                                 if (isRequired(*ita))
2127                                         break;
2128                         }
2129                         // Is any alternative available? => use the first one
2130                         // (bug 9498)
2131                         if (ita == end) {
2132                                 for (ita = alternatives.begin(); ita != end; ++ita) {
2133                                         if (isAvailable(*ita)) {
2134                                                 require(*ita);
2135                                                 break;
2136                                         }
2137                                 }
2138                         }
2139                         // This will not work, but not requiring something
2140                         // would be more confusing
2141                         if (ita == end)
2142                                 require(alternatives.front());
2143                         features_.erase(it);
2144                         it = features_.begin();
2145                 } else
2146                         ++it;
2147         }
2148 }
2149
2150
2151 void LaTeXFeatures::expandMultiples()
2152 {
2153         for (Features::iterator it = features_.begin(); it != features_.end();) {
2154                 if (contains(*it, ',')) {
2155                         vector<string> const multiples = getVectorFromString(*it, ",");
2156                         vector<string>::const_iterator const end = multiples.end();
2157                         vector<string>::const_iterator itm = multiples.begin();
2158                         // Do nothing if any multiple is already required
2159                         for (; itm != end; ++itm) {
2160                                 if (!isRequired(*itm))
2161                                         require(*itm);
2162                         }
2163                         features_.erase(it);
2164                         it = features_.begin();
2165                 } else
2166                         ++it;
2167         }
2168 }
2169
2170
2171 } // namespace lyx