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