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");
912 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
913 TexRow & texrow) const
915 os << "\\documentclass";
917 DocumentClass const & tclass = documentClass();
919 ostringstream clsoptions; // the document class options.
921 if (tokenPos(tclass.opt_fontsize(),
922 '|', fontsize) >= 0) {
923 // only write if existing in list (and not default)
924 clsoptions << fontsize << "pt,";
927 // custom, A3, B3 and B4 paper sizes need geometry
928 bool nonstandard_papersize = papersize == PAPER_B3
929 || papersize == PAPER_B4
930 || papersize == PAPER_A3
931 || papersize == PAPER_CUSTOM;
936 clsoptions << "a4paper,";
939 clsoptions << "letterpaper,";
942 clsoptions << "a5paper,";
945 clsoptions << "b5paper,";
947 case PAPER_USEXECUTIVE:
948 clsoptions << "executivepaper,";
951 clsoptions << "legalpaper,";
963 if (sides != tclass.sides()) {
966 clsoptions << "oneside,";
969 clsoptions << "twoside,";
975 if (columns != tclass.columns()) {
977 clsoptions << "twocolumn,";
979 clsoptions << "onecolumn,";
983 && orientation == ORIENTATION_LANDSCAPE)
984 clsoptions << "landscape,";
986 // language should be a parameter to \documentclass
987 if (language->babel() == "hebrew"
988 && default_language->babel() != "hebrew")
989 // This seems necessary
990 features.useLanguage(default_language);
992 ostringstream language_options;
993 bool const use_babel = features.useBabel();
995 language_options << features.getLanguages();
996 if (!language->babel().empty()) {
997 if (!language_options.str().empty())
998 language_options << ',';
999 language_options << language->babel();
1001 // when Vietnamese is used, babel must directly be loaded with the
1002 // language options, not in the class options, see
1003 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1004 size_t viet = language_options.str().find("vietnam");
1005 // viet = string::npos when not found
1006 // when Japanese is used, babel must directly be loaded with the
1007 // language options, not in the class options, see
1008 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1009 size_t japan = language_options.str().find("japanese");
1010 // japan = string::npos when not found
1011 if (lyxrc.language_global_options && !language_options.str().empty()
1012 && viet == string::npos && japan == string::npos)
1013 clsoptions << language_options.str() << ',';
1016 // the user-defined options
1017 if (!options.empty()) {
1018 clsoptions << options << ',';
1021 string strOptions(clsoptions.str());
1022 if (!strOptions.empty()) {
1023 strOptions = rtrim(strOptions, ",");
1025 os << '[' << from_utf8(strOptions) << ']';
1028 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1030 // end of \documentclass defs
1032 // font selection must be done before loading fontenc.sty
1033 string const fonts =
1034 loadFonts(fontsRoman, fontsSans,
1035 fontsTypewriter, fontsSC, fontsOSF,
1036 fontsSansScale, fontsTypewriterScale);
1037 if (!fonts.empty()) {
1038 os << from_ascii(fonts);
1041 if (fontsDefaultFamily != "default")
1042 os << "\\renewcommand{\\familydefault}{\\"
1043 << from_ascii(fontsDefaultFamily) << "}\n";
1045 // set font encoding
1046 // this one is not per buffer
1047 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1048 if (lyxrc.fontenc != "default") {
1049 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1050 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1051 << ",LFE,LAE]{fontenc}\n";
1054 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1060 // handle inputenc etc.
1061 writeEncodingPreamble(os, features, texrow);
1063 if (!listings_params.empty()) {
1064 os << "\\usepackage{listings}\n";
1067 // do not test validity because listings_params is supposed to be valid
1068 string par = InsetListingsParams(listings_params).separatedParams(true);
1069 os << from_ascii(par);
1070 // count the number of newlines
1071 for (size_t i = 0; i < par.size(); ++i)
1077 if (use_geometry || nonstandard_papersize) {
1078 os << "\\usepackage{geometry}\n";
1080 os << "\\geometry{verbose";
1081 if (orientation == ORIENTATION_LANDSCAPE)
1083 switch (papersize) {
1085 if (!paperwidth.empty())
1086 os << ",paperwidth="
1087 << from_ascii(paperwidth);
1088 if (!paperheight.empty())
1089 os << ",paperheight="
1090 << from_ascii(paperheight);
1092 case PAPER_USLETTER:
1093 os << ",letterpaper";
1096 os << ",legalpaper";
1098 case PAPER_USEXECUTIVE:
1099 os << ",executivepaper";
1120 // default papersize ie PAPER_DEFAULT
1121 switch (lyxrc.default_papersize) {
1122 case PAPER_DEFAULT: // keep compiler happy
1123 case PAPER_USLETTER:
1124 os << ",letterpaper";
1127 os << ",legalpaper";
1129 case PAPER_USEXECUTIVE:
1130 os << ",executivepaper";
1150 if (!topmargin.empty())
1151 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1152 if (!bottommargin.empty())
1153 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1154 if (!leftmargin.empty())
1155 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1156 if (!rightmargin.empty())
1157 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1158 if (!headheight.empty())
1159 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1160 if (!headsep.empty())
1161 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1162 if (!footskip.empty())
1163 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1164 if (!columnsep.empty())
1165 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1168 } else if (orientation == ORIENTATION_LANDSCAPE) {
1169 features.require("papersize");
1172 if (tokenPos(tclass.opt_pagestyle(),
1173 '|', pagestyle) >= 0) {
1174 if (pagestyle == "fancy") {
1175 os << "\\usepackage{fancyhdr}\n";
1178 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1182 // Only if class has a ToC hierarchy
1183 if (tclass.hasTocLevels()) {
1184 if (secnumdepth != tclass.secnumdepth()) {
1185 os << "\\setcounter{secnumdepth}{"
1190 if (tocdepth != tclass.tocdepth()) {
1191 os << "\\setcounter{tocdepth}{"
1198 if (paragraph_separation) {
1199 switch (getDefSkip().kind()) {
1200 case VSpace::SMALLSKIP:
1201 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1203 case VSpace::MEDSKIP:
1204 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1206 case VSpace::BIGSKIP:
1207 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1209 case VSpace::LENGTH:
1210 os << "\\setlength{\\parskip}{"
1211 << from_utf8(getDefSkip().length().asLatexString())
1214 default: // should never happen // Then delete it.
1215 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1220 os << "\\setlength{\\parindent}{0pt}\n";
1224 // If we use jurabib, we have to call babel here.
1225 if (use_babel && features.isRequired("jurabib")) {
1226 os << from_ascii(babelCall(language_options.str()))
1228 << from_ascii(features.getBabelOptions());
1232 // Now insert the LyX specific LaTeX commands...
1234 // The optional packages;
1235 docstring lyxpreamble(from_ascii(features.getPackages()));
1238 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1240 // We try to load babel late, in case it interferes with other
1241 // packages. But some packages also need babel to be loaded
1242 // before, e.g. jurabib has to be called after babel. So load
1243 // babel after the optional packages but before the
1244 // user-defined preamble. This allows the users to redefine
1245 // babel commands, e.g. to translate the word "Index" to the
1246 // German "Stichwortverzeichnis". For more infos why this
1247 // place was chosen, see
1248 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1249 // If you encounter problems, you can shift babel to its old
1250 // place behind the user-defined preamble. But in this case
1251 // you must change the Vietnamese support from currently
1252 // "\usepackage[vietnamese]{babel}" to:
1253 // \usepackage{vietnamese}
1254 // \usepackage{babel}
1255 // because vietnamese must be loaded before hyperref
1256 if (use_babel && !features.isRequired("jurabib")) {
1258 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1259 lyxpreamble += from_utf8(features.getBabelOptions());
1263 // * Hyperref manual: "Make sure it comes last of your loaded
1264 // packages, to give it a fighting chance of not being over-written,
1265 // since its job is to redefine many LATEX commands."
1266 // * Email from Heiko Oberdiek: "It is usually better to load babel
1267 // before hyperref. Then hyperref has a chance to detect babel.
1268 // * Has to be loaded before the "LyX specific LaTeX commands" to
1269 // avoid errors with algorithm floats.
1270 // use hyperref explicitely when it is required
1271 if (features.isRequired("hyperref")) {
1272 odocstringstream oss;
1273 pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
1274 lyxpreamble += oss.str();
1277 // Will be surrounded by \makeatletter and \makeatother when needed
1278 docstring atlyxpreamble;
1280 // Some macros LyX will need
1281 docstring tmppreamble(from_ascii(features.getMacros()));
1283 if (!tmppreamble.empty())
1284 atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1285 "LyX specific LaTeX commands.\n"
1286 + tmppreamble + '\n';
1288 // the text class specific preamble
1289 tmppreamble = features.getTClassPreamble();
1290 if (!tmppreamble.empty())
1291 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1292 "Textclass specific LaTeX commands.\n"
1293 + tmppreamble + '\n';
1295 /* the user-defined preamble */
1296 if (!preamble.empty())
1298 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1299 "User specified LaTeX commands.\n"
1300 + from_utf8(preamble) + '\n';
1302 // subfig loads internally the LaTeX package "caption". As
1303 // caption is a very popular package, users will load it in
1304 // the preamble. Therefore we must load subfig behind the
1305 // user-defined preamble and check if the caption package was
1306 // loaded or not. For the case that caption is loaded before
1307 // subfig, there is the subfig option "caption=false". This
1308 // option also works when a koma-script class is used and
1309 // koma's own caption commands are used instead of caption. We
1310 // use \PassOptionsToPackage here because the user could have
1311 // already loaded subfig in the preamble.
1312 if (features.isRequired("subfig")) {
1313 atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n"
1314 " \\PassOptionsToPackage{caption=false}{subfig}}\n"
1315 "\\usepackage{subfig}\n";
1318 // Itemize bullet settings need to be last in case the user
1319 // defines their own bullets that use a package included
1320 // in the user-defined preamble -- ARRae
1321 // Actually it has to be done much later than that
1322 // since some packages like frenchb make modifications
1323 // at \begin{document} time -- JMarc
1324 docstring bullets_def;
1325 for (int i = 0; i < 4; ++i) {
1326 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1327 if (bullets_def.empty())
1328 bullets_def += "\\AtBeginDocument{\n";
1329 bullets_def += " \\def\\labelitemi";
1331 // `i' is one less than the item to modify
1338 bullets_def += "ii";
1344 bullets_def += '{' +
1345 user_defined_bullet(i).getText()
1350 if (!bullets_def.empty())
1351 atlyxpreamble += bullets_def + "}\n\n";
1353 if (atlyxpreamble.find(from_ascii("@")) != docstring::npos)
1354 lyxpreamble += "\n\\makeatletter\n"
1355 + atlyxpreamble + "\\makeatother\n\n";
1357 lyxpreamble += '\n' + atlyxpreamble;
1360 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1361 for (int j = 0; j != nlines; ++j) {
1370 void BufferParams::useClassDefaults()
1372 DocumentClass const & tclass = documentClass();
1374 sides = tclass.sides();
1375 columns = tclass.columns();
1376 pagestyle = tclass.pagestyle();
1377 options = tclass.options();
1378 // Only if class has a ToC hierarchy
1379 if (tclass.hasTocLevels()) {
1380 secnumdepth = tclass.secnumdepth();
1381 tocdepth = tclass.tocdepth();
1386 bool BufferParams::hasClassDefaults() const
1388 DocumentClass const & tclass = documentClass();
1390 return sides == tclass.sides()
1391 && columns == tclass.columns()
1392 && pagestyle == tclass.pagestyle()
1393 && options == tclass.options()
1394 && secnumdepth == tclass.secnumdepth()
1395 && tocdepth == tclass.tocdepth();
1399 DocumentClass const & BufferParams::documentClass() const
1405 DocumentClass const * BufferParams::documentClassPtr() const {
1410 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1411 // evil, but this function is evil
1412 doc_class_ = const_cast<DocumentClass *>(tc);
1416 bool BufferParams::setBaseClass(string const & classname)
1418 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1419 LayoutFileList & bcl = LayoutFileList::get();
1420 if (!bcl.haveClass(classname)) {
1422 bformat(_("The document class %1$s could not be found. "
1423 "A default textclass with default layouts will be used. "
1424 "LyX might not be able to produce output unless a correct "
1425 "textclass is selected from the document settings dialog."),
1426 from_utf8(classname));
1427 frontend::Alert::error(_("Document class not found"), s);
1428 bcl.addEmptyClass(classname);
1431 if (bcl[classname].load()) {
1432 pimpl_->baseClass_ = classname;
1437 bformat(_("The document class %1$s could not be loaded."),
1438 from_utf8(classname));
1439 frontend::Alert::error(_("Could not load class"), s);
1444 LayoutFile const * BufferParams::baseClass() const
1446 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
1447 return &(LayoutFileList::get()[pimpl_->baseClass_]);
1453 LayoutFileIndex const & BufferParams::baseClassID() const
1455 return pimpl_->baseClass_;
1459 void BufferParams::makeDocumentClass()
1464 doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass()));
1466 //FIXME It might be worth loading the children's modules here,
1467 //just as we load their bibliographies and such, instead of just
1468 //doing a check in InsetInclude.
1469 LayoutModuleList::const_iterator it = layoutModules_.begin();
1470 for (; it != layoutModules_.end(); it++) {
1471 string const modName = *it;
1472 LyXModule * lm = moduleList[modName];
1474 docstring const msg =
1475 bformat(_("The module %1$s has been requested by\n"
1476 "this document but has not been found in the list of\n"
1477 "available modules. If you recently installed it, you\n"
1478 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1479 frontend::Alert::warning(_("Module not available"),
1480 msg + _("Some layouts may not be available."));
1481 LYXERR0("BufferParams::makeDocumentClass(): Module " <<
1482 modName << " requested but not found in module list.");
1485 if (!lm->isAvailable()) {
1486 docstring const msg =
1487 bformat(_("The module %1$s requires a package that is\n"
1488 "not available in your LaTeX installation. LaTeX output\n"
1489 "may not be possible.\n"), from_utf8(modName));
1490 frontend::Alert::warning(_("Package not available"), msg);
1492 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1493 if (!doc_class_->read(layout_file, TextClass::MODULE)) {
1494 docstring const msg =
1495 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1496 frontend::Alert::warning(_("Read Error"), msg);
1499 if (!local_layout.empty()) {
1500 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
1501 docstring const msg = _("Error reading internal layout information");
1502 frontend::Alert::warning(_("Read Error"), msg);
1508 vector<string> const & BufferParams::getModules() const
1510 return layoutModules_;
1515 bool BufferParams::addLayoutModule(string const & modName)
1517 LayoutModuleList::const_iterator it = layoutModules_.begin();
1518 LayoutModuleList::const_iterator end = layoutModules_.end();
1519 for (; it != end; it++)
1522 layoutModules_.push_back(modName);
1527 void BufferParams::clearLayoutModules()
1529 layoutModules_.clear();
1533 Font const BufferParams::getFont() const
1535 FontInfo f = documentClass().defaultfont();
1536 if (fontsDefaultFamily == "rmdefault")
1537 f.setFamily(ROMAN_FAMILY);
1538 else if (fontsDefaultFamily == "sfdefault")
1539 f.setFamily(SANS_FAMILY);
1540 else if (fontsDefaultFamily == "ttdefault")
1541 f.setFamily(TYPEWRITER_FAMILY);
1542 return Font(f, language);
1546 void BufferParams::readPreamble(Lexer & lex)
1548 if (lex.getString() != "\\begin_preamble")
1549 lyxerr << "Error (BufferParams::readPreamble):"
1550 "consistency check failed." << endl;
1552 preamble = lex.getLongString("\\end_preamble");
1556 void BufferParams::readLocalLayout(Lexer & lex)
1558 if (lex.getString() != "\\begin_local_layout")
1559 lyxerr << "Error (BufferParams::readLocalLayout):"
1560 "consistency check failed." << endl;
1562 local_layout = lex.getLongString("\\end_local_layout");
1566 void BufferParams::readLanguage(Lexer & lex)
1568 if (!lex.next()) return;
1570 string const tmptok = lex.getString();
1572 // check if tmptok is part of tex_babel in tex-defs.h
1573 language = languages.getLanguage(tmptok);
1575 // Language tmptok was not found
1576 language = default_language;
1577 lyxerr << "Warning: Setting language `"
1578 << tmptok << "' to `" << language->lang()
1584 void BufferParams::readGraphicsDriver(Lexer & lex)
1589 string const tmptok = lex.getString();
1590 // check if tmptok is part of tex_graphics in tex_defs.h
1593 string const test = tex_graphics[n++];
1595 if (test == tmptok) {
1596 graphicsDriver = tmptok;
1601 "Warning: graphics driver `$$Token' not recognized!\n"
1602 " Setting graphics driver to `default'.\n");
1603 graphicsDriver = "default";
1610 void BufferParams::readBullets(Lexer & lex)
1615 int const index = lex.getInteger();
1617 int temp_int = lex.getInteger();
1618 user_defined_bullet(index).setFont(temp_int);
1619 temp_bullet(index).setFont(temp_int);
1621 user_defined_bullet(index).setCharacter(temp_int);
1622 temp_bullet(index).setCharacter(temp_int);
1624 user_defined_bullet(index).setSize(temp_int);
1625 temp_bullet(index).setSize(temp_int);
1629 void BufferParams::readBulletsLaTeX(Lexer & lex)
1631 // The bullet class should be able to read this.
1634 int const index = lex.getInteger();
1636 docstring const temp_str = lex.getDocString();
1638 user_defined_bullet(index).setText(temp_str);
1639 temp_bullet(index).setText(temp_str);
1643 void BufferParams::readModules(Lexer & lex)
1645 if (!lex.eatLine()) {
1646 lyxerr << "Error (BufferParams::readModules):"
1647 "Unexpected end of input." << endl;
1651 string mod = lex.getString();
1652 if (mod == "\\end_modules")
1654 addLayoutModule(mod);
1660 string BufferParams::paperSizeName(PapersizePurpose purpose) const
1662 char real_papersize = papersize;
1663 if (real_papersize == PAPER_DEFAULT)
1664 real_papersize = lyxrc.default_papersize;
1666 switch (real_papersize) {
1668 // could be anything, so don't guess
1670 case PAPER_CUSTOM: {
1671 if (purpose == XDVI && !paperwidth.empty() &&
1672 !paperheight.empty()) {
1673 // heightxwidth<unit>
1674 string first = paperwidth;
1675 string second = paperheight;
1676 if (orientation == ORIENTATION_LANDSCAPE)
1679 return first.erase(first.length() - 2)
1691 // dvips and dvipdfm do not know this
1692 if (purpose == DVIPS || purpose == DVIPDFM)
1696 // dvipdfm does not know this
1697 if (purpose == DVIPDFM)
1701 // dvipdfm does not know this
1702 if (purpose == DVIPDFM)
1705 case PAPER_USEXECUTIVE:
1706 // dvipdfm does not know this
1707 if (purpose == DVIPDFM)
1712 case PAPER_USLETTER:
1714 if (purpose == XDVI)
1721 string const BufferParams::dvips_options() const
1726 && papersize == PAPER_CUSTOM
1727 && !lyxrc.print_paper_dimension_flag.empty()
1728 && !paperwidth.empty()
1729 && !paperheight.empty()) {
1730 // using a custom papersize
1731 result = lyxrc.print_paper_dimension_flag;
1732 result += ' ' + paperwidth;
1733 result += ',' + paperheight;
1735 string const paper_option = paperSizeName(DVIPS);
1736 if (!paper_option.empty() && (paper_option != "letter" ||
1737 orientation != ORIENTATION_LANDSCAPE)) {
1738 // dvips won't accept -t letter -t landscape.
1739 // In all other cases, include the paper size
1741 result = lyxrc.print_paper_flag;
1742 result += ' ' + paper_option;
1745 if (orientation == ORIENTATION_LANDSCAPE &&
1746 papersize != PAPER_CUSTOM)
1747 result += ' ' + lyxrc.print_landscape_flag;
1752 string BufferParams::babelCall(string const & lang_opts) const
1754 string lang_pack = lyxrc.language_package;
1755 if (lang_pack != "\\usepackage{babel}")
1757 // suppress the babel call when there is no babel language defined
1758 // for the document language in the lib/languages file and if no
1759 // other languages are used (lang_opts is then empty)
1760 if (lang_opts.empty())
1762 // when Vietnamese is used, babel must directly be loaded with the
1763 // language options, see
1764 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1765 size_t viet = lang_opts.find("vietnam");
1766 // viet = string::npos when not found
1767 // when Japanese is used, babel must directly be loaded with the
1768 // language options, see
1769 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1770 size_t japan = lang_opts.find("japanese");
1771 // japan = string::npos when not found
1772 if (!lyxrc.language_global_options || viet != string::npos || japan != string::npos)
1773 return "\\usepackage[" + lang_opts + "]{babel}";
1778 void BufferParams::writeEncodingPreamble(odocstream & os,
1779 LaTeXFeatures & features, TexRow & texrow) const
1781 if (inputenc == "auto") {
1782 string const doc_encoding =
1783 language->encoding()->latexName();
1784 Encoding::Package const package =
1785 language->encoding()->package();
1787 // Create a list with all the input encodings used
1789 set<string> encodings =
1790 features.getEncodingSet(doc_encoding);
1792 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1793 // package inputenc must be omitted. Therefore set the encoding to empty.
1794 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1795 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1796 doc_encoding == "SJIS-plain")
1799 if (!encodings.empty() || package == Encoding::inputenc) {
1800 os << "\\usepackage[";
1801 set<string>::const_iterator it = encodings.begin();
1802 set<string>::const_iterator const end = encodings.end();
1804 os << from_ascii(*it);
1807 for (; it != end; ++it)
1808 os << ',' << from_ascii(*it);
1809 if (package == Encoding::inputenc) {
1810 if (!encodings.empty())
1812 os << from_ascii(doc_encoding);
1814 os << "]{inputenc}\n";
1817 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1818 os << "\\usepackage{CJK}\n";
1821 } else if (inputenc != "default") {
1822 switch (encoding().package()) {
1823 case Encoding::none:
1825 case Encoding::inputenc:
1826 os << "\\usepackage[" << from_ascii(inputenc)
1831 os << "\\usepackage{CJK}\n";
1837 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1838 // armscii8 is used for Armenian.
1839 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1840 os << "\\usepackage{armtex}\n";
1846 string const BufferParams::loadFonts(string const & rm,
1847 string const & sf, string const & tt,
1848 bool const & sc, bool const & osf,
1849 int const & sfscale, int const & ttscale) const
1851 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1852 several packages have been replaced by others, that might not
1853 be installed on every system. We have to take care for that
1854 (see psnfss.pdf). We try to support all psnfss fonts as well
1855 as the fonts that have become de facto standard in the LaTeX
1856 world (e.g. Latin Modern). We do not support obsolete fonts
1857 (like PSLatex). In general, it should be possible to mix any
1858 rm font with any sf or tt font, respectively. (JSpitzm)
1860 -- separate math fonts.
1863 if (rm == "default" && sf == "default" && tt == "default")
1870 // Computer Modern (must be explicitely selectable -- there might be classes
1871 // that define a different default font!
1873 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1874 // osf for Computer Modern needs eco.sty
1876 os << "\\usepackage{eco}\n";
1878 // Latin Modern Roman
1879 else if (rm == "lmodern")
1880 os << "\\usepackage{lmodern}\n";
1882 else if (rm == "ae") {
1883 // not needed when using OT1 font encoding.
1884 if (lyxrc.fontenc != "default")
1885 os << "\\usepackage{ae,aecompl}\n";
1888 else if (rm == "times") {
1889 // try to load the best available package
1890 if (LaTeXFeatures::isAvailable("mathptmx"))
1891 os << "\\usepackage{mathptmx}\n";
1892 else if (LaTeXFeatures::isAvailable("mathptm"))
1893 os << "\\usepackage{mathptm}\n";
1895 os << "\\usepackage{times}\n";
1898 else if (rm == "palatino") {
1899 // try to load the best available package
1900 if (LaTeXFeatures::isAvailable("mathpazo")) {
1901 os << "\\usepackage";
1907 // "osf" includes "sc"!
1911 os << "{mathpazo}\n";
1913 else if (LaTeXFeatures::isAvailable("mathpple"))
1914 os << "\\usepackage{mathpple}\n";
1916 os << "\\usepackage{palatino}\n";
1919 else if (rm == "utopia") {
1920 // fourier supersedes utopia.sty, but does
1921 // not work with OT1 encoding.
1922 if (LaTeXFeatures::isAvailable("fourier")
1923 && lyxrc.fontenc != "default") {
1924 os << "\\usepackage";
1935 os << "{fourier}\n";
1938 os << "\\usepackage{utopia}\n";
1940 // Bera (complete fontset)
1941 else if (rm == "bera" && sf == "default" && tt == "default")
1942 os << "\\usepackage{bera}\n";
1944 else if (rm != "default")
1945 os << "\\usepackage" << "{" << rm << "}\n";
1948 // Helvetica, Bera Sans
1949 if (sf == "helvet" || sf == "berasans") {
1951 os << "\\usepackage[scaled=" << float(sfscale) / 100
1952 << "]{" << sf << "}\n";
1954 os << "\\usepackage{" << sf << "}\n";
1957 else if (sf == "avant")
1958 os << "\\usepackage{" << sf << "}\n";
1959 // Computer Modern, Latin Modern, CM Bright
1960 else if (sf != "default")
1961 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1963 // monospaced/typewriter
1964 // Courier, LuxiMono
1965 if (tt == "luximono" || tt == "beramono") {
1967 os << "\\usepackage[scaled=" << float(ttscale) / 100
1968 << "]{" << tt << "}\n";
1970 os << "\\usepackage{" << tt << "}\n";
1973 else if (tt == "courier" )
1974 os << "\\usepackage{" << tt << "}\n";
1975 // Computer Modern, Latin Modern, CM Bright
1976 else if (tt != "default")
1977 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1983 Encoding const & BufferParams::encoding() const
1985 if (inputenc == "auto" || inputenc == "default")
1986 return *language->encoding();
1987 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
1990 LYXERR0("Unknown inputenc value `" << inputenc
1991 << "'. Using `auto' instead.");
1992 return *language->encoding();
1996 CiteEngine BufferParams::citeEngine() const
1998 // FIXME the class should provide the numerical/
1999 // authoryear choice
2000 if (documentClass().provides("natbib")
2001 && cite_engine_ != ENGINE_NATBIB_NUMERICAL)
2002 return ENGINE_NATBIB_AUTHORYEAR;
2003 return cite_engine_;
2007 void BufferParams::setCiteEngine(CiteEngine cite_engine)
2009 cite_engine_ = cite_engine;