2 * \file BufferParams.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Alfredo Braunstein
7 * \author Lars Gullik Bjønnes
8 * \author Jean-Marc Lasgouttes
10 * \author André Pönitz
11 * \author Martin Vermeer
13 * Full author contact details are available in file CREDITS.
18 #include "BufferParams.h"
21 #include "LayoutFile.h"
22 #include "BranchList.h"
23 #include "buffer_funcs.h"
28 #include "LaTeXFeatures.h"
29 #include "ModuleList.h"
33 #include "OutputParams.h"
37 #include "PDFOptions.h"
39 #include "frontends/alert.h"
41 #include "insets/InsetListingsParams.h"
43 #include "support/convert.h"
44 #include "support/debug.h"
45 #include "support/docstream.h"
46 #include "support/FileName.h"
47 #include "support/filetools.h"
48 #include "support/gettext.h"
49 #include "support/Messages.h"
50 #include "support/Translator.h"
51 #include "support/lstrings.h"
57 using namespace lyx::support;
60 static char const * const string_paragraph_separation[] = {
65 static char const * const string_quotes_language[] = {
66 "english", "swedish", "german", "polish", "french", "danish", ""
70 static char const * const string_papersize[] = {
71 "default", "custom", "letterpaper", "legalpaper", "executivepaper",
72 "a3paper", "a4paper", "a5paper", "b3paper", "b4paper", "b5paper", ""
76 static char const * const string_orientation[] = {
77 "portrait", "landscape", ""
81 static char const * const string_footnotekinds[] = {
82 "footnote", "margin", "fig", "tab", "alg", "wide-fig", "wide-tab", ""
86 static char const * const tex_graphics[] = {
87 "default", "dvips", "dvitops", "emtex",
88 "ln", "oztex", "textures", "none", ""
97 // Paragraph separation
98 typedef Translator<string, BufferParams::ParagraphSeparation> ParSepTranslator;
101 ParSepTranslator const init_parseptranslator()
103 ParSepTranslator translator
104 (string_paragraph_separation[0], BufferParams::ParagraphIndentSeparation);
105 translator.addPair(string_paragraph_separation[1], BufferParams::ParagraphSkipSeparation);
110 ParSepTranslator const & parseptranslator()
112 static ParSepTranslator translator = init_parseptranslator();
118 typedef Translator<string, InsetQuotes::QuoteLanguage> QuotesLangTranslator;
121 QuotesLangTranslator const init_quoteslangtranslator()
123 QuotesLangTranslator translator
124 (string_quotes_language[0], InsetQuotes::EnglishQuotes);
125 translator.addPair(string_quotes_language[1], InsetQuotes::SwedishQuotes);
126 translator.addPair(string_quotes_language[2], InsetQuotes::GermanQuotes);
127 translator.addPair(string_quotes_language[3], InsetQuotes::PolishQuotes);
128 translator.addPair(string_quotes_language[4], InsetQuotes::FrenchQuotes);
129 translator.addPair(string_quotes_language[5], InsetQuotes::DanishQuotes);
134 QuotesLangTranslator const & quoteslangtranslator()
136 static QuotesLangTranslator translator = init_quoteslangtranslator();
142 typedef Translator<string, PAPER_SIZE> PaperSizeTranslator;
145 static PaperSizeTranslator initPaperSizeTranslator()
147 PaperSizeTranslator translator(string_papersize[0], PAPER_DEFAULT);
148 translator.addPair(string_papersize[1], PAPER_CUSTOM);
149 translator.addPair(string_papersize[2], PAPER_USLETTER);
150 translator.addPair(string_papersize[3], PAPER_USLEGAL);
151 translator.addPair(string_papersize[4], PAPER_USEXECUTIVE);
152 translator.addPair(string_papersize[5], PAPER_A3);
153 translator.addPair(string_papersize[6], PAPER_A4);
154 translator.addPair(string_papersize[7], PAPER_A5);
155 translator.addPair(string_papersize[8], PAPER_B3);
156 translator.addPair(string_papersize[9], PAPER_B4);
157 translator.addPair(string_papersize[10], PAPER_B5);
162 PaperSizeTranslator const & papersizetranslator()
164 static PaperSizeTranslator translator = initPaperSizeTranslator();
170 typedef Translator<string, PAPER_ORIENTATION> PaperOrientationTranslator;
173 PaperOrientationTranslator const init_paperorientationtranslator()
175 PaperOrientationTranslator translator(string_orientation[0], ORIENTATION_PORTRAIT);
176 translator.addPair(string_orientation[1], ORIENTATION_LANDSCAPE);
181 PaperOrientationTranslator const & paperorientationtranslator()
183 static PaperOrientationTranslator translator = init_paperorientationtranslator();
189 typedef Translator<int, PageSides> SidesTranslator;
192 SidesTranslator const init_sidestranslator()
194 SidesTranslator translator(1, OneSide);
195 translator.addPair(2, TwoSides);
200 SidesTranslator const & sidestranslator()
202 static SidesTranslator translator = init_sidestranslator();
208 typedef Translator<int, BufferParams::Package> PackageTranslator;
211 PackageTranslator const init_packagetranslator()
213 PackageTranslator translator(0, BufferParams::package_off);
214 translator.addPair(1, BufferParams::package_auto);
215 translator.addPair(2, BufferParams::package_on);
220 PackageTranslator const & packagetranslator()
222 static PackageTranslator translator = init_packagetranslator();
228 typedef Translator<string, CiteEngine> CiteEngineTranslator;
231 CiteEngineTranslator const init_citeenginetranslator()
233 CiteEngineTranslator translator("basic", ENGINE_BASIC);
234 translator.addPair("natbib_numerical", ENGINE_NATBIB_NUMERICAL);
235 translator.addPair("natbib_authoryear", ENGINE_NATBIB_AUTHORYEAR);
236 translator.addPair("jurabib", ENGINE_JURABIB);
241 CiteEngineTranslator const & citeenginetranslator()
243 static CiteEngineTranslator translator = init_citeenginetranslator();
249 typedef Translator<string, Spacing::Space> SpaceTranslator;
252 SpaceTranslator const init_spacetranslator()
254 SpaceTranslator translator("default", Spacing::Default);
255 translator.addPair("single", Spacing::Single);
256 translator.addPair("onehalf", Spacing::Onehalf);
257 translator.addPair("double", Spacing::Double);
258 translator.addPair("other", Spacing::Other);
263 SpaceTranslator const & spacetranslator()
265 static SpaceTranslator translator = init_spacetranslator();
273 class BufferParams::Impl
278 AuthorList authorlist;
279 BranchList branchlist;
280 Bullet temp_bullets[4];
281 Bullet user_defined_bullets[4];
283 /** This is the amount of space used for paragraph_separation "skip",
284 * and for detached paragraphs in "indented" documents.
287 PDFOptions pdfoptions;
288 LayoutFileIndex baseClass_;
292 BufferParams::Impl::Impl()
293 : defskip(VSpace::MEDSKIP), baseClass_(string(""))
295 // set initial author
297 authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
302 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
306 return new BufferParams::Impl(*ptr);
310 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
316 BufferParams::BufferParams()
319 setBaseClass(defaultBaseclass());
321 paragraph_separation = ParagraphIndentSeparation;
322 quotes_language = InsetQuotes::EnglishQuotes;
323 fontsize = "default";
326 papersize = PAPER_DEFAULT;
327 orientation = ORIENTATION_PORTRAIT;
328 use_geometry = false;
329 use_amsmath = package_auto;
330 use_esint = package_auto;
331 cite_engine_ = ENGINE_BASIC;
332 use_bibtopic = false;
333 trackChanges = false;
334 outputChanges = false;
337 language = default_language;
338 fontsRoman = "default";
339 fontsSans = "default";
340 fontsTypewriter = "default";
341 fontsDefaultFamily = "default";
344 fontsSansScale = 100;
345 fontsTypewriterScale = 100;
347 graphicsDriver = "default";
350 listings_params = string();
351 pagestyle = "default";
353 for (int iter = 0; iter < 4; ++iter) {
354 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
355 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
360 docstring BufferParams::B_(string const & l10n) const
362 LASSERT(language, /**/);
363 return getMessages(language->code()).get(l10n);
367 AuthorList & BufferParams::authors()
369 return pimpl_->authorlist;
373 AuthorList const & BufferParams::authors() const
375 return pimpl_->authorlist;
379 BranchList & BufferParams::branchlist()
381 return pimpl_->branchlist;
385 BranchList const & BufferParams::branchlist() const
387 return pimpl_->branchlist;
391 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
393 LASSERT(index < 4, /**/);
394 return pimpl_->temp_bullets[index];
398 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
400 LASSERT(index < 4, /**/);
401 return pimpl_->temp_bullets[index];
405 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
407 LASSERT(index < 4, /**/);
408 return pimpl_->user_defined_bullets[index];
412 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
414 LASSERT(index < 4, /**/);
415 return pimpl_->user_defined_bullets[index];
419 Spacing & BufferParams::spacing()
421 return pimpl_->spacing;
425 Spacing const & BufferParams::spacing() const
427 return pimpl_->spacing;
431 PDFOptions & BufferParams::pdfoptions()
433 return pimpl_->pdfoptions;
437 PDFOptions const & BufferParams::pdfoptions() const
439 return pimpl_->pdfoptions;
443 VSpace const & BufferParams::getDefSkip() const
445 return pimpl_->defskip;
449 void BufferParams::setDefSkip(VSpace const & vs)
451 pimpl_->defskip = vs;
455 string BufferParams::readToken(Lexer & lex, string const & token,
456 FileName const & filepath)
458 if (token == "\\textclass") {
460 string const classname = lex.getString();
461 // if there exists a local layout file, ignore the system one
462 // NOTE: in this case, the textclass (.cls file) is assumed to be available.
464 LayoutFileList & bcl = LayoutFileList::get();
465 if (tcp.empty() && !filepath.empty())
466 tcp = bcl.addLayoutFile(classname, filepath.absFilename(), LayoutFileList::Local);
469 else if (bcl.haveClass(classname)) {
470 setBaseClass(classname);
472 // a warning will be given for unknown class
473 setBaseClass(defaultBaseclass());
476 // FIXME: this warning will be given even if there exists a local .cls
477 // file. Even worse, the .lyx file can not be compiled or exported
478 // because the textclass is marked as unavilable.
479 if (!baseClass()->isTeXClassAvailable()) {
480 docstring const msg =
481 bformat(_("The layout file requested by this document,\n"
483 "is not usable. This is probably because a LaTeX\n"
484 "class or style file required by it is not\n"
485 "available. See the Customization documentation\n"
486 "for more information.\n"), from_utf8(classname));
487 frontend::Alert::warning(_("Document class not available"),
488 msg + _("LyX will not be able to produce output."));
491 } else if (token == "\\begin_preamble") {
493 } else if (token == "\\begin_local_layout") {
494 readLocalLayout(lex);
495 } else if (token == "\\begin_modules") {
497 } else if (token == "\\options") {
499 options = lex.getString();
500 } else if (token == "\\master") {
502 master = lex.getString();
503 } else if (token == "\\language") {
505 } else if (token == "\\inputencoding") {
507 } else if (token == "\\graphics") {
508 readGraphicsDriver(lex);
509 } else if (token == "\\font_roman") {
511 } else if (token == "\\font_sans") {
513 } else if (token == "\\font_typewriter") {
514 lex >> fontsTypewriter;
515 } else if (token == "\\font_default_family") {
516 lex >> fontsDefaultFamily;
517 } else if (token == "\\font_sc") {
519 } else if (token == "\\font_osf") {
521 } else if (token == "\\font_sf_scale") {
522 lex >> fontsSansScale;
523 } else if (token == "\\font_tt_scale") {
524 lex >> fontsTypewriterScale;
525 } else if (token == "\\font_cjk") {
527 } else if (token == "\\paragraph_separation") {
530 paragraph_separation = parseptranslator().find(parsep);
531 } else if (token == "\\defskip") {
533 string defskip = lex.getString();
534 if (defskip == "defskip")
537 pimpl_->defskip = VSpace(defskip);
538 } else if (token == "\\quotes_language") {
541 quotes_language = quoteslangtranslator().find(quotes_lang);
542 } else if (token == "\\papersize") {
545 papersize = papersizetranslator().find(ppsize);
546 } else if (token == "\\use_geometry") {
548 } else if (token == "\\use_amsmath") {
551 use_amsmath = packagetranslator().find(use_ams);
552 } else if (token == "\\use_esint") {
555 use_esint = packagetranslator().find(useesint);
556 } else if (token == "\\cite_engine") {
559 cite_engine_ = citeenginetranslator().find(engine);
560 } else if (token == "\\use_bibtopic") {
562 } else if (token == "\\tracking_changes") {
564 } else if (token == "\\output_changes") {
565 lex >> outputChanges;
566 } else if (token == "\\branch") {
568 docstring branch = lex.getDocString();
569 branchlist().add(branch);
572 string const tok = lex.getString();
573 if (tok == "\\end_branch")
575 Branch * branch_ptr = branchlist().find(branch);
576 if (tok == "\\selected") {
579 branch_ptr->setSelected(lex.getInteger());
581 // not yet operational
582 if (tok == "\\color") {
584 string color = lex.getString();
586 branch_ptr->setColor(color);
587 // Update also the Color table:
589 color = lcolor.getX11Name(Color_background);
591 lcolor.setColor(to_utf8(branch), color);
595 } else if (token == "\\author") {
597 istringstream ss(lex.getString());
600 author_map.push_back(pimpl_->authorlist.record(a));
601 } else if (token == "\\paperorientation") {
604 orientation = paperorientationtranslator().find(orient);
605 } else if (token == "\\paperwidth") {
607 } else if (token == "\\paperheight") {
609 } else if (token == "\\leftmargin") {
611 } else if (token == "\\topmargin") {
613 } else if (token == "\\rightmargin") {
615 } else if (token == "\\bottommargin") {
617 } else if (token == "\\headheight") {
619 } else if (token == "\\headsep") {
621 } else if (token == "\\footskip") {
623 } else if (token == "\\columnsep") {
625 } else if (token == "\\paperfontsize") {
627 } else if (token == "\\papercolumns") {
629 } else if (token == "\\listings_params") {
632 listings_params = InsetListingsParams(par).params();
633 } else if (token == "\\papersides") {
636 sides = sidestranslator().find(psides);
637 } else if (token == "\\paperpagestyle") {
639 } else if (token == "\\bullet") {
641 } else if (token == "\\bulletLaTeX") {
642 readBulletsLaTeX(lex);
643 } else if (token == "\\secnumdepth") {
645 } else if (token == "\\tocdepth") {
647 } else if (token == "\\spacing") {
651 if (nspacing == "other") {
654 spacing().set(spacetranslator().find(nspacing), tmp_val);
655 } else if (token == "\\float_placement") {
656 lex >> float_placement;
658 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
659 string toktmp = pdfoptions().readToken(lex, token);
660 if (!toktmp.empty()) {
661 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
666 lyxerr << "BufferParams::readToken(): Unknown token: " <<
675 void BufferParams::writeFile(ostream & os) const
677 // The top of the file is written by the buffer.
678 // Prints out the buffer info into the .lyx file given by file
681 os << "\\textclass " << baseClass()->name() << '\n';
684 if (!preamble.empty()) {
685 // remove '\n' from the end of preamble
686 string const tmppreamble = rtrim(preamble, "\n");
687 os << "\\begin_preamble\n"
689 << "\n\\end_preamble\n";
693 if (!options.empty()) {
694 os << "\\options " << options << '\n';
697 // the master document
698 if (!master.empty()) {
699 os << "\\master " << master << '\n';
703 if (!layoutModules_.empty()) {
704 os << "\\begin_modules" << '\n';
705 LayoutModuleList::const_iterator it = layoutModules_.begin();
706 for (; it != layoutModules_.end(); it++)
708 os << "\\end_modules" << '\n';
711 // local layout information
712 if (!local_layout.empty()) {
713 // remove '\n' from the end
714 string const tmplocal = rtrim(local_layout, "\n");
715 os << "\\begin_local_layout\n"
717 << "\n\\end_local_layout\n";
720 // then the text parameters
721 if (language != ignore_language)
722 os << "\\language " << language->lang() << '\n';
723 os << "\\inputencoding " << inputenc
724 << "\n\\font_roman " << fontsRoman
725 << "\n\\font_sans " << fontsSans
726 << "\n\\font_typewriter " << fontsTypewriter
727 << "\n\\font_default_family " << fontsDefaultFamily
728 << "\n\\font_sc " << convert<string>(fontsSC)
729 << "\n\\font_osf " << convert<string>(fontsOSF)
730 << "\n\\font_sf_scale " << fontsSansScale
731 << "\n\\font_tt_scale " << fontsTypewriterScale
733 if (!fontsCJK.empty()) {
734 os << "\\font_cjk " << fontsCJK << '\n';
736 os << "\n\\graphics " << graphicsDriver << '\n';
738 if (!float_placement.empty()) {
739 os << "\\float_placement " << float_placement << '\n';
741 os << "\\paperfontsize " << fontsize << '\n';
743 spacing().writeFile(os);
744 pdfoptions().writeFile(os);
746 os << "\\papersize " << string_papersize[papersize]
747 << "\n\\use_geometry " << convert<string>(use_geometry)
748 << "\n\\use_amsmath " << use_amsmath
749 << "\n\\use_esint " << use_esint
750 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
751 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
752 << "\n\\paperorientation " << string_orientation[orientation]
755 BranchList::const_iterator it = branchlist().begin();
756 BranchList::const_iterator end = branchlist().end();
757 for (; it != end; ++it) {
758 os << "\\branch " << to_utf8(it->getBranch())
759 << "\n\\selected " << it->getSelected()
760 << "\n\\color " << lyx::X11hexname(it->getColor())
765 if (!paperwidth.empty())
766 os << "\\paperwidth "
767 << VSpace(paperwidth).asLyXCommand() << '\n';
768 if (!paperheight.empty())
769 os << "\\paperheight "
770 << VSpace(paperheight).asLyXCommand() << '\n';
771 if (!leftmargin.empty())
772 os << "\\leftmargin "
773 << VSpace(leftmargin).asLyXCommand() << '\n';
774 if (!topmargin.empty())
776 << VSpace(topmargin).asLyXCommand() << '\n';
777 if (!rightmargin.empty())
778 os << "\\rightmargin "
779 << VSpace(rightmargin).asLyXCommand() << '\n';
780 if (!bottommargin.empty())
781 os << "\\bottommargin "
782 << VSpace(bottommargin).asLyXCommand() << '\n';
783 if (!headheight.empty())
784 os << "\\headheight "
785 << VSpace(headheight).asLyXCommand() << '\n';
786 if (!headsep.empty())
788 << VSpace(headsep).asLyXCommand() << '\n';
789 if (!footskip.empty())
791 << VSpace(footskip).asLyXCommand() << '\n';
792 if (!columnsep.empty())
794 << VSpace(columnsep).asLyXCommand() << '\n';
795 os << "\\secnumdepth " << secnumdepth
796 << "\n\\tocdepth " << tocdepth
797 << "\n\\paragraph_separation "
798 << string_paragraph_separation[paragraph_separation]
799 << "\n\\defskip " << getDefSkip().asLyXCommand()
800 << "\n\\quotes_language "
801 << string_quotes_language[quotes_language]
802 << "\n\\papercolumns " << columns
803 << "\n\\papersides " << sides
804 << "\n\\paperpagestyle " << pagestyle << '\n';
805 if (!listings_params.empty())
806 os << "\\listings_params \"" <<
807 InsetListingsParams(listings_params).encodedString() << "\"\n";
808 for (int i = 0; i < 4; ++i) {
809 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
810 if (user_defined_bullet(i).getFont() != -1) {
811 os << "\\bullet " << i << " "
812 << user_defined_bullet(i).getFont() << " "
813 << user_defined_bullet(i).getCharacter() << " "
814 << user_defined_bullet(i).getSize() << "\n";
818 os << "\\bulletLaTeX " << i << " \""
819 << lyx::to_ascii(user_defined_bullet(i).getText())
825 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
826 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
828 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
829 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
830 for (; a_it != a_end; ++a_it) {
831 if (a_it->second.used())
832 os << "\\author " << a_it->second << "\n";
834 os << "\\author " << Author() << "\n";
839 void BufferParams::validate(LaTeXFeatures & features) const
841 features.require(documentClass().requires());
844 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
845 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
846 LaTeXFeatures::isAvailable("xcolor");
848 switch (features.runparams().flavor) {
849 case OutputParams::LATEX:
851 features.require("ct-dvipost");
852 features.require("dvipost");
853 } else if (xcolorsoul) {
854 features.require("ct-xcolor-soul");
855 features.require("soul");
856 features.require("xcolor");
858 features.require("ct-none");
861 case OutputParams::PDFLATEX:
863 features.require("ct-xcolor-soul");
864 features.require("soul");
865 features.require("xcolor");
866 // improves color handling in PDF output
867 features.require("pdfcolmk");
869 features.require("ct-none");
877 // Floats with 'Here definitely' as default setting.
878 if (float_placement.find('H') != string::npos)
879 features.require("float");
881 // AMS Style is at document level
882 if (use_amsmath == package_on
883 || documentClass().provides("amsmath"))
884 features.require("amsmath");
885 if (use_esint == package_on)
886 features.require("esint");
888 // Document-level line spacing
889 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
890 features.require("setspace");
892 // the bullet shapes are buffer level not paragraph level
893 // so they are tested here
894 for (int i = 0; i < 4; ++i) {
895 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
897 int const font = user_defined_bullet(i).getFont();
899 int const c = user_defined_bullet(i).getCharacter();
905 features.require("latexsym");
907 } else if (font == 1) {
908 features.require("amssymb");
909 } else if (font >= 2 && font <= 5) {
910 features.require("pifont");
914 if (pdfoptions().use_hyperref)
915 features.require("hyperref");
919 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
920 TexRow & texrow) const
922 os << "\\documentclass";
924 DocumentClass const & tclass = documentClass();
926 ostringstream clsoptions; // the document class options.
928 if (tokenPos(tclass.opt_fontsize(),
929 '|', fontsize) >= 0) {
930 // only write if existing in list (and not default)
931 clsoptions << fontsize << "pt,";
934 // custom, A3, B3 and B4 paper sizes need geometry
935 bool nonstandard_papersize = papersize == PAPER_B3
936 || papersize == PAPER_B4
937 || papersize == PAPER_A3
938 || papersize == PAPER_CUSTOM;
943 clsoptions << "a4paper,";
946 clsoptions << "letterpaper,";
949 clsoptions << "a5paper,";
952 clsoptions << "b5paper,";
954 case PAPER_USEXECUTIVE:
955 clsoptions << "executivepaper,";
958 clsoptions << "legalpaper,";
970 if (sides != tclass.sides()) {
973 clsoptions << "oneside,";
976 clsoptions << "twoside,";
982 if (columns != tclass.columns()) {
984 clsoptions << "twocolumn,";
986 clsoptions << "onecolumn,";
990 && orientation == ORIENTATION_LANDSCAPE)
991 clsoptions << "landscape,";
993 // language should be a parameter to \documentclass
994 if (language->babel() == "hebrew"
995 && default_language->babel() != "hebrew")
996 // This seems necessary
997 features.useLanguage(default_language);
999 ostringstream language_options;
1000 bool const use_babel = features.useBabel();
1002 language_options << features.getLanguages();
1003 if (!language->babel().empty()) {
1004 if (!language_options.str().empty())
1005 language_options << ',';
1006 language_options << language->babel();
1008 // when Vietnamese is used, babel must directly be loaded with the
1009 // language options, not in the class options, see
1010 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1011 size_t viet = language_options.str().find("vietnam");
1012 // viet = string::npos when not found
1013 // when Japanese is used, babel must directly be loaded with the
1014 // language options, not in the class options, see
1015 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1016 size_t japan = language_options.str().find("japanese");
1017 // japan = string::npos when not found
1018 if (lyxrc.language_global_options && !language_options.str().empty()
1019 && viet == string::npos && japan == string::npos)
1020 clsoptions << language_options.str() << ',';
1023 // the user-defined options
1024 if (!options.empty()) {
1025 clsoptions << options << ',';
1028 string strOptions(clsoptions.str());
1029 if (!strOptions.empty()) {
1030 strOptions = rtrim(strOptions, ",");
1032 os << '[' << from_utf8(strOptions) << ']';
1035 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1037 // end of \documentclass defs
1039 // font selection must be done before loading fontenc.sty
1040 string const fonts =
1041 loadFonts(fontsRoman, fontsSans,
1042 fontsTypewriter, fontsSC, fontsOSF,
1043 fontsSansScale, fontsTypewriterScale);
1044 if (!fonts.empty()) {
1045 os << from_ascii(fonts);
1048 if (fontsDefaultFamily != "default")
1049 os << "\\renewcommand{\\familydefault}{\\"
1050 << from_ascii(fontsDefaultFamily) << "}\n";
1052 // set font encoding
1053 // this one is not per buffer
1054 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1055 if (lyxrc.fontenc != "default") {
1056 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1057 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1058 << ",LFE,LAE]{fontenc}\n";
1061 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1067 // handle inputenc etc.
1068 writeEncodingPreamble(os, features, texrow);
1070 if (!listings_params.empty()) {
1071 os << "\\usepackage{listings}\n";
1074 // do not test validity because listings_params is supposed to be valid
1075 string par = InsetListingsParams(listings_params).separatedParams(true);
1076 os << from_ascii(par);
1077 // count the number of newlines
1078 for (size_t i = 0; i < par.size(); ++i)
1084 if (use_geometry || nonstandard_papersize) {
1085 os << "\\usepackage{geometry}\n";
1087 os << "\\geometry{verbose";
1088 if (orientation == ORIENTATION_LANDSCAPE)
1090 switch (papersize) {
1092 if (!paperwidth.empty())
1093 os << ",paperwidth="
1094 << from_ascii(paperwidth);
1095 if (!paperheight.empty())
1096 os << ",paperheight="
1097 << from_ascii(paperheight);
1099 case PAPER_USLETTER:
1100 os << ",letterpaper";
1103 os << ",legalpaper";
1105 case PAPER_USEXECUTIVE:
1106 os << ",executivepaper";
1127 // default papersize ie PAPER_DEFAULT
1128 switch (lyxrc.default_papersize) {
1129 case PAPER_DEFAULT: // keep compiler happy
1130 case PAPER_USLETTER:
1131 os << ",letterpaper";
1134 os << ",legalpaper";
1136 case PAPER_USEXECUTIVE:
1137 os << ",executivepaper";
1157 if (!topmargin.empty())
1158 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1159 if (!bottommargin.empty())
1160 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1161 if (!leftmargin.empty())
1162 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1163 if (!rightmargin.empty())
1164 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1165 if (!headheight.empty())
1166 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1167 if (!headsep.empty())
1168 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1169 if (!footskip.empty())
1170 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1171 if (!columnsep.empty())
1172 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1175 } else if (orientation == ORIENTATION_LANDSCAPE) {
1176 features.require("papersize");
1179 if (tokenPos(tclass.opt_pagestyle(),
1180 '|', pagestyle) >= 0) {
1181 if (pagestyle == "fancy") {
1182 os << "\\usepackage{fancyhdr}\n";
1185 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1189 // Only if class has a ToC hierarchy
1190 if (tclass.hasTocLevels()) {
1191 if (secnumdepth != tclass.secnumdepth()) {
1192 os << "\\setcounter{secnumdepth}{"
1197 if (tocdepth != tclass.tocdepth()) {
1198 os << "\\setcounter{tocdepth}{"
1205 if (paragraph_separation) {
1206 switch (getDefSkip().kind()) {
1207 case VSpace::SMALLSKIP:
1208 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1210 case VSpace::MEDSKIP:
1211 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1213 case VSpace::BIGSKIP:
1214 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1216 case VSpace::LENGTH:
1217 os << "\\setlength{\\parskip}{"
1218 << from_utf8(getDefSkip().length().asLatexString())
1221 default: // should never happen // Then delete it.
1222 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1227 os << "\\setlength{\\parindent}{0pt}\n";
1231 // If we use jurabib, we have to call babel here.
1232 if (use_babel && features.isRequired("jurabib")) {
1233 os << from_ascii(babelCall(language_options.str()))
1235 << from_ascii(features.getBabelOptions());
1239 // Now insert the LyX specific LaTeX commands...
1241 // The optional packages;
1242 docstring lyxpreamble(from_ascii(features.getPackages()));
1245 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1247 // We try to load babel late, in case it interferes with other
1248 // packages. But some packages also need babel to be loaded
1249 // before, e.g. jurabib has to be called after babel. So load
1250 // babel after the optional packages but before the
1251 // user-defined preamble. This allows the users to redefine
1252 // babel commands, e.g. to translate the word "Index" to the
1253 // German "Stichwortverzeichnis". For more infos why this
1254 // place was chosen, see
1255 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1256 // If you encounter problems, you can shift babel to its old
1257 // place behind the user-defined preamble. But in this case
1258 // you must change the Vietnamese support from currently
1259 // "\usepackage[vietnamese]{babel}" to:
1260 // \usepackage{vietnamese}
1261 // \usepackage{babel}
1262 // because vietnamese must be loaded before hyperref
1263 if (use_babel && !features.isRequired("jurabib")) {
1265 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1266 lyxpreamble += from_utf8(features.getBabelOptions());
1270 // * Hyperref manual: "Make sure it comes last of your loaded
1271 // packages, to give it a fighting chance of not being over-written,
1272 // since its job is to redefine many LATEX commands."
1273 // * Email from Heiko Oberdiek: "It is usually better to load babel
1274 // before hyperref. Then hyperref has a chance to detect babel.
1275 // * Has to be loaded before the "LyX specific LaTeX commands" to
1276 // avoid errors with algorithm floats.
1277 // use hyperref explicitely when it is required
1278 if (features.isRequired("hyperref")) {
1279 odocstringstream oss;
1280 pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
1281 lyxpreamble += oss.str();
1284 // Will be surrounded by \makeatletter and \makeatother when needed
1285 docstring atlyxpreamble;
1287 // Some macros LyX will need
1288 docstring tmppreamble(from_ascii(features.getMacros()));
1290 if (!tmppreamble.empty())
1291 atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1292 "LyX specific LaTeX commands.\n"
1293 + tmppreamble + '\n';
1295 // the text class specific preamble
1296 tmppreamble = features.getTClassPreamble();
1297 if (!tmppreamble.empty())
1298 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1299 "Textclass specific LaTeX commands.\n"
1300 + tmppreamble + '\n';
1302 /* the user-defined preamble */
1303 if (!preamble.empty())
1305 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1306 "User specified LaTeX commands.\n"
1307 + from_utf8(preamble) + '\n';
1309 // subfig loads internally the LaTeX package "caption". As
1310 // caption is a very popular package, users will load it in
1311 // the preamble. Therefore we must load subfig behind the
1312 // user-defined preamble and check if the caption package was
1313 // loaded or not. For the case that caption is loaded before
1314 // subfig, there is the subfig option "caption=false". This
1315 // option also works when a koma-script class is used and
1316 // koma's own caption commands are used instead of caption. We
1317 // use \PassOptionsToPackage here because the user could have
1318 // already loaded subfig in the preamble.
1319 if (features.isRequired("subfig")) {
1320 atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n"
1321 " \\PassOptionsToPackage{caption=false}{subfig}}\n"
1322 "\\usepackage{subfig}\n";
1325 // Itemize bullet settings need to be last in case the user
1326 // defines their own bullets that use a package included
1327 // in the user-defined preamble -- ARRae
1328 // Actually it has to be done much later than that
1329 // since some packages like frenchb make modifications
1330 // at \begin{document} time -- JMarc
1331 docstring bullets_def;
1332 for (int i = 0; i < 4; ++i) {
1333 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1334 if (bullets_def.empty())
1335 bullets_def += "\\AtBeginDocument{\n";
1336 bullets_def += " \\def\\labelitemi";
1338 // `i' is one less than the item to modify
1345 bullets_def += "ii";
1351 bullets_def += '{' +
1352 user_defined_bullet(i).getText()
1357 if (!bullets_def.empty())
1358 atlyxpreamble += bullets_def + "}\n\n";
1360 if (atlyxpreamble.find(from_ascii("@")) != docstring::npos)
1361 lyxpreamble += "\n\\makeatletter\n"
1362 + atlyxpreamble + "\\makeatother\n\n";
1364 lyxpreamble += '\n' + atlyxpreamble;
1367 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1368 for (int j = 0; j != nlines; ++j) {
1377 void BufferParams::useClassDefaults()
1379 DocumentClass const & tclass = documentClass();
1381 sides = tclass.sides();
1382 columns = tclass.columns();
1383 pagestyle = tclass.pagestyle();
1384 options = tclass.options();
1385 // Only if class has a ToC hierarchy
1386 if (tclass.hasTocLevels()) {
1387 secnumdepth = tclass.secnumdepth();
1388 tocdepth = tclass.tocdepth();
1393 bool BufferParams::hasClassDefaults() const
1395 DocumentClass const & tclass = documentClass();
1397 return sides == tclass.sides()
1398 && columns == tclass.columns()
1399 && pagestyle == tclass.pagestyle()
1400 && options == tclass.options()
1401 && secnumdepth == tclass.secnumdepth()
1402 && tocdepth == tclass.tocdepth();
1406 DocumentClass const & BufferParams::documentClass() const
1412 DocumentClass const * BufferParams::documentClassPtr() const {
1417 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1418 // evil, but this function is evil
1419 doc_class_ = const_cast<DocumentClass *>(tc);
1423 bool BufferParams::setBaseClass(string const & classname)
1425 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1426 LayoutFileList const & bcl = LayoutFileList::get();
1427 if (!bcl.haveClass(classname)) {
1429 bformat(_("The document class %1$s could not be found."),
1430 from_utf8(classname));
1431 frontend::Alert::error(_("Class not found"), s);
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 // when 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 // when 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 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare 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;