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 == "\\paragraph_separation") {
528 paragraph_separation = parseptranslator().find(parsep);
529 } else if (token == "\\defskip") {
531 string defskip = lex.getString();
532 if (defskip == "defskip")
535 pimpl_->defskip = VSpace(defskip);
536 } else if (token == "\\quotes_language") {
539 quotes_language = quoteslangtranslator().find(quotes_lang);
540 } else if (token == "\\papersize") {
543 papersize = papersizetranslator().find(ppsize);
544 } else if (token == "\\use_geometry") {
546 } else if (token == "\\use_amsmath") {
549 use_amsmath = packagetranslator().find(use_ams);
550 } else if (token == "\\use_esint") {
553 use_esint = packagetranslator().find(useesint);
554 } else if (token == "\\cite_engine") {
557 cite_engine_ = citeenginetranslator().find(engine);
558 } else if (token == "\\use_bibtopic") {
560 } else if (token == "\\tracking_changes") {
562 } else if (token == "\\output_changes") {
563 lex >> outputChanges;
564 } else if (token == "\\branch") {
566 docstring branch = lex.getDocString();
567 branchlist().add(branch);
570 string const tok = lex.getString();
571 if (tok == "\\end_branch")
573 Branch * branch_ptr = branchlist().find(branch);
574 if (tok == "\\selected") {
577 branch_ptr->setSelected(lex.getInteger());
579 // not yet operational
580 if (tok == "\\color") {
582 string color = lex.getString();
584 branch_ptr->setColor(color);
585 // Update also the Color table:
587 color = lcolor.getX11Name(Color_background);
589 lcolor.setColor(to_utf8(branch), color);
593 } else if (token == "\\author") {
595 istringstream ss(lex.getString());
598 author_map.push_back(pimpl_->authorlist.record(a));
599 } else if (token == "\\paperorientation") {
602 orientation = paperorientationtranslator().find(orient);
603 } else if (token == "\\paperwidth") {
605 } else if (token == "\\paperheight") {
607 } else if (token == "\\leftmargin") {
609 } else if (token == "\\topmargin") {
611 } else if (token == "\\rightmargin") {
613 } else if (token == "\\bottommargin") {
615 } else if (token == "\\headheight") {
617 } else if (token == "\\headsep") {
619 } else if (token == "\\footskip") {
621 } else if (token == "\\columnsep") {
623 } else if (token == "\\paperfontsize") {
625 } else if (token == "\\papercolumns") {
627 } else if (token == "\\listings_params") {
630 listings_params = InsetListingsParams(par).params();
631 } else if (token == "\\papersides") {
634 sides = sidestranslator().find(psides);
635 } else if (token == "\\paperpagestyle") {
637 } else if (token == "\\bullet") {
639 } else if (token == "\\bulletLaTeX") {
640 readBulletsLaTeX(lex);
641 } else if (token == "\\secnumdepth") {
643 } else if (token == "\\tocdepth") {
645 } else if (token == "\\spacing") {
649 if (nspacing == "other") {
652 spacing().set(spacetranslator().find(nspacing), tmp_val);
653 } else if (token == "\\float_placement") {
654 lex >> float_placement;
656 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
657 string toktmp = pdfoptions().readToken(lex, token);
658 if (!toktmp.empty()) {
659 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
664 lyxerr << "BufferParams::readToken(): Unknown token: " <<
673 void BufferParams::writeFile(ostream & os) const
675 // The top of the file is written by the buffer.
676 // Prints out the buffer info into the .lyx file given by file
679 os << "\\textclass " << baseClass()->name() << '\n';
682 if (!preamble.empty()) {
683 // remove '\n' from the end of preamble
684 string const tmppreamble = rtrim(preamble, "\n");
685 os << "\\begin_preamble\n"
687 << "\n\\end_preamble\n";
691 if (!options.empty()) {
692 os << "\\options " << options << '\n';
695 // the master document
696 if (!master.empty()) {
697 os << "\\master " << master << '\n';
701 if (!layoutModules_.empty()) {
702 os << "\\begin_modules" << '\n';
703 LayoutModuleList::const_iterator it = layoutModules_.begin();
704 for (; it != layoutModules_.end(); it++)
706 os << "\\end_modules" << '\n';
709 // local layout information
710 if (!local_layout.empty()) {
711 // remove '\n' from the end
712 string const tmplocal = rtrim(local_layout, "\n");
713 os << "\\begin_local_layout\n"
715 << "\n\\end_local_layout\n";
718 // then the text parameters
719 if (language != ignore_language)
720 os << "\\language " << language->lang() << '\n';
721 os << "\\inputencoding " << inputenc
722 << "\n\\font_roman " << fontsRoman
723 << "\n\\font_sans " << fontsSans
724 << "\n\\font_typewriter " << fontsTypewriter
725 << "\n\\font_default_family " << fontsDefaultFamily
726 << "\n\\font_sc " << convert<string>(fontsSC)
727 << "\n\\font_osf " << convert<string>(fontsOSF)
728 << "\n\\font_sf_scale " << fontsSansScale
729 << "\n\\font_tt_scale " << fontsTypewriterScale
730 << "\n\\graphics " << graphicsDriver << '\n';
732 if (!float_placement.empty()) {
733 os << "\\float_placement " << float_placement << '\n';
735 os << "\\paperfontsize " << fontsize << '\n';
737 spacing().writeFile(os);
738 pdfoptions().writeFile(os);
740 os << "\\papersize " << string_papersize[papersize]
741 << "\n\\use_geometry " << convert<string>(use_geometry)
742 << "\n\\use_amsmath " << use_amsmath
743 << "\n\\use_esint " << use_esint
744 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
745 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
746 << "\n\\paperorientation " << string_orientation[orientation]
749 BranchList::const_iterator it = branchlist().begin();
750 BranchList::const_iterator end = branchlist().end();
751 for (; it != end; ++it) {
752 os << "\\branch " << to_utf8(it->getBranch())
753 << "\n\\selected " << it->getSelected()
754 << "\n\\color " << lyx::X11hexname(it->getColor())
759 if (!paperwidth.empty())
760 os << "\\paperwidth "
761 << VSpace(paperwidth).asLyXCommand() << '\n';
762 if (!paperheight.empty())
763 os << "\\paperheight "
764 << VSpace(paperheight).asLyXCommand() << '\n';
765 if (!leftmargin.empty())
766 os << "\\leftmargin "
767 << VSpace(leftmargin).asLyXCommand() << '\n';
768 if (!topmargin.empty())
770 << VSpace(topmargin).asLyXCommand() << '\n';
771 if (!rightmargin.empty())
772 os << "\\rightmargin "
773 << VSpace(rightmargin).asLyXCommand() << '\n';
774 if (!bottommargin.empty())
775 os << "\\bottommargin "
776 << VSpace(bottommargin).asLyXCommand() << '\n';
777 if (!headheight.empty())
778 os << "\\headheight "
779 << VSpace(headheight).asLyXCommand() << '\n';
780 if (!headsep.empty())
782 << VSpace(headsep).asLyXCommand() << '\n';
783 if (!footskip.empty())
785 << VSpace(footskip).asLyXCommand() << '\n';
786 if (!columnsep.empty())
788 << VSpace(columnsep).asLyXCommand() << '\n';
789 os << "\\secnumdepth " << secnumdepth
790 << "\n\\tocdepth " << tocdepth
791 << "\n\\paragraph_separation "
792 << string_paragraph_separation[paragraph_separation]
793 << "\n\\defskip " << getDefSkip().asLyXCommand()
794 << "\n\\quotes_language "
795 << string_quotes_language[quotes_language]
796 << "\n\\papercolumns " << columns
797 << "\n\\papersides " << sides
798 << "\n\\paperpagestyle " << pagestyle << '\n';
799 if (!listings_params.empty())
800 os << "\\listings_params \"" <<
801 InsetListingsParams(listings_params).encodedString() << "\"\n";
802 for (int i = 0; i < 4; ++i) {
803 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
804 if (user_defined_bullet(i).getFont() != -1) {
805 os << "\\bullet " << i << " "
806 << user_defined_bullet(i).getFont() << " "
807 << user_defined_bullet(i).getCharacter() << " "
808 << user_defined_bullet(i).getSize() << "\n";
812 os << "\\bulletLaTeX " << i << " \""
813 << lyx::to_ascii(user_defined_bullet(i).getText())
819 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
820 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
822 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
823 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
824 for (; a_it != a_end; ++a_it) {
825 if (a_it->second.used())
826 os << "\\author " << a_it->second << "\n";
828 os << "\\author " << Author() << "\n";
833 void BufferParams::validate(LaTeXFeatures & features) const
835 features.require(documentClass().requires());
838 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
839 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
840 LaTeXFeatures::isAvailable("xcolor");
842 switch (features.runparams().flavor) {
843 case OutputParams::LATEX:
845 features.require("ct-dvipost");
846 features.require("dvipost");
847 } else if (xcolorsoul) {
848 features.require("ct-xcolor-soul");
849 features.require("soul");
850 features.require("xcolor");
852 features.require("ct-none");
855 case OutputParams::PDFLATEX:
857 features.require("ct-xcolor-soul");
858 features.require("soul");
859 features.require("xcolor");
860 // improves color handling in PDF output
861 features.require("pdfcolmk");
863 features.require("ct-none");
871 // Floats with 'Here definitely' as default setting.
872 if (float_placement.find('H') != string::npos)
873 features.require("float");
875 // AMS Style is at document level
876 if (use_amsmath == package_on
877 || documentClass().provides("amsmath"))
878 features.require("amsmath");
879 if (use_esint == package_on)
880 features.require("esint");
882 // Document-level line spacing
883 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
884 features.require("setspace");
886 // the bullet shapes are buffer level not paragraph level
887 // so they are tested here
888 for (int i = 0; i < 4; ++i) {
889 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
891 int const font = user_defined_bullet(i).getFont();
893 int const c = user_defined_bullet(i).getCharacter();
899 features.require("latexsym");
901 } else if (font == 1) {
902 features.require("amssymb");
903 } else if (font >= 2 && font <= 5) {
904 features.require("pifont");
908 if (pdfoptions().use_hyperref)
909 features.require("hyperref");
913 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
914 TexRow & texrow) const
916 os << "\\documentclass";
918 DocumentClass const & tclass = documentClass();
920 ostringstream clsoptions; // the document class options.
922 if (tokenPos(tclass.opt_fontsize(),
923 '|', fontsize) >= 0) {
924 // only write if existing in list (and not default)
925 clsoptions << fontsize << "pt,";
928 // custom, A3, B3 and B4 paper sizes need geometry
929 bool nonstandard_papersize = papersize == PAPER_B3
930 || papersize == PAPER_B4
931 || papersize == PAPER_A3
932 || papersize == PAPER_CUSTOM;
937 clsoptions << "a4paper,";
940 clsoptions << "letterpaper,";
943 clsoptions << "a5paper,";
946 clsoptions << "b5paper,";
948 case PAPER_USEXECUTIVE:
949 clsoptions << "executivepaper,";
952 clsoptions << "legalpaper,";
964 if (sides != tclass.sides()) {
967 clsoptions << "oneside,";
970 clsoptions << "twoside,";
976 if (columns != tclass.columns()) {
978 clsoptions << "twocolumn,";
980 clsoptions << "onecolumn,";
984 && orientation == ORIENTATION_LANDSCAPE)
985 clsoptions << "landscape,";
987 // language should be a parameter to \documentclass
988 if (language->babel() == "hebrew"
989 && default_language->babel() != "hebrew")
990 // This seems necessary
991 features.useLanguage(default_language);
993 ostringstream language_options;
994 bool const use_babel = features.useBabel();
996 language_options << features.getLanguages();
997 if (!language->babel().empty()) {
998 if (!language_options.str().empty())
999 language_options << ',';
1000 language_options << language->babel();
1002 // when Vietnamese is used, babel must directly be loaded with the
1003 // language options, not in the class options, see
1004 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1005 size_t viet = language_options.str().find("vietnam");
1006 // viet = string::npos when not found
1007 // when Japanese is used, babel must directly be loaded with the
1008 // language options, not in the class options, see
1009 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1010 size_t japan = language_options.str().find("japanese");
1011 // japan = string::npos when not found
1012 if (lyxrc.language_global_options && !language_options.str().empty()
1013 && viet == string::npos && japan == string::npos)
1014 clsoptions << language_options.str() << ',';
1017 // the user-defined options
1018 if (!options.empty()) {
1019 clsoptions << options << ',';
1022 string strOptions(clsoptions.str());
1023 if (!strOptions.empty()) {
1024 strOptions = rtrim(strOptions, ",");
1026 os << '[' << from_utf8(strOptions) << ']';
1029 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1031 // end of \documentclass defs
1033 // font selection must be done before loading fontenc.sty
1034 string const fonts =
1035 loadFonts(fontsRoman, fontsSans,
1036 fontsTypewriter, fontsSC, fontsOSF,
1037 fontsSansScale, fontsTypewriterScale);
1038 if (!fonts.empty()) {
1039 os << from_ascii(fonts);
1042 if (fontsDefaultFamily != "default")
1043 os << "\\renewcommand{\\familydefault}{\\"
1044 << from_ascii(fontsDefaultFamily) << "}\n";
1046 // set font encoding
1047 // this one is not per buffer
1048 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1049 if (lyxrc.fontenc != "default") {
1050 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1051 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1052 << ",LFE,LAE]{fontenc}\n";
1055 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1061 // handle inputenc etc.
1062 writeEncodingPreamble(os, features, texrow);
1064 if (!listings_params.empty()) {
1065 os << "\\usepackage{listings}\n";
1068 // do not test validity because listings_params is supposed to be valid
1069 string par = InsetListingsParams(listings_params).separatedParams(true);
1070 os << from_ascii(par);
1071 // count the number of newlines
1072 for (size_t i = 0; i < par.size(); ++i)
1078 if (use_geometry || nonstandard_papersize) {
1079 os << "\\usepackage{geometry}\n";
1081 os << "\\geometry{verbose";
1082 if (orientation == ORIENTATION_LANDSCAPE)
1084 switch (papersize) {
1086 if (!paperwidth.empty())
1087 os << ",paperwidth="
1088 << from_ascii(paperwidth);
1089 if (!paperheight.empty())
1090 os << ",paperheight="
1091 << from_ascii(paperheight);
1093 case PAPER_USLETTER:
1094 os << ",letterpaper";
1097 os << ",legalpaper";
1099 case PAPER_USEXECUTIVE:
1100 os << ",executivepaper";
1121 // default papersize ie PAPER_DEFAULT
1122 switch (lyxrc.default_papersize) {
1123 case PAPER_DEFAULT: // keep compiler happy
1124 case PAPER_USLETTER:
1125 os << ",letterpaper";
1128 os << ",legalpaper";
1130 case PAPER_USEXECUTIVE:
1131 os << ",executivepaper";
1151 if (!topmargin.empty())
1152 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1153 if (!bottommargin.empty())
1154 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1155 if (!leftmargin.empty())
1156 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1157 if (!rightmargin.empty())
1158 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1159 if (!headheight.empty())
1160 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1161 if (!headsep.empty())
1162 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1163 if (!footskip.empty())
1164 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1165 if (!columnsep.empty())
1166 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1171 if (tokenPos(tclass.opt_pagestyle(),
1172 '|', pagestyle) >= 0) {
1173 if (pagestyle == "fancy") {
1174 os << "\\usepackage{fancyhdr}\n";
1177 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1181 // Only if class has a ToC hierarchy
1182 if (tclass.hasTocLevels()) {
1183 if (secnumdepth != tclass.secnumdepth()) {
1184 os << "\\setcounter{secnumdepth}{"
1189 if (tocdepth != tclass.tocdepth()) {
1190 os << "\\setcounter{tocdepth}{"
1197 if (paragraph_separation) {
1198 switch (getDefSkip().kind()) {
1199 case VSpace::SMALLSKIP:
1200 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1202 case VSpace::MEDSKIP:
1203 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1205 case VSpace::BIGSKIP:
1206 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1208 case VSpace::LENGTH:
1209 os << "\\setlength{\\parskip}{"
1210 << from_utf8(getDefSkip().length().asLatexString())
1213 default: // should never happen // Then delete it.
1214 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1219 os << "\\setlength{\\parindent}{0pt}\n";
1223 // If we use jurabib, we have to call babel here.
1224 if (use_babel && features.isRequired("jurabib")) {
1225 os << from_ascii(babelCall(language_options.str()))
1227 << from_ascii(features.getBabelOptions());
1231 // Now insert the LyX specific LaTeX commands...
1233 // The optional packages;
1234 docstring lyxpreamble(from_ascii(features.getPackages()));
1237 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1239 // We try to load babel late, in case it interferes
1240 // with other packages. But some packages also need babel to be loaded
1241 // before, e.g. jurabib has to be called after babel.
1242 // So load babel after the optional packages but before the user-defined
1243 // preamble. This allows the users to redefine babel commands, e.g. to
1244 // translate the word "Index" to the German "Stichwortverzeichnis".
1245 // For more infos why this place was chosen, see
1246 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1247 // If you encounter problems, you can shift babel to its old place behind
1248 // the user-defined preamble. But in this case you must change the Vietnamese
1249 // support from currently "\usepackage[vietnamese]{babel}" to:
1250 // \usepackage{vietnamese}
1251 // \usepackage{babel}
1252 // because vietnamese must be loaded before hyperref
1253 if (use_babel && !features.isRequired("jurabib")) {
1255 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1256 lyxpreamble += from_utf8(features.getBabelOptions());
1260 // * Hyperref manual: "Make sure it comes last of your loaded
1261 // packages, to give it a fighting chance of not being over-written,
1262 // since its job is to redefine many LATEX commands."
1263 // * Email from Heiko Oberdiek: "It is usually better to load babel
1264 // before hyperref. Then hyperref has a chance to detect babel.
1265 // * Has to be loaded before the "LyX specific LaTeX commands" to
1266 // avoid errors with algorithm floats.
1267 // use hyperref explicitely when it is required
1268 if (features.isRequired("hyperref")) {
1269 odocstringstream oss;
1270 pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
1271 lyxpreamble += oss.str();
1274 // Will be surrounded by \makeatletter and \makeatother when needed
1275 docstring atlyxpreamble;
1277 // Some macros LyX will need
1278 docstring tmppreamble(from_ascii(features.getMacros()));
1280 if (!tmppreamble.empty())
1281 atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1282 "LyX specific LaTeX commands.\n"
1283 + tmppreamble + '\n';
1285 // the text class specific preamble
1286 tmppreamble = features.getTClassPreamble();
1287 if (!tmppreamble.empty())
1288 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1289 "Textclass specific LaTeX commands.\n"
1290 + tmppreamble + '\n';
1292 /* the user-defined preamble */
1293 if (!preamble.empty())
1295 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1296 "User specified LaTeX commands.\n"
1297 + from_utf8(preamble) + '\n';
1299 // subfig loads internally the LaTeX package "caption". As caption is a very
1300 // popular package, users will load it in the preamble. Therefore we must load
1301 // subfig behind the user-defined preamble and check if the caption package
1302 // was loaded or not.
1303 // For the case that caption is loaded before subfig, there is the subfig
1304 // option "caption=false". This option also works when a koma-script class is
1305 // used and koma's own caption commands are used instead of caption.
1306 // We use \PassOptionsToPackage here because the user could have already
1307 // loaded subfig in the preamble.
1308 if (features.isRequired("subfig")) {
1309 atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n"
1310 " \\PassOptionsToPackage{caption=false}{subfig}}\n"
1311 "\\usepackage{subfig}\n";
1314 // Itemize bullet settings need to be last in case the user
1315 // defines their own bullets that use a package included
1316 // in the user-defined preamble -- ARRae
1317 // Actually it has to be done much later than that
1318 // since some packages like frenchb make modifications
1319 // at \begin{document} time -- JMarc
1320 docstring bullets_def;
1321 for (int i = 0; i < 4; ++i) {
1322 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1323 if (bullets_def.empty())
1324 bullets_def += "\\AtBeginDocument{\n";
1325 bullets_def += " \\def\\labelitemi";
1327 // `i' is one less than the item to modify
1334 bullets_def += "ii";
1340 bullets_def += '{' +
1341 user_defined_bullet(i).getText()
1346 if (!bullets_def.empty())
1347 atlyxpreamble += bullets_def + "}\n\n";
1349 if (atlyxpreamble.find(from_ascii("@")) != docstring::npos)
1350 lyxpreamble += "\n\\makeatletter\n"
1351 + atlyxpreamble + "\\makeatother\n\n";
1353 lyxpreamble += '\n' + atlyxpreamble;
1356 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1357 for (int j = 0; j != nlines; ++j) {
1366 void BufferParams::useClassDefaults()
1368 DocumentClass const & tclass = documentClass();
1370 sides = tclass.sides();
1371 columns = tclass.columns();
1372 pagestyle = tclass.pagestyle();
1373 options = tclass.options();
1374 // Only if class has a ToC hierarchy
1375 if (tclass.hasTocLevels()) {
1376 secnumdepth = tclass.secnumdepth();
1377 tocdepth = tclass.tocdepth();
1382 bool BufferParams::hasClassDefaults() const
1384 DocumentClass const & tclass = documentClass();
1386 return sides == tclass.sides()
1387 && columns == tclass.columns()
1388 && pagestyle == tclass.pagestyle()
1389 && options == tclass.options()
1390 && secnumdepth == tclass.secnumdepth()
1391 && tocdepth == tclass.tocdepth();
1395 DocumentClass const & BufferParams::documentClass() const
1401 DocumentClass * BufferParams::documentClassPtr() const {
1406 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1407 // evil, but this function is evil
1408 doc_class_ = const_cast<DocumentClass *>(tc);
1412 bool BufferParams::setBaseClass(string const & classname)
1414 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1415 LayoutFileList const & bcl = LayoutFileList::get();
1416 if (!bcl.haveClass(classname)) {
1418 bformat(_("The document class %1$s could not be found."),
1419 from_utf8(classname));
1420 frontend::Alert::error(_("Class not found"), s);
1424 if (bcl[classname].load()) {
1425 pimpl_->baseClass_ = classname;
1430 bformat(_("The document class %1$s could not be loaded."),
1431 from_utf8(classname));
1432 frontend::Alert::error(_("Could not load class"), s);
1437 LayoutFile const * BufferParams::baseClass() const
1439 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
1440 return &(LayoutFileList::get()[pimpl_->baseClass_]);
1446 LayoutFileIndex const & BufferParams::baseClassID() const
1448 return pimpl_->baseClass_;
1452 void BufferParams::makeDocumentClass()
1457 doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass()));
1459 //FIXME It might be worth loading the children's modules here,
1460 //just as we load their bibliographies and such, instead of just
1461 //doing a check in InsetInclude.
1462 LayoutModuleList::const_iterator it = layoutModules_.begin();
1463 for (; it != layoutModules_.end(); it++) {
1464 string const modName = *it;
1465 LyXModule * lm = moduleList[modName];
1467 docstring const msg =
1468 bformat(_("The module %1$s has been requested by\n"
1469 "this document but has not been found in the list of\n"
1470 "available modules. If you recently installed it, you\n"
1471 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1472 frontend::Alert::warning(_("Module not available"),
1473 msg + _("Some layouts may not be available."));
1474 LYXERR0("BufferParams::makeDocumentClass(): Module " <<
1475 modName << " requested but not found in module list.");
1478 if (!lm->isAvailable()) {
1479 docstring const msg =
1480 bformat(_("The module %1$s requires a package that is\n"
1481 "not available in your LaTeX installation. LaTeX output\n"
1482 "may not be possible.\n"), from_utf8(modName));
1483 frontend::Alert::warning(_("Package not available"), msg);
1485 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1486 if (!doc_class_->read(layout_file, TextClass::MODULE)) {
1487 docstring const msg =
1488 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1489 frontend::Alert::warning(_("Read Error"), msg);
1492 if (!local_layout.empty()) {
1493 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
1494 docstring const msg = _("Error reading internal layout information");
1495 frontend::Alert::warning(_("Read Error"), msg);
1501 vector<string> const & BufferParams::getModules() const
1503 return layoutModules_;
1508 bool BufferParams::addLayoutModule(string const & modName)
1510 LayoutModuleList::const_iterator it = layoutModules_.begin();
1511 LayoutModuleList::const_iterator end = layoutModules_.end();
1512 for (; it != end; it++)
1515 layoutModules_.push_back(modName);
1520 void BufferParams::clearLayoutModules()
1522 layoutModules_.clear();
1526 Font const BufferParams::getFont() const
1528 FontInfo f = documentClass().defaultfont();
1529 if (fontsDefaultFamily == "rmdefault")
1530 f.setFamily(ROMAN_FAMILY);
1531 else if (fontsDefaultFamily == "sfdefault")
1532 f.setFamily(SANS_FAMILY);
1533 else if (fontsDefaultFamily == "ttdefault")
1534 f.setFamily(TYPEWRITER_FAMILY);
1535 return Font(f, language);
1539 void BufferParams::readPreamble(Lexer & lex)
1541 if (lex.getString() != "\\begin_preamble")
1542 lyxerr << "Error (BufferParams::readPreamble):"
1543 "consistency check failed." << endl;
1545 preamble = lex.getLongString("\\end_preamble");
1549 void BufferParams::readLocalLayout(Lexer & lex)
1551 if (lex.getString() != "\\begin_local_layout")
1552 lyxerr << "Error (BufferParams::readLocalLayout):"
1553 "consistency check failed." << endl;
1555 local_layout = lex.getLongString("\\end_local_layout");
1559 void BufferParams::readLanguage(Lexer & lex)
1561 if (!lex.next()) return;
1563 string const tmptok = lex.getString();
1565 // check if tmptok is part of tex_babel in tex-defs.h
1566 language = languages.getLanguage(tmptok);
1568 // Language tmptok was not found
1569 language = default_language;
1570 lyxerr << "Warning: Setting language `"
1571 << tmptok << "' to `" << language->lang()
1577 void BufferParams::readGraphicsDriver(Lexer & lex)
1582 string const tmptok = lex.getString();
1583 // check if tmptok is part of tex_graphics in tex_defs.h
1586 string const test = tex_graphics[n++];
1588 if (test == tmptok) {
1589 graphicsDriver = tmptok;
1594 "Warning: graphics driver `$$Token' not recognized!\n"
1595 " Setting graphics driver to `default'.\n");
1596 graphicsDriver = "default";
1603 void BufferParams::readBullets(Lexer & lex)
1608 int const index = lex.getInteger();
1610 int temp_int = lex.getInteger();
1611 user_defined_bullet(index).setFont(temp_int);
1612 temp_bullet(index).setFont(temp_int);
1614 user_defined_bullet(index).setCharacter(temp_int);
1615 temp_bullet(index).setCharacter(temp_int);
1617 user_defined_bullet(index).setSize(temp_int);
1618 temp_bullet(index).setSize(temp_int);
1622 void BufferParams::readBulletsLaTeX(Lexer & lex)
1624 // The bullet class should be able to read this.
1627 int const index = lex.getInteger();
1629 docstring const temp_str = lex.getDocString();
1631 user_defined_bullet(index).setText(temp_str);
1632 temp_bullet(index).setText(temp_str);
1636 void BufferParams::readModules(Lexer & lex)
1638 if (!lex.eatLine()) {
1639 lyxerr << "Error (BufferParams::readModules):"
1640 "Unexpected end of input." << endl;
1644 string mod = lex.getString();
1645 if (mod == "\\end_modules")
1647 addLayoutModule(mod);
1653 string BufferParams::paperSizeName(PapersizePurpose purpose) const
1655 char real_papersize = papersize;
1656 if (real_papersize == PAPER_DEFAULT)
1657 real_papersize = lyxrc.default_papersize;
1659 switch (real_papersize) {
1661 // could be anything, so don't guess
1663 case PAPER_CUSTOM: {
1664 if (purpose == XDVI && !paperwidth.empty() &&
1665 !paperheight.empty()) {
1666 // heightxwidth<unit>
1667 string first = paperwidth;
1668 string second = paperheight;
1669 if (orientation == ORIENTATION_LANDSCAPE)
1672 return first.erase(first.length() - 2)
1684 // dvips and dvipdfm do not know this
1685 if (purpose == DVIPS || purpose == DVIPDFM)
1689 // dvipdfm does not know this
1690 if (purpose == DVIPDFM)
1694 // dvipdfm does not know this
1695 if (purpose == DVIPDFM)
1698 case PAPER_USEXECUTIVE:
1699 // dvipdfm does not know this
1700 if (purpose == DVIPDFM)
1705 case PAPER_USLETTER:
1707 if (purpose == XDVI)
1714 string const BufferParams::dvips_options() const
1719 && papersize == PAPER_CUSTOM
1720 && !lyxrc.print_paper_dimension_flag.empty()
1721 && !paperwidth.empty()
1722 && !paperheight.empty()) {
1723 // using a custom papersize
1724 result = lyxrc.print_paper_dimension_flag;
1725 result += ' ' + paperwidth;
1726 result += ',' + paperheight;
1728 string const paper_option = paperSizeName(DVIPS);
1729 if (!paper_option.empty() && (paper_option != "letter" ||
1730 orientation != ORIENTATION_LANDSCAPE)) {
1731 // dvips won't accept -t letter -t landscape.
1732 // In all other cases, include the paper size
1734 result = lyxrc.print_paper_flag;
1735 result += ' ' + paper_option;
1738 if (orientation == ORIENTATION_LANDSCAPE &&
1739 papersize != PAPER_CUSTOM)
1740 result += ' ' + lyxrc.print_landscape_flag;
1745 string BufferParams::babelCall(string const & lang_opts) const
1747 string lang_pack = lyxrc.language_package;
1748 if (lang_pack != "\\usepackage{babel}")
1750 // suppress the babel call when there is no babel language defined
1751 // for the document language in the lib/languages file and if no
1752 // other languages are used (lang_opts is then empty)
1753 if (lang_opts.empty())
1755 // when Vietnamese is used, babel must directly be loaded with the
1756 // language options, see
1757 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1758 size_t viet = lang_opts.find("vietnam");
1759 // viet = string::npos when not found
1760 // when Japanese is used, babel must directly be loaded with the
1761 // language options, see
1762 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1763 size_t japan = lang_opts.find("japanese");
1764 // japan = string::npos when not found
1765 if (!lyxrc.language_global_options || viet != string::npos || japan != string::npos)
1766 return "\\usepackage[" + lang_opts + "]{babel}";
1771 void BufferParams::writeEncodingPreamble(odocstream & os,
1772 LaTeXFeatures & features, TexRow & texrow) const
1774 if (inputenc == "auto") {
1775 string const doc_encoding =
1776 language->encoding()->latexName();
1777 Encoding::Package const package =
1778 language->encoding()->package();
1780 // Create a list with all the input encodings used
1782 set<string> encodings =
1783 features.getEncodingSet(doc_encoding);
1785 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1786 // package inputenc must be omitted. Therefore set the encoding to empty.
1787 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1788 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1789 doc_encoding == "SJIS-plain")
1792 if (!encodings.empty() || package == Encoding::inputenc) {
1793 os << "\\usepackage[";
1794 set<string>::const_iterator it = encodings.begin();
1795 set<string>::const_iterator const end = encodings.end();
1797 os << from_ascii(*it);
1800 for (; it != end; ++it)
1801 os << ',' << from_ascii(*it);
1802 if (package == Encoding::inputenc) {
1803 if (!encodings.empty())
1805 os << from_ascii(doc_encoding);
1807 os << "]{inputenc}\n";
1810 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1811 os << "\\usepackage{CJK}\n";
1814 } else if (inputenc != "default") {
1815 switch (encoding().package()) {
1816 case Encoding::none:
1818 case Encoding::inputenc:
1819 os << "\\usepackage[" << from_ascii(inputenc)
1824 os << "\\usepackage{CJK}\n";
1830 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1831 // armscii8 is used for Armenian.
1832 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1833 os << "\\usepackage{armtex}\n";
1839 string const BufferParams::loadFonts(string const & rm,
1840 string const & sf, string const & tt,
1841 bool const & sc, bool const & osf,
1842 int const & sfscale, int const & ttscale) const
1844 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1845 several packages have been replaced by others, that might not
1846 be installed on every system. We have to take care for that
1847 (see psnfss.pdf). We try to support all psnfss fonts as well
1848 as the fonts that have become de facto standard in the LaTeX
1849 world (e.g. Latin Modern). We do not support obsolete fonts
1850 (like PSLatex). In general, it should be possible to mix any
1851 rm font with any sf or tt font, respectively. (JSpitzm)
1853 -- separate math fonts.
1856 if (rm == "default" && sf == "default" && tt == "default")
1863 // Computer Modern (must be explicitely selectable -- there might be classes
1864 // that define a different default font!
1866 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1867 // osf for Computer Modern needs eco.sty
1869 os << "\\usepackage{eco}\n";
1871 // Latin Modern Roman
1872 else if (rm == "lmodern")
1873 os << "\\usepackage{lmodern}\n";
1875 else if (rm == "ae") {
1876 // not needed when using OT1 font encoding.
1877 if (lyxrc.fontenc != "default")
1878 os << "\\usepackage{ae,aecompl}\n";
1881 else if (rm == "times") {
1882 // try to load the best available package
1883 if (LaTeXFeatures::isAvailable("mathptmx"))
1884 os << "\\usepackage{mathptmx}\n";
1885 else if (LaTeXFeatures::isAvailable("mathptm"))
1886 os << "\\usepackage{mathptm}\n";
1888 os << "\\usepackage{times}\n";
1891 else if (rm == "palatino") {
1892 // try to load the best available package
1893 if (LaTeXFeatures::isAvailable("mathpazo")) {
1894 os << "\\usepackage";
1900 // "osf" includes "sc"!
1904 os << "{mathpazo}\n";
1906 else if (LaTeXFeatures::isAvailable("mathpple"))
1907 os << "\\usepackage{mathpple}\n";
1909 os << "\\usepackage{palatino}\n";
1912 else if (rm == "utopia") {
1913 // fourier supersedes utopia.sty, but does
1914 // not work with OT1 encoding.
1915 if (LaTeXFeatures::isAvailable("fourier")
1916 && lyxrc.fontenc != "default") {
1917 os << "\\usepackage";
1928 os << "{fourier}\n";
1931 os << "\\usepackage{utopia}\n";
1933 // Bera (complete fontset)
1934 else if (rm == "bera" && sf == "default" && tt == "default")
1935 os << "\\usepackage{bera}\n";
1937 else if (rm != "default")
1938 os << "\\usepackage" << "{" << rm << "}\n";
1941 // Helvetica, Bera Sans
1942 if (sf == "helvet" || sf == "berasans") {
1944 os << "\\usepackage[scaled=" << float(sfscale) / 100
1945 << "]{" << sf << "}\n";
1947 os << "\\usepackage{" << sf << "}\n";
1950 else if (sf == "avant")
1951 os << "\\usepackage{" << sf << "}\n";
1952 // Computer Modern, Latin Modern, CM Bright
1953 else if (sf != "default")
1954 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1956 // monospaced/typewriter
1957 // Courier, LuxiMono
1958 if (tt == "luximono" || tt == "beramono") {
1960 os << "\\usepackage[scaled=" << float(ttscale) / 100
1961 << "]{" << tt << "}\n";
1963 os << "\\usepackage{" << tt << "}\n";
1966 else if (tt == "courier" )
1967 os << "\\usepackage{" << tt << "}\n";
1968 // Computer Modern, Latin Modern, CM Bright
1969 else if (tt != "default")
1970 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1976 Encoding const & BufferParams::encoding() const
1978 if (inputenc == "auto" || inputenc == "default")
1979 return *language->encoding();
1980 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
1983 LYXERR0("Unknown inputenc value `" << inputenc
1984 << "'. Using `auto' instead.");
1985 return *language->encoding();
1989 CiteEngine BufferParams::citeEngine() const
1991 // FIXME the class should provide the numerical/
1992 // authoryear choice
1993 if (documentClass().provides("natbib")
1994 && cite_engine_ != ENGINE_NATBIB_NUMERICAL)
1995 return ENGINE_NATBIB_AUTHORYEAR;
1996 return cite_engine_;
2000 void BufferParams::setCiteEngine(CiteEngine cite_engine)
2002 cite_engine_ = cite_engine;