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