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