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