]> git.lyx.org Git - lyx.git/blob - src/bufferparams.C
convert author names and status messages to docstring
[lyx.git] / src / bufferparams.C
1 /**
2  * \file bufferparams.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Alfredo Braunstein
7  * \author Lars Gullik Bjønnes
8  * \author Jean-Marc Lasgouttes
9  * \author John Levon
10  * \author André Pönitz
11  * \author Martin Vermeer
12  *
13  * Full author contact details are available in file CREDITS.
14  */
15
16 #include <config.h>
17
18 #include "bufferparams.h"
19
20 #include "author.h"
21 #include "BranchList.h"
22 #include "Bullet.h"
23 #include "debug.h"
24 #include "encoding.h"
25 #include "gettext.h"
26 #include "language.h"
27 #include "LaTeXFeatures.h"
28 #include "LColor.h"
29 #include "lyxfont.h"
30 #include "lyxlex.h"
31 #include "lyxrc.h"
32 #include "lyxtextclasslist.h"
33 #include "outputparams.h"
34 #include "tex-strings.h"
35 #include "Spacing.h"
36 #include "texrow.h"
37 #include "vspace.h"
38
39 #include "frontends/Alert.h"
40
41 #include "support/lyxalgo.h" // for lyx::count
42 #include "support/convert.h"
43 #include "support/translator.h"
44
45 #include <boost/array.hpp>
46
47 #include <sstream>
48
49
50 namespace lyx {
51
52 using support::bformat;
53 using support::rtrim;
54 using support::tokenPos;
55
56 using std::endl;
57 using std::string;
58 using std::istringstream;
59 using std::ostream;
60 using std::ostringstream;
61 using std::pair;
62
63 namespace Alert = lyx::frontend::Alert;
64
65
66 // Local translators
67 namespace {
68
69 // Paragraph separation
70 typedef Translator<string, BufferParams::PARSEP> ParSepTranslator;
71
72
73 ParSepTranslator const init_parseptranslator()
74 {
75         ParSepTranslator translator(string_paragraph_separation[0], BufferParams::PARSEP_INDENT);
76         translator.addPair(string_paragraph_separation[1], BufferParams::PARSEP_SKIP);
77         return translator;
78 }
79
80
81 ParSepTranslator const & parseptranslator()
82 {
83         static ParSepTranslator translator = init_parseptranslator();
84         return translator;
85 }
86
87
88 // Quotes language
89 typedef Translator<string, InsetQuotes::quote_language> QuotesLangTranslator;
90
91
92 QuotesLangTranslator const init_quoteslangtranslator()
93 {
94         QuotesLangTranslator translator(string_quotes_language[0], InsetQuotes::EnglishQ);
95         translator.addPair(string_quotes_language[1], InsetQuotes::SwedishQ);
96         translator.addPair(string_quotes_language[2], InsetQuotes::GermanQ);
97         translator.addPair(string_quotes_language[3], InsetQuotes::PolishQ);
98         translator.addPair(string_quotes_language[4], InsetQuotes::FrenchQ);
99         translator.addPair(string_quotes_language[5], InsetQuotes::DanishQ);
100         return translator;
101 }
102
103
104 QuotesLangTranslator const & quoteslangtranslator()
105 {
106         static QuotesLangTranslator translator = init_quoteslangtranslator();
107         return translator;
108 }
109
110
111 // Paper size
112 typedef Translator<std::string, PAPER_SIZE> PaperSizeTranslator;
113
114
115 PaperSizeTranslator const init_papersizetranslator()
116 {
117         PaperSizeTranslator translator(string_papersize[0], PAPER_DEFAULT);
118         translator.addPair(string_papersize[1], PAPER_CUSTOM);
119         translator.addPair(string_papersize[2], PAPER_USLETTER);
120         translator.addPair(string_papersize[3], PAPER_USLEGAL);
121         translator.addPair(string_papersize[4], PAPER_USEXECUTIVE);
122         translator.addPair(string_papersize[5], PAPER_A3);
123         translator.addPair(string_papersize[6], PAPER_A4);
124         translator.addPair(string_papersize[7], PAPER_A5);
125         translator.addPair(string_papersize[8], PAPER_B3);
126         translator.addPair(string_papersize[9], PAPER_B4);
127         translator.addPair(string_papersize[10], PAPER_B5);
128         return translator;
129 }
130
131
132 PaperSizeTranslator const & papersizetranslator()
133 {
134         static PaperSizeTranslator translator = init_papersizetranslator();
135         return translator;
136 }
137
138
139 // Paper orientation
140 typedef Translator<string, PAPER_ORIENTATION> PaperOrientationTranslator;
141
142
143 PaperOrientationTranslator const init_paperorientationtranslator()
144 {
145         PaperOrientationTranslator translator(string_orientation[0], ORIENTATION_PORTRAIT);
146         translator.addPair(string_orientation[1], ORIENTATION_LANDSCAPE);
147         return translator;
148 }
149
150
151 PaperOrientationTranslator const & paperorientationtranslator()
152 {
153         static PaperOrientationTranslator translator = init_paperorientationtranslator();
154         return translator;
155 }
156
157
158 // Page sides
159 typedef Translator<int, LyXTextClass::PageSides> SidesTranslator;
160
161
162 SidesTranslator const init_sidestranslator()
163 {
164         SidesTranslator translator(1, LyXTextClass::OneSide);
165         translator.addPair(2, LyXTextClass::TwoSides);
166         return translator;
167 }
168
169
170 SidesTranslator const & sidestranslator()
171 {
172         static SidesTranslator translator = init_sidestranslator();
173         return translator;
174 }
175
176
177 // LaTeX packages
178 typedef Translator<int, BufferParams::Package> PackageTranslator;
179
180
181 PackageTranslator const init_packagetranslator()
182 {
183         PackageTranslator translator(0, BufferParams::package_off);
184         translator.addPair(1, BufferParams::package_auto);
185         translator.addPair(2, BufferParams::package_on);
186         return translator;
187 }
188
189
190 PackageTranslator const & packagetranslator()
191 {
192         static PackageTranslator translator = init_packagetranslator();
193         return translator;
194 }
195
196
197 // Cite engine
198 typedef Translator<string, biblio::CiteEngine> CiteEngineTranslator;
199
200
201 CiteEngineTranslator const init_citeenginetranslator()
202 {
203         CiteEngineTranslator translator("basic", biblio::ENGINE_BASIC);
204         translator.addPair("natbib_numerical", biblio::ENGINE_NATBIB_NUMERICAL);
205         translator.addPair("natbib_authoryear", biblio::ENGINE_NATBIB_AUTHORYEAR);
206         translator.addPair("jurabib", biblio::ENGINE_JURABIB);
207         return translator;
208 }
209
210
211 CiteEngineTranslator const & citeenginetranslator()
212 {
213         static CiteEngineTranslator translator = init_citeenginetranslator();
214         return translator;
215 }
216
217
218 // Spacing
219 typedef Translator<string, Spacing::Space> SpaceTranslator;
220
221
222 SpaceTranslator const init_spacetranslator()
223 {
224         SpaceTranslator translator("default", Spacing::Default);
225         translator.addPair("single", Spacing::Single);
226         translator.addPair("onehalf", Spacing::Onehalf);
227         translator.addPair("double", Spacing::Double);
228         translator.addPair("other", Spacing::Other);
229         return translator;
230 }
231
232
233 SpaceTranslator const & spacetranslator()
234 {
235         static SpaceTranslator translator = init_spacetranslator();
236         return translator;
237 }
238
239 // ends annonym namespace
240 }
241
242
243 class BufferParams::Impl
244 {
245 public:
246         Impl();
247
248         AuthorList authorlist;
249         BranchList branchlist;
250         boost::array<Bullet, 4> temp_bullets;
251         boost::array<Bullet, 4> user_defined_bullets;
252         Spacing spacing;
253         /** This is the amount of space used for paragraph_separation "skip",
254          * and for detached paragraphs in "indented" documents.
255          */
256         VSpace defskip;
257 };
258
259
260 BufferParams::Impl::Impl()
261         : defskip(VSpace::MEDSKIP)
262 {
263         // set initial author
264         // FIXME UNICODE
265         authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
266 }
267
268
269 BufferParams::Impl *
270 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
271 {
272         BOOST_ASSERT(ptr);
273
274         return new BufferParams::Impl(*ptr);
275 }
276
277
278 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
279 {
280         delete ptr;
281 }
282
283
284 BufferParams::BufferParams()
285         : // Initialize textclass to point to article. if `first' is
286           // true in the returned pair, then `second' is the textclass
287           // number; if it is false, second is 0. In both cases, second
288           // is what we want.
289         textclass(textclasslist.numberOfClass("article").second),
290         pimpl_(new Impl)
291 {
292         paragraph_separation = PARSEP_INDENT;
293         quotes_language = InsetQuotes::EnglishQ;
294         fontsize = "default";
295
296         /*  PaperLayout */
297         papersize = PAPER_DEFAULT;
298         orientation = ORIENTATION_PORTRAIT;
299         use_geometry = false;
300         use_amsmath = package_auto;
301         use_esint = package_auto;
302         cite_engine = biblio::ENGINE_BASIC;
303         use_bibtopic = false;
304         trackChanges = false;
305         outputChanges = false;
306         secnumdepth = 3;
307         tocdepth = 3;
308         language = default_language;
309         fontsRoman = "default";
310         fontsSans = "default";
311         fontsTypewriter = "default";
312         fontsDefaultFamily = "default";
313         fontsSC = false;
314         fontsOSF = false;
315         fontsSansScale = 100;
316         fontsTypewriterScale = 100;
317         inputenc = "auto";
318         graphicsDriver = "default";
319         sides = LyXTextClass::OneSide;
320         columns = 1;
321         pagestyle = "default";
322         compressed = false;
323         for (int iter = 0; iter < 4; ++iter) {
324                 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
325                 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
326         }
327 }
328
329
330 BufferParams::~BufferParams()
331 {}
332
333
334 AuthorList & BufferParams::authors()
335 {
336         return pimpl_->authorlist;
337 }
338
339
340 AuthorList const & BufferParams::authors() const
341 {
342         return pimpl_->authorlist;
343 }
344
345
346 BranchList & BufferParams::branchlist()
347 {
348         return pimpl_->branchlist;
349 }
350
351
352 BranchList const & BufferParams::branchlist() const
353 {
354         return pimpl_->branchlist;
355 }
356
357
358 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
359 {
360         BOOST_ASSERT(index < 4);
361         return pimpl_->temp_bullets[index];
362 }
363
364
365 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
366 {
367         BOOST_ASSERT(index < 4);
368         return pimpl_->temp_bullets[index];
369 }
370
371
372 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
373 {
374         BOOST_ASSERT(index < 4);
375         return pimpl_->user_defined_bullets[index];
376 }
377
378
379 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
380 {
381         BOOST_ASSERT(index < 4);
382         return pimpl_->user_defined_bullets[index];
383 }
384
385
386 Spacing & BufferParams::spacing()
387 {
388         return pimpl_->spacing;
389 }
390
391
392 Spacing const & BufferParams::spacing() const
393 {
394         return pimpl_->spacing;
395 }
396
397
398 VSpace const & BufferParams::getDefSkip() const
399 {
400         return pimpl_->defskip;
401 }
402
403
404 void BufferParams::setDefSkip(VSpace const & vs)
405 {
406         pimpl_->defskip = vs;
407 }
408
409
410 string const BufferParams::readToken(LyXLex & lex, string const & token)
411 {
412         if (token == "\\textclass") {
413                 lex.next();
414                 string const classname = lex.getString();
415                 pair<bool, lyx::textclass_type> pp =
416                         textclasslist.numberOfClass(classname);
417                 if (pp.first) {
418                         textclass = pp.second;
419                 } else {
420                         // if text class does not exist, try to load it from filepath
421                         pp = textclasslist.addTextClass(classname, filepath);
422                         if (pp.first) {
423                                 textclass = pp.second;
424                         } else {
425                                 textclass = 0;
426                                 return classname;
427                         }
428                 }
429                 // FIXME: isTeXClassAvailable will try to load the layout file, but will
430                 // fail because of the lack of path info. Warnings will be given although
431                 // the layout file will be correctly loaded later.
432                 if (!getLyXTextClass().isTeXClassAvailable()) {
433                         docstring const msg =
434                                 bformat(_("The document uses a missing "
435                                                        "TeX class \"%1$s\".\n"), from_utf8(classname));
436                         Alert::warning(_("Document class not available"),
437                                        msg + _("LyX will not be able to produce output."));
438                 }
439         } else if (token == "\\begin_preamble") {
440                 readPreamble(lex);
441         } else if (token == "\\options") {
442                 lex.eatLine();
443                 options = lex.getString();
444         } else if (token == "\\language") {
445                 readLanguage(lex);
446         } else if (token == "\\inputencoding") {
447                 lex >> inputenc;
448         } else if (token == "\\graphics") {
449                 readGraphicsDriver(lex);
450         } else if (token == "\\font_roman") {
451                 lex >> fontsRoman;
452         } else if (token == "\\font_sans") {
453                 lex >> fontsSans;
454         } else if (token == "\\font_typewriter") {
455                 lex >> fontsTypewriter;
456         } else if (token == "\\font_default_family") {
457                 lex >> fontsDefaultFamily;
458         } else if (token == "\\font_sc") {
459                 lex >> fontsSC;
460         } else if (token == "\\font_osf") {
461                 lex >> fontsOSF;
462         } else if (token == "\\font_sf_scale") {
463                 lex >> fontsSansScale;
464         } else if (token == "\\font_tt_scale") {
465                 lex >> fontsTypewriterScale;
466         } else if (token == "\\paragraph_separation") {
467                 string parsep;
468                 lex >> parsep;
469                 paragraph_separation = parseptranslator().find(parsep);
470         } else if (token == "\\defskip") {
471                 lex.next();
472                 pimpl_->defskip = VSpace(lex.getString());
473         } else if (token == "\\quotes_language") {
474                 string quotes_lang;
475                 lex >> quotes_lang;
476                 quotes_language = quoteslangtranslator().find(quotes_lang);
477         } else if (token == "\\papersize") {
478                 string ppsize;
479                 lex >> ppsize;
480                 papersize = papersizetranslator().find(ppsize);
481         } else if (token == "\\use_geometry") {
482                 lex >> use_geometry;
483         } else if (token == "\\use_amsmath") {
484                 int use_ams;
485                 lex >> use_ams;
486                 use_amsmath = packagetranslator().find(use_ams);
487         } else if (token == "\\use_esint") {
488                 int useesint;
489                 lex >> useesint;
490                 use_esint = packagetranslator().find(useesint);
491         } else if (token == "\\cite_engine") {
492                 string engine;
493                 lex >> engine;
494                 cite_engine = citeenginetranslator().find(engine);
495         } else if (token == "\\use_bibtopic") {
496                 lex >> use_bibtopic;
497         } else if (token == "\\tracking_changes") {
498                 lex >> trackChanges;
499         } else if (token == "\\output_changes") {
500                 lex >> outputChanges;
501         } else if (token == "\\branch") {
502                 lex.next();
503                 docstring branch = lex.getDocString();
504                 branchlist().add(branch);
505                 while (true) {
506                         lex.next();
507                         string const tok = lex.getString();
508                         if (tok == "\\end_branch")
509                                 break;
510                         Branch * branch_ptr = branchlist().find(branch);
511                         if (tok == "\\selected") {
512                                 lex.next();
513                                 if (branch_ptr)
514                                         branch_ptr->setSelected(lex.getInteger());
515                         }
516                         // not yet operational
517                         if (tok == "\\color") {
518                                 lex.eatLine();
519                                 string color = lex.getString();
520                                 if (branch_ptr)
521                                         branch_ptr->setColor(color);
522                                 // Update also the LColor table:
523                                 if (color == "none")
524                                         color = lcolor.getX11Name(LColor::background);
525                                 // FIXME UNICODE
526                                 lcolor.setColor(to_utf8(branch), color);
527
528                         }
529                 }
530         } else if (token == "\\author") {
531                 lex.eatLine();
532                 istringstream ss(lex.getString());
533                 Author a;
534                 ss >> a;
535                 author_map.push_back(pimpl_->authorlist.record(a));
536         } else if (token == "\\paperorientation") {
537                 string orient;
538                 lex >> orient;
539                 orientation = paperorientationtranslator().find(orient);
540         } else if (token == "\\paperwidth") {
541                 lex >> paperwidth;
542         } else if (token == "\\paperheight") {
543                 lex >> paperheight;
544         } else if (token == "\\leftmargin") {
545                 lex >> leftmargin;
546         } else if (token == "\\topmargin") {
547                 lex >> topmargin;
548         } else if (token == "\\rightmargin") {
549                 lex >> rightmargin;
550         } else if (token == "\\bottommargin") {
551                 lex >> bottommargin;
552         } else if (token == "\\headheight") {
553                 lex >> headheight;
554         } else if (token == "\\headsep") {
555                 lex >> headsep;
556         } else if (token == "\\footskip") {
557                 lex >> footskip;
558         } else if (token == "\\paperfontsize") {
559                 lex >> fontsize;
560         } else if (token == "\\papercolumns") {
561                 lex >> columns;
562         } else if (token == "\\papersides") {
563                 int psides;
564                 lex >> psides;
565                 sides = sidestranslator().find(psides);
566         } else if (token == "\\paperpagestyle") {
567                 lex >> pagestyle;
568         } else if (token == "\\bullet") {
569                 readBullets(lex);
570         } else if (token == "\\bulletLaTeX") {
571                 readBulletsLaTeX(lex);
572         } else if (token == "\\secnumdepth") {
573                 lex >> secnumdepth;
574         } else if (token == "\\tocdepth") {
575                 lex >> tocdepth;
576         } else if (token == "\\spacing") {
577                 string nspacing;
578                 lex >> nspacing;
579                 string tmp_val;
580                 if (nspacing == "other") {
581                         lex >> tmp_val;
582                 }
583                 spacing().set(spacetranslator().find(nspacing), tmp_val);
584         } else if (token == "\\float_placement") {
585                 lex >> float_placement;
586         } else {
587                 return token;
588         }
589
590         return string();
591 }
592
593
594 void BufferParams::writeFile(ostream & os) const
595 {
596         // The top of the file is written by the buffer.
597         // Prints out the buffer info into the .lyx file given by file
598
599         // the textclass
600         os << "\\textclass " << textclasslist[textclass].name() << '\n';
601
602         // then the the preamble
603         if (!preamble.empty()) {
604                 // remove '\n' from the end of preamble
605                 string const tmppreamble = rtrim(preamble, "\n");
606                 os << "\\begin_preamble\n"
607                    << tmppreamble
608                    << "\n\\end_preamble\n";
609         }
610
611         // the options
612         if (!options.empty()) {
613                 os << "\\options " << options << '\n';
614         }
615
616         // then the text parameters
617         if (language != ignore_language)
618                 os << "\\language " << language->lang() << '\n';
619         os << "\\inputencoding " << inputenc
620            << "\n\\font_roman " << fontsRoman
621            << "\n\\font_sans " << fontsSans
622            << "\n\\font_typewriter " << fontsTypewriter
623            << "\n\\font_default_family " << fontsDefaultFamily
624            << "\n\\font_sc " << convert<string>(fontsSC)
625            << "\n\\font_osf " << convert<string>(fontsOSF)
626            << "\n\\font_sf_scale " << fontsSansScale
627            << "\n\\font_tt_scale " << fontsTypewriterScale
628            << "\n\\graphics " << graphicsDriver << '\n';
629
630         if (!float_placement.empty()) {
631                 os << "\\float_placement " << float_placement << '\n';
632         }
633         os << "\\paperfontsize " << fontsize << '\n';
634
635         spacing().writeFile(os);
636
637         os << "\\papersize " << string_papersize[papersize]
638            << "\n\\use_geometry " << convert<string>(use_geometry)
639            << "\n\\use_amsmath " << use_amsmath
640            << "\n\\use_esint " << use_esint
641            << "\n\\cite_engine " << citeenginetranslator().find(cite_engine)
642            << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
643            << "\n\\paperorientation " << string_orientation[orientation]
644            << '\n';
645
646         BranchList::const_iterator it = branchlist().begin();
647         BranchList::const_iterator end = branchlist().end();
648         for (; it != end; ++it) {
649                 os << "\\branch " << to_utf8(it->getBranch())
650                    << "\n\\selected " << it->getSelected()
651                    << "\n\\color " << lyx::X11hexname(it->getColor())
652                    << "\n\\end_branch"
653                    << "\n";
654         }
655
656         if (!paperwidth.empty())
657                 os << "\\paperwidth "
658                    << VSpace(paperwidth).asLyXCommand() << '\n';
659         if (!paperheight.empty())
660                 os << "\\paperheight "
661                    << VSpace(paperheight).asLyXCommand() << '\n';
662         if (!leftmargin.empty())
663                 os << "\\leftmargin "
664                    << VSpace(leftmargin).asLyXCommand() << '\n';
665         if (!topmargin.empty())
666                 os << "\\topmargin "
667                    << VSpace(topmargin).asLyXCommand() << '\n';
668         if (!rightmargin.empty())
669                 os << "\\rightmargin "
670                    << VSpace(rightmargin).asLyXCommand() << '\n';
671         if (!bottommargin.empty())
672                 os << "\\bottommargin "
673                    << VSpace(bottommargin).asLyXCommand() << '\n';
674         if (!headheight.empty())
675                 os << "\\headheight "
676                    << VSpace(headheight).asLyXCommand() << '\n';
677         if (!headsep.empty())
678                 os << "\\headsep "
679                    << VSpace(headsep).asLyXCommand() << '\n';
680         if (!footskip.empty())
681                 os << "\\footskip "
682                    << VSpace(footskip).asLyXCommand() << '\n';
683         os << "\\secnumdepth " << secnumdepth
684            << "\n\\tocdepth " << tocdepth
685            << "\n\\paragraph_separation "
686            << string_paragraph_separation[paragraph_separation]
687            << "\n\\defskip " << getDefSkip().asLyXCommand()
688            << "\n\\quotes_language "
689            << string_quotes_language[quotes_language]
690            << "\n\\papercolumns " << columns
691            << "\n\\papersides " << sides
692            << "\n\\paperpagestyle " << pagestyle << '\n';
693         for (int i = 0; i < 4; ++i) {
694                 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
695                         if (user_defined_bullet(i).getFont() != -1) {
696                                 os << "\\bullet " << i << " "
697                                    << user_defined_bullet(i).getFont() << " "
698                                    << user_defined_bullet(i).getCharacter() << " "
699                                    << user_defined_bullet(i).getSize() << "\n";
700                         }
701                         else {
702                                 // FIXME UNICODE
703                                 os << "\\bulletLaTeX " << i << " \""
704                                    << lyx::to_ascii(user_defined_bullet(i).getText())
705                                    << "\"\n";
706                         }
707                 }
708         }
709
710         os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
711         os << "\\output_changes " << convert<string>(outputChanges) << "\n";
712
713         AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
714         AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
715         for (; a_it != a_end; ++a_it) {
716                 os << "\\author " << a_it->second << "\n";
717         }
718 }
719
720
721 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
722                               TexRow & texrow) const
723 {
724         os << "\\documentclass";
725
726         LyXTextClass const & tclass = getLyXTextClass();
727
728         ostringstream clsoptions; // the document class options.
729
730         if (tokenPos(tclass.opt_fontsize(),
731                      '|', fontsize) >= 0) {
732                 // only write if existing in list (and not default)
733                 clsoptions << fontsize << "pt,";
734         }
735
736         // custom, A3, B3 and B4 paper sizes need geometry
737         bool nonstandard_papersize = papersize == PAPER_B3 
738                 || papersize == PAPER_B4
739                 || papersize == PAPER_A3
740                 || papersize == PAPER_CUSTOM;
741
742         if (!use_geometry) {
743                 switch (papersize) {
744                 case PAPER_A4:
745                         clsoptions << "a4paper,";
746                         break;
747                 case PAPER_USLETTER:
748                         clsoptions << "letterpaper,";
749                         break;
750                 case PAPER_A5:
751                         clsoptions << "a5paper,";
752                         break;
753                 case PAPER_B5:
754                         clsoptions << "b5paper,";
755                         break;
756                 case PAPER_USEXECUTIVE:
757                         clsoptions << "executivepaper,";
758                         break;
759                 case PAPER_USLEGAL:
760                         clsoptions << "legalpaper,";
761                         break;
762                 case PAPER_DEFAULT:
763                 case PAPER_A3:
764                 case PAPER_B3:
765                 case PAPER_B4:
766                 case PAPER_CUSTOM:
767                         break;
768                 }
769         }
770
771         // if needed
772         if (sides != tclass.sides()) {
773                 switch (sides) {
774                 case LyXTextClass::OneSide:
775                         clsoptions << "oneside,";
776                         break;
777                 case LyXTextClass::TwoSides:
778                         clsoptions << "twoside,";
779                         break;
780                 }
781         }
782
783         // if needed
784         if (columns != tclass.columns()) {
785                 if (columns == 2)
786                         clsoptions << "twocolumn,";
787                 else
788                         clsoptions << "onecolumn,";
789         }
790
791         if (!use_geometry
792             && orientation == ORIENTATION_LANDSCAPE)
793                 clsoptions << "landscape,";
794
795         // language should be a parameter to \documentclass
796         if (language->babel() == "hebrew"
797             && default_language->babel() != "hebrew")
798                 // This seems necessary
799                 features.useLanguage(default_language);
800
801         ostringstream language_options;
802         bool const use_babel = features.useBabel();
803         if (use_babel) {
804                 language_options << features.getLanguages();
805                 language_options << language->babel();
806                 if (lyxrc.language_global_options)
807                         clsoptions << language_options.str() << ',';
808         }
809
810         // the user-defined options
811         if (!options.empty()) {
812                 clsoptions << options << ',';
813         }
814
815         string strOptions(clsoptions.str());
816         if (!strOptions.empty()) {
817                 strOptions = rtrim(strOptions, ",");
818                 // FIXME UNICODE
819                 os << '[' << from_utf8(strOptions) << ']';
820         }
821
822         os << '{' << from_ascii(tclass.latexname()) << "}\n";
823         texrow.newline();
824         // end of \documentclass defs
825
826         // font selection must be done before loading fontenc.sty
827         string const fonts =
828                 loadFonts(features, fontsRoman, fontsSans,
829                           fontsTypewriter, fontsSC, fontsOSF,
830                           fontsSansScale, fontsTypewriterScale);
831         if (!fonts.empty()) {
832                 os << from_ascii(fonts);
833                 texrow.newline();
834         }
835         if (fontsDefaultFamily != "default")
836                 os << "\\renewcommand{\\familydefault}{\\"
837                    << from_ascii(fontsDefaultFamily) << "}\n";
838         // this one is not per buffer
839         if (lyxrc.fontenc != "default") {
840                 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
841                    << "]{fontenc}\n";
842                 texrow.newline();
843         }
844
845         if (inputenc == "auto") {
846                 string const doc_encoding =
847                         language->encoding()->latexName();
848
849                 // Create a list with all the input encodings used
850                 // in the document
851                 std::set<string> encodings =
852                         features.getEncodingSet(doc_encoding);
853
854                 os << "\\usepackage[";
855                 std::set<string>::const_iterator it = encodings.begin();
856                 std::set<string>::const_iterator const end = encodings.end();
857                 for (; it != end; ++it)
858                         os << from_ascii(*it) << ',';
859                 os << from_ascii(doc_encoding) << "]{inputenc}\n";
860                 texrow.newline();
861         } else if (inputenc != "default") {
862                 os << "\\usepackage[" << from_ascii(inputenc)
863                    << "]{inputenc}\n";
864                 texrow.newline();
865         }
866
867         if (use_geometry || nonstandard_papersize) {
868                 os << "\\usepackage{geometry}\n";
869                 texrow.newline();
870                 os << "\\geometry{verbose";
871                 if (orientation == ORIENTATION_LANDSCAPE)
872                         os << ",landscape";
873                 switch (papersize) {
874                 case PAPER_CUSTOM:
875                         if (!paperwidth.empty())
876                                 os << ",paperwidth="
877                                    << from_ascii(paperwidth);
878                         if (!paperheight.empty())
879                                 os << ",paperheight="
880                                    << from_ascii(paperheight);
881                         break;
882                 case PAPER_USLETTER:
883                         os << ",letterpaper";
884                         break;
885                 case PAPER_USLEGAL:
886                         os << ",legalpaper";
887                         break;
888                 case PAPER_USEXECUTIVE:
889                         os << ",executivepaper";
890                         break;
891                 case PAPER_A3:
892                         os << ",a3paper";
893                         break;
894                 case PAPER_A4:
895                         os << ",a4paper";
896                         break;
897                 case PAPER_A5:
898                         os << ",a5paper";
899                         break;
900                 case PAPER_B3:
901                         os << ",b3paper";
902                         break;
903                 case PAPER_B4:
904                         os << ",b4paper";
905                         break;
906                 case PAPER_B5:
907                         os << ",b5paper";
908                         break;
909                 default:
910                         // default papersize ie PAPER_DEFAULT
911                         switch (lyxrc.default_papersize) {
912                         case PAPER_DEFAULT: // keep compiler happy
913                         case PAPER_USLETTER:
914                                 os << ",letterpaper";
915                                 break;
916                         case PAPER_USLEGAL:
917                                 os << ",legalpaper";
918                                 break;
919                         case PAPER_USEXECUTIVE:
920                                 os << ",executivepaper";
921                                 break;
922                         case PAPER_A3:
923                                 os << ",a3paper";
924                                 break;
925                         case PAPER_A4:
926                                 os << ",a4paper";
927                                 break;
928                         case PAPER_A5:
929                                 os << ",a5paper";
930                                 break;
931                         case PAPER_B5:
932                                 os << ",b5paper";
933                                 break;
934                         case PAPER_B3:
935                         case PAPER_B4:
936                         case PAPER_CUSTOM:
937                                 break;
938                         }
939                 }
940                 if (!topmargin.empty())
941                         os << ",tmargin=" << from_ascii(topmargin);
942                 if (!bottommargin.empty())
943                         os << ",bmargin=" << from_ascii(bottommargin);
944                 if (!leftmargin.empty())
945                         os << ",lmargin=" << from_ascii(leftmargin);
946                 if (!rightmargin.empty())
947                         os << ",rmargin=" << from_ascii(rightmargin);
948                 if (!headheight.empty())
949                         os << ",headheight=" << from_ascii(headheight);
950                 if (!headsep.empty())
951                         os << ",headsep=" << from_ascii(headsep);
952                 if (!footskip.empty())
953                         os << ",footskip=" << from_ascii(footskip);
954                 os << "}\n";
955                 texrow.newline();
956         }
957
958         if (tokenPos(tclass.opt_pagestyle(),
959                      '|', pagestyle) >= 0) {
960                 if (pagestyle == "fancy") {
961                         os << "\\usepackage{fancyhdr}\n";
962                         texrow.newline();
963                 }
964                 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
965                 texrow.newline();
966         }
967
968         // Only if class has a ToC hierarchy
969         if (tclass.hasTocLevels()) {
970                 if (secnumdepth != tclass.secnumdepth()) {
971                         os << "\\setcounter{secnumdepth}{"
972                            << secnumdepth
973                            << "}\n";
974                         texrow.newline();
975                 }
976                 if (tocdepth != tclass.tocdepth()) {
977                         os << "\\setcounter{tocdepth}{"
978                            << tocdepth
979                            << "}\n";
980                         texrow.newline();
981                 }
982         }
983
984         if (paragraph_separation) {
985                 switch (getDefSkip().kind()) {
986                 case VSpace::SMALLSKIP:
987                         os << "\\setlength\\parskip{\\smallskipamount}\n";
988                         break;
989                 case VSpace::MEDSKIP:
990                         os << "\\setlength\\parskip{\\medskipamount}\n";
991                         break;
992                 case VSpace::BIGSKIP:
993                         os << "\\setlength\\parskip{\\bigskipamount}\n";
994                         break;
995                 case VSpace::LENGTH:
996                         os << "\\setlength\\parskip{"
997                            << from_utf8(getDefSkip().length().asLatexString())
998                            << "}\n";
999                         break;
1000                 default: // should never happen // Then delete it.
1001                         os << "\\setlength\\parskip{\\medskipamount}\n";
1002                         break;
1003                 }
1004                 texrow.newline();
1005
1006                 os << "\\setlength\\parindent{0pt}\n";
1007                 texrow.newline();
1008         }
1009
1010         // If we use jurabib, we have to call babel here.
1011         if (use_babel && features.isRequired("jurabib")) {
1012                 os << from_ascii(babelCall(language_options.str()))
1013                    << '\n'
1014                    << from_ascii(features.getBabelOptions());
1015                 texrow.newline();
1016         }
1017
1018         // Now insert the LyX specific LaTeX commands...
1019
1020         // The optional packages;
1021         docstring lyxpreamble(from_ascii(features.getPackages()));
1022
1023         // this might be useful...
1024         lyxpreamble += "\n\\makeatletter\n";
1025
1026         // Some macros LyX will need
1027         docstring tmppreamble(from_ascii(features.getMacros()));
1028
1029         if (!tmppreamble.empty()) {
1030                 lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1031                         "LyX specific LaTeX commands.\n"
1032                         + tmppreamble + '\n';
1033         }
1034
1035         // the text class specific preamble
1036         tmppreamble = features.getTClassPreamble();
1037         if (!tmppreamble.empty()) {
1038                 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1039                         "Textclass specific LaTeX commands.\n"
1040                         + tmppreamble + '\n';
1041         }
1042
1043         /* the user-defined preamble */
1044         if (!preamble.empty()) {
1045                 // FIXME UNICODE
1046                 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1047                         "User specified LaTeX commands.\n"
1048                         + from_utf8(preamble) + '\n';
1049         }
1050
1051         // Itemize bullet settings need to be last in case the user
1052         // defines their own bullets that use a package included
1053         // in the user-defined preamble -- ARRae
1054         // Actually it has to be done much later than that
1055         // since some packages like frenchb make modifications
1056         // at \begin{document} time -- JMarc
1057         docstring bullets_def;
1058         for (int i = 0; i < 4; ++i) {
1059                 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1060                         if (bullets_def.empty())
1061                                 bullets_def += "\\AtBeginDocument{\n";
1062                         bullets_def += "  \\def\\labelitemi";
1063                         switch (i) {
1064                                 // `i' is one less than the item to modify
1065                         case 0:
1066                                 break;
1067                         case 1:
1068                                 bullets_def += 'i';
1069                                 break;
1070                         case 2:
1071                                 bullets_def += "ii";
1072                                 break;
1073                         case 3:
1074                                 bullets_def += 'v';
1075                                 break;
1076                         }
1077                         bullets_def += '{' +
1078                                 user_defined_bullet(i).getText()
1079                                 + "}\n";
1080                 }
1081         }
1082
1083         if (!bullets_def.empty())
1084                 lyxpreamble += bullets_def + "}\n\n";
1085
1086         // We try to load babel late, in case it interferes
1087         // with other packages.
1088         // Jurabib has to be called after babel, though.
1089         if (use_babel && !features.isRequired("jurabib")) {
1090                 // FIXME UNICODE
1091                 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1092                 lyxpreamble += from_utf8(features.getBabelOptions());
1093         }
1094
1095         lyxpreamble += "\\makeatother\n";
1096
1097         // dvipost settings come after everything else
1098         if (features.isAvailable("dvipost") && outputChanges) {
1099                 lyxpreamble +=
1100                         "\\dvipostlayout\n"
1101                         "\\dvipost{osstart color push Red}\n"
1102                         "\\dvipost{osend color pop}\n"
1103                         "\\dvipost{cbstart color push Blue}\n"
1104                         "\\dvipost{cbend color pop}\n";
1105         }
1106
1107         int const nlines =
1108                 int(lyx::count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1109         for (int j = 0; j != nlines; ++j) {
1110                 texrow.newline();
1111         }
1112
1113         os << lyxpreamble;
1114         return use_babel;
1115 }
1116
1117
1118 void BufferParams::useClassDefaults()
1119 {
1120         LyXTextClass const & tclass = textclasslist[textclass];
1121
1122         sides = tclass.sides();
1123         columns = tclass.columns();
1124         pagestyle = tclass.pagestyle();
1125         options = tclass.options();
1126         // Only if class has a ToC hierarchy
1127         if (tclass.hasTocLevels()) {
1128                 secnumdepth = tclass.secnumdepth();
1129                 tocdepth = tclass.tocdepth();
1130         }
1131 }
1132
1133
1134 bool BufferParams::hasClassDefaults() const
1135 {
1136         LyXTextClass const & tclass = textclasslist[textclass];
1137
1138         return (sides == tclass.sides()
1139                 && columns == tclass.columns()
1140                 && pagestyle == tclass.pagestyle()
1141                 && options == tclass.options()
1142                 && secnumdepth == tclass.secnumdepth()
1143                 && tocdepth == tclass.tocdepth());
1144 }
1145
1146
1147 LyXTextClass const & BufferParams::getLyXTextClass() const
1148 {
1149         return textclasslist[textclass];
1150 }
1151
1152
1153 LyXFont const BufferParams::getFont() const
1154 {
1155         LyXFont f = getLyXTextClass().defaultfont();
1156         f.setLanguage(language);
1157         if (fontsDefaultFamily == "rmdefault")
1158                 f.setFamily(LyXFont::ROMAN_FAMILY);
1159         else if (fontsDefaultFamily == "sfdefault")
1160                 f.setFamily(LyXFont::SANS_FAMILY);
1161         else if (fontsDefaultFamily == "ttdefault")
1162                 f.setFamily(LyXFont::TYPEWRITER_FAMILY);
1163         return f;
1164 }
1165
1166
1167 void BufferParams::readPreamble(LyXLex & lex)
1168 {
1169         if (lex.getString() != "\\begin_preamble")
1170                 lyxerr << "Error (BufferParams::readPreamble):"
1171                         "consistency check failed." << endl;
1172
1173         preamble = lex.getLongString("\\end_preamble");
1174 }
1175
1176
1177 void BufferParams::readLanguage(LyXLex & lex)
1178 {
1179         if (!lex.next()) return;
1180
1181         string const tmptok = lex.getString();
1182
1183         // check if tmptok is part of tex_babel in tex-defs.h
1184         language = languages.getLanguage(tmptok);
1185         if (!language) {
1186                 // Language tmptok was not found
1187                 language = default_language;
1188                 lyxerr << "Warning: Setting language `"
1189                        << tmptok << "' to `" << language->lang()
1190                        << "'." << endl;
1191         }
1192 }
1193
1194
1195 void BufferParams::readGraphicsDriver(LyXLex & lex)
1196 {
1197         if (!lex.next()) return;
1198
1199         string const tmptok = lex.getString();
1200         // check if tmptok is part of tex_graphics in tex_defs.h
1201         int n = 0;
1202         while (true) {
1203                 string const test = tex_graphics[n++];
1204
1205                 if (test == tmptok) {
1206                         graphicsDriver = tmptok;
1207                         break;
1208                 } else if (test == "") {
1209                         lex.printError(
1210                                 "Warning: graphics driver `$$Token' not recognized!\n"
1211                                 "         Setting graphics driver to `default'.\n");
1212                         graphicsDriver = "default";
1213                         break;
1214                 }
1215         }
1216 }
1217
1218
1219 void BufferParams::readBullets(LyXLex & lex)
1220 {
1221         if (!lex.next()) return;
1222
1223         int const index = lex.getInteger();
1224         lex.next();
1225         int temp_int = lex.getInteger();
1226         user_defined_bullet(index).setFont(temp_int);
1227         temp_bullet(index).setFont(temp_int);
1228         lex >> temp_int;
1229         user_defined_bullet(index).setCharacter(temp_int);
1230         temp_bullet(index).setCharacter(temp_int);
1231         lex >> temp_int;
1232         user_defined_bullet(index).setSize(temp_int);
1233         temp_bullet(index).setSize(temp_int);
1234 }
1235
1236
1237 void BufferParams::readBulletsLaTeX(LyXLex & lex)
1238 {
1239         // The bullet class should be able to read this.
1240         if (!lex.next()) return;
1241         int const index = lex.getInteger();
1242         lex.next(true);
1243         docstring const temp_str = lex.getDocString();
1244
1245         user_defined_bullet(index).setText(temp_str);
1246         temp_bullet(index).setText(temp_str);
1247 }
1248
1249
1250 string const BufferParams::paperSizeName() const
1251 {
1252         char real_papersize = papersize;
1253         if (real_papersize == PAPER_DEFAULT)
1254                 real_papersize = lyxrc.default_papersize;
1255
1256         switch (real_papersize) {
1257         case PAPER_A3:
1258                 return "a3";
1259         case PAPER_A4:
1260                 return "a4";
1261         case PAPER_A5:
1262                 return "a5";
1263         case PAPER_B5:
1264                 return "b5";
1265         case PAPER_USEXECUTIVE:
1266                 return "foolscap";
1267         case PAPER_USLEGAL:
1268                 return "legal";
1269         case PAPER_USLETTER:
1270         default:
1271                 return "letter";
1272         }
1273 }
1274
1275
1276 string const BufferParams::dvips_options() const
1277 {
1278         string result;
1279
1280         if (use_geometry
1281             && papersize == PAPER_CUSTOM
1282             && !lyxrc.print_paper_dimension_flag.empty()
1283             && !paperwidth.empty()
1284             && !paperheight.empty()) {
1285                 // using a custom papersize
1286                 result = lyxrc.print_paper_dimension_flag;
1287                 result += ' ' + paperwidth;
1288                 result += ',' + paperheight;
1289         } else {
1290                 string const paper_option = paperSizeName();
1291                 if (paper_option != "letter" ||
1292                     orientation != ORIENTATION_LANDSCAPE) {
1293                         // dvips won't accept -t letter -t landscape.
1294                         // In all other cases, include the paper size
1295                         // explicitly.
1296                         result = lyxrc.print_paper_flag;
1297                         result += ' ' + paper_option;
1298                 }
1299         }
1300         if (orientation == ORIENTATION_LANDSCAPE &&
1301             papersize != PAPER_CUSTOM)
1302                 result += ' ' + lyxrc.print_landscape_flag;
1303         return result;
1304 }
1305
1306
1307 string const BufferParams::babelCall(string const & lang_opts) const
1308 {
1309         string tmp = lyxrc.language_package;
1310         if (!lyxrc.language_global_options && tmp == "\\usepackage{babel}")
1311                 tmp = string("\\usepackage[") + lang_opts + "]{babel}";
1312         return tmp;
1313 }
1314
1315
1316 string const BufferParams::loadFonts(LaTeXFeatures & features, string const & rm,
1317                                      string const & sf, string const & tt,
1318                                      bool const & sc, bool const & osf,
1319                                      int const & sfscale, int const & ttscale) const
1320 {
1321         /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1322            several packages have been replaced by others, that might not
1323            be installed on every system. We have to take care for that
1324            (see psnfss.pdf). We try to support all psnfss fonts as well
1325            as the fonts that have become de facto standard in the LaTeX
1326            world (e.g. Latin Modern). We do not support obsolete fonts
1327            (like PSLatex). In general, it should be possible to mix any
1328            rm font with any sf or tt font, respectively. (JSpitzm)
1329            TODO:
1330                 -- separate math fonts.
1331         */
1332
1333         if (rm == "default" && sf == "default" && tt == "default")
1334                 //nothing to do
1335                 return string();
1336
1337         ostringstream os;
1338
1339         // ROMAN FONTS
1340         // Computer Modern (must be explicitely selectable -- there might be classes
1341         // that define a different default font!
1342         if (rm == "cmr") {
1343                 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1344                 // osf for Computer Modern needs eco.sty
1345                 if (osf)
1346                         os << "\\usepackage{eco}\n";
1347         }
1348         // Latin Modern Roman
1349         else if (rm == "lmodern")
1350                 os << "\\usepackage{lmodern}\n";
1351         // AE
1352         else if (rm == "ae") {
1353                 // not needed when using OT1 font encoding.
1354                 if (lyxrc.fontenc != "default")
1355                         os << "\\usepackage{ae,aecompl}\n";
1356         }
1357         // Times
1358         else if (rm == "times") {
1359                 // try to load the best available package
1360                 if (features.isAvailable("mathptmx"))
1361                         os << "\\usepackage{mathptmx}\n";
1362                 else if (features.isAvailable("mathptm"))
1363                         os << "\\usepackage{mathptm}\n";
1364                 else
1365                         os << "\\usepackage{times}\n";
1366         }
1367         // Palatino
1368         else if (rm == "palatino") {
1369                 // try to load the best available package
1370                 if (features.isAvailable("mathpazo")) {
1371                         os << "\\usepackage";
1372                         if (osf || sc) {
1373                                 os << '[';
1374                                 if (!osf)
1375                                         os << "sc";
1376                                 else
1377                                         // "osf" includes "sc"!
1378                                         os << "osf";
1379                                 os << ']';
1380                         }
1381                         os << "{mathpazo}\n";
1382                 }
1383                 else if (features.isAvailable("mathpple"))
1384                         os << "\\usepackage{mathpple}\n";
1385                 else
1386                         os << "\\usepackage{palatino}\n";
1387         }
1388         // Utopia
1389         else if (rm == "utopia") {
1390                 // fourier supersedes utopia.sty, but does
1391                 // not work with OT1 encoding.
1392                 if (features.isAvailable("fourier")
1393                     && lyxrc.fontenc != "default") {
1394                         os << "\\usepackage";
1395                         if (osf || sc) {
1396                                 os << '[';
1397                                 if (sc)
1398                                         os << "expert";
1399                                 if (osf && sc)
1400                                         os << ',';
1401                                 if (osf)
1402                                         os << "oldstyle";
1403                                 os << ']';
1404                         }
1405                         os << "{fourier}\n";
1406                 }
1407                 else
1408                         os << "\\usepackage{utopia}\n";
1409         }
1410         // Bera (complete fontset)
1411         else if (rm == "bera" && sf == "default" && tt == "default")
1412                 os << "\\usepackage{bera}\n";
1413         // everything else
1414         else if (rm != "default")
1415                 os << "\\usepackage" << "{" << rm << "}\n";
1416
1417         // SANS SERIF
1418         // Helvetica, Bera Sans
1419         if (sf == "helvet" || sf == "berasans") {
1420                 if (sfscale != 100)
1421                         os << "\\usepackage[scaled=" << float(sfscale) / 100
1422                            << "]{" << sf << "}\n";
1423                 else
1424                         os << "\\usepackage{" << sf << "}\n";
1425         }
1426         // Avant Garde
1427         else if (sf == "avant")
1428                 os << "\\usepackage{" << sf << "}\n";
1429         // Computer Modern, Latin Modern, CM Bright
1430         else if (sf != "default")
1431                 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1432
1433         // monospaced/typewriter
1434         // Courier, LuxiMono
1435         if (tt == "luximono" || tt == "beramono") {
1436                 if (ttscale != 100)
1437                         os << "\\usepackage[scaled=" << float(ttscale) / 100
1438                            << "]{" << tt << "}\n";
1439                 else
1440                         os << "\\usepackage{" << tt << "}\n";
1441         }
1442         // Courier
1443         else if (tt == "courier" )
1444                 os << "\\usepackage{" << tt << "}\n";
1445         // Computer Modern, Latin Modern, CM Bright
1446         else if  (tt != "default")
1447                 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1448
1449         return os.str();
1450 }
1451
1452
1453 Encoding const & BufferParams::encoding() const
1454 {
1455         if (inputenc == "auto")
1456                 return *(language->encoding());
1457         Encoding const * const enc = encodings.getFromLaTeXName(inputenc);
1458         if (enc)
1459                 return *enc;
1460         lyxerr << "Unknown inputenc value `" << inputenc
1461                << "'. Using `auto' instead." << endl;
1462         return *(language->encoding());
1463 }
1464
1465 } // namespace lyx