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