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