2 * \file BufferParams.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Alfredo Braunstein
7 * \author Lars Gullik Bjønnes
8 * \author Jean-Marc Lasgouttes
10 * \author André Pönitz
11 * \author Martin Vermeer
13 * Full author contact details are available in file CREDITS.
18 #include "BufferParams.h"
21 #include "LayoutFile.h"
22 #include "BranchList.h"
23 #include "buffer_funcs.h"
28 #include "LaTeXFeatures.h"
29 #include "ModuleList.h"
33 #include "OutputParams.h"
37 #include "PDFOptions.h"
39 #include "frontends/alert.h"
41 #include "insets/InsetListingsParams.h"
43 #include "support/convert.h"
44 #include "support/debug.h"
45 #include "support/docstream.h"
46 #include "support/FileName.h"
47 #include "support/filetools.h"
48 #include "support/gettext.h"
49 #include "support/Messages.h"
50 #include "support/Translator.h"
51 #include "support/lstrings.h"
57 using namespace lyx::support;
60 static char const * const string_paragraph_separation[] = {
65 static char const * const string_quotes_language[] = {
66 "english", "swedish", "german", "polish", "french", "danish", ""
70 static char const * const string_papersize[] = {
71 "default", "custom", "letterpaper", "legalpaper", "executivepaper",
72 "a3paper", "a4paper", "a5paper", "b3paper", "b4paper", "b5paper", ""
76 static char const * const string_orientation[] = {
77 "portrait", "landscape", ""
81 static char const * const string_footnotekinds[] = {
82 "footnote", "margin", "fig", "tab", "alg", "wide-fig", "wide-tab", ""
86 static char const * const tex_graphics[] = {
87 "default", "dvips", "dvitops", "emtex",
88 "ln", "oztex", "textures", "none", ""
97 // Paragraph separation
98 typedef Translator<string, BufferParams::ParagraphSeparation> ParSepTranslator;
101 ParSepTranslator const init_parseptranslator()
103 ParSepTranslator translator
104 (string_paragraph_separation[0], BufferParams::ParagraphIndentSeparation);
105 translator.addPair(string_paragraph_separation[1], BufferParams::ParagraphSkipSeparation);
110 ParSepTranslator const & parseptranslator()
112 static ParSepTranslator translator = init_parseptranslator();
118 typedef Translator<string, InsetQuotes::QuoteLanguage> QuotesLangTranslator;
121 QuotesLangTranslator const init_quoteslangtranslator()
123 QuotesLangTranslator translator
124 (string_quotes_language[0], InsetQuotes::EnglishQuotes);
125 translator.addPair(string_quotes_language[1], InsetQuotes::SwedishQuotes);
126 translator.addPair(string_quotes_language[2], InsetQuotes::GermanQuotes);
127 translator.addPair(string_quotes_language[3], InsetQuotes::PolishQuotes);
128 translator.addPair(string_quotes_language[4], InsetQuotes::FrenchQuotes);
129 translator.addPair(string_quotes_language[5], InsetQuotes::DanishQuotes);
134 QuotesLangTranslator const & quoteslangtranslator()
136 static QuotesLangTranslator translator = init_quoteslangtranslator();
142 typedef Translator<string, PAPER_SIZE> PaperSizeTranslator;
145 static PaperSizeTranslator initPaperSizeTranslator()
147 PaperSizeTranslator translator(string_papersize[0], PAPER_DEFAULT);
148 translator.addPair(string_papersize[1], PAPER_CUSTOM);
149 translator.addPair(string_papersize[2], PAPER_USLETTER);
150 translator.addPair(string_papersize[3], PAPER_USLEGAL);
151 translator.addPair(string_papersize[4], PAPER_USEXECUTIVE);
152 translator.addPair(string_papersize[5], PAPER_A3);
153 translator.addPair(string_papersize[6], PAPER_A4);
154 translator.addPair(string_papersize[7], PAPER_A5);
155 translator.addPair(string_papersize[8], PAPER_B3);
156 translator.addPair(string_papersize[9], PAPER_B4);
157 translator.addPair(string_papersize[10], PAPER_B5);
162 PaperSizeTranslator const & papersizetranslator()
164 static PaperSizeTranslator translator = initPaperSizeTranslator();
170 typedef Translator<string, PAPER_ORIENTATION> PaperOrientationTranslator;
173 PaperOrientationTranslator const init_paperorientationtranslator()
175 PaperOrientationTranslator translator(string_orientation[0], ORIENTATION_PORTRAIT);
176 translator.addPair(string_orientation[1], ORIENTATION_LANDSCAPE);
181 PaperOrientationTranslator const & paperorientationtranslator()
183 static PaperOrientationTranslator translator = init_paperorientationtranslator();
189 typedef Translator<int, PageSides> SidesTranslator;
192 SidesTranslator const init_sidestranslator()
194 SidesTranslator translator(1, OneSide);
195 translator.addPair(2, TwoSides);
200 SidesTranslator const & sidestranslator()
202 static SidesTranslator translator = init_sidestranslator();
208 typedef Translator<int, BufferParams::Package> PackageTranslator;
211 PackageTranslator const init_packagetranslator()
213 PackageTranslator translator(0, BufferParams::package_off);
214 translator.addPair(1, BufferParams::package_auto);
215 translator.addPair(2, BufferParams::package_on);
220 PackageTranslator const & packagetranslator()
222 static PackageTranslator translator = init_packagetranslator();
228 typedef Translator<string, CiteEngine> CiteEngineTranslator;
231 CiteEngineTranslator const init_citeenginetranslator()
233 CiteEngineTranslator translator("basic", ENGINE_BASIC);
234 translator.addPair("natbib_numerical", ENGINE_NATBIB_NUMERICAL);
235 translator.addPair("natbib_authoryear", ENGINE_NATBIB_AUTHORYEAR);
236 translator.addPair("jurabib", ENGINE_JURABIB);
241 CiteEngineTranslator const & citeenginetranslator()
243 static CiteEngineTranslator translator = init_citeenginetranslator();
249 typedef Translator<string, Spacing::Space> SpaceTranslator;
252 SpaceTranslator const init_spacetranslator()
254 SpaceTranslator translator("default", Spacing::Default);
255 translator.addPair("single", Spacing::Single);
256 translator.addPair("onehalf", Spacing::Onehalf);
257 translator.addPair("double", Spacing::Double);
258 translator.addPair("other", Spacing::Other);
263 SpaceTranslator const & spacetranslator()
265 static SpaceTranslator translator = init_spacetranslator();
273 class BufferParams::Impl
278 AuthorList authorlist;
279 BranchList branchlist;
280 Bullet temp_bullets[4];
281 Bullet user_defined_bullets[4];
283 /** This is the amount of space used for paragraph_separation "skip",
284 * and for detached paragraphs in "indented" documents.
287 PDFOptions pdfoptions;
288 LayoutFileIndex baseClass_;
292 BufferParams::Impl::Impl()
293 : defskip(VSpace::MEDSKIP), baseClass_(string(""))
295 // set initial author
297 authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
302 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
306 return new BufferParams::Impl(*ptr);
310 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
316 BufferParams::BufferParams()
319 setBaseClass(defaultBaseclass());
321 paragraph_separation = ParagraphIndentSeparation;
322 quotes_language = InsetQuotes::EnglishQuotes;
323 fontsize = "default";
326 papersize = PAPER_DEFAULT;
327 orientation = ORIENTATION_PORTRAIT;
328 use_geometry = false;
329 use_amsmath = package_auto;
330 use_esint = package_auto;
331 cite_engine_ = ENGINE_BASIC;
332 use_bibtopic = false;
333 trackChanges = false;
334 outputChanges = false;
337 language = default_language;
338 fontsRoman = "default";
339 fontsSans = "default";
340 fontsTypewriter = "default";
341 fontsDefaultFamily = "default";
344 fontsSansScale = 100;
345 fontsTypewriterScale = 100;
347 graphicsDriver = "default";
350 listings_params = string();
351 pagestyle = "default";
353 for (int iter = 0; iter < 4; ++iter) {
354 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
355 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
360 docstring BufferParams::B_(string const & l10n) const
362 LASSERT(language, /**/);
363 return getMessages(language->code()).get(l10n);
367 AuthorList & BufferParams::authors()
369 return pimpl_->authorlist;
373 AuthorList const & BufferParams::authors() const
375 return pimpl_->authorlist;
379 BranchList & BufferParams::branchlist()
381 return pimpl_->branchlist;
385 BranchList const & BufferParams::branchlist() const
387 return pimpl_->branchlist;
391 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
393 LASSERT(index < 4, /**/);
394 return pimpl_->temp_bullets[index];
398 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
400 LASSERT(index < 4, /**/);
401 return pimpl_->temp_bullets[index];
405 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
407 LASSERT(index < 4, /**/);
408 return pimpl_->user_defined_bullets[index];
412 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
414 LASSERT(index < 4, /**/);
415 return pimpl_->user_defined_bullets[index];
419 Spacing & BufferParams::spacing()
421 return pimpl_->spacing;
425 Spacing const & BufferParams::spacing() const
427 return pimpl_->spacing;
431 PDFOptions & BufferParams::pdfoptions()
433 return pimpl_->pdfoptions;
437 PDFOptions const & BufferParams::pdfoptions() const
439 return pimpl_->pdfoptions;
443 VSpace const & BufferParams::getDefSkip() const
445 return pimpl_->defskip;
449 void BufferParams::setDefSkip(VSpace const & vs)
451 pimpl_->defskip = vs;
455 string BufferParams::readToken(Lexer & lex, string const & token,
456 FileName const & filepath)
458 if (token == "\\textclass") {
460 string const classname = lex.getString();
461 // if there exists a local layout file, ignore the system one
462 // NOTE: in this case, the textclass (.cls file) is assumed to be available.
464 LayoutFileList & bcl = LayoutFileList::get();
465 if (tcp.empty() && !filepath.empty())
466 tcp = bcl.addLayoutFile(classname, filepath.absFilename(), LayoutFileList::Local);
469 else if (bcl.haveClass(classname)) {
470 setBaseClass(classname);
472 // a warning will be given for unknown class
473 setBaseClass(defaultBaseclass());
476 // FIXME: this warning will be given even if there exists a local .cls
477 // file. Even worse, the .lyx file can not be compiled or exported
478 // because the textclass is marked as unavilable.
479 if (!baseClass()->isTeXClassAvailable()) {
480 docstring const msg =
481 bformat(_("The layout file requested by this document,\n"
483 "is not usable. This is probably because a LaTeX\n"
484 "class or style file required by it is not\n"
485 "available. See the Customization documentation\n"
486 "for more information.\n"), from_utf8(classname));
487 frontend::Alert::warning(_("Document class not available"),
488 msg + _("LyX will not be able to produce output."));
491 } else if (token == "\\begin_preamble") {
493 } else if (token == "\\begin_local_layout") {
494 readLocalLayout(lex);
495 } else if (token == "\\begin_modules") {
497 } else if (token == "\\options") {
499 options = lex.getString();
500 } else if (token == "\\master") {
502 master = lex.getString();
503 } else if (token == "\\language") {
505 } else if (token == "\\inputencoding") {
507 } else if (token == "\\graphics") {
508 readGraphicsDriver(lex);
509 } else if (token == "\\font_roman") {
511 } else if (token == "\\font_sans") {
513 } else if (token == "\\font_typewriter") {
514 lex >> fontsTypewriter;
515 } else if (token == "\\font_default_family") {
516 lex >> fontsDefaultFamily;
517 } else if (token == "\\font_sc") {
519 } else if (token == "\\font_osf") {
521 } else if (token == "\\font_sf_scale") {
522 lex >> fontsSansScale;
523 } else if (token == "\\font_tt_scale") {
524 lex >> fontsTypewriterScale;
525 } else if (token == "\\font_cjk") {
527 } else if (token == "\\paragraph_separation") {
530 paragraph_separation = parseptranslator().find(parsep);
531 } else if (token == "\\defskip") {
533 string defskip = lex.getString();
534 if (defskip == "defskip")
537 pimpl_->defskip = VSpace(defskip);
538 } else if (token == "\\quotes_language") {
541 quotes_language = quoteslangtranslator().find(quotes_lang);
542 } else if (token == "\\papersize") {
545 papersize = papersizetranslator().find(ppsize);
546 } else if (token == "\\use_geometry") {
548 } else if (token == "\\use_amsmath") {
551 use_amsmath = packagetranslator().find(use_ams);
552 } else if (token == "\\use_esint") {
555 use_esint = packagetranslator().find(useesint);
556 } else if (token == "\\cite_engine") {
559 cite_engine_ = citeenginetranslator().find(engine);
560 } else if (token == "\\use_bibtopic") {
562 } else if (token == "\\tracking_changes") {
564 } else if (token == "\\output_changes") {
565 lex >> outputChanges;
566 } else if (token == "\\branch") {
568 docstring branch = lex.getDocString();
569 branchlist().add(branch);
572 string const tok = lex.getString();
573 if (tok == "\\end_branch")
575 Branch * branch_ptr = branchlist().find(branch);
576 if (tok == "\\selected") {
579 branch_ptr->setSelected(lex.getInteger());
581 // not yet operational
582 if (tok == "\\color") {
584 string color = lex.getString();
586 branch_ptr->setColor(color);
587 // Update also the Color table:
589 color = lcolor.getX11Name(Color_background);
591 lcolor.setColor(to_utf8(branch), color);
595 } else if (token == "\\author") {
597 istringstream ss(lex.getString());
600 author_map.push_back(pimpl_->authorlist.record(a));
601 } else if (token == "\\paperorientation") {
604 orientation = paperorientationtranslator().find(orient);
605 } else if (token == "\\paperwidth") {
607 } else if (token == "\\paperheight") {
609 } else if (token == "\\leftmargin") {
611 } else if (token == "\\topmargin") {
613 } else if (token == "\\rightmargin") {
615 } else if (token == "\\bottommargin") {
617 } else if (token == "\\headheight") {
619 } else if (token == "\\headsep") {
621 } else if (token == "\\footskip") {
623 } else if (token == "\\columnsep") {
625 } else if (token == "\\paperfontsize") {
627 } else if (token == "\\papercolumns") {
629 } else if (token == "\\listings_params") {
632 listings_params = InsetListingsParams(par).params();
633 } else if (token == "\\papersides") {
636 sides = sidestranslator().find(psides);
637 } else if (token == "\\paperpagestyle") {
639 } else if (token == "\\bullet") {
641 } else if (token == "\\bulletLaTeX") {
642 readBulletsLaTeX(lex);
643 } else if (token == "\\secnumdepth") {
645 } else if (token == "\\tocdepth") {
647 } else if (token == "\\spacing") {
651 if (nspacing == "other") {
654 spacing().set(spacetranslator().find(nspacing), tmp_val);
655 } else if (token == "\\float_placement") {
656 lex >> float_placement;
658 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
659 string toktmp = pdfoptions().readToken(lex, token);
660 if (!toktmp.empty()) {
661 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
666 lyxerr << "BufferParams::readToken(): Unknown token: " <<
675 void BufferParams::writeFile(ostream & os) const
677 // The top of the file is written by the buffer.
678 // Prints out the buffer info into the .lyx file given by file
681 os << "\\textclass " << baseClass()->name() << '\n';
684 if (!preamble.empty()) {
685 // remove '\n' from the end of preamble
686 string const tmppreamble = rtrim(preamble, "\n");
687 os << "\\begin_preamble\n"
689 << "\n\\end_preamble\n";
693 if (!options.empty()) {
694 os << "\\options " << options << '\n';
697 // the master document
698 if (!master.empty()) {
699 os << "\\master " << master << '\n';
703 if (!layoutModules_.empty()) {
704 os << "\\begin_modules" << '\n';
705 LayoutModuleList::const_iterator it = layoutModules_.begin();
706 for (; it != layoutModules_.end(); it++)
708 os << "\\end_modules" << '\n';
711 // local layout information
712 if (!local_layout.empty()) {
713 // remove '\n' from the end
714 string const tmplocal = rtrim(local_layout, "\n");
715 os << "\\begin_local_layout\n"
717 << "\n\\end_local_layout\n";
720 // then the text parameters
721 if (language != ignore_language)
722 os << "\\language " << language->lang() << '\n';
723 os << "\\inputencoding " << inputenc
724 << "\n\\font_roman " << fontsRoman
725 << "\n\\font_sans " << fontsSans
726 << "\n\\font_typewriter " << fontsTypewriter
727 << "\n\\font_default_family " << fontsDefaultFamily
728 << "\n\\font_sc " << convert<string>(fontsSC)
729 << "\n\\font_osf " << convert<string>(fontsOSF)
730 << "\n\\font_sf_scale " << fontsSansScale
731 << "\n\\font_tt_scale " << fontsTypewriterScale
733 if (!fontsCJK.empty()) {
734 os << "\\font_cjk " << fontsCJK << '\n';
736 os << "\n\\graphics " << graphicsDriver << '\n';
738 if (!float_placement.empty()) {
739 os << "\\float_placement " << float_placement << '\n';
741 os << "\\paperfontsize " << fontsize << '\n';
743 spacing().writeFile(os);
744 pdfoptions().writeFile(os);
746 os << "\\papersize " << string_papersize[papersize]
747 << "\n\\use_geometry " << convert<string>(use_geometry)
748 << "\n\\use_amsmath " << use_amsmath
749 << "\n\\use_esint " << use_esint
750 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
751 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
752 << "\n\\paperorientation " << string_orientation[orientation]
755 BranchList::const_iterator it = branchlist().begin();
756 BranchList::const_iterator end = branchlist().end();
757 for (; it != end; ++it) {
758 os << "\\branch " << to_utf8(it->getBranch())
759 << "\n\\selected " << it->getSelected()
760 << "\n\\color " << lyx::X11hexname(it->getColor())
765 if (!paperwidth.empty())
766 os << "\\paperwidth "
767 << VSpace(paperwidth).asLyXCommand() << '\n';
768 if (!paperheight.empty())
769 os << "\\paperheight "
770 << VSpace(paperheight).asLyXCommand() << '\n';
771 if (!leftmargin.empty())
772 os << "\\leftmargin "
773 << VSpace(leftmargin).asLyXCommand() << '\n';
774 if (!topmargin.empty())
776 << VSpace(topmargin).asLyXCommand() << '\n';
777 if (!rightmargin.empty())
778 os << "\\rightmargin "
779 << VSpace(rightmargin).asLyXCommand() << '\n';
780 if (!bottommargin.empty())
781 os << "\\bottommargin "
782 << VSpace(bottommargin).asLyXCommand() << '\n';
783 if (!headheight.empty())
784 os << "\\headheight "
785 << VSpace(headheight).asLyXCommand() << '\n';
786 if (!headsep.empty())
788 << VSpace(headsep).asLyXCommand() << '\n';
789 if (!footskip.empty())
791 << VSpace(footskip).asLyXCommand() << '\n';
792 if (!columnsep.empty())
794 << VSpace(columnsep).asLyXCommand() << '\n';
795 os << "\\secnumdepth " << secnumdepth
796 << "\n\\tocdepth " << tocdepth
797 << "\n\\paragraph_separation "
798 << string_paragraph_separation[paragraph_separation]
799 << "\n\\defskip " << getDefSkip().asLyXCommand()
800 << "\n\\quotes_language "
801 << string_quotes_language[quotes_language]
802 << "\n\\papercolumns " << columns
803 << "\n\\papersides " << sides
804 << "\n\\paperpagestyle " << pagestyle << '\n';
805 if (!listings_params.empty())
806 os << "\\listings_params \"" <<
807 InsetListingsParams(listings_params).encodedString() << "\"\n";
808 for (int i = 0; i < 4; ++i) {
809 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
810 if (user_defined_bullet(i).getFont() != -1) {
811 os << "\\bullet " << i << " "
812 << user_defined_bullet(i).getFont() << " "
813 << user_defined_bullet(i).getCharacter() << " "
814 << user_defined_bullet(i).getSize() << "\n";
818 os << "\\bulletLaTeX " << i << " \""
819 << lyx::to_ascii(user_defined_bullet(i).getText())
825 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
826 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
828 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
829 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
830 for (; a_it != a_end; ++a_it) {
831 if (a_it->second.used())
832 os << "\\author " << a_it->second << "\n";
834 os << "\\author " << Author() << "\n";
839 void BufferParams::validate(LaTeXFeatures & features) const
841 features.require(documentClass().requires());
844 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
845 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
846 LaTeXFeatures::isAvailable("xcolor");
848 switch (features.runparams().flavor) {
849 case OutputParams::LATEX:
851 features.require("ct-dvipost");
852 features.require("dvipost");
853 } else if (xcolorsoul) {
854 features.require("ct-xcolor-soul");
855 features.require("soul");
856 features.require("xcolor");
858 features.require("ct-none");
861 case OutputParams::PDFLATEX:
863 features.require("ct-xcolor-soul");
864 features.require("soul");
865 features.require("xcolor");
866 // improves color handling in PDF output
867 features.require("pdfcolmk");
869 features.require("ct-none");
877 // Floats with 'Here definitely' as default setting.
878 if (float_placement.find('H') != string::npos)
879 features.require("float");
881 // AMS Style is at document level
882 if (use_amsmath == package_on
883 || documentClass().provides("amsmath"))
884 features.require("amsmath");
885 if (use_esint == package_on)
886 features.require("esint");
888 // Document-level line spacing
889 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
890 features.require("setspace");
892 // the bullet shapes are buffer level not paragraph level
893 // so they are tested here
894 for (int i = 0; i < 4; ++i) {
895 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
897 int const font = user_defined_bullet(i).getFont();
899 int const c = user_defined_bullet(i).getCharacter();
905 features.require("latexsym");
907 } else if (font == 1) {
908 features.require("amssymb");
909 } else if (font >= 2 && font <= 5) {
910 features.require("pifont");
914 if (pdfoptions().use_hyperref)
915 features.require("hyperref");
919 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
920 TexRow & texrow) const
922 os << "\\documentclass";
924 DocumentClass const & tclass = documentClass();
926 ostringstream clsoptions; // the document class options.
928 if (tokenPos(tclass.opt_fontsize(),
929 '|', fontsize) >= 0) {
930 // only write if existing in list (and not default)
931 clsoptions << fontsize << "pt,";
934 // custom, A3, B3 and B4 paper sizes need geometry
935 bool nonstandard_papersize = papersize == PAPER_B3
936 || papersize == PAPER_B4
937 || papersize == PAPER_A3
938 || papersize == PAPER_CUSTOM;
943 clsoptions << "a4paper,";
946 clsoptions << "letterpaper,";
949 clsoptions << "a5paper,";
952 clsoptions << "b5paper,";
954 case PAPER_USEXECUTIVE:
955 clsoptions << "executivepaper,";
958 clsoptions << "legalpaper,";
970 if (sides != tclass.sides()) {
973 clsoptions << "oneside,";
976 clsoptions << "twoside,";
982 if (columns != tclass.columns()) {
984 clsoptions << "twocolumn,";
986 clsoptions << "onecolumn,";
990 && orientation == ORIENTATION_LANDSCAPE)
991 clsoptions << "landscape,";
993 // language should be a parameter to \documentclass
994 if (language->babel() == "hebrew"
995 && default_language->babel() != "hebrew")
996 // This seems necessary
997 features.useLanguage(default_language);
999 ostringstream language_options;
1000 bool const use_babel = features.useBabel();
1002 language_options << features.getLanguages();
1003 if (!language->babel().empty()) {
1004 if (!language_options.str().empty())
1005 language_options << ',';
1006 language_options << language->babel();
1008 // when Vietnamese is used, babel must directly be loaded with the
1009 // language options, not in the class options, see
1010 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1011 size_t viet = language_options.str().find("vietnam");
1012 // viet = string::npos when not found
1013 // when Japanese is used, babel must directly be loaded with the
1014 // language options, not in the class options, see
1015 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1016 size_t japan = language_options.str().find("japanese");
1017 // japan = string::npos when not found
1018 if (lyxrc.language_global_options && !language_options.str().empty()
1019 && viet == string::npos && japan == string::npos)
1020 clsoptions << language_options.str() << ',';
1023 // the user-defined options
1024 if (!options.empty()) {
1025 clsoptions << options << ',';
1028 string strOptions(clsoptions.str());
1029 if (!strOptions.empty()) {
1030 strOptions = rtrim(strOptions, ",");
1032 os << '[' << from_utf8(strOptions) << ']';
1035 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1037 // end of \documentclass defs
1039 // font selection must be done before loading fontenc.sty
1040 string const fonts =
1041 loadFonts(fontsRoman, fontsSans,
1042 fontsTypewriter, fontsSC, fontsOSF,
1043 fontsSansScale, fontsTypewriterScale);
1044 if (!fonts.empty()) {
1045 os << from_ascii(fonts);
1048 if (fontsDefaultFamily != "default")
1049 os << "\\renewcommand{\\familydefault}{\\"
1050 << from_ascii(fontsDefaultFamily) << "}\n";
1052 // set font encoding
1053 // this one is not per buffer
1054 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1055 if (lyxrc.fontenc != "default") {
1056 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1057 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1058 << ",LFE,LAE]{fontenc}\n";
1061 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1067 // handle inputenc etc.
1068 writeEncodingPreamble(os, features, texrow);
1070 if (!listings_params.empty()) {
1071 os << "\\usepackage{listings}\n";
1074 // do not test validity because listings_params is supposed to be valid
1075 string par = InsetListingsParams(listings_params).separatedParams(true);
1076 os << from_ascii(par);
1077 // count the number of newlines
1078 for (size_t i = 0; i < par.size(); ++i)
1084 if (use_geometry || nonstandard_papersize) {
1085 os << "\\usepackage{geometry}\n";
1087 os << "\\geometry{verbose";
1088 if (orientation == ORIENTATION_LANDSCAPE)
1090 switch (papersize) {
1092 if (!paperwidth.empty())
1093 os << ",paperwidth="
1094 << from_ascii(paperwidth);
1095 if (!paperheight.empty())
1096 os << ",paperheight="
1097 << from_ascii(paperheight);
1099 case PAPER_USLETTER:
1100 os << ",letterpaper";
1103 os << ",legalpaper";
1105 case PAPER_USEXECUTIVE:
1106 os << ",executivepaper";
1127 // default papersize ie PAPER_DEFAULT
1128 switch (lyxrc.default_papersize) {
1129 case PAPER_DEFAULT: // keep compiler happy
1130 case PAPER_USLETTER:
1131 os << ",letterpaper";
1134 os << ",legalpaper";
1136 case PAPER_USEXECUTIVE:
1137 os << ",executivepaper";
1157 if (!topmargin.empty())
1158 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1159 if (!bottommargin.empty())
1160 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1161 if (!leftmargin.empty())
1162 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1163 if (!rightmargin.empty())
1164 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1165 if (!headheight.empty())
1166 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1167 if (!headsep.empty())
1168 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1169 if (!footskip.empty())
1170 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1171 if (!columnsep.empty())
1172 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1177 if (tokenPos(tclass.opt_pagestyle(),
1178 '|', pagestyle) >= 0) {
1179 if (pagestyle == "fancy") {
1180 os << "\\usepackage{fancyhdr}\n";
1183 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1187 // Only if class has a ToC hierarchy
1188 if (tclass.hasTocLevels()) {
1189 if (secnumdepth != tclass.secnumdepth()) {
1190 os << "\\setcounter{secnumdepth}{"
1195 if (tocdepth != tclass.tocdepth()) {
1196 os << "\\setcounter{tocdepth}{"
1203 if (paragraph_separation) {
1204 switch (getDefSkip().kind()) {
1205 case VSpace::SMALLSKIP:
1206 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1208 case VSpace::MEDSKIP:
1209 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1211 case VSpace::BIGSKIP:
1212 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1214 case VSpace::LENGTH:
1215 os << "\\setlength{\\parskip}{"
1216 << from_utf8(getDefSkip().length().asLatexString())
1219 default: // should never happen // Then delete it.
1220 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1225 os << "\\setlength{\\parindent}{0pt}\n";
1229 // If we use jurabib, we have to call babel here.
1230 if (use_babel && features.isRequired("jurabib")) {
1231 os << from_ascii(babelCall(language_options.str()))
1233 << from_ascii(features.getBabelOptions());
1237 // Now insert the LyX specific LaTeX commands...
1239 // The optional packages;
1240 docstring lyxpreamble(from_ascii(features.getPackages()));
1243 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1245 // We try to load babel late, in case it interferes
1246 // with other packages. But some packages also need babel to be loaded
1247 // before, e.g. jurabib has to be called after babel.
1248 // So load babel after the optional packages but before the user-defined
1249 // preamble. This allows the users to redefine babel commands, e.g. to
1250 // translate the word "Index" to the German "Stichwortverzeichnis".
1251 // For more infos why this place was chosen, see
1252 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1253 // If you encounter problems, you can shift babel to its old place behind
1254 // the user-defined preamble. But in this case you must change the Vietnamese
1255 // support from currently "\usepackage[vietnamese]{babel}" to:
1256 // \usepackage{vietnamese}
1257 // \usepackage{babel}
1258 // because vietnamese must be loaded before hyperref
1259 if (use_babel && !features.isRequired("jurabib")) {
1261 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1262 lyxpreamble += from_utf8(features.getBabelOptions());
1266 // * Hyperref manual: "Make sure it comes last of your loaded
1267 // packages, to give it a fighting chance of not being over-written,
1268 // since its job is to redefine many LATEX commands."
1269 // * Email from Heiko Oberdiek: "It is usually better to load babel
1270 // before hyperref. Then hyperref has a chance to detect babel.
1271 // * Has to be loaded before the "LyX specific LaTeX commands" to
1272 // avoid errors with algorithm floats.
1273 // use hyperref explicitely when it is required
1274 if (features.isRequired("hyperref")) {
1275 odocstringstream oss;
1276 pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
1277 lyxpreamble += oss.str();
1280 // Will be surrounded by \makeatletter and \makeatother when needed
1281 docstring atlyxpreamble;
1283 // Some macros LyX will need
1284 docstring tmppreamble(from_ascii(features.getMacros()));
1286 if (!tmppreamble.empty())
1287 atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1288 "LyX specific LaTeX commands.\n"
1289 + tmppreamble + '\n';
1291 // the text class specific preamble
1292 tmppreamble = features.getTClassPreamble();
1293 if (!tmppreamble.empty())
1294 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1295 "Textclass specific LaTeX commands.\n"
1296 + tmppreamble + '\n';
1298 /* the user-defined preamble */
1299 if (!preamble.empty())
1301 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1302 "User specified LaTeX commands.\n"
1303 + from_utf8(preamble) + '\n';
1305 // subfig loads internally the LaTeX package "caption". As caption is a very
1306 // popular package, users will load it in the preamble. Therefore we must load
1307 // subfig behind the user-defined preamble and check if the caption package
1308 // was loaded or not.
1309 // For the case that caption is loaded before subfig, there is the subfig
1310 // option "caption=false". This option also works when a koma-script class is
1311 // used and koma's own caption commands are used instead of caption.
1312 // We use \PassOptionsToPackage here because the user could have already
1313 // loaded subfig in the preamble.
1314 if (features.isRequired("subfig")) {
1315 atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n"
1316 " \\PassOptionsToPackage{caption=false}{subfig}}\n"
1317 "\\usepackage{subfig}\n";
1320 // Itemize bullet settings need to be last in case the user
1321 // defines their own bullets that use a package included
1322 // in the user-defined preamble -- ARRae
1323 // Actually it has to be done much later than that
1324 // since some packages like frenchb make modifications
1325 // at \begin{document} time -- JMarc
1326 docstring bullets_def;
1327 for (int i = 0; i < 4; ++i) {
1328 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1329 if (bullets_def.empty())
1330 bullets_def += "\\AtBeginDocument{\n";
1331 bullets_def += " \\def\\labelitemi";
1333 // `i' is one less than the item to modify
1340 bullets_def += "ii";
1346 bullets_def += '{' +
1347 user_defined_bullet(i).getText()
1352 if (!bullets_def.empty())
1353 atlyxpreamble += bullets_def + "}\n\n";
1355 if (atlyxpreamble.find(from_ascii("@")) != docstring::npos)
1356 lyxpreamble += "\n\\makeatletter\n"
1357 + atlyxpreamble + "\\makeatother\n\n";
1359 lyxpreamble += '\n' + atlyxpreamble;
1362 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1363 for (int j = 0; j != nlines; ++j) {
1372 void BufferParams::useClassDefaults()
1374 DocumentClass const & tclass = documentClass();
1376 sides = tclass.sides();
1377 columns = tclass.columns();
1378 pagestyle = tclass.pagestyle();
1379 options = tclass.options();
1380 // Only if class has a ToC hierarchy
1381 if (tclass.hasTocLevels()) {
1382 secnumdepth = tclass.secnumdepth();
1383 tocdepth = tclass.tocdepth();
1388 bool BufferParams::hasClassDefaults() const
1390 DocumentClass const & tclass = documentClass();
1392 return sides == tclass.sides()
1393 && columns == tclass.columns()
1394 && pagestyle == tclass.pagestyle()
1395 && options == tclass.options()
1396 && secnumdepth == tclass.secnumdepth()
1397 && tocdepth == tclass.tocdepth();
1401 DocumentClass const & BufferParams::documentClass() const
1407 DocumentClass const * BufferParams::documentClassPtr() const {
1412 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1413 // evil, but this function is evil
1414 doc_class_ = const_cast<DocumentClass *>(tc);
1418 bool BufferParams::setBaseClass(string const & classname)
1420 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1421 LayoutFileList const & bcl = LayoutFileList::get();
1422 if (!bcl.haveClass(classname)) {
1424 bformat(_("The document class %1$s could not be found."),
1425 from_utf8(classname));
1426 frontend::Alert::error(_("Class not found"), s);
1430 if (bcl[classname].load()) {
1431 pimpl_->baseClass_ = classname;
1436 bformat(_("The document class %1$s could not be loaded."),
1437 from_utf8(classname));
1438 frontend::Alert::error(_("Could not load class"), s);
1443 LayoutFile const * BufferParams::baseClass() const
1445 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
1446 return &(LayoutFileList::get()[pimpl_->baseClass_]);
1452 LayoutFileIndex const & BufferParams::baseClassID() const
1454 return pimpl_->baseClass_;
1458 void BufferParams::makeDocumentClass()
1463 doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass()));
1465 //FIXME It might be worth loading the children's modules here,
1466 //just as we load their bibliographies and such, instead of just
1467 //doing a check in InsetInclude.
1468 LayoutModuleList::const_iterator it = layoutModules_.begin();
1469 for (; it != layoutModules_.end(); it++) {
1470 string const modName = *it;
1471 LyXModule * lm = moduleList[modName];
1473 docstring const msg =
1474 bformat(_("The module %1$s has been requested by\n"
1475 "this document but has not been found in the list of\n"
1476 "available modules. If you recently installed it, you\n"
1477 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1478 frontend::Alert::warning(_("Module not available"),
1479 msg + _("Some layouts may not be available."));
1480 LYXERR0("BufferParams::makeDocumentClass(): Module " <<
1481 modName << " requested but not found in module list.");
1484 if (!lm->isAvailable()) {
1485 docstring const msg =
1486 bformat(_("The module %1$s requires a package that is\n"
1487 "not available in your LaTeX installation. LaTeX output\n"
1488 "may not be possible.\n"), from_utf8(modName));
1489 frontend::Alert::warning(_("Package not available"), msg);
1491 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1492 if (!doc_class_->read(layout_file, TextClass::MODULE)) {
1493 docstring const msg =
1494 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1495 frontend::Alert::warning(_("Read Error"), msg);
1498 if (!local_layout.empty()) {
1499 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
1500 docstring const msg = _("Error reading internal layout information");
1501 frontend::Alert::warning(_("Read Error"), msg);
1507 vector<string> const & BufferParams::getModules() const
1509 return layoutModules_;
1514 bool BufferParams::addLayoutModule(string const & modName)
1516 LayoutModuleList::const_iterator it = layoutModules_.begin();
1517 LayoutModuleList::const_iterator end = layoutModules_.end();
1518 for (; it != end; it++)
1521 layoutModules_.push_back(modName);
1526 void BufferParams::clearLayoutModules()
1528 layoutModules_.clear();
1532 Font const BufferParams::getFont() const
1534 FontInfo f = documentClass().defaultfont();
1535 if (fontsDefaultFamily == "rmdefault")
1536 f.setFamily(ROMAN_FAMILY);
1537 else if (fontsDefaultFamily == "sfdefault")
1538 f.setFamily(SANS_FAMILY);
1539 else if (fontsDefaultFamily == "ttdefault")
1540 f.setFamily(TYPEWRITER_FAMILY);
1541 return Font(f, language);
1545 void BufferParams::readPreamble(Lexer & lex)
1547 if (lex.getString() != "\\begin_preamble")
1548 lyxerr << "Error (BufferParams::readPreamble):"
1549 "consistency check failed." << endl;
1551 preamble = lex.getLongString("\\end_preamble");
1555 void BufferParams::readLocalLayout(Lexer & lex)
1557 if (lex.getString() != "\\begin_local_layout")
1558 lyxerr << "Error (BufferParams::readLocalLayout):"
1559 "consistency check failed." << endl;
1561 local_layout = lex.getLongString("\\end_local_layout");
1565 void BufferParams::readLanguage(Lexer & lex)
1567 if (!lex.next()) return;
1569 string const tmptok = lex.getString();
1571 // check if tmptok is part of tex_babel in tex-defs.h
1572 language = languages.getLanguage(tmptok);
1574 // Language tmptok was not found
1575 language = default_language;
1576 lyxerr << "Warning: Setting language `"
1577 << tmptok << "' to `" << language->lang()
1583 void BufferParams::readGraphicsDriver(Lexer & lex)
1588 string const tmptok = lex.getString();
1589 // check if tmptok is part of tex_graphics in tex_defs.h
1592 string const test = tex_graphics[n++];
1594 if (test == tmptok) {
1595 graphicsDriver = tmptok;
1600 "Warning: graphics driver `$$Token' not recognized!\n"
1601 " Setting graphics driver to `default'.\n");
1602 graphicsDriver = "default";
1609 void BufferParams::readBullets(Lexer & lex)
1614 int const index = lex.getInteger();
1616 int temp_int = lex.getInteger();
1617 user_defined_bullet(index).setFont(temp_int);
1618 temp_bullet(index).setFont(temp_int);
1620 user_defined_bullet(index).setCharacter(temp_int);
1621 temp_bullet(index).setCharacter(temp_int);
1623 user_defined_bullet(index).setSize(temp_int);
1624 temp_bullet(index).setSize(temp_int);
1628 void BufferParams::readBulletsLaTeX(Lexer & lex)
1630 // The bullet class should be able to read this.
1633 int const index = lex.getInteger();
1635 docstring const temp_str = lex.getDocString();
1637 user_defined_bullet(index).setText(temp_str);
1638 temp_bullet(index).setText(temp_str);
1642 void BufferParams::readModules(Lexer & lex)
1644 if (!lex.eatLine()) {
1645 lyxerr << "Error (BufferParams::readModules):"
1646 "Unexpected end of input." << endl;
1650 string mod = lex.getString();
1651 if (mod == "\\end_modules")
1653 addLayoutModule(mod);
1659 string BufferParams::paperSizeName(PapersizePurpose purpose) const
1661 char real_papersize = papersize;
1662 if (real_papersize == PAPER_DEFAULT)
1663 real_papersize = lyxrc.default_papersize;
1665 switch (real_papersize) {
1667 // could be anything, so don't guess
1669 case PAPER_CUSTOM: {
1670 if (purpose == XDVI && !paperwidth.empty() &&
1671 !paperheight.empty()) {
1672 // heightxwidth<unit>
1673 string first = paperwidth;
1674 string second = paperheight;
1675 if (orientation == ORIENTATION_LANDSCAPE)
1678 return first.erase(first.length() - 2)
1690 // dvips and dvipdfm do not know this
1691 if (purpose == DVIPS || purpose == DVIPDFM)
1695 // dvipdfm does not know this
1696 if (purpose == DVIPDFM)
1700 // dvipdfm does not know this
1701 if (purpose == DVIPDFM)
1704 case PAPER_USEXECUTIVE:
1705 // dvipdfm does not know this
1706 if (purpose == DVIPDFM)
1711 case PAPER_USLETTER:
1713 if (purpose == XDVI)
1720 string const BufferParams::dvips_options() const
1725 && papersize == PAPER_CUSTOM
1726 && !lyxrc.print_paper_dimension_flag.empty()
1727 && !paperwidth.empty()
1728 && !paperheight.empty()) {
1729 // using a custom papersize
1730 result = lyxrc.print_paper_dimension_flag;
1731 result += ' ' + paperwidth;
1732 result += ',' + paperheight;
1734 string const paper_option = paperSizeName(DVIPS);
1735 if (!paper_option.empty() && (paper_option != "letter" ||
1736 orientation != ORIENTATION_LANDSCAPE)) {
1737 // dvips won't accept -t letter -t landscape.
1738 // In all other cases, include the paper size
1740 result = lyxrc.print_paper_flag;
1741 result += ' ' + paper_option;
1744 if (orientation == ORIENTATION_LANDSCAPE &&
1745 papersize != PAPER_CUSTOM)
1746 result += ' ' + lyxrc.print_landscape_flag;
1751 string BufferParams::babelCall(string const & lang_opts) const
1753 string lang_pack = lyxrc.language_package;
1754 if (lang_pack != "\\usepackage{babel}")
1756 // suppress the babel call when there is no babel language defined
1757 // for the document language in the lib/languages file and if no
1758 // other languages are used (lang_opts is then empty)
1759 if (lang_opts.empty())
1761 // when Vietnamese is used, babel must directly be loaded with the
1762 // language options, see
1763 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1764 size_t viet = lang_opts.find("vietnam");
1765 // viet = string::npos when not found
1766 // when Japanese is used, babel must directly be loaded with the
1767 // language options, see
1768 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1769 size_t japan = lang_opts.find("japanese");
1770 // japan = string::npos when not found
1771 if (!lyxrc.language_global_options || viet != string::npos || japan != string::npos)
1772 return "\\usepackage[" + lang_opts + "]{babel}";
1777 void BufferParams::writeEncodingPreamble(odocstream & os,
1778 LaTeXFeatures & features, TexRow & texrow) const
1780 if (inputenc == "auto") {
1781 string const doc_encoding =
1782 language->encoding()->latexName();
1783 Encoding::Package const package =
1784 language->encoding()->package();
1786 // Create a list with all the input encodings used
1788 set<string> encodings =
1789 features.getEncodingSet(doc_encoding);
1791 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1792 // package inputenc must be omitted. Therefore set the encoding to empty.
1793 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1794 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1795 doc_encoding == "SJIS-plain")
1798 if (!encodings.empty() || package == Encoding::inputenc) {
1799 os << "\\usepackage[";
1800 set<string>::const_iterator it = encodings.begin();
1801 set<string>::const_iterator const end = encodings.end();
1803 os << from_ascii(*it);
1806 for (; it != end; ++it)
1807 os << ',' << from_ascii(*it);
1808 if (package == Encoding::inputenc) {
1809 if (!encodings.empty())
1811 os << from_ascii(doc_encoding);
1813 os << "]{inputenc}\n";
1816 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1817 os << "\\usepackage{CJK}\n";
1820 } else if (inputenc != "default") {
1821 switch (encoding().package()) {
1822 case Encoding::none:
1824 case Encoding::inputenc:
1825 os << "\\usepackage[" << from_ascii(inputenc)
1830 os << "\\usepackage{CJK}\n";
1836 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1837 // armscii8 is used for Armenian.
1838 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1839 os << "\\usepackage{armtex}\n";
1845 string const BufferParams::loadFonts(string const & rm,
1846 string const & sf, string const & tt,
1847 bool const & sc, bool const & osf,
1848 int const & sfscale, int const & ttscale) const
1850 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1851 several packages have been replaced by others, that might not
1852 be installed on every system. We have to take care for that
1853 (see psnfss.pdf). We try to support all psnfss fonts as well
1854 as the fonts that have become de facto standard in the LaTeX
1855 world (e.g. Latin Modern). We do not support obsolete fonts
1856 (like PSLatex). In general, it should be possible to mix any
1857 rm font with any sf or tt font, respectively. (JSpitzm)
1859 -- separate math fonts.
1862 if (rm == "default" && sf == "default" && tt == "default")
1869 // Computer Modern (must be explicitely selectable -- there might be classes
1870 // that define a different default font!
1872 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1873 // osf for Computer Modern needs eco.sty
1875 os << "\\usepackage{eco}\n";
1877 // Latin Modern Roman
1878 else if (rm == "lmodern")
1879 os << "\\usepackage{lmodern}\n";
1881 else if (rm == "ae") {
1882 // not needed when using OT1 font encoding.
1883 if (lyxrc.fontenc != "default")
1884 os << "\\usepackage{ae,aecompl}\n";
1887 else if (rm == "times") {
1888 // try to load the best available package
1889 if (LaTeXFeatures::isAvailable("mathptmx"))
1890 os << "\\usepackage{mathptmx}\n";
1891 else if (LaTeXFeatures::isAvailable("mathptm"))
1892 os << "\\usepackage{mathptm}\n";
1894 os << "\\usepackage{times}\n";
1897 else if (rm == "palatino") {
1898 // try to load the best available package
1899 if (LaTeXFeatures::isAvailable("mathpazo")) {
1900 os << "\\usepackage";
1906 // "osf" includes "sc"!
1910 os << "{mathpazo}\n";
1912 else if (LaTeXFeatures::isAvailable("mathpple"))
1913 os << "\\usepackage{mathpple}\n";
1915 os << "\\usepackage{palatino}\n";
1918 else if (rm == "utopia") {
1919 // fourier supersedes utopia.sty, but does
1920 // not work with OT1 encoding.
1921 if (LaTeXFeatures::isAvailable("fourier")
1922 && lyxrc.fontenc != "default") {
1923 os << "\\usepackage";
1934 os << "{fourier}\n";
1937 os << "\\usepackage{utopia}\n";
1939 // Bera (complete fontset)
1940 else if (rm == "bera" && sf == "default" && tt == "default")
1941 os << "\\usepackage{bera}\n";
1943 else if (rm != "default")
1944 os << "\\usepackage" << "{" << rm << "}\n";
1947 // Helvetica, Bera Sans
1948 if (sf == "helvet" || sf == "berasans") {
1950 os << "\\usepackage[scaled=" << float(sfscale) / 100
1951 << "]{" << sf << "}\n";
1953 os << "\\usepackage{" << sf << "}\n";
1956 else if (sf == "avant")
1957 os << "\\usepackage{" << sf << "}\n";
1958 // Computer Modern, Latin Modern, CM Bright
1959 else if (sf != "default")
1960 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1962 // monospaced/typewriter
1963 // Courier, LuxiMono
1964 if (tt == "luximono" || tt == "beramono") {
1966 os << "\\usepackage[scaled=" << float(ttscale) / 100
1967 << "]{" << tt << "}\n";
1969 os << "\\usepackage{" << tt << "}\n";
1972 else if (tt == "courier" )
1973 os << "\\usepackage{" << tt << "}\n";
1974 // Computer Modern, Latin Modern, CM Bright
1975 else if (tt != "default")
1976 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1982 Encoding const & BufferParams::encoding() const
1984 if (inputenc == "auto" || inputenc == "default")
1985 return *language->encoding();
1986 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
1989 LYXERR0("Unknown inputenc value `" << inputenc
1990 << "'. Using `auto' instead.");
1991 return *language->encoding();
1995 CiteEngine BufferParams::citeEngine() const
1997 // FIXME the class should provide the numerical/
1998 // authoryear choice
1999 if (documentClass().provides("natbib")
2000 && cite_engine_ != ENGINE_NATBIB_NUMERICAL)
2001 return ENGINE_NATBIB_AUTHORYEAR;
2002 return cite_engine_;
2006 void BufferParams::setCiteEngine(CiteEngine cite_engine)
2008 cite_engine_ = cite_engine;