]> git.lyx.org Git - lyx.git/blob - src/bufferparams.C
Change lyx2lyx conversion and LaTeX export of documents with
[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                 // thailatex does not use the inputenc package, but sets up
855                 // babel directly for tis620-0 encoding, therefore we must
856                 // not request inputenc for tis620-0 encoding
857                 if (!encodings.empty() || doc_encoding != "tis620-0") {
858                         os << "\\usepackage[";
859                         std::set<string>::const_iterator it = encodings.begin();
860                         std::set<string>::const_iterator const end = encodings.end();
861                         if (it != end) {
862                                 os << from_ascii(*it);
863                                 ++it;
864                         }
865                         for (; it != end; ++it)
866                                 os << ',' << from_ascii(*it);
867                         if (doc_encoding != "tis620-0") {
868                                 if (!encodings.empty())
869                                         os << ',';
870                                 os << from_ascii(doc_encoding);
871                         }
872                         os << "]{inputenc}\n";
873                         texrow.newline();
874                 }
875         } else if (inputenc != "default" && inputenc != "tis620-0") {
876                 os << "\\usepackage[" << from_ascii(inputenc)
877                    << "]{inputenc}\n";
878                 texrow.newline();
879         }
880
881         if (use_geometry || nonstandard_papersize) {
882                 os << "\\usepackage{geometry}\n";
883                 texrow.newline();
884                 os << "\\geometry{verbose";
885                 if (orientation == ORIENTATION_LANDSCAPE)
886                         os << ",landscape";
887                 switch (papersize) {
888                 case PAPER_CUSTOM:
889                         if (!paperwidth.empty())
890                                 os << ",paperwidth="
891                                    << from_ascii(paperwidth);
892                         if (!paperheight.empty())
893                                 os << ",paperheight="
894                                    << from_ascii(paperheight);
895                         break;
896                 case PAPER_USLETTER:
897                         os << ",letterpaper";
898                         break;
899                 case PAPER_USLEGAL:
900                         os << ",legalpaper";
901                         break;
902                 case PAPER_USEXECUTIVE:
903                         os << ",executivepaper";
904                         break;
905                 case PAPER_A3:
906                         os << ",a3paper";
907                         break;
908                 case PAPER_A4:
909                         os << ",a4paper";
910                         break;
911                 case PAPER_A5:
912                         os << ",a5paper";
913                         break;
914                 case PAPER_B3:
915                         os << ",b3paper";
916                         break;
917                 case PAPER_B4:
918                         os << ",b4paper";
919                         break;
920                 case PAPER_B5:
921                         os << ",b5paper";
922                         break;
923                 default:
924                         // default papersize ie PAPER_DEFAULT
925                         switch (lyxrc.default_papersize) {
926                         case PAPER_DEFAULT: // keep compiler happy
927                         case PAPER_USLETTER:
928                                 os << ",letterpaper";
929                                 break;
930                         case PAPER_USLEGAL:
931                                 os << ",legalpaper";
932                                 break;
933                         case PAPER_USEXECUTIVE:
934                                 os << ",executivepaper";
935                                 break;
936                         case PAPER_A3:
937                                 os << ",a3paper";
938                                 break;
939                         case PAPER_A4:
940                                 os << ",a4paper";
941                                 break;
942                         case PAPER_A5:
943                                 os << ",a5paper";
944                                 break;
945                         case PAPER_B5:
946                                 os << ",b5paper";
947                                 break;
948                         case PAPER_B3:
949                         case PAPER_B4:
950                         case PAPER_CUSTOM:
951                                 break;
952                         }
953                 }
954                 if (!topmargin.empty())
955                         os << ",tmargin=" << from_ascii(topmargin);
956                 if (!bottommargin.empty())
957                         os << ",bmargin=" << from_ascii(bottommargin);
958                 if (!leftmargin.empty())
959                         os << ",lmargin=" << from_ascii(leftmargin);
960                 if (!rightmargin.empty())
961                         os << ",rmargin=" << from_ascii(rightmargin);
962                 if (!headheight.empty())
963                         os << ",headheight=" << from_ascii(headheight);
964                 if (!headsep.empty())
965                         os << ",headsep=" << from_ascii(headsep);
966                 if (!footskip.empty())
967                         os << ",footskip=" << from_ascii(footskip);
968                 os << "}\n";
969                 texrow.newline();
970         }
971
972         if (tokenPos(tclass.opt_pagestyle(),
973                      '|', pagestyle) >= 0) {
974                 if (pagestyle == "fancy") {
975                         os << "\\usepackage{fancyhdr}\n";
976                         texrow.newline();
977                 }
978                 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
979                 texrow.newline();
980         }
981
982         // Only if class has a ToC hierarchy
983         if (tclass.hasTocLevels()) {
984                 if (secnumdepth != tclass.secnumdepth()) {
985                         os << "\\setcounter{secnumdepth}{"
986                            << secnumdepth
987                            << "}\n";
988                         texrow.newline();
989                 }
990                 if (tocdepth != tclass.tocdepth()) {
991                         os << "\\setcounter{tocdepth}{"
992                            << tocdepth
993                            << "}\n";
994                         texrow.newline();
995                 }
996         }
997
998         if (paragraph_separation) {
999                 switch (getDefSkip().kind()) {
1000                 case VSpace::SMALLSKIP:
1001                         os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1002                         break;
1003                 case VSpace::MEDSKIP:
1004                         os << "\\setlength{\\parskip}{\\medskipamount}\n";
1005                         break;
1006                 case VSpace::BIGSKIP:
1007                         os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1008                         break;
1009                 case VSpace::LENGTH:
1010                         os << "\\setlength{\\parskip}{"
1011                            << from_utf8(getDefSkip().length().asLatexString())
1012                            << "}\n";
1013                         break;
1014                 default: // should never happen // Then delete it.
1015                         os << "\\setlength{\\parskip}{\\medskipamount}\n";
1016                         break;
1017                 }
1018                 texrow.newline();
1019
1020                 os << "\\setlength{\\parindent}{0pt}\n";
1021                 texrow.newline();
1022         }
1023
1024         // If we use jurabib, we have to call babel here.
1025         if (use_babel && features.isRequired("jurabib")) {
1026                 os << from_ascii(babelCall(language_options.str()))
1027                    << '\n'
1028                    << from_ascii(features.getBabelOptions());
1029                 texrow.newline();
1030         }
1031
1032         // Now insert the LyX specific LaTeX commands...
1033
1034         // The optional packages;
1035         docstring lyxpreamble(from_ascii(features.getPackages()));
1036
1037         // this might be useful...
1038         lyxpreamble += "\n\\makeatletter\n";
1039
1040         // Some macros LyX will need
1041         docstring tmppreamble(from_ascii(features.getMacros()));
1042
1043         if (!tmppreamble.empty()) {
1044                 lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1045                         "LyX specific LaTeX commands.\n"
1046                         + tmppreamble + '\n';
1047         }
1048
1049         // the text class specific preamble
1050         tmppreamble = features.getTClassPreamble();
1051         if (!tmppreamble.empty()) {
1052                 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1053                         "Textclass specific LaTeX commands.\n"
1054                         + tmppreamble + '\n';
1055         }
1056
1057         /* the user-defined preamble */
1058         if (!preamble.empty()) {
1059                 // FIXME UNICODE
1060                 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1061                         "User specified LaTeX commands.\n"
1062                         + from_utf8(preamble) + '\n';
1063         }
1064
1065         // Itemize bullet settings need to be last in case the user
1066         // defines their own bullets that use a package included
1067         // in the user-defined preamble -- ARRae
1068         // Actually it has to be done much later than that
1069         // since some packages like frenchb make modifications
1070         // at \begin{document} time -- JMarc
1071         docstring bullets_def;
1072         for (int i = 0; i < 4; ++i) {
1073                 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1074                         if (bullets_def.empty())
1075                                 bullets_def += "\\AtBeginDocument{\n";
1076                         bullets_def += "  \\def\\labelitemi";
1077                         switch (i) {
1078                                 // `i' is one less than the item to modify
1079                         case 0:
1080                                 break;
1081                         case 1:
1082                                 bullets_def += 'i';
1083                                 break;
1084                         case 2:
1085                                 bullets_def += "ii";
1086                                 break;
1087                         case 3:
1088                                 bullets_def += 'v';
1089                                 break;
1090                         }
1091                         bullets_def += '{' +
1092                                 user_defined_bullet(i).getText()
1093                                 + "}\n";
1094                 }
1095         }
1096
1097         if (!bullets_def.empty())
1098                 lyxpreamble += bullets_def + "}\n\n";
1099
1100         // We try to load babel late, in case it interferes
1101         // with other packages.
1102         // Jurabib has to be called after babel, though.
1103         if (use_babel && !features.isRequired("jurabib")) {
1104                 // FIXME UNICODE
1105                 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1106                 lyxpreamble += from_utf8(features.getBabelOptions());
1107         }
1108
1109         lyxpreamble += "\\makeatother\n";
1110
1111         // dvipost settings come after everything else
1112         if (features.isAvailable("dvipost") && outputChanges) {
1113                 lyxpreamble +=
1114                         "\\dvipostlayout\n"
1115                         "\\dvipost{osstart color push Red}\n"
1116                         "\\dvipost{osend color pop}\n"
1117                         "\\dvipost{cbstart color push Blue}\n"
1118                         "\\dvipost{cbend color pop}\n";
1119         }
1120
1121         int const nlines =
1122                 int(lyx::count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1123         for (int j = 0; j != nlines; ++j) {
1124                 texrow.newline();
1125         }
1126
1127         os << lyxpreamble;
1128         return use_babel;
1129 }
1130
1131
1132 void BufferParams::useClassDefaults()
1133 {
1134         LyXTextClass const & tclass = textclasslist[textclass];
1135
1136         sides = tclass.sides();
1137         columns = tclass.columns();
1138         pagestyle = tclass.pagestyle();
1139         options = tclass.options();
1140         // Only if class has a ToC hierarchy
1141         if (tclass.hasTocLevels()) {
1142                 secnumdepth = tclass.secnumdepth();
1143                 tocdepth = tclass.tocdepth();
1144         }
1145 }
1146
1147
1148 bool BufferParams::hasClassDefaults() const
1149 {
1150         LyXTextClass const & tclass = textclasslist[textclass];
1151
1152         return (sides == tclass.sides()
1153                 && columns == tclass.columns()
1154                 && pagestyle == tclass.pagestyle()
1155                 && options == tclass.options()
1156                 && secnumdepth == tclass.secnumdepth()
1157                 && tocdepth == tclass.tocdepth());
1158 }
1159
1160
1161 LyXTextClass const & BufferParams::getLyXTextClass() const
1162 {
1163         return textclasslist[textclass];
1164 }
1165
1166
1167 LyXFont const BufferParams::getFont() const
1168 {
1169         LyXFont f = getLyXTextClass().defaultfont();
1170         f.setLanguage(language);
1171         if (fontsDefaultFamily == "rmdefault")
1172                 f.setFamily(LyXFont::ROMAN_FAMILY);
1173         else if (fontsDefaultFamily == "sfdefault")
1174                 f.setFamily(LyXFont::SANS_FAMILY);
1175         else if (fontsDefaultFamily == "ttdefault")
1176                 f.setFamily(LyXFont::TYPEWRITER_FAMILY);
1177         return f;
1178 }
1179
1180
1181 void BufferParams::readPreamble(LyXLex & lex)
1182 {
1183         if (lex.getString() != "\\begin_preamble")
1184                 lyxerr << "Error (BufferParams::readPreamble):"
1185                         "consistency check failed." << endl;
1186
1187         preamble = lex.getLongString("\\end_preamble");
1188 }
1189
1190
1191 void BufferParams::readLanguage(LyXLex & lex)
1192 {
1193         if (!lex.next()) return;
1194
1195         string const tmptok = lex.getString();
1196
1197         // check if tmptok is part of tex_babel in tex-defs.h
1198         language = languages.getLanguage(tmptok);
1199         if (!language) {
1200                 // Language tmptok was not found
1201                 language = default_language;
1202                 lyxerr << "Warning: Setting language `"
1203                        << tmptok << "' to `" << language->lang()
1204                        << "'." << endl;
1205         }
1206 }
1207
1208
1209 void BufferParams::readGraphicsDriver(LyXLex & lex)
1210 {
1211         if (!lex.next()) return;
1212
1213         string const tmptok = lex.getString();
1214         // check if tmptok is part of tex_graphics in tex_defs.h
1215         int n = 0;
1216         while (true) {
1217                 string const test = tex_graphics[n++];
1218
1219                 if (test == tmptok) {
1220                         graphicsDriver = tmptok;
1221                         break;
1222                 } else if (test == "") {
1223                         lex.printError(
1224                                 "Warning: graphics driver `$$Token' not recognized!\n"
1225                                 "         Setting graphics driver to `default'.\n");
1226                         graphicsDriver = "default";
1227                         break;
1228                 }
1229         }
1230 }
1231
1232
1233 void BufferParams::readBullets(LyXLex & lex)
1234 {
1235         if (!lex.next()) return;
1236
1237         int const index = lex.getInteger();
1238         lex.next();
1239         int temp_int = lex.getInteger();
1240         user_defined_bullet(index).setFont(temp_int);
1241         temp_bullet(index).setFont(temp_int);
1242         lex >> temp_int;
1243         user_defined_bullet(index).setCharacter(temp_int);
1244         temp_bullet(index).setCharacter(temp_int);
1245         lex >> temp_int;
1246         user_defined_bullet(index).setSize(temp_int);
1247         temp_bullet(index).setSize(temp_int);
1248 }
1249
1250
1251 void BufferParams::readBulletsLaTeX(LyXLex & lex)
1252 {
1253         // The bullet class should be able to read this.
1254         if (!lex.next()) return;
1255         int const index = lex.getInteger();
1256         lex.next(true);
1257         docstring const temp_str = lex.getDocString();
1258
1259         user_defined_bullet(index).setText(temp_str);
1260         temp_bullet(index).setText(temp_str);
1261 }
1262
1263
1264 string const BufferParams::paperSizeName() const
1265 {
1266         char real_papersize = papersize;
1267         if (real_papersize == PAPER_DEFAULT)
1268                 real_papersize = lyxrc.default_papersize;
1269
1270         switch (real_papersize) {
1271         case PAPER_A3:
1272                 return "a3";
1273         case PAPER_A4:
1274                 return "a4";
1275         case PAPER_A5:
1276                 return "a5";
1277         case PAPER_B5:
1278                 return "b5";
1279         case PAPER_USEXECUTIVE:
1280                 return "foolscap";
1281         case PAPER_USLEGAL:
1282                 return "legal";
1283         case PAPER_USLETTER:
1284         default:
1285                 return "letter";
1286         }
1287 }
1288
1289
1290 string const BufferParams::dvips_options() const
1291 {
1292         string result;
1293
1294         if (use_geometry
1295             && papersize == PAPER_CUSTOM
1296             && !lyxrc.print_paper_dimension_flag.empty()
1297             && !paperwidth.empty()
1298             && !paperheight.empty()) {
1299                 // using a custom papersize
1300                 result = lyxrc.print_paper_dimension_flag;
1301                 result += ' ' + paperwidth;
1302                 result += ',' + paperheight;
1303         } else {
1304                 string const paper_option = paperSizeName();
1305                 if (paper_option != "letter" ||
1306                     orientation != ORIENTATION_LANDSCAPE) {
1307                         // dvips won't accept -t letter -t landscape.
1308                         // In all other cases, include the paper size
1309                         // explicitly.
1310                         result = lyxrc.print_paper_flag;
1311                         result += ' ' + paper_option;
1312                 }
1313         }
1314         if (orientation == ORIENTATION_LANDSCAPE &&
1315             papersize != PAPER_CUSTOM)
1316                 result += ' ' + lyxrc.print_landscape_flag;
1317         return result;
1318 }
1319
1320
1321 string const BufferParams::babelCall(string const & lang_opts) const
1322 {
1323         string tmp = lyxrc.language_package;
1324         if (!lyxrc.language_global_options && tmp == "\\usepackage{babel}")
1325                 tmp = string("\\usepackage[") + lang_opts + "]{babel}";
1326         return tmp;
1327 }
1328
1329
1330 string const BufferParams::loadFonts(LaTeXFeatures & features, string const & rm,
1331                                      string const & sf, string const & tt,
1332                                      bool const & sc, bool const & osf,
1333                                      int const & sfscale, int const & ttscale) const
1334 {
1335         /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1336            several packages have been replaced by others, that might not
1337            be installed on every system. We have to take care for that
1338            (see psnfss.pdf). We try to support all psnfss fonts as well
1339            as the fonts that have become de facto standard in the LaTeX
1340            world (e.g. Latin Modern). We do not support obsolete fonts
1341            (like PSLatex). In general, it should be possible to mix any
1342            rm font with any sf or tt font, respectively. (JSpitzm)
1343            TODO:
1344                 -- separate math fonts.
1345         */
1346
1347         if (rm == "default" && sf == "default" && tt == "default")
1348                 //nothing to do
1349                 return string();
1350
1351         ostringstream os;
1352
1353         // ROMAN FONTS
1354         // Computer Modern (must be explicitely selectable -- there might be classes
1355         // that define a different default font!
1356         if (rm == "cmr") {
1357                 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1358                 // osf for Computer Modern needs eco.sty
1359                 if (osf)
1360                         os << "\\usepackage{eco}\n";
1361         }
1362         // Latin Modern Roman
1363         else if (rm == "lmodern")
1364                 os << "\\usepackage{lmodern}\n";
1365         // AE
1366         else if (rm == "ae") {
1367                 // not needed when using OT1 font encoding.
1368                 if (lyxrc.fontenc != "default")
1369                         os << "\\usepackage{ae,aecompl}\n";
1370         }
1371         // Times
1372         else if (rm == "times") {
1373                 // try to load the best available package
1374                 if (features.isAvailable("mathptmx"))
1375                         os << "\\usepackage{mathptmx}\n";
1376                 else if (features.isAvailable("mathptm"))
1377                         os << "\\usepackage{mathptm}\n";
1378                 else
1379                         os << "\\usepackage{times}\n";
1380         }
1381         // Palatino
1382         else if (rm == "palatino") {
1383                 // try to load the best available package
1384                 if (features.isAvailable("mathpazo")) {
1385                         os << "\\usepackage";
1386                         if (osf || sc) {
1387                                 os << '[';
1388                                 if (!osf)
1389                                         os << "sc";
1390                                 else
1391                                         // "osf" includes "sc"!
1392                                         os << "osf";
1393                                 os << ']';
1394                         }
1395                         os << "{mathpazo}\n";
1396                 }
1397                 else if (features.isAvailable("mathpple"))
1398                         os << "\\usepackage{mathpple}\n";
1399                 else
1400                         os << "\\usepackage{palatino}\n";
1401         }
1402         // Utopia
1403         else if (rm == "utopia") {
1404                 // fourier supersedes utopia.sty, but does
1405                 // not work with OT1 encoding.
1406                 if (features.isAvailable("fourier")
1407                     && lyxrc.fontenc != "default") {
1408                         os << "\\usepackage";
1409                         if (osf || sc) {
1410                                 os << '[';
1411                                 if (sc)
1412                                         os << "expert";
1413                                 if (osf && sc)
1414                                         os << ',';
1415                                 if (osf)
1416                                         os << "oldstyle";
1417                                 os << ']';
1418                         }
1419                         os << "{fourier}\n";
1420                 }
1421                 else
1422                         os << "\\usepackage{utopia}\n";
1423         }
1424         // Bera (complete fontset)
1425         else if (rm == "bera" && sf == "default" && tt == "default")
1426                 os << "\\usepackage{bera}\n";
1427         // everything else
1428         else if (rm != "default")
1429                 os << "\\usepackage" << "{" << rm << "}\n";
1430
1431         // SANS SERIF
1432         // Helvetica, Bera Sans
1433         if (sf == "helvet" || sf == "berasans") {
1434                 if (sfscale != 100)
1435                         os << "\\usepackage[scaled=" << float(sfscale) / 100
1436                            << "]{" << sf << "}\n";
1437                 else
1438                         os << "\\usepackage{" << sf << "}\n";
1439         }
1440         // Avant Garde
1441         else if (sf == "avant")
1442                 os << "\\usepackage{" << sf << "}\n";
1443         // Computer Modern, Latin Modern, CM Bright
1444         else if (sf != "default")
1445                 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1446
1447         // monospaced/typewriter
1448         // Courier, LuxiMono
1449         if (tt == "luximono" || tt == "beramono") {
1450                 if (ttscale != 100)
1451                         os << "\\usepackage[scaled=" << float(ttscale) / 100
1452                            << "]{" << tt << "}\n";
1453                 else
1454                         os << "\\usepackage{" << tt << "}\n";
1455         }
1456         // Courier
1457         else if (tt == "courier" )
1458                 os << "\\usepackage{" << tt << "}\n";
1459         // Computer Modern, Latin Modern, CM Bright
1460         else if  (tt != "default")
1461                 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1462
1463         return os.str();
1464 }
1465
1466
1467 Encoding const & BufferParams::encoding() const
1468 {
1469         if (inputenc == "auto" || inputenc == "default")
1470                 return *(language->encoding());
1471         Encoding const * const enc =
1472                 encodings.getFromLaTeXName(inputenc);
1473         if (enc)
1474                 return *enc;
1475         lyxerr << "Unknown inputenc value `" << inputenc
1476                << "'. Using `auto' instead." << endl;
1477         return *(language->encoding());
1478 }
1479
1480 } // namespace lyx