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