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