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