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.addLocalLayout(classname, filepath.absFilename());
470 setBaseClass(classname);
471 // We assume that a tex class exists for local or unknown layouts so this warning
472 // will only be given for system layouts.
473 if (!baseClass()->isTeXClassAvailable()) {
474 docstring const msg =
475 bformat(_("The layout file requested by this document,\n"
477 "is not usable. This is probably because a LaTeX\n"
478 "class or style file required by it is not\n"
479 "available. See the Customization documentation\n"
480 "for more information.\n"), from_utf8(classname));
481 frontend::Alert::warning(_("Document class not available"),
482 msg + _("LyX will not be able to produce output."));
484 } else if (token == "\\begin_preamble") {
486 } else if (token == "\\begin_local_layout") {
487 readLocalLayout(lex);
488 } else if (token == "\\begin_modules") {
490 } else if (token == "\\options") {
492 options = lex.getString();
493 } else if (token == "\\master") {
495 master = lex.getString();
496 } else if (token == "\\language") {
498 } else if (token == "\\inputencoding") {
500 } else if (token == "\\graphics") {
501 readGraphicsDriver(lex);
502 } else if (token == "\\font_roman") {
504 } else if (token == "\\font_sans") {
506 } else if (token == "\\font_typewriter") {
507 lex >> fontsTypewriter;
508 } else if (token == "\\font_default_family") {
509 lex >> fontsDefaultFamily;
510 } else if (token == "\\font_sc") {
512 } else if (token == "\\font_osf") {
514 } else if (token == "\\font_sf_scale") {
515 lex >> fontsSansScale;
516 } else if (token == "\\font_tt_scale") {
517 lex >> fontsTypewriterScale;
518 } else if (token == "\\font_cjk") {
520 } else if (token == "\\paragraph_separation") {
523 paragraph_separation = parseptranslator().find(parsep);
524 } else if (token == "\\defskip") {
526 string defskip = lex.getString();
527 if (defskip == "defskip")
530 pimpl_->defskip = VSpace(defskip);
531 } else if (token == "\\quotes_language") {
534 quotes_language = quoteslangtranslator().find(quotes_lang);
535 } else if (token == "\\papersize") {
538 papersize = papersizetranslator().find(ppsize);
539 } else if (token == "\\use_geometry") {
541 } else if (token == "\\use_amsmath") {
544 use_amsmath = packagetranslator().find(use_ams);
545 } else if (token == "\\use_esint") {
548 use_esint = packagetranslator().find(useesint);
549 } else if (token == "\\cite_engine") {
552 cite_engine_ = citeenginetranslator().find(engine);
553 } else if (token == "\\use_bibtopic") {
555 } else if (token == "\\tracking_changes") {
557 } else if (token == "\\output_changes") {
558 lex >> outputChanges;
559 } else if (token == "\\branch") {
561 docstring branch = lex.getDocString();
562 branchlist().add(branch);
565 string const tok = lex.getString();
566 if (tok == "\\end_branch")
568 Branch * branch_ptr = branchlist().find(branch);
569 if (tok == "\\selected") {
572 branch_ptr->setSelected(lex.getInteger());
574 // not yet operational
575 if (tok == "\\color") {
577 string color = lex.getString();
579 branch_ptr->setColor(color);
580 // Update also the Color table:
582 color = lcolor.getX11Name(Color_background);
584 lcolor.setColor(to_utf8(branch), color);
588 } else if (token == "\\author") {
590 istringstream ss(lex.getString());
593 author_map.push_back(pimpl_->authorlist.record(a));
594 } else if (token == "\\paperorientation") {
597 orientation = paperorientationtranslator().find(orient);
598 } else if (token == "\\paperwidth") {
600 } else if (token == "\\paperheight") {
602 } else if (token == "\\leftmargin") {
604 } else if (token == "\\topmargin") {
606 } else if (token == "\\rightmargin") {
608 } else if (token == "\\bottommargin") {
610 } else if (token == "\\headheight") {
612 } else if (token == "\\headsep") {
614 } else if (token == "\\footskip") {
616 } else if (token == "\\columnsep") {
618 } else if (token == "\\paperfontsize") {
620 } else if (token == "\\papercolumns") {
622 } else if (token == "\\listings_params") {
625 listings_params = InsetListingsParams(par).params();
626 } else if (token == "\\papersides") {
629 sides = sidestranslator().find(psides);
630 } else if (token == "\\paperpagestyle") {
632 } else if (token == "\\bullet") {
634 } else if (token == "\\bulletLaTeX") {
635 readBulletsLaTeX(lex);
636 } else if (token == "\\secnumdepth") {
638 } else if (token == "\\tocdepth") {
640 } else if (token == "\\spacing") {
644 if (nspacing == "other") {
647 spacing().set(spacetranslator().find(nspacing), tmp_val);
648 } else if (token == "\\float_placement") {
649 lex >> float_placement;
651 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
652 string toktmp = pdfoptions().readToken(lex, token);
653 if (!toktmp.empty()) {
654 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
659 lyxerr << "BufferParams::readToken(): Unknown token: " <<
668 void BufferParams::writeFile(ostream & os) const
670 // The top of the file is written by the buffer.
671 // Prints out the buffer info into the .lyx file given by file
674 os << "\\textclass " << baseClass()->name() << '\n';
677 if (!preamble.empty()) {
678 // remove '\n' from the end of preamble
679 string const tmppreamble = rtrim(preamble, "\n");
680 os << "\\begin_preamble\n"
682 << "\n\\end_preamble\n";
686 if (!options.empty()) {
687 os << "\\options " << options << '\n';
690 // the master document
691 if (!master.empty()) {
692 os << "\\master " << master << '\n';
696 if (!layoutModules_.empty()) {
697 os << "\\begin_modules" << '\n';
698 LayoutModuleList::const_iterator it = layoutModules_.begin();
699 for (; it != layoutModules_.end(); it++)
701 os << "\\end_modules" << '\n';
704 // local layout information
705 if (!local_layout.empty()) {
706 // remove '\n' from the end
707 string const tmplocal = rtrim(local_layout, "\n");
708 os << "\\begin_local_layout\n"
710 << "\n\\end_local_layout\n";
713 // then the text parameters
714 if (language != ignore_language)
715 os << "\\language " << language->lang() << '\n';
716 os << "\\inputencoding " << inputenc
717 << "\n\\font_roman " << fontsRoman
718 << "\n\\font_sans " << fontsSans
719 << "\n\\font_typewriter " << fontsTypewriter
720 << "\n\\font_default_family " << fontsDefaultFamily
721 << "\n\\font_sc " << convert<string>(fontsSC)
722 << "\n\\font_osf " << convert<string>(fontsOSF)
723 << "\n\\font_sf_scale " << fontsSansScale
724 << "\n\\font_tt_scale " << fontsTypewriterScale
726 if (!fontsCJK.empty()) {
727 os << "\\font_cjk " << fontsCJK << '\n';
729 os << "\n\\graphics " << graphicsDriver << '\n';
731 if (!float_placement.empty()) {
732 os << "\\float_placement " << float_placement << '\n';
734 os << "\\paperfontsize " << fontsize << '\n';
736 spacing().writeFile(os);
737 pdfoptions().writeFile(os);
739 os << "\\papersize " << string_papersize[papersize]
740 << "\n\\use_geometry " << convert<string>(use_geometry)
741 << "\n\\use_amsmath " << use_amsmath
742 << "\n\\use_esint " << use_esint
743 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
744 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
745 << "\n\\paperorientation " << string_orientation[orientation]
748 BranchList::const_iterator it = branchlist().begin();
749 BranchList::const_iterator end = branchlist().end();
750 for (; it != end; ++it) {
751 os << "\\branch " << to_utf8(it->getBranch())
752 << "\n\\selected " << it->getSelected()
753 << "\n\\color " << lyx::X11hexname(it->getColor())
758 if (!paperwidth.empty())
759 os << "\\paperwidth "
760 << VSpace(paperwidth).asLyXCommand() << '\n';
761 if (!paperheight.empty())
762 os << "\\paperheight "
763 << VSpace(paperheight).asLyXCommand() << '\n';
764 if (!leftmargin.empty())
765 os << "\\leftmargin "
766 << VSpace(leftmargin).asLyXCommand() << '\n';
767 if (!topmargin.empty())
769 << VSpace(topmargin).asLyXCommand() << '\n';
770 if (!rightmargin.empty())
771 os << "\\rightmargin "
772 << VSpace(rightmargin).asLyXCommand() << '\n';
773 if (!bottommargin.empty())
774 os << "\\bottommargin "
775 << VSpace(bottommargin).asLyXCommand() << '\n';
776 if (!headheight.empty())
777 os << "\\headheight "
778 << VSpace(headheight).asLyXCommand() << '\n';
779 if (!headsep.empty())
781 << VSpace(headsep).asLyXCommand() << '\n';
782 if (!footskip.empty())
784 << VSpace(footskip).asLyXCommand() << '\n';
785 if (!columnsep.empty())
787 << VSpace(columnsep).asLyXCommand() << '\n';
788 os << "\\secnumdepth " << secnumdepth
789 << "\n\\tocdepth " << tocdepth
790 << "\n\\paragraph_separation "
791 << string_paragraph_separation[paragraph_separation]
792 << "\n\\defskip " << getDefSkip().asLyXCommand()
793 << "\n\\quotes_language "
794 << string_quotes_language[quotes_language]
795 << "\n\\papercolumns " << columns
796 << "\n\\papersides " << sides
797 << "\n\\paperpagestyle " << pagestyle << '\n';
798 if (!listings_params.empty())
799 os << "\\listings_params \"" <<
800 InsetListingsParams(listings_params).encodedString() << "\"\n";
801 for (int i = 0; i < 4; ++i) {
802 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
803 if (user_defined_bullet(i).getFont() != -1) {
804 os << "\\bullet " << i << " "
805 << user_defined_bullet(i).getFont() << " "
806 << user_defined_bullet(i).getCharacter() << " "
807 << user_defined_bullet(i).getSize() << "\n";
811 os << "\\bulletLaTeX " << i << " \""
812 << lyx::to_ascii(user_defined_bullet(i).getText())
818 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
819 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
821 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
822 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
823 for (; a_it != a_end; ++a_it) {
824 if (a_it->second.used())
825 os << "\\author " << a_it->second << "\n";
827 os << "\\author " << Author() << "\n";
832 void BufferParams::validate(LaTeXFeatures & features) const
834 features.require(documentClass().requires());
837 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
838 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
839 LaTeXFeatures::isAvailable("xcolor");
841 switch (features.runparams().flavor) {
842 case OutputParams::LATEX:
844 features.require("ct-dvipost");
845 features.require("dvipost");
846 } else if (xcolorsoul) {
847 features.require("ct-xcolor-soul");
848 features.require("soul");
849 features.require("xcolor");
851 features.require("ct-none");
854 case OutputParams::PDFLATEX:
856 features.require("ct-xcolor-soul");
857 features.require("soul");
858 features.require("xcolor");
859 // improves color handling in PDF output
860 features.require("pdfcolmk");
862 features.require("ct-none");
870 // Floats with 'Here definitely' as default setting.
871 if (float_placement.find('H') != string::npos)
872 features.require("float");
874 // AMS Style is at document level
875 if (use_amsmath == package_on
876 || documentClass().provides("amsmath"))
877 features.require("amsmath");
878 if (use_esint == package_on)
879 features.require("esint");
881 // Document-level line spacing
882 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
883 features.require("setspace");
885 // the bullet shapes are buffer level not paragraph level
886 // so they are tested here
887 for (int i = 0; i < 4; ++i) {
888 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
890 int const font = user_defined_bullet(i).getFont();
892 int const c = user_defined_bullet(i).getCharacter();
898 features.require("latexsym");
900 } else if (font == 1) {
901 features.require("amssymb");
902 } else if (font >= 2 && font <= 5) {
903 features.require("pifont");
907 if (pdfoptions().use_hyperref)
908 features.require("hyperref");
910 if (language->lang() == "vietnamese")
911 features.require("vietnamese");
912 else if (language->lang() == "japanese")
913 features.require("japanese");
917 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
918 TexRow & texrow) const
920 os << "\\documentclass";
922 DocumentClass const & tclass = documentClass();
924 ostringstream clsoptions; // the document class options.
926 if (tokenPos(tclass.opt_fontsize(),
927 '|', fontsize) >= 0) {
928 // only write if existing in list (and not default)
929 clsoptions << fontsize << "pt,";
932 // custom, A3, B3 and B4 paper sizes need geometry
933 bool nonstandard_papersize = papersize == PAPER_B3
934 || papersize == PAPER_B4
935 || papersize == PAPER_A3
936 || papersize == PAPER_CUSTOM;
941 clsoptions << "a4paper,";
944 clsoptions << "letterpaper,";
947 clsoptions << "a5paper,";
950 clsoptions << "b5paper,";
952 case PAPER_USEXECUTIVE:
953 clsoptions << "executivepaper,";
956 clsoptions << "legalpaper,";
968 if (sides != tclass.sides()) {
971 clsoptions << "oneside,";
974 clsoptions << "twoside,";
980 if (columns != tclass.columns()) {
982 clsoptions << "twocolumn,";
984 clsoptions << "onecolumn,";
988 && orientation == ORIENTATION_LANDSCAPE)
989 clsoptions << "landscape,";
991 // language should be a parameter to \documentclass
992 if (language->babel() == "hebrew"
993 && default_language->babel() != "hebrew")
994 // This seems necessary
995 features.useLanguage(default_language);
997 ostringstream language_options;
998 bool const use_babel = features.useBabel();
1000 language_options << features.getLanguages();
1001 if (!language->babel().empty()) {
1002 if (!language_options.str().empty())
1003 language_options << ',';
1004 language_options << language->babel();
1006 // if Vietnamese is used, babel must directly be loaded with the
1007 // language options, not in the class options, see
1008 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1009 size_t viet = language_options.str().find("vietnam");
1010 // viet = string::npos when not found
1011 // if Japanese is used, babel must directly be loaded with the
1012 // language options, not in the class options, see
1013 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1014 size_t japan = language_options.str().find("japanese");
1015 // japan = string::npos when not found
1016 if (lyxrc.language_global_options && !language_options.str().empty()
1017 && viet == string::npos && japan == string::npos)
1018 clsoptions << language_options.str() << ',';
1021 // the user-defined options
1022 if (!options.empty()) {
1023 clsoptions << options << ',';
1026 string strOptions(clsoptions.str());
1027 if (!strOptions.empty()) {
1028 strOptions = rtrim(strOptions, ",");
1030 os << '[' << from_utf8(strOptions) << ']';
1033 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1035 // end of \documentclass defs
1037 // font selection must be done before loading fontenc.sty
1038 string const fonts =
1039 loadFonts(fontsRoman, fontsSans,
1040 fontsTypewriter, fontsSC, fontsOSF,
1041 fontsSansScale, fontsTypewriterScale);
1042 if (!fonts.empty()) {
1043 os << from_ascii(fonts);
1046 if (fontsDefaultFamily != "default")
1047 os << "\\renewcommand{\\familydefault}{\\"
1048 << from_ascii(fontsDefaultFamily) << "}\n";
1050 // set font encoding
1051 // this one is not per buffer
1052 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1053 if (lyxrc.fontenc != "default") {
1054 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1055 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1056 << ",LFE,LAE]{fontenc}\n";
1059 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1065 // handle inputenc etc.
1066 writeEncodingPreamble(os, features, texrow);
1068 if (!listings_params.empty()) {
1069 os << "\\usepackage{listings}\n";
1072 // do not test validity because listings_params is supposed to be valid
1073 string par = InsetListingsParams(listings_params).separatedParams(true);
1074 os << from_ascii(par);
1075 // count the number of newlines
1076 for (size_t i = 0; i < par.size(); ++i)
1082 if (use_geometry || nonstandard_papersize) {
1083 os << "\\usepackage{geometry}\n";
1085 os << "\\geometry{verbose";
1086 if (orientation == ORIENTATION_LANDSCAPE)
1088 switch (papersize) {
1090 if (!paperwidth.empty())
1091 os << ",paperwidth="
1092 << from_ascii(paperwidth);
1093 if (!paperheight.empty())
1094 os << ",paperheight="
1095 << from_ascii(paperheight);
1097 case PAPER_USLETTER:
1098 os << ",letterpaper";
1101 os << ",legalpaper";
1103 case PAPER_USEXECUTIVE:
1104 os << ",executivepaper";
1125 // default papersize ie PAPER_DEFAULT
1126 switch (lyxrc.default_papersize) {
1127 case PAPER_DEFAULT: // keep compiler happy
1128 case PAPER_USLETTER:
1129 os << ",letterpaper";
1132 os << ",legalpaper";
1134 case PAPER_USEXECUTIVE:
1135 os << ",executivepaper";
1155 if (!topmargin.empty())
1156 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1157 if (!bottommargin.empty())
1158 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1159 if (!leftmargin.empty())
1160 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1161 if (!rightmargin.empty())
1162 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1163 if (!headheight.empty())
1164 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1165 if (!headsep.empty())
1166 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1167 if (!footskip.empty())
1168 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1169 if (!columnsep.empty())
1170 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1173 } else if (orientation == ORIENTATION_LANDSCAPE) {
1174 features.require("papersize");
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 // If we use hyperref or japanese or vietnamese, we have to call babel here.
1246 if (use_babel && !features.isRequired("jurabib")
1247 && (features.isRequired("hyperref") || features.isRequired("vietnamese")
1248 || features.isRequired("japanese"))) {
1250 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1251 lyxpreamble += from_utf8(features.getBabelOptions());
1255 // * Hyperref manual: "Make sure it comes last of your loaded
1256 // packages, to give it a fighting chance of not being over-written,
1257 // since its job is to redefine many LATEX commands."
1258 // * Email from Heiko Oberdiek: "It is usually better to load babel
1259 // before hyperref. Then hyperref has a chance to detect babel.
1260 // * Has to be loaded before the "LyX specific LaTeX commands" to
1261 // avoid errors with algorithm floats.
1262 // use hyperref explicitely when it is required
1263 if (features.isRequired("hyperref")) {
1264 odocstringstream oss;
1265 pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
1266 lyxpreamble += oss.str();
1269 // Will be surrounded by \makeatletter and \makeatother when needed
1270 docstring atlyxpreamble;
1272 // Some macros LyX will need
1273 docstring tmppreamble(from_ascii(features.getMacros()));
1275 if (!tmppreamble.empty())
1276 atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1277 "LyX specific LaTeX commands.\n"
1278 + tmppreamble + '\n';
1280 // the text class specific preamble
1281 tmppreamble = features.getTClassPreamble();
1282 if (!tmppreamble.empty())
1283 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1284 "Textclass specific LaTeX commands.\n"
1285 + tmppreamble + '\n';
1287 /* the user-defined preamble */
1288 if (!preamble.empty())
1290 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1291 "User specified LaTeX commands.\n"
1292 + from_utf8(preamble) + '\n';
1294 // subfig loads internally the LaTeX package "caption". As
1295 // caption is a very popular package, users will load it in
1296 // the preamble. Therefore we must load subfig behind the
1297 // user-defined preamble and check if the caption package was
1298 // loaded or not. For the case that caption is loaded before
1299 // subfig, there is the subfig option "caption=false". This
1300 // option also works when a koma-script class is used and
1301 // koma's own caption commands are used instead of caption. We
1302 // use \PassOptionsToPackage here because the user could have
1303 // already loaded subfig in the preamble.
1304 if (features.isRequired("subfig")) {
1305 atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n"
1306 " \\PassOptionsToPackage{caption=false}{subfig}}\n"
1307 "\\usepackage{subfig}\n";
1310 // Itemize bullet settings need to be last in case the user
1311 // defines their own bullets that use a package included
1312 // in the user-defined preamble -- ARRae
1313 // Actually it has to be done much later than that
1314 // since some packages like frenchb make modifications
1315 // at \begin{document} time -- JMarc
1316 docstring bullets_def;
1317 for (int i = 0; i < 4; ++i) {
1318 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1319 if (bullets_def.empty())
1320 bullets_def += "\\AtBeginDocument{\n";
1321 bullets_def += " \\def\\labelitemi";
1323 // `i' is one less than the item to modify
1330 bullets_def += "ii";
1336 bullets_def += '{' +
1337 user_defined_bullet(i).getText()
1342 if (!bullets_def.empty())
1343 atlyxpreamble += bullets_def + "}\n\n";
1345 if (atlyxpreamble.find(from_ascii("@")) != docstring::npos)
1346 lyxpreamble += "\n\\makeatletter\n"
1347 + atlyxpreamble + "\\makeatother\n\n";
1349 lyxpreamble += '\n' + atlyxpreamble;
1351 // We try to load babel late, in case it interferes
1352 // with other packages.
1353 // Jurabib and Hyperref have to be called after babel, though.
1354 if (use_babel && !features.isRequired("jurabib")
1355 && !features.isRequired("hyperref")
1356 && !features.isRequired("vietnamese")
1357 && !features.isRequired("japanese")) {
1359 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1360 lyxpreamble += from_utf8(features.getBabelOptions()) + '\n';
1364 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1365 for (int j = 0; j != nlines; ++j) {
1374 void BufferParams::useClassDefaults()
1376 DocumentClass const & tclass = documentClass();
1378 sides = tclass.sides();
1379 columns = tclass.columns();
1380 pagestyle = tclass.pagestyle();
1381 options = tclass.options();
1382 // Only if class has a ToC hierarchy
1383 if (tclass.hasTocLevels()) {
1384 secnumdepth = tclass.secnumdepth();
1385 tocdepth = tclass.tocdepth();
1390 bool BufferParams::hasClassDefaults() const
1392 DocumentClass const & tclass = documentClass();
1394 return sides == tclass.sides()
1395 && columns == tclass.columns()
1396 && pagestyle == tclass.pagestyle()
1397 && options == tclass.options()
1398 && secnumdepth == tclass.secnumdepth()
1399 && tocdepth == tclass.tocdepth();
1403 DocumentClass const & BufferParams::documentClass() const
1409 DocumentClass const * BufferParams::documentClassPtr() const {
1414 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1415 // evil, but this function is evil
1416 doc_class_ = const_cast<DocumentClass *>(tc);
1420 bool BufferParams::setBaseClass(string const & classname)
1422 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1423 LayoutFileList & bcl = LayoutFileList::get();
1424 if (!bcl.haveClass(classname)) {
1426 bformat(_("The document class %1$s could not be found. "
1427 "A default textclass with default layouts will be used. "
1428 "LyX might not be able to produce output unless a correct "
1429 "textclass is selected from the document settings dialog."),
1430 from_utf8(classname));
1431 frontend::Alert::error(_("Document class not found"), s);
1432 bcl.addEmptyClass(classname);
1435 if (bcl[classname].load()) {
1436 pimpl_->baseClass_ = classname;
1441 bformat(_("The document class %1$s could not be loaded."),
1442 from_utf8(classname));
1443 frontend::Alert::error(_("Could not load class"), s);
1448 LayoutFile const * BufferParams::baseClass() const
1450 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
1451 return &(LayoutFileList::get()[pimpl_->baseClass_]);
1457 LayoutFileIndex const & BufferParams::baseClassID() const
1459 return pimpl_->baseClass_;
1463 void BufferParams::makeDocumentClass()
1468 doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass()));
1470 //FIXME It might be worth loading the children's modules here,
1471 //just as we load their bibliographies and such, instead of just
1472 //doing a check in InsetInclude.
1473 LayoutModuleList::const_iterator it = layoutModules_.begin();
1474 for (; it != layoutModules_.end(); it++) {
1475 string const modName = *it;
1476 LyXModule * lm = moduleList[modName];
1478 docstring const msg =
1479 bformat(_("The module %1$s has been requested by\n"
1480 "this document but has not been found in the list of\n"
1481 "available modules. If you recently installed it, you\n"
1482 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1483 frontend::Alert::warning(_("Module not available"),
1484 msg + _("Some layouts may not be available."));
1485 LYXERR0("BufferParams::makeDocumentClass(): Module " <<
1486 modName << " requested but not found in module list.");
1489 if (!lm->isAvailable()) {
1490 docstring const msg =
1491 bformat(_("The module %1$s requires a package that is\n"
1492 "not available in your LaTeX installation. LaTeX output\n"
1493 "may not be possible.\n"), from_utf8(modName));
1494 frontend::Alert::warning(_("Package not available"), msg);
1496 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1497 if (!doc_class_->read(layout_file, TextClass::MODULE)) {
1498 docstring const msg =
1499 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1500 frontend::Alert::warning(_("Read Error"), msg);
1503 if (!local_layout.empty()) {
1504 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
1505 docstring const msg = _("Error reading internal layout information");
1506 frontend::Alert::warning(_("Read Error"), msg);
1512 vector<string> const & BufferParams::getModules() const
1514 return layoutModules_;
1519 bool BufferParams::addLayoutModule(string const & modName)
1521 LayoutModuleList::const_iterator it = layoutModules_.begin();
1522 LayoutModuleList::const_iterator end = layoutModules_.end();
1523 for (; it != end; it++)
1526 layoutModules_.push_back(modName);
1531 void BufferParams::clearLayoutModules()
1533 layoutModules_.clear();
1537 Font const BufferParams::getFont() const
1539 FontInfo f = documentClass().defaultfont();
1540 if (fontsDefaultFamily == "rmdefault")
1541 f.setFamily(ROMAN_FAMILY);
1542 else if (fontsDefaultFamily == "sfdefault")
1543 f.setFamily(SANS_FAMILY);
1544 else if (fontsDefaultFamily == "ttdefault")
1545 f.setFamily(TYPEWRITER_FAMILY);
1546 return Font(f, language);
1550 void BufferParams::readPreamble(Lexer & lex)
1552 if (lex.getString() != "\\begin_preamble")
1553 lyxerr << "Error (BufferParams::readPreamble):"
1554 "consistency check failed." << endl;
1556 preamble = lex.getLongString("\\end_preamble");
1560 void BufferParams::readLocalLayout(Lexer & lex)
1562 if (lex.getString() != "\\begin_local_layout")
1563 lyxerr << "Error (BufferParams::readLocalLayout):"
1564 "consistency check failed." << endl;
1566 local_layout = lex.getLongString("\\end_local_layout");
1570 void BufferParams::readLanguage(Lexer & lex)
1572 if (!lex.next()) return;
1574 string const tmptok = lex.getString();
1576 // check if tmptok is part of tex_babel in tex-defs.h
1577 language = languages.getLanguage(tmptok);
1579 // Language tmptok was not found
1580 language = default_language;
1581 lyxerr << "Warning: Setting language `"
1582 << tmptok << "' to `" << language->lang()
1588 void BufferParams::readGraphicsDriver(Lexer & lex)
1593 string const tmptok = lex.getString();
1594 // check if tmptok is part of tex_graphics in tex_defs.h
1597 string const test = tex_graphics[n++];
1599 if (test == tmptok) {
1600 graphicsDriver = tmptok;
1605 "Warning: graphics driver `$$Token' not recognized!\n"
1606 " Setting graphics driver to `default'.\n");
1607 graphicsDriver = "default";
1614 void BufferParams::readBullets(Lexer & lex)
1619 int const index = lex.getInteger();
1621 int temp_int = lex.getInteger();
1622 user_defined_bullet(index).setFont(temp_int);
1623 temp_bullet(index).setFont(temp_int);
1625 user_defined_bullet(index).setCharacter(temp_int);
1626 temp_bullet(index).setCharacter(temp_int);
1628 user_defined_bullet(index).setSize(temp_int);
1629 temp_bullet(index).setSize(temp_int);
1633 void BufferParams::readBulletsLaTeX(Lexer & lex)
1635 // The bullet class should be able to read this.
1638 int const index = lex.getInteger();
1640 docstring const temp_str = lex.getDocString();
1642 user_defined_bullet(index).setText(temp_str);
1643 temp_bullet(index).setText(temp_str);
1647 void BufferParams::readModules(Lexer & lex)
1649 if (!lex.eatLine()) {
1650 lyxerr << "Error (BufferParams::readModules):"
1651 "Unexpected end of input." << endl;
1655 string mod = lex.getString();
1656 if (mod == "\\end_modules")
1658 addLayoutModule(mod);
1664 string BufferParams::paperSizeName(PapersizePurpose purpose) const
1666 char real_papersize = papersize;
1667 if (real_papersize == PAPER_DEFAULT)
1668 real_papersize = lyxrc.default_papersize;
1670 switch (real_papersize) {
1672 // could be anything, so don't guess
1674 case PAPER_CUSTOM: {
1675 if (purpose == XDVI && !paperwidth.empty() &&
1676 !paperheight.empty()) {
1677 // heightxwidth<unit>
1678 string first = paperwidth;
1679 string second = paperheight;
1680 if (orientation == ORIENTATION_LANDSCAPE)
1683 return first.erase(first.length() - 2)
1695 // dvips and dvipdfm do not know this
1696 if (purpose == DVIPS || purpose == DVIPDFM)
1700 // dvipdfm does not know this
1701 if (purpose == DVIPDFM)
1705 // dvipdfm does not know this
1706 if (purpose == DVIPDFM)
1709 case PAPER_USEXECUTIVE:
1710 // dvipdfm does not know this
1711 if (purpose == DVIPDFM)
1716 case PAPER_USLETTER:
1718 if (purpose == XDVI)
1725 string const BufferParams::dvips_options() const
1730 && papersize == PAPER_CUSTOM
1731 && !lyxrc.print_paper_dimension_flag.empty()
1732 && !paperwidth.empty()
1733 && !paperheight.empty()) {
1734 // using a custom papersize
1735 result = lyxrc.print_paper_dimension_flag;
1736 result += ' ' + paperwidth;
1737 result += ',' + paperheight;
1739 string const paper_option = paperSizeName(DVIPS);
1740 if (!paper_option.empty() && (paper_option != "letter" ||
1741 orientation != ORIENTATION_LANDSCAPE)) {
1742 // dvips won't accept -t letter -t landscape.
1743 // In all other cases, include the paper size
1745 result = lyxrc.print_paper_flag;
1746 result += ' ' + paper_option;
1749 if (orientation == ORIENTATION_LANDSCAPE &&
1750 papersize != PAPER_CUSTOM)
1751 result += ' ' + lyxrc.print_landscape_flag;
1756 string BufferParams::babelCall(string const & lang_opts) const
1758 string lang_pack = lyxrc.language_package;
1759 if (lang_pack != "\\usepackage{babel}")
1761 // suppress the babel call when there is no babel language defined
1762 // for the document language in the lib/languages file and if no
1763 // other languages are used (lang_opts is then empty)
1764 if (lang_opts.empty())
1766 // If Vietnamese is used, babel must directly be loaded with the
1767 // language options, see
1768 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1769 size_t viet = lang_opts.find("vietnam");
1770 // viet = string::npos when not found
1771 // If Japanese is used, babel must directly be loaded with the
1772 // language options, see
1773 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1774 size_t japan = lang_opts.find("japanese");
1775 // japan = string::npos when not found
1776 if (!lyxrc.language_global_options || viet != string::npos || japan != string::npos)
1777 return "\\usepackage[" + lang_opts + "]{babel}";
1782 void BufferParams::writeEncodingPreamble(odocstream & os,
1783 LaTeXFeatures & features, TexRow & texrow) const
1785 if (inputenc == "auto") {
1786 string const doc_encoding =
1787 language->encoding()->latexName();
1788 Encoding::Package const package =
1789 language->encoding()->package();
1791 // Create a list with all the input encodings used
1793 set<string> encodings =
1794 features.getEncodingSet(doc_encoding);
1796 // If the encodings EUC-JP-plain, JIS-plain, or SJIS-plain are used, the
1797 // package inputenc must be omitted. Therefore set the encoding to empty.
1798 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1799 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1800 doc_encoding == "SJIS-plain")
1803 if (!encodings.empty() || package == Encoding::inputenc) {
1804 os << "\\usepackage[";
1805 set<string>::const_iterator it = encodings.begin();
1806 set<string>::const_iterator const end = encodings.end();
1808 os << from_ascii(*it);
1811 for (; it != end; ++it)
1812 os << ',' << from_ascii(*it);
1813 if (package == Encoding::inputenc) {
1814 if (!encodings.empty())
1816 os << from_ascii(doc_encoding);
1818 os << "]{inputenc}\n";
1821 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1822 os << "\\usepackage{CJK}\n";
1825 } else if (inputenc != "default") {
1826 switch (encoding().package()) {
1827 case Encoding::none:
1829 case Encoding::inputenc:
1830 os << "\\usepackage[" << from_ascii(inputenc)
1835 os << "\\usepackage{CJK}\n";
1841 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1842 // armscii8 is used for Armenian.
1843 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1844 os << "\\usepackage{armtex}\n";
1850 string const BufferParams::loadFonts(string const & rm,
1851 string const & sf, string const & tt,
1852 bool const & sc, bool const & osf,
1853 int const & sfscale, int const & ttscale) const
1855 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1856 several packages have been replaced by others, that might not
1857 be installed on every system. We have to take care for that
1858 (see psnfss.pdf). We try to support all psnfss fonts as well
1859 as the fonts that have become de facto standard in the LaTeX
1860 world (e.g. Latin Modern). We do not support obsolete fonts
1861 (like PSLatex). In general, it should be possible to mix any
1862 rm font with any sf or tt font, respectively. (JSpitzm)
1864 -- separate math fonts.
1867 if (rm == "default" && sf == "default" && tt == "default")
1874 // Computer Modern (must be explicitely selectable -- there might be classes
1875 // that define a different default font!
1877 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1878 // osf for Computer Modern needs eco.sty
1880 os << "\\usepackage{eco}\n";
1882 // Latin Modern Roman
1883 else if (rm == "lmodern")
1884 os << "\\usepackage{lmodern}\n";
1886 else if (rm == "ae") {
1887 // not needed when using OT1 font encoding.
1888 if (lyxrc.fontenc != "default")
1889 os << "\\usepackage{ae,aecompl}\n";
1892 else if (rm == "times") {
1893 // try to load the best available package
1894 if (LaTeXFeatures::isAvailable("mathptmx"))
1895 os << "\\usepackage{mathptmx}\n";
1896 else if (LaTeXFeatures::isAvailable("mathptm"))
1897 os << "\\usepackage{mathptm}\n";
1899 os << "\\usepackage{times}\n";
1902 else if (rm == "palatino") {
1903 // try to load the best available package
1904 if (LaTeXFeatures::isAvailable("mathpazo")) {
1905 os << "\\usepackage";
1911 // "osf" includes "sc"!
1915 os << "{mathpazo}\n";
1917 else if (LaTeXFeatures::isAvailable("mathpple"))
1918 os << "\\usepackage{mathpple}\n";
1920 os << "\\usepackage{palatino}\n";
1923 else if (rm == "utopia") {
1924 // fourier supersedes utopia.sty, but does
1925 // not work with OT1 encoding.
1926 if (LaTeXFeatures::isAvailable("fourier")
1927 && lyxrc.fontenc != "default") {
1928 os << "\\usepackage";
1939 os << "{fourier}\n";
1942 os << "\\usepackage{utopia}\n";
1944 // Bera (complete fontset)
1945 else if (rm == "bera" && sf == "default" && tt == "default")
1946 os << "\\usepackage{bera}\n";
1948 else if (rm != "default")
1949 os << "\\usepackage" << "{" << rm << "}\n";
1952 // Helvetica, Bera Sans
1953 if (sf == "helvet" || sf == "berasans") {
1955 os << "\\usepackage[scaled=" << float(sfscale) / 100
1956 << "]{" << sf << "}\n";
1958 os << "\\usepackage{" << sf << "}\n";
1961 else if (sf == "avant")
1962 os << "\\usepackage{" << sf << "}\n";
1963 // Computer Modern, Latin Modern, CM Bright
1964 else if (sf != "default")
1965 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1967 // monospaced/typewriter
1968 // Courier, LuxiMono
1969 if (tt == "luximono" || tt == "beramono") {
1971 os << "\\usepackage[scaled=" << float(ttscale) / 100
1972 << "]{" << tt << "}\n";
1974 os << "\\usepackage{" << tt << "}\n";
1977 else if (tt == "courier" )
1978 os << "\\usepackage{" << tt << "}\n";
1979 // Computer Modern, Latin Modern, CM Bright
1980 else if (tt != "default")
1981 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1987 Encoding const & BufferParams::encoding() const
1989 if (inputenc == "auto" || inputenc == "default")
1990 return *language->encoding();
1991 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
1994 LYXERR0("Unknown inputenc value `" << inputenc
1995 << "'. Using `auto' instead.");
1996 return *language->encoding();
2000 CiteEngine BufferParams::citeEngine() const
2002 // FIXME the class should provide the numerical/
2003 // authoryear choice
2004 if (documentClass().provides("natbib")
2005 && cite_engine_ != ENGINE_NATBIB_NUMERICAL)
2006 return ENGINE_NATBIB_AUTHORYEAR;
2007 return cite_engine_;
2011 void BufferParams::setCiteEngine(CiteEngine cite_engine)
2013 cite_engine_ = cite_engine;