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 "BranchList.h"
22 #include "buffer_funcs.h"
27 #include "LaTeXFeatures.h"
28 #include "ModuleList.h"
32 #include "TextClassList.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", "executivepaper", "legalpaper",
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::PARSEP> ParSepTranslator;
101 ParSepTranslator const init_parseptranslator()
103 ParSepTranslator translator(string_paragraph_separation[0], BufferParams::PARSEP_INDENT);
104 translator.addPair(string_paragraph_separation[1], BufferParams::PARSEP_SKIP);
109 ParSepTranslator const & parseptranslator()
111 static ParSepTranslator translator = init_parseptranslator();
117 typedef Translator<string, InsetQuotes::quote_language> QuotesLangTranslator;
120 QuotesLangTranslator const init_quoteslangtranslator()
122 QuotesLangTranslator translator(string_quotes_language[0], InsetQuotes::EnglishQ);
123 translator.addPair(string_quotes_language[1], InsetQuotes::SwedishQ);
124 translator.addPair(string_quotes_language[2], InsetQuotes::GermanQ);
125 translator.addPair(string_quotes_language[3], InsetQuotes::PolishQ);
126 translator.addPair(string_quotes_language[4], InsetQuotes::FrenchQ);
127 translator.addPair(string_quotes_language[5], InsetQuotes::DanishQ);
132 QuotesLangTranslator const & quoteslangtranslator()
134 static QuotesLangTranslator translator = init_quoteslangtranslator();
140 typedef Translator<string, PAPER_SIZE> PaperSizeTranslator;
143 PaperSizeTranslator const init_papersizetranslator()
145 PaperSizeTranslator translator(string_papersize[0], PAPER_DEFAULT);
146 translator.addPair(string_papersize[1], PAPER_CUSTOM);
147 translator.addPair(string_papersize[2], PAPER_USLETTER);
148 translator.addPair(string_papersize[3], PAPER_USLEGAL);
149 translator.addPair(string_papersize[4], PAPER_USEXECUTIVE);
150 translator.addPair(string_papersize[5], PAPER_A3);
151 translator.addPair(string_papersize[6], PAPER_A4);
152 translator.addPair(string_papersize[7], PAPER_A5);
153 translator.addPair(string_papersize[8], PAPER_B3);
154 translator.addPair(string_papersize[9], PAPER_B4);
155 translator.addPair(string_papersize[10], PAPER_B5);
160 PaperSizeTranslator const & papersizetranslator()
162 static PaperSizeTranslator translator = init_papersizetranslator();
168 typedef Translator<string, PAPER_ORIENTATION> PaperOrientationTranslator;
171 PaperOrientationTranslator const init_paperorientationtranslator()
173 PaperOrientationTranslator translator(string_orientation[0], ORIENTATION_PORTRAIT);
174 translator.addPair(string_orientation[1], ORIENTATION_LANDSCAPE);
179 PaperOrientationTranslator const & paperorientationtranslator()
181 static PaperOrientationTranslator translator = init_paperorientationtranslator();
187 typedef Translator<int, PageSides> SidesTranslator;
190 SidesTranslator const init_sidestranslator()
192 SidesTranslator translator(1, OneSide);
193 translator.addPair(2, TwoSides);
198 SidesTranslator const & sidestranslator()
200 static SidesTranslator translator = init_sidestranslator();
206 typedef Translator<int, BufferParams::Package> PackageTranslator;
209 PackageTranslator const init_packagetranslator()
211 PackageTranslator translator(0, BufferParams::package_off);
212 translator.addPair(1, BufferParams::package_auto);
213 translator.addPair(2, BufferParams::package_on);
218 PackageTranslator const & packagetranslator()
220 static PackageTranslator translator = init_packagetranslator();
226 typedef Translator<string, biblio::CiteEngine> CiteEngineTranslator;
229 CiteEngineTranslator const init_citeenginetranslator()
231 CiteEngineTranslator translator("basic", biblio::ENGINE_BASIC);
232 translator.addPair("natbib_numerical", biblio::ENGINE_NATBIB_NUMERICAL);
233 translator.addPair("natbib_authoryear", biblio::ENGINE_NATBIB_AUTHORYEAR);
234 translator.addPair("jurabib", biblio::ENGINE_JURABIB);
239 CiteEngineTranslator const & citeenginetranslator()
241 static CiteEngineTranslator translator = init_citeenginetranslator();
247 typedef Translator<string, Spacing::Space> SpaceTranslator;
250 SpaceTranslator const init_spacetranslator()
252 SpaceTranslator translator("default", Spacing::Default);
253 translator.addPair("single", Spacing::Single);
254 translator.addPair("onehalf", Spacing::Onehalf);
255 translator.addPair("double", Spacing::Double);
256 translator.addPair("other", Spacing::Other);
261 SpaceTranslator const & spacetranslator()
263 static SpaceTranslator translator = init_spacetranslator();
271 class BufferParams::Impl
276 AuthorList authorlist;
277 BranchList branchlist;
278 Bullet temp_bullets[4];
279 Bullet user_defined_bullets[4];
281 /** This is the amount of space used for paragraph_separation "skip",
282 * and for detached paragraphs in "indented" documents.
285 PDFOptions pdfoptions;
287 /// the base TextClass associated with the document
288 TextClassIndex baseClass_;
289 /// the possibly modular TextClass actually in use
290 TextClassIndex textClass_;
294 BufferParams::Impl::Impl()
295 : defskip(VSpace::MEDSKIP), baseClass_(0), textClass_(0)
297 // set initial author
299 authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
304 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
308 return new BufferParams::Impl(*ptr);
312 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
318 BufferParams::BufferParams()
321 setBaseClass(defaultTextclass());
323 paragraph_separation = PARSEP_INDENT;
324 quotes_language = InsetQuotes::EnglishQ;
325 fontsize = "default";
328 papersize = PAPER_DEFAULT;
329 orientation = ORIENTATION_PORTRAIT;
330 use_geometry = false;
331 use_amsmath = package_auto;
332 use_esint = package_auto;
333 cite_engine_ = biblio::ENGINE_BASIC;
334 use_bibtopic = false;
335 trackChanges = false;
336 outputChanges = false;
339 language = default_language;
340 fontsRoman = "default";
341 fontsSans = "default";
342 fontsTypewriter = "default";
343 fontsDefaultFamily = "default";
346 fontsSansScale = 100;
347 fontsTypewriterScale = 100;
349 graphicsDriver = "default";
352 listings_params = string();
353 pagestyle = "default";
356 for (int iter = 0; iter < 4; ++iter) {
357 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
358 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
363 BufferParams::~BufferParams()
367 docstring const BufferParams::B_(string const & l10n) const
369 BOOST_ASSERT(language);
370 return getMessages(language->code()).get(l10n);
374 AuthorList & BufferParams::authors()
376 return pimpl_->authorlist;
380 AuthorList const & BufferParams::authors() const
382 return pimpl_->authorlist;
386 BranchList & BufferParams::branchlist()
388 return pimpl_->branchlist;
392 BranchList const & BufferParams::branchlist() const
394 return pimpl_->branchlist;
398 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
400 BOOST_ASSERT(index < 4);
401 return pimpl_->temp_bullets[index];
405 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
407 BOOST_ASSERT(index < 4);
408 return pimpl_->temp_bullets[index];
412 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
414 BOOST_ASSERT(index < 4);
415 return pimpl_->user_defined_bullets[index];
419 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
421 BOOST_ASSERT(index < 4);
422 return pimpl_->user_defined_bullets[index];
426 Spacing & BufferParams::spacing()
428 return pimpl_->spacing;
432 Spacing const & BufferParams::spacing() const
434 return pimpl_->spacing;
438 PDFOptions & BufferParams::pdfoptions()
440 return pimpl_->pdfoptions;
444 PDFOptions const & BufferParams::pdfoptions() const
446 return pimpl_->pdfoptions;
450 VSpace const & BufferParams::getDefSkip() const
452 return pimpl_->defskip;
456 void BufferParams::setDefSkip(VSpace const & vs)
458 pimpl_->defskip = vs;
462 string const BufferParams::readToken(Lexer & lex, string const & token,
463 FileName const & filepath)
465 if (token == "\\textclass") {
467 string const classname = lex.getString();
468 // if there exists a local layout file, ignore the system one
469 // NOTE: in this case, the textclass (.cls file) is assumed to be available.
470 pair<bool, TextClassIndex> pp =
471 make_pair(false, TextClassIndex(0));
472 if (!filepath.empty())
473 pp = textclasslist.addTextClass(
474 classname, filepath.absFilename());
476 setBaseClass(pp.second);
478 pp = textclasslist.numberOfClass(classname);
480 setBaseClass(pp.second);
482 // a warning will be given for unknown class
483 setBaseClass(defaultTextclass());
487 // FIXME: this warning will be given even if there exists a local .cls
488 // file. Even worse, the .lyx file can not be compiled or exported
489 // because the textclass is marked as unavilable.
490 if (!textClass().isTeXClassAvailable()) {
491 docstring const msg =
492 bformat(_("The layout file requested by this document,\n"
494 "is not usable. This is probably because a LaTeX\n"
495 "class or style file required by it is not\n"
496 "available. See the Customization documentation\n"
497 "for more information.\n"), from_utf8(classname));
498 frontend::Alert::warning(_("Document class not available"),
499 msg + _("LyX will not be able to produce output."));
502 } else if (token == "\\begin_preamble") {
504 } else if (token == "\\begin_modules") {
506 } else if (token == "\\options") {
508 options = lex.getString();
509 } else if (token == "\\language") {
511 } else if (token == "\\inputencoding") {
513 } else if (token == "\\graphics") {
514 readGraphicsDriver(lex);
515 } else if (token == "\\font_roman") {
517 } else if (token == "\\font_sans") {
519 } else if (token == "\\font_typewriter") {
520 lex >> fontsTypewriter;
521 } else if (token == "\\font_default_family") {
522 lex >> fontsDefaultFamily;
523 } else if (token == "\\font_sc") {
525 } else if (token == "\\font_osf") {
527 } else if (token == "\\font_sf_scale") {
528 lex >> fontsSansScale;
529 } else if (token == "\\font_tt_scale") {
530 lex >> fontsTypewriterScale;
531 } else if (token == "\\paragraph_separation") {
534 paragraph_separation = parseptranslator().find(parsep);
535 } else if (token == "\\defskip") {
537 string defskip = lex.getString();
538 if (defskip == "defskip")
541 pimpl_->defskip = VSpace(defskip);
542 } else if (token == "\\quotes_language") {
545 quotes_language = quoteslangtranslator().find(quotes_lang);
546 } else if (token == "\\papersize") {
549 papersize = papersizetranslator().find(ppsize);
550 } else if (token == "\\use_geometry") {
552 } else if (token == "\\use_amsmath") {
555 use_amsmath = packagetranslator().find(use_ams);
556 } else if (token == "\\use_esint") {
559 use_esint = packagetranslator().find(useesint);
560 } else if (token == "\\cite_engine") {
563 cite_engine_ = citeenginetranslator().find(engine);
564 } else if (token == "\\use_bibtopic") {
566 } else if (token == "\\tracking_changes") {
568 } else if (token == "\\output_changes") {
569 lex >> outputChanges;
570 } else if (token == "\\branch") {
572 docstring branch = lex.getDocString();
573 branchlist().add(branch);
576 string const tok = lex.getString();
577 if (tok == "\\end_branch")
579 Branch * branch_ptr = branchlist().find(branch);
580 if (tok == "\\selected") {
583 branch_ptr->setSelected(lex.getInteger());
585 // not yet operational
586 if (tok == "\\color") {
588 string color = lex.getString();
590 branch_ptr->setColor(color);
591 // Update also the Color table:
593 color = lcolor.getX11Name(Color_background);
595 lcolor.setColor(to_utf8(branch), color);
599 } else if (token == "\\author") {
601 istringstream ss(lex.getString());
604 author_map.push_back(pimpl_->authorlist.record(a));
605 } else if (token == "\\paperorientation") {
608 orientation = paperorientationtranslator().find(orient);
609 } else if (token == "\\paperwidth") {
611 } else if (token == "\\paperheight") {
613 } else if (token == "\\leftmargin") {
615 } else if (token == "\\topmargin") {
617 } else if (token == "\\rightmargin") {
619 } else if (token == "\\bottommargin") {
621 } else if (token == "\\headheight") {
623 } else if (token == "\\headsep") {
625 } else if (token == "\\footskip") {
627 } else if (token == "\\columnsep") {
629 } else if (token == "\\paperfontsize") {
631 } else if (token == "\\papercolumns") {
633 } else if (token == "\\listings_params") {
636 listings_params = InsetListingsParams(par).params();
637 } else if (token == "\\papersides") {
640 sides = sidestranslator().find(psides);
641 } else if (token == "\\paperpagestyle") {
643 } else if (token == "\\bullet") {
645 } else if (token == "\\bulletLaTeX") {
646 readBulletsLaTeX(lex);
647 } else if (token == "\\secnumdepth") {
649 } else if (token == "\\tocdepth") {
651 } else if (token == "\\spacing") {
655 if (nspacing == "other") {
658 spacing().set(spacetranslator().find(nspacing), tmp_val);
659 } else if (token == "\\float_placement") {
660 lex >> float_placement;
662 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
663 string toktmp = pdfoptions().readToken(lex, token);
664 if (!toktmp.empty()) {
665 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
670 lyxerr << "BufferParams::readToken(): Unknown token: " <<
679 void BufferParams::writeFile(ostream & os) const
681 // The top of the file is written by the buffer.
682 // Prints out the buffer info into the .lyx file given by file
685 os << "\\textclass " << textClass().name() << '\n';
688 if (!preamble.empty()) {
689 // remove '\n' from the end of preamble
690 string const tmppreamble = rtrim(preamble, "\n");
691 os << "\\begin_preamble\n"
693 << "\n\\end_preamble\n";
697 if (!options.empty()) {
698 os << "\\options " << options << '\n';
702 if (!layoutModules_.empty()) {
703 os << "\\begin_modules" << '\n';
704 LayoutModuleList::const_iterator it = layoutModules_.begin();
705 for (; it != layoutModules_.end(); it++)
707 os << "\\end_modules" << '\n';
710 // then the text parameters
711 if (language != ignore_language)
712 os << "\\language " << language->lang() << '\n';
713 os << "\\inputencoding " << inputenc
714 << "\n\\font_roman " << fontsRoman
715 << "\n\\font_sans " << fontsSans
716 << "\n\\font_typewriter " << fontsTypewriter
717 << "\n\\font_default_family " << fontsDefaultFamily
718 << "\n\\font_sc " << convert<string>(fontsSC)
719 << "\n\\font_osf " << convert<string>(fontsOSF)
720 << "\n\\font_sf_scale " << fontsSansScale
721 << "\n\\font_tt_scale " << fontsTypewriterScale
722 << "\n\\graphics " << graphicsDriver << '\n';
724 if (!float_placement.empty()) {
725 os << "\\float_placement " << float_placement << '\n';
727 os << "\\paperfontsize " << fontsize << '\n';
729 spacing().writeFile(os);
730 pdfoptions().writeFile(os);
732 os << "\\papersize " << string_papersize[papersize]
733 << "\n\\use_geometry " << convert<string>(use_geometry)
734 << "\n\\use_amsmath " << use_amsmath
735 << "\n\\use_esint " << use_esint
736 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
737 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
738 << "\n\\paperorientation " << string_orientation[orientation]
741 BranchList::const_iterator it = branchlist().begin();
742 BranchList::const_iterator end = branchlist().end();
743 for (; it != end; ++it) {
744 os << "\\branch " << to_utf8(it->getBranch())
745 << "\n\\selected " << it->getSelected()
746 << "\n\\color " << lyx::X11hexname(it->getColor())
751 if (!paperwidth.empty())
752 os << "\\paperwidth "
753 << VSpace(paperwidth).asLyXCommand() << '\n';
754 if (!paperheight.empty())
755 os << "\\paperheight "
756 << VSpace(paperheight).asLyXCommand() << '\n';
757 if (!leftmargin.empty())
758 os << "\\leftmargin "
759 << VSpace(leftmargin).asLyXCommand() << '\n';
760 if (!topmargin.empty())
762 << VSpace(topmargin).asLyXCommand() << '\n';
763 if (!rightmargin.empty())
764 os << "\\rightmargin "
765 << VSpace(rightmargin).asLyXCommand() << '\n';
766 if (!bottommargin.empty())
767 os << "\\bottommargin "
768 << VSpace(bottommargin).asLyXCommand() << '\n';
769 if (!headheight.empty())
770 os << "\\headheight "
771 << VSpace(headheight).asLyXCommand() << '\n';
772 if (!headsep.empty())
774 << VSpace(headsep).asLyXCommand() << '\n';
775 if (!footskip.empty())
777 << VSpace(footskip).asLyXCommand() << '\n';
778 if (!columnsep.empty())
780 << VSpace(columnsep).asLyXCommand() << '\n';
781 os << "\\secnumdepth " << secnumdepth
782 << "\n\\tocdepth " << tocdepth
783 << "\n\\paragraph_separation "
784 << string_paragraph_separation[paragraph_separation]
785 << "\n\\defskip " << getDefSkip().asLyXCommand()
786 << "\n\\quotes_language "
787 << string_quotes_language[quotes_language]
788 << "\n\\papercolumns " << columns
789 << "\n\\papersides " << sides
790 << "\n\\paperpagestyle " << pagestyle << '\n';
791 if (!listings_params.empty())
792 os << "\\listings_params \"" <<
793 InsetListingsParams(listings_params).encodedString() << "\"\n";
794 for (int i = 0; i < 4; ++i) {
795 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
796 if (user_defined_bullet(i).getFont() != -1) {
797 os << "\\bullet " << i << " "
798 << user_defined_bullet(i).getFont() << " "
799 << user_defined_bullet(i).getCharacter() << " "
800 << user_defined_bullet(i).getSize() << "\n";
804 os << "\\bulletLaTeX " << i << " \""
805 << lyx::to_ascii(user_defined_bullet(i).getText())
811 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
812 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
814 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
815 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
816 for (; a_it != a_end; ++a_it) {
817 if (a_it->second.used())
818 os << "\\author " << a_it->second << "\n";
820 os << "\\author " << Author() << "\n";
825 void BufferParams::validate(LaTeXFeatures & features) const
827 features.require(textClass().requires());
830 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
831 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
832 LaTeXFeatures::isAvailable("xcolor");
834 switch (features.runparams().flavor) {
835 case OutputParams::LATEX:
837 features.require("ct-dvipost");
838 features.require("dvipost");
839 } else if (xcolorsoul) {
840 features.require("ct-xcolor-soul");
841 features.require("soul");
842 features.require("xcolor");
844 features.require("ct-none");
847 case OutputParams::PDFLATEX:
849 features.require("ct-xcolor-soul");
850 features.require("soul");
851 features.require("xcolor");
852 // improves color handling in PDF output
853 features.require("pdfcolmk");
855 features.require("ct-none");
863 // Floats with 'Here definitely' as default setting.
864 if (float_placement.find('H') != string::npos)
865 features.require("float");
867 // AMS Style is at document level
868 if (use_amsmath == package_on || textClass().provides("amsmath"))
869 features.require("amsmath");
870 if (use_esint == package_on)
871 features.require("esint");
873 // Document-level line spacing
874 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
875 features.require("setspace");
877 // the bullet shapes are buffer level not paragraph level
878 // so they are tested here
879 for (int i = 0; i < 4; ++i) {
880 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
882 int const font = user_defined_bullet(i).getFont();
884 int const c = user_defined_bullet(i).getCharacter();
890 features.require("latexsym");
892 } else if (font == 1) {
893 features.require("amssymb");
894 } else if (font >= 2 && font <= 5) {
895 features.require("pifont");
899 if (pdfoptions().use_hyperref)
900 features.require("hyperref");
904 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
905 TexRow & texrow) const
907 os << "\\documentclass";
909 TextClass const & tclass = textClass();
910 ostringstream clsoptions; // the document class options.
912 if (tokenPos(tclass.opt_fontsize(),
913 '|', fontsize) >= 0) {
914 // only write if existing in list (and not default)
915 clsoptions << fontsize << "pt,";
918 // custom, A3, B3 and B4 paper sizes need geometry
919 bool nonstandard_papersize = papersize == PAPER_B3
920 || papersize == PAPER_B4
921 || papersize == PAPER_A3
922 || papersize == PAPER_CUSTOM;
927 clsoptions << "a4paper,";
930 clsoptions << "letterpaper,";
933 clsoptions << "a5paper,";
936 clsoptions << "b5paper,";
938 case PAPER_USEXECUTIVE:
939 clsoptions << "executivepaper,";
942 clsoptions << "legalpaper,";
954 if (sides != tclass.sides()) {
957 clsoptions << "oneside,";
960 clsoptions << "twoside,";
966 if (columns != tclass.columns()) {
968 clsoptions << "twocolumn,";
970 clsoptions << "onecolumn,";
974 && orientation == ORIENTATION_LANDSCAPE)
975 clsoptions << "landscape,";
977 // language should be a parameter to \documentclass
978 if (language->babel() == "hebrew"
979 && default_language->babel() != "hebrew")
980 // This seems necessary
981 features.useLanguage(default_language);
983 ostringstream language_options;
984 bool const use_babel = features.useBabel();
986 language_options << features.getLanguages();
987 if (!language->babel().empty()) {
988 if (!language_options.str().empty())
989 language_options << ',';
990 language_options << language->babel();
992 // when Vietnamese is used, babel must directly be loaded with the
993 // language options, not in the class options, see
994 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
995 size_t viet = language_options.str().find("vietnam");
996 // viet = string::npos when not found
997 if (lyxrc.language_global_options && !language_options.str().empty()
998 && viet == string::npos)
999 clsoptions << language_options.str() << ',';
1002 // the user-defined options
1003 if (!options.empty()) {
1004 clsoptions << options << ',';
1007 string strOptions(clsoptions.str());
1008 if (!strOptions.empty()) {
1009 strOptions = rtrim(strOptions, ",");
1011 os << '[' << from_utf8(strOptions) << ']';
1014 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1016 // end of \documentclass defs
1018 // font selection must be done before loading fontenc.sty
1019 string const fonts =
1020 loadFonts(fontsRoman, fontsSans,
1021 fontsTypewriter, fontsSC, fontsOSF,
1022 fontsSansScale, fontsTypewriterScale);
1023 if (!fonts.empty()) {
1024 os << from_ascii(fonts);
1027 if (fontsDefaultFamily != "default")
1028 os << "\\renewcommand{\\familydefault}{\\"
1029 << from_ascii(fontsDefaultFamily) << "}\n";
1031 // set font encoding
1032 // this one is not per buffer
1033 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1034 if (lyxrc.fontenc != "default") {
1035 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1036 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1037 << ",LFE,LAE]{fontenc}\n";
1040 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1046 // handle inputenc etc.
1047 writeEncodingPreamble(os, features, texrow);
1049 if (!listings_params.empty()) {
1050 os << "\\usepackage{listings}\n";
1053 // do not test validity because listings_params is supposed to be valid
1054 string par = InsetListingsParams(listings_params).separatedParams(true);
1055 os << from_ascii(par);
1056 // count the number of newlines
1057 for (size_t i = 0; i < par.size(); ++i)
1063 if (use_geometry || nonstandard_papersize) {
1064 os << "\\usepackage{geometry}\n";
1066 os << "\\geometry{verbose";
1067 if (orientation == ORIENTATION_LANDSCAPE)
1069 switch (papersize) {
1071 if (!paperwidth.empty())
1072 os << ",paperwidth="
1073 << from_ascii(paperwidth);
1074 if (!paperheight.empty())
1075 os << ",paperheight="
1076 << from_ascii(paperheight);
1078 case PAPER_USLETTER:
1079 os << ",letterpaper";
1082 os << ",legalpaper";
1084 case PAPER_USEXECUTIVE:
1085 os << ",executivepaper";
1106 // default papersize ie PAPER_DEFAULT
1107 switch (lyxrc.default_papersize) {
1108 case PAPER_DEFAULT: // keep compiler happy
1109 case PAPER_USLETTER:
1110 os << ",letterpaper";
1113 os << ",legalpaper";
1115 case PAPER_USEXECUTIVE:
1116 os << ",executivepaper";
1136 if (!topmargin.empty())
1137 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1138 if (!bottommargin.empty())
1139 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1140 if (!leftmargin.empty())
1141 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1142 if (!rightmargin.empty())
1143 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1144 if (!headheight.empty())
1145 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1146 if (!headsep.empty())
1147 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1148 if (!footskip.empty())
1149 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1150 if (!columnsep.empty())
1151 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1156 if (tokenPos(tclass.opt_pagestyle(),
1157 '|', pagestyle) >= 0) {
1158 if (pagestyle == "fancy") {
1159 os << "\\usepackage{fancyhdr}\n";
1162 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1166 // Only if class has a ToC hierarchy
1167 if (tclass.hasTocLevels()) {
1168 if (secnumdepth != tclass.secnumdepth()) {
1169 os << "\\setcounter{secnumdepth}{"
1174 if (tocdepth != tclass.tocdepth()) {
1175 os << "\\setcounter{tocdepth}{"
1182 if (paragraph_separation) {
1183 switch (getDefSkip().kind()) {
1184 case VSpace::SMALLSKIP:
1185 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1187 case VSpace::MEDSKIP:
1188 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1190 case VSpace::BIGSKIP:
1191 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1193 case VSpace::LENGTH:
1194 os << "\\setlength{\\parskip}{"
1195 << from_utf8(getDefSkip().length().asLatexString())
1198 default: // should never happen // Then delete it.
1199 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1204 os << "\\setlength{\\parindent}{0pt}\n";
1208 // If we use jurabib, we have to call babel here.
1209 if (use_babel && features.isRequired("jurabib")) {
1210 os << from_ascii(babelCall(language_options.str()))
1212 << from_ascii(features.getBabelOptions());
1216 // Now insert the LyX specific LaTeX commands...
1218 // The optional packages;
1219 docstring lyxpreamble(from_ascii(features.getPackages()));
1222 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1224 // We try to load babel late, in case it interferes
1225 // with other packages. But some packages also need babel to be loaded
1226 // before, e.g. jurabib has to be called after babel.
1227 // So load babel after the optional packages but before the user-defined
1228 // preamble. This allows the users to redefine babel commands, e.g. to
1229 // translate the word "Index" to the German "Stichwortverzeichnis".
1230 // For more infos why this place was chosen, see
1231 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1232 // If you encounter problems, you can shift babel to its old place behind
1233 // the user-defined preamble. But in this case you must change the Vietnamese
1234 // support from currently "\usepackage[vietnamese]{babel}" to:
1235 // \usepackage{vietnamese}
1236 // \usepackage{babel}
1237 // because vietnamese must be loaded before hyperref
1238 if (use_babel && !features.isRequired("jurabib")) {
1240 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1241 lyxpreamble += from_utf8(features.getBabelOptions());
1244 // When the language "japanese-plain" is used, the package "japanese" must
1245 // be loaded behind babel (it provides babel support for Japanese) but before
1247 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1248 if (language->lang() == "japanese-plain" &&
1249 !textClass().provides("japanese")) {
1250 //load babel in case it was not loaded due to an empty language list
1251 if (language_options.str().empty())
1252 lyxpreamble += "\\usepackage{babel}\n";
1253 lyxpreamble += "\\usepackage{japanese}\n";
1257 // * Hyperref manual: "Make sure it comes last of your loaded
1258 // packages, to give it a fighting chance of not being over-written,
1259 // since its job is to redefine many LATEX commands."
1260 // * Email from Heiko Oberdiek: "It is usually better to load babel
1261 // before hyperref. Then hyperref has a chance to detect babel.
1262 // * Has to be loaded before the "LyX specific LaTeX commands" to
1263 // avoid errors with algorithm floats.
1264 // use hyperref explicitely when it is required
1265 if (features.isRequired("hyperref")) {
1266 odocstringstream oss;
1267 pdfoptions().writeLaTeX(oss, textClass().provides("hyperref"));
1268 lyxpreamble += oss.str();
1271 // this might be useful...
1272 lyxpreamble += "\n\\makeatletter\n";
1274 // Some macros LyX will need
1275 docstring tmppreamble(from_ascii(features.getMacros()));
1277 if (!tmppreamble.empty()) {
1278 lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1279 "LyX specific LaTeX commands.\n"
1280 + tmppreamble + '\n';
1283 // the text class specific preamble
1284 tmppreamble = features.getTClassPreamble();
1285 if (!tmppreamble.empty()) {
1286 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1287 "Textclass specific LaTeX commands.\n"
1288 + tmppreamble + '\n';
1291 /* the user-defined preamble */
1292 if (!preamble.empty()) {
1294 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1295 "User specified LaTeX commands.\n"
1296 + from_utf8(preamble) + '\n';
1299 // Itemize bullet settings need to be last in case the user
1300 // defines their own bullets that use a package included
1301 // in the user-defined preamble -- ARRae
1302 // Actually it has to be done much later than that
1303 // since some packages like frenchb make modifications
1304 // at \begin{document} time -- JMarc
1305 docstring bullets_def;
1306 for (int i = 0; i < 4; ++i) {
1307 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1308 if (bullets_def.empty())
1309 bullets_def += "\\AtBeginDocument{\n";
1310 bullets_def += " \\def\\labelitemi";
1312 // `i' is one less than the item to modify
1319 bullets_def += "ii";
1325 bullets_def += '{' +
1326 user_defined_bullet(i).getText()
1331 if (!bullets_def.empty())
1332 lyxpreamble += bullets_def + "}\n\n";
1334 lyxpreamble += "\\makeatother\n\n";
1337 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1338 for (int j = 0; j != nlines; ++j) {
1347 void BufferParams::useClassDefaults()
1349 TextClass const & tclass = textclasslist[pimpl_->baseClass_];
1351 sides = tclass.sides();
1352 columns = tclass.columns();
1353 pagestyle = tclass.pagestyle();
1354 options = tclass.options();
1355 // Only if class has a ToC hierarchy
1356 if (tclass.hasTocLevels()) {
1357 secnumdepth = tclass.secnumdepth();
1358 tocdepth = tclass.tocdepth();
1363 bool BufferParams::hasClassDefaults() const
1365 TextClass const & tclass = textclasslist[pimpl_->baseClass_];
1367 return sides == tclass.sides()
1368 && columns == tclass.columns()
1369 && pagestyle == tclass.pagestyle()
1370 && options == tclass.options()
1371 && secnumdepth == tclass.secnumdepth()
1372 && tocdepth == tclass.tocdepth();
1376 TextClass const & BufferParams::textClass() const
1378 return textclasslist[pimpl_->textClass_];
1382 TextClassIndex BufferParams::textClassIndex() const
1384 return pimpl_->textClass_;
1388 void BufferParams::setTextClass(TextClassIndex const & tc)
1390 pimpl_->textClass_ = tc;
1394 bool BufferParams::setBaseClass(TextClassIndex const & tc)
1396 if (textclasslist[tc].load()) {
1397 pimpl_->baseClass_ = tc;
1402 bformat(_("The document class %1$s could not be loaded."),
1403 from_utf8(textclasslist[tc].name()));
1404 frontend::Alert::error(_("Could not load class"), s);
1409 TextClassIndex BufferParams::baseClass() const
1411 return pimpl_->baseClass_;
1415 void BufferParams::makeTextClass()
1417 pimpl_->textClass_ = baseClass();
1419 //FIXME It might be worth loading the children's modules here,
1420 //just as we load their bibliographies and such, instead of just
1421 //doing a check in InsetInclude.
1422 LayoutModuleList::const_iterator it = layoutModules_.begin();
1423 for (; it != layoutModules_.end(); it++) {
1424 string const modName = *it;
1425 LyXModule * lm = moduleList[modName];
1427 docstring const msg =
1428 bformat(_("The module %1$s has been requested by\n"
1429 "this document but has not been found in the list of\n"
1430 "available modules. If you recently installed it, you\n"
1431 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1432 frontend::Alert::warning(_("Module not available"),
1433 msg + _("Some layouts may not be available."));
1434 lyxerr << "BufferParams::makeTextClass(): Module " <<
1435 modName << " requested but not found in module list." <<
1439 if (!lm->isAvailable()) {
1440 docstring const msg =
1441 bformat(_("The module %1$s requires a package that is\n"
1442 "not available in your LaTeX installation. LaTeX output\n"
1443 "may not be possible.\n"), from_utf8(modName));
1444 frontend::Alert::warning(_("Package not available"), msg);
1446 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1447 if (!textclasslist.at(pimpl_->textClass_).read(layout_file, TextClass::MODULE)) {
1448 docstring const msg =
1449 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1450 frontend::Alert::warning(_("Read Error"), msg);
1456 vector<string> const & BufferParams::getModules() const
1458 return layoutModules_;
1463 bool BufferParams::addLayoutModule(string const & modName)
1465 LayoutModuleList::const_iterator it = layoutModules_.begin();
1466 LayoutModuleList::const_iterator end = layoutModules_.end();
1467 for (; it != end; it++) {
1471 if (it != layoutModules_.end())
1473 layoutModules_.push_back(modName);
1478 void BufferParams::clearLayoutModules()
1480 layoutModules_.clear();
1484 Font const BufferParams::getFont() const
1486 FontInfo f = textClass().defaultfont();
1487 if (fontsDefaultFamily == "rmdefault")
1488 f.setFamily(ROMAN_FAMILY);
1489 else if (fontsDefaultFamily == "sfdefault")
1490 f.setFamily(SANS_FAMILY);
1491 else if (fontsDefaultFamily == "ttdefault")
1492 f.setFamily(TYPEWRITER_FAMILY);
1493 return Font(f, language);
1497 void BufferParams::readPreamble(Lexer & lex)
1499 if (lex.getString() != "\\begin_preamble")
1500 lyxerr << "Error (BufferParams::readPreamble):"
1501 "consistency check failed." << endl;
1503 preamble = lex.getLongString("\\end_preamble");
1507 void BufferParams::readLanguage(Lexer & lex)
1509 if (!lex.next()) return;
1511 string const tmptok = lex.getString();
1513 // check if tmptok is part of tex_babel in tex-defs.h
1514 language = languages.getLanguage(tmptok);
1516 // Language tmptok was not found
1517 language = default_language;
1518 lyxerr << "Warning: Setting language `"
1519 << tmptok << "' to `" << language->lang()
1525 void BufferParams::readGraphicsDriver(Lexer & lex)
1530 string const tmptok = lex.getString();
1531 // check if tmptok is part of tex_graphics in tex_defs.h
1534 string const test = tex_graphics[n++];
1536 if (test == tmptok) {
1537 graphicsDriver = tmptok;
1539 } else if (test == "") {
1541 "Warning: graphics driver `$$Token' not recognized!\n"
1542 " Setting graphics driver to `default'.\n");
1543 graphicsDriver = "default";
1550 void BufferParams::readBullets(Lexer & lex)
1555 int const index = lex.getInteger();
1557 int temp_int = lex.getInteger();
1558 user_defined_bullet(index).setFont(temp_int);
1559 temp_bullet(index).setFont(temp_int);
1561 user_defined_bullet(index).setCharacter(temp_int);
1562 temp_bullet(index).setCharacter(temp_int);
1564 user_defined_bullet(index).setSize(temp_int);
1565 temp_bullet(index).setSize(temp_int);
1569 void BufferParams::readBulletsLaTeX(Lexer & lex)
1571 // The bullet class should be able to read this.
1574 int const index = lex.getInteger();
1576 docstring const temp_str = lex.getDocString();
1578 user_defined_bullet(index).setText(temp_str);
1579 temp_bullet(index).setText(temp_str);
1583 void BufferParams::readModules(Lexer & lex)
1585 if (!lex.eatLine()) {
1586 lyxerr << "Error (BufferParams::readModules):"
1587 "Unexpected end of input." << endl;
1591 string mod = lex.getString();
1592 if (mod == "\\end_modules")
1594 addLayoutModule(mod);
1600 string const BufferParams::paperSizeName(Papersize_Purpose const & purpose) const
1602 char real_papersize = papersize;
1603 if (real_papersize == PAPER_DEFAULT)
1604 real_papersize = lyxrc.default_papersize;
1606 switch (real_papersize) {
1608 // could be anything, so don't guess
1610 case PAPER_CUSTOM: {
1611 if (purpose == XDVI && !paperwidth.empty() &&
1612 !paperheight.empty()) {
1613 // heightxwidth<unit>
1614 string first = paperwidth;
1615 string second = paperheight;
1616 if (orientation == ORIENTATION_LANDSCAPE)
1619 return first.erase(first.length() - 2)
1631 // dvips and dvipdfm do not know this
1632 if (purpose == DVIPS || purpose == DVIPDFM)
1636 // dvipdfm does not know this
1637 if (purpose == DVIPDFM)
1641 // dvipdfm does not know this
1642 if (purpose == DVIPDFM)
1645 case PAPER_USEXECUTIVE:
1646 // dvipdfm does not know this
1647 if (purpose == DVIPDFM)
1652 case PAPER_USLETTER:
1654 if (purpose == XDVI)
1661 string const BufferParams::dvips_options() const
1666 && papersize == PAPER_CUSTOM
1667 && !lyxrc.print_paper_dimension_flag.empty()
1668 && !paperwidth.empty()
1669 && !paperheight.empty()) {
1670 // using a custom papersize
1671 result = lyxrc.print_paper_dimension_flag;
1672 result += ' ' + paperwidth;
1673 result += ',' + paperheight;
1675 string const paper_option = paperSizeName(DVIPS);
1676 if (!paper_option.empty() && (paper_option != "letter" ||
1677 orientation != ORIENTATION_LANDSCAPE)) {
1678 // dvips won't accept -t letter -t landscape.
1679 // In all other cases, include the paper size
1681 result = lyxrc.print_paper_flag;
1682 result += ' ' + paper_option;
1685 if (orientation == ORIENTATION_LANDSCAPE &&
1686 papersize != PAPER_CUSTOM)
1687 result += ' ' + lyxrc.print_landscape_flag;
1692 string const BufferParams::babelCall(string const & lang_opts) const
1694 string lang_pack = lyxrc.language_package;
1695 if (lang_pack != "\\usepackage{babel}")
1697 // suppress the babel call when there is no babel language defined
1698 // for the document language in the lib/languages file and if no
1699 // other languages are used (lang_opts is then empty)
1700 if (lang_opts.empty())
1702 // when Vietnamese is used, babel must directly be loaded with the
1703 // language options, see
1704 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1705 size_t viet = lang_opts.find("vietnam");
1706 // viet = string::npos when not found
1707 if (!lyxrc.language_global_options || viet != string::npos)
1708 return "\\usepackage[" + lang_opts + "]{babel}";
1713 void BufferParams::writeEncodingPreamble(odocstream & os,
1714 LaTeXFeatures & features, TexRow & texrow) const
1716 if (inputenc == "auto") {
1717 string const doc_encoding =
1718 language->encoding()->latexName();
1719 Encoding::Package const package =
1720 language->encoding()->package();
1722 // Create a list with all the input encodings used
1724 set<string> encodings =
1725 features.getEncodingSet(doc_encoding);
1727 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1728 // package inputenc must be omitted. Therefore set the encoding to empty.
1729 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1730 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1731 doc_encoding == "SJIS-plain")
1734 if (!encodings.empty() || package == Encoding::inputenc) {
1735 os << "\\usepackage[";
1736 set<string>::const_iterator it = encodings.begin();
1737 set<string>::const_iterator const end = encodings.end();
1739 os << from_ascii(*it);
1742 for (; it != end; ++it)
1743 os << ',' << from_ascii(*it);
1744 if (package == Encoding::inputenc) {
1745 if (!encodings.empty())
1747 os << from_ascii(doc_encoding);
1749 os << "]{inputenc}\n";
1752 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1753 os << "\\usepackage{CJK}\n";
1756 } else if (inputenc != "default") {
1757 switch (encoding().package()) {
1758 case Encoding::none:
1760 case Encoding::inputenc:
1761 os << "\\usepackage[" << from_ascii(inputenc)
1766 os << "\\usepackage{CJK}\n";
1772 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1773 // armscii8 is used for Armenian.
1774 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1775 os << "\\usepackage{armtex}\n";
1781 string const BufferParams::loadFonts(string const & rm,
1782 string const & sf, string const & tt,
1783 bool const & sc, bool const & osf,
1784 int const & sfscale, int const & ttscale) const
1786 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1787 several packages have been replaced by others, that might not
1788 be installed on every system. We have to take care for that
1789 (see psnfss.pdf). We try to support all psnfss fonts as well
1790 as the fonts that have become de facto standard in the LaTeX
1791 world (e.g. Latin Modern). We do not support obsolete fonts
1792 (like PSLatex). In general, it should be possible to mix any
1793 rm font with any sf or tt font, respectively. (JSpitzm)
1795 -- separate math fonts.
1798 if (rm == "default" && sf == "default" && tt == "default")
1805 // Computer Modern (must be explicitely selectable -- there might be classes
1806 // that define a different default font!
1808 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1809 // osf for Computer Modern needs eco.sty
1811 os << "\\usepackage{eco}\n";
1813 // Latin Modern Roman
1814 else if (rm == "lmodern")
1815 os << "\\usepackage{lmodern}\n";
1817 else if (rm == "ae") {
1818 // not needed when using OT1 font encoding.
1819 if (lyxrc.fontenc != "default")
1820 os << "\\usepackage{ae,aecompl}\n";
1823 else if (rm == "times") {
1824 // try to load the best available package
1825 if (LaTeXFeatures::isAvailable("mathptmx"))
1826 os << "\\usepackage{mathptmx}\n";
1827 else if (LaTeXFeatures::isAvailable("mathptm"))
1828 os << "\\usepackage{mathptm}\n";
1830 os << "\\usepackage{times}\n";
1833 else if (rm == "palatino") {
1834 // try to load the best available package
1835 if (LaTeXFeatures::isAvailable("mathpazo")) {
1836 os << "\\usepackage";
1842 // "osf" includes "sc"!
1846 os << "{mathpazo}\n";
1848 else if (LaTeXFeatures::isAvailable("mathpple"))
1849 os << "\\usepackage{mathpple}\n";
1851 os << "\\usepackage{palatino}\n";
1854 else if (rm == "utopia") {
1855 // fourier supersedes utopia.sty, but does
1856 // not work with OT1 encoding.
1857 if (LaTeXFeatures::isAvailable("fourier")
1858 && lyxrc.fontenc != "default") {
1859 os << "\\usepackage";
1870 os << "{fourier}\n";
1873 os << "\\usepackage{utopia}\n";
1875 // Bera (complete fontset)
1876 else if (rm == "bera" && sf == "default" && tt == "default")
1877 os << "\\usepackage{bera}\n";
1879 else if (rm != "default")
1880 os << "\\usepackage" << "{" << rm << "}\n";
1883 // Helvetica, Bera Sans
1884 if (sf == "helvet" || sf == "berasans") {
1886 os << "\\usepackage[scaled=" << float(sfscale) / 100
1887 << "]{" << sf << "}\n";
1889 os << "\\usepackage{" << sf << "}\n";
1892 else if (sf == "avant")
1893 os << "\\usepackage{" << sf << "}\n";
1894 // Computer Modern, Latin Modern, CM Bright
1895 else if (sf != "default")
1896 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1898 // monospaced/typewriter
1899 // Courier, LuxiMono
1900 if (tt == "luximono" || tt == "beramono") {
1902 os << "\\usepackage[scaled=" << float(ttscale) / 100
1903 << "]{" << tt << "}\n";
1905 os << "\\usepackage{" << tt << "}\n";
1908 else if (tt == "courier" )
1909 os << "\\usepackage{" << tt << "}\n";
1910 // Computer Modern, Latin Modern, CM Bright
1911 else if (tt != "default")
1912 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1918 Encoding const & BufferParams::encoding() const
1920 if (inputenc == "auto" || inputenc == "default")
1921 return *(language->encoding());
1922 Encoding const * const enc =
1923 encodings.getFromLaTeXName(inputenc);
1926 lyxerr << "Unknown inputenc value `" << inputenc
1927 << "'. Using `auto' instead." << endl;
1928 return *(language->encoding());
1932 biblio::CiteEngine BufferParams::getEngine() const
1934 // FIXME the class should provide the numerical/
1935 // authoryear choice
1936 if (textClass().provides("natbib")
1937 && cite_engine_ != biblio::ENGINE_NATBIB_NUMERICAL)
1938 return biblio::ENGINE_NATBIB_AUTHORYEAR;
1939 return cite_engine_;
1943 void BufferParams::setCiteEngine(biblio::CiteEngine const cite_engine)
1945 cite_engine_ = cite_engine;