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;
289 BufferParams::Impl::Impl()
290 : defskip(VSpace::MEDSKIP)
292 // set initial author
294 authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
299 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
303 return new BufferParams::Impl(*ptr);
307 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
313 BufferParams::BufferParams()
316 setBaseClass(defaultTextclass());
318 paragraph_separation = PARSEP_INDENT;
319 quotes_language = InsetQuotes::EnglishQ;
320 fontsize = "default";
323 papersize = PAPER_DEFAULT;
324 orientation = ORIENTATION_PORTRAIT;
325 use_geometry = false;
326 use_amsmath = package_auto;
327 use_esint = package_auto;
328 cite_engine_ = biblio::ENGINE_BASIC;
329 use_bibtopic = false;
330 trackChanges = false;
331 outputChanges = false;
334 language = default_language;
335 fontsRoman = "default";
336 fontsSans = "default";
337 fontsTypewriter = "default";
338 fontsDefaultFamily = "default";
341 fontsSansScale = 100;
342 fontsTypewriterScale = 100;
344 graphicsDriver = "default";
347 listings_params = string();
348 pagestyle = "default";
351 for (int iter = 0; iter < 4; ++iter) {
352 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
353 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
358 BufferParams::~BufferParams()
362 docstring const BufferParams::B_(string const & l10n) const
364 BOOST_ASSERT(language);
365 return getMessages(language->code()).get(l10n);
369 AuthorList & BufferParams::authors()
371 return pimpl_->authorlist;
375 AuthorList const & BufferParams::authors() const
377 return pimpl_->authorlist;
381 BranchList & BufferParams::branchlist()
383 return pimpl_->branchlist;
387 BranchList const & BufferParams::branchlist() const
389 return pimpl_->branchlist;
393 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
395 BOOST_ASSERT(index < 4);
396 return pimpl_->temp_bullets[index];
400 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
402 BOOST_ASSERT(index < 4);
403 return pimpl_->temp_bullets[index];
407 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
409 BOOST_ASSERT(index < 4);
410 return pimpl_->user_defined_bullets[index];
414 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
416 BOOST_ASSERT(index < 4);
417 return pimpl_->user_defined_bullets[index];
421 Spacing & BufferParams::spacing()
423 return pimpl_->spacing;
427 Spacing const & BufferParams::spacing() const
429 return pimpl_->spacing;
433 PDFOptions & BufferParams::pdfoptions()
435 return pimpl_->pdfoptions;
439 PDFOptions const & BufferParams::pdfoptions() const
441 return pimpl_->pdfoptions;
445 VSpace const & BufferParams::getDefSkip() const
447 return pimpl_->defskip;
451 void BufferParams::setDefSkip(VSpace const & vs)
453 pimpl_->defskip = vs;
457 string const BufferParams::readToken(Lexer & lex, string const & token,
458 FileName const & filepath)
460 if (token == "\\textclass") {
462 string const classname = lex.getString();
463 // if there exists a local layout file, ignore the system one
464 // NOTE: in this case, the textclass (.cls file) is assumed to be available.
465 pair<bool, lyx::textclass_type> pp =
466 make_pair(false, textclass_type(0));
467 if (!filepath.empty())
468 pp = textclasslist.addTextClass(
469 classname, filepath.absFilename());
471 setBaseClass(pp.second);
473 pp = textclasslist.numberOfClass(classname);
475 setBaseClass(pp.second);
477 // a warning will be given for unknown class
478 setBaseClass(defaultTextclass());
482 // FIXME: this warning will be given even if there exists a local .cls
483 // file. Even worse, the .lyx file can not be compiled or exported
484 // because the textclass is marked as unavilable.
485 if (!getTextClass().isTeXClassAvailable()) {
486 docstring const msg =
487 bformat(_("The layout file requested by this document,\n"
489 "is not usable. This is probably because a LaTeX\n"
490 "class or style file required by it is not\n"
491 "available. See the Customization documentation\n"
492 "for more information.\n"), from_utf8(classname));
493 frontend::Alert::warning(_("Document class not available"),
494 msg + _("LyX will not be able to produce output."));
497 } else if (token == "\\begin_preamble") {
499 } else if (token == "\\begin_modules") {
501 } else if (token == "\\options") {
503 options = lex.getString();
504 } else if (token == "\\language") {
506 } else if (token == "\\inputencoding") {
508 } else if (token == "\\graphics") {
509 readGraphicsDriver(lex);
510 } else if (token == "\\font_roman") {
512 } else if (token == "\\font_sans") {
514 } else if (token == "\\font_typewriter") {
515 lex >> fontsTypewriter;
516 } else if (token == "\\font_default_family") {
517 lex >> fontsDefaultFamily;
518 } else if (token == "\\font_sc") {
520 } else if (token == "\\font_osf") {
522 } else if (token == "\\font_sf_scale") {
523 lex >> fontsSansScale;
524 } else if (token == "\\font_tt_scale") {
525 lex >> fontsTypewriterScale;
526 } else if (token == "\\paragraph_separation") {
529 paragraph_separation = parseptranslator().find(parsep);
530 } else if (token == "\\defskip") {
532 string defskip = lex.getString();
533 if (defskip == "defskip")
536 pimpl_->defskip = VSpace(defskip);
537 } else if (token == "\\quotes_language") {
540 quotes_language = quoteslangtranslator().find(quotes_lang);
541 } else if (token == "\\papersize") {
544 papersize = papersizetranslator().find(ppsize);
545 } else if (token == "\\use_geometry") {
547 } else if (token == "\\use_amsmath") {
550 use_amsmath = packagetranslator().find(use_ams);
551 } else if (token == "\\use_esint") {
554 use_esint = packagetranslator().find(useesint);
555 } else if (token == "\\cite_engine") {
558 cite_engine_ = citeenginetranslator().find(engine);
559 } else if (token == "\\use_bibtopic") {
561 } else if (token == "\\tracking_changes") {
563 } else if (token == "\\output_changes") {
564 lex >> outputChanges;
565 } else if (token == "\\branch") {
567 docstring branch = lex.getDocString();
568 branchlist().add(branch);
571 string const tok = lex.getString();
572 if (tok == "\\end_branch")
574 Branch * branch_ptr = branchlist().find(branch);
575 if (tok == "\\selected") {
578 branch_ptr->setSelected(lex.getInteger());
580 // not yet operational
581 if (tok == "\\color") {
583 string color = lex.getString();
585 branch_ptr->setColor(color);
586 // Update also the Color table:
588 color = lcolor.getX11Name(Color_background);
590 lcolor.setColor(to_utf8(branch), color);
594 } else if (token == "\\author") {
596 istringstream ss(lex.getString());
599 author_map.push_back(pimpl_->authorlist.record(a));
600 } else if (token == "\\paperorientation") {
603 orientation = paperorientationtranslator().find(orient);
604 } else if (token == "\\paperwidth") {
606 } else if (token == "\\paperheight") {
608 } else if (token == "\\leftmargin") {
610 } else if (token == "\\topmargin") {
612 } else if (token == "\\rightmargin") {
614 } else if (token == "\\bottommargin") {
616 } else if (token == "\\headheight") {
618 } else if (token == "\\headsep") {
620 } else if (token == "\\footskip") {
622 } else if (token == "\\paperfontsize") {
624 } else if (token == "\\papercolumns") {
626 } else if (token == "\\listings_params") {
629 listings_params = InsetListingsParams(par).params();
630 } else if (token == "\\papersides") {
633 sides = sidestranslator().find(psides);
634 } else if (token == "\\paperpagestyle") {
636 } else if (token == "\\bullet") {
638 } else if (token == "\\bulletLaTeX") {
639 readBulletsLaTeX(lex);
640 } else if (token == "\\secnumdepth") {
642 } else if (token == "\\tocdepth") {
644 } else if (token == "\\spacing") {
648 if (nspacing == "other") {
651 spacing().set(spacetranslator().find(nspacing), tmp_val);
652 } else if (token == "\\float_placement") {
653 lex >> float_placement;
655 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
656 string toktmp = pdfoptions().readToken(lex, token);
657 if (!toktmp.empty()) {
658 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
663 lyxerr << "BufferParams::readToken(): Unknown token: " <<
672 void BufferParams::writeFile(ostream & os) const
674 // The top of the file is written by the buffer.
675 // Prints out the buffer info into the .lyx file given by file
678 os << "\\textclass " << textclasslist[baseClass_].name() << '\n';
681 if (!preamble.empty()) {
682 // remove '\n' from the end of preamble
683 string const tmppreamble = rtrim(preamble, "\n");
684 os << "\\begin_preamble\n"
686 << "\n\\end_preamble\n";
690 if (!options.empty()) {
691 os << "\\options " << options << '\n';
695 if (!layoutModules_.empty()) {
696 os << "\\begin_modules" << '\n';
697 LayoutModuleList::const_iterator it = layoutModules_.begin();
698 for (; it != layoutModules_.end(); it++)
700 os << "\\end_modules" << '\n';
703 // then the text parameters
704 if (language != ignore_language)
705 os << "\\language " << language->lang() << '\n';
706 os << "\\inputencoding " << inputenc
707 << "\n\\font_roman " << fontsRoman
708 << "\n\\font_sans " << fontsSans
709 << "\n\\font_typewriter " << fontsTypewriter
710 << "\n\\font_default_family " << fontsDefaultFamily
711 << "\n\\font_sc " << convert<string>(fontsSC)
712 << "\n\\font_osf " << convert<string>(fontsOSF)
713 << "\n\\font_sf_scale " << fontsSansScale
714 << "\n\\font_tt_scale " << fontsTypewriterScale
715 << "\n\\graphics " << graphicsDriver << '\n';
717 if (!float_placement.empty()) {
718 os << "\\float_placement " << float_placement << '\n';
720 os << "\\paperfontsize " << fontsize << '\n';
722 spacing().writeFile(os);
723 pdfoptions().writeFile(os);
725 os << "\\papersize " << string_papersize[papersize]
726 << "\n\\use_geometry " << convert<string>(use_geometry)
727 << "\n\\use_amsmath " << use_amsmath
728 << "\n\\use_esint " << use_esint
729 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
730 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
731 << "\n\\paperorientation " << string_orientation[orientation]
734 BranchList::const_iterator it = branchlist().begin();
735 BranchList::const_iterator end = branchlist().end();
736 for (; it != end; ++it) {
737 os << "\\branch " << to_utf8(it->getBranch())
738 << "\n\\selected " << it->getSelected()
739 << "\n\\color " << lyx::X11hexname(it->getColor())
744 if (!paperwidth.empty())
745 os << "\\paperwidth "
746 << VSpace(paperwidth).asLyXCommand() << '\n';
747 if (!paperheight.empty())
748 os << "\\paperheight "
749 << VSpace(paperheight).asLyXCommand() << '\n';
750 if (!leftmargin.empty())
751 os << "\\leftmargin "
752 << VSpace(leftmargin).asLyXCommand() << '\n';
753 if (!topmargin.empty())
755 << VSpace(topmargin).asLyXCommand() << '\n';
756 if (!rightmargin.empty())
757 os << "\\rightmargin "
758 << VSpace(rightmargin).asLyXCommand() << '\n';
759 if (!bottommargin.empty())
760 os << "\\bottommargin "
761 << VSpace(bottommargin).asLyXCommand() << '\n';
762 if (!headheight.empty())
763 os << "\\headheight "
764 << VSpace(headheight).asLyXCommand() << '\n';
765 if (!headsep.empty())
767 << VSpace(headsep).asLyXCommand() << '\n';
768 if (!footskip.empty())
770 << VSpace(footskip).asLyXCommand() << '\n';
771 os << "\\secnumdepth " << secnumdepth
772 << "\n\\tocdepth " << tocdepth
773 << "\n\\paragraph_separation "
774 << string_paragraph_separation[paragraph_separation]
775 << "\n\\defskip " << getDefSkip().asLyXCommand()
776 << "\n\\quotes_language "
777 << string_quotes_language[quotes_language]
778 << "\n\\papercolumns " << columns
779 << "\n\\papersides " << sides
780 << "\n\\paperpagestyle " << pagestyle << '\n';
781 if (!listings_params.empty())
782 os << "\\listings_params \"" <<
783 InsetListingsParams(listings_params).encodedString() << "\"\n";
784 for (int i = 0; i < 4; ++i) {
785 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
786 if (user_defined_bullet(i).getFont() != -1) {
787 os << "\\bullet " << i << " "
788 << user_defined_bullet(i).getFont() << " "
789 << user_defined_bullet(i).getCharacter() << " "
790 << user_defined_bullet(i).getSize() << "\n";
794 os << "\\bulletLaTeX " << i << " \""
795 << lyx::to_ascii(user_defined_bullet(i).getText())
801 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
802 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
804 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
805 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
806 for (; a_it != a_end; ++a_it) {
807 if (a_it->second.used())
808 os << "\\author " << a_it->second << "\n";
810 os << "\\author " << Author() << "\n";
815 void BufferParams::validate(LaTeXFeatures & features) const
817 features.require(getTextClass().requires());
820 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
821 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
822 LaTeXFeatures::isAvailable("xcolor");
824 switch (features.runparams().flavor) {
825 case OutputParams::LATEX:
827 features.require("ct-dvipost");
828 features.require("dvipost");
829 } else if (xcolorsoul) {
830 features.require("ct-xcolor-soul");
831 features.require("soul");
832 features.require("xcolor");
834 features.require("ct-none");
837 case OutputParams::PDFLATEX:
839 features.require("ct-xcolor-soul");
840 features.require("soul");
841 features.require("xcolor");
842 // improves color handling in PDF output
843 features.require("pdfcolmk");
845 features.require("ct-none");
853 // Floats with 'Here definitely' as default setting.
854 if (float_placement.find('H') != string::npos)
855 features.require("float");
857 // AMS Style is at document level
858 if (use_amsmath == package_on
859 || getTextClass().provides("amsmath"))
860 features.require("amsmath");
861 if (use_esint == package_on)
862 features.require("esint");
864 // Document-level line spacing
865 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
866 features.require("setspace");
868 // the bullet shapes are buffer level not paragraph level
869 // so they are tested here
870 for (int i = 0; i < 4; ++i) {
871 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
873 int const font = user_defined_bullet(i).getFont();
875 int const c = user_defined_bullet(i).getCharacter();
881 features.require("latexsym");
883 } else if (font == 1) {
884 features.require("amssymb");
885 } else if (font >= 2 && font <= 5) {
886 features.require("pifont");
890 if (pdfoptions().use_hyperref)
891 features.require("hyperref");
895 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
896 TexRow & texrow) const
898 os << "\\documentclass";
900 TextClass const & tclass = getTextClass();
902 ostringstream clsoptions; // the document class options.
904 if (tokenPos(tclass.opt_fontsize(),
905 '|', fontsize) >= 0) {
906 // only write if existing in list (and not default)
907 clsoptions << fontsize << "pt,";
910 // custom, A3, B3 and B4 paper sizes need geometry
911 bool nonstandard_papersize = papersize == PAPER_B3
912 || papersize == PAPER_B4
913 || papersize == PAPER_A3
914 || papersize == PAPER_CUSTOM;
919 clsoptions << "a4paper,";
922 clsoptions << "letterpaper,";
925 clsoptions << "a5paper,";
928 clsoptions << "b5paper,";
930 case PAPER_USEXECUTIVE:
931 clsoptions << "executivepaper,";
934 clsoptions << "legalpaper,";
946 if (sides != tclass.sides()) {
949 clsoptions << "oneside,";
952 clsoptions << "twoside,";
958 if (columns != tclass.columns()) {
960 clsoptions << "twocolumn,";
962 clsoptions << "onecolumn,";
966 && orientation == ORIENTATION_LANDSCAPE)
967 clsoptions << "landscape,";
969 // language should be a parameter to \documentclass
970 if (language->babel() == "hebrew"
971 && default_language->babel() != "hebrew")
972 // This seems necessary
973 features.useLanguage(default_language);
975 ostringstream language_options;
976 bool const use_babel = features.useBabel();
978 language_options << features.getLanguages();
979 if (!language->babel().empty()) {
980 if (!language_options.str().empty())
981 language_options << ',';
982 language_options << language->babel();
984 // when Vietnamese is used, babel must directly be loaded with the
985 // language options, not in the class options, see
986 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
987 size_t viet = language_options.str().find("vietnam");
988 // viet = string::npos when not found
989 if (lyxrc.language_global_options && !language_options.str().empty()
990 && viet == string::npos)
991 clsoptions << language_options.str() << ',';
994 // the user-defined options
995 if (!options.empty()) {
996 clsoptions << options << ',';
999 string strOptions(clsoptions.str());
1000 if (!strOptions.empty()) {
1001 strOptions = rtrim(strOptions, ",");
1003 os << '[' << from_utf8(strOptions) << ']';
1006 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1008 // end of \documentclass defs
1010 // font selection must be done before loading fontenc.sty
1011 string const fonts =
1012 loadFonts(fontsRoman, fontsSans,
1013 fontsTypewriter, fontsSC, fontsOSF,
1014 fontsSansScale, fontsTypewriterScale);
1015 if (!fonts.empty()) {
1016 os << from_ascii(fonts);
1019 if (fontsDefaultFamily != "default")
1020 os << "\\renewcommand{\\familydefault}{\\"
1021 << from_ascii(fontsDefaultFamily) << "}\n";
1023 // set font encoding
1024 // this one is not per buffer
1025 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1026 if (lyxrc.fontenc != "default") {
1027 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1028 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1029 << ",LFE,LAE]{fontenc}\n";
1032 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1038 // handle inputenc etc.
1039 writeEncodingPreamble(os, features, texrow);
1041 if (!listings_params.empty()) {
1042 os << "\\usepackage{listings}\n";
1045 // do not test validity because listings_params is supposed to be valid
1046 string par = InsetListingsParams(listings_params).separatedParams(true);
1047 os << from_ascii(par);
1048 // count the number of newlines
1049 for (size_t i = 0; i < par.size(); ++i)
1055 if (use_geometry || nonstandard_papersize) {
1056 os << "\\usepackage{geometry}\n";
1058 os << "\\geometry{verbose";
1059 if (orientation == ORIENTATION_LANDSCAPE)
1061 switch (papersize) {
1063 if (!paperwidth.empty())
1064 os << ",paperwidth="
1065 << from_ascii(paperwidth);
1066 if (!paperheight.empty())
1067 os << ",paperheight="
1068 << from_ascii(paperheight);
1070 case PAPER_USLETTER:
1071 os << ",letterpaper";
1074 os << ",legalpaper";
1076 case PAPER_USEXECUTIVE:
1077 os << ",executivepaper";
1098 // default papersize ie PAPER_DEFAULT
1099 switch (lyxrc.default_papersize) {
1100 case PAPER_DEFAULT: // keep compiler happy
1101 case PAPER_USLETTER:
1102 os << ",letterpaper";
1105 os << ",legalpaper";
1107 case PAPER_USEXECUTIVE:
1108 os << ",executivepaper";
1128 if (!topmargin.empty())
1129 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1130 if (!bottommargin.empty())
1131 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1132 if (!leftmargin.empty())
1133 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1134 if (!rightmargin.empty())
1135 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1136 if (!headheight.empty())
1137 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1138 if (!headsep.empty())
1139 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1140 if (!footskip.empty())
1141 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1146 if (tokenPos(tclass.opt_pagestyle(),
1147 '|', pagestyle) >= 0) {
1148 if (pagestyle == "fancy") {
1149 os << "\\usepackage{fancyhdr}\n";
1152 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1156 // Only if class has a ToC hierarchy
1157 if (tclass.hasTocLevels()) {
1158 if (secnumdepth != tclass.secnumdepth()) {
1159 os << "\\setcounter{secnumdepth}{"
1164 if (tocdepth != tclass.tocdepth()) {
1165 os << "\\setcounter{tocdepth}{"
1172 if (paragraph_separation) {
1173 switch (getDefSkip().kind()) {
1174 case VSpace::SMALLSKIP:
1175 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1177 case VSpace::MEDSKIP:
1178 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1180 case VSpace::BIGSKIP:
1181 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1183 case VSpace::LENGTH:
1184 os << "\\setlength{\\parskip}{"
1185 << from_utf8(getDefSkip().length().asLatexString())
1188 default: // should never happen // Then delete it.
1189 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1194 os << "\\setlength{\\parindent}{0pt}\n";
1198 // If we use jurabib, we have to call babel here.
1199 if (use_babel && features.isRequired("jurabib")) {
1200 os << from_ascii(babelCall(language_options.str()))
1202 << from_ascii(features.getBabelOptions());
1206 // Now insert the LyX specific LaTeX commands...
1208 // The optional packages;
1209 docstring lyxpreamble(from_ascii(features.getPackages()));
1212 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1214 // We try to load babel late, in case it interferes
1215 // with other packages. But some packages also need babel to be loaded
1216 // before, e.g. jurabib has to be called after babel.
1217 // So load babel after the optional packages but before the user-defined
1218 // preamble. This allows the users to redefine babel commands, e.g. to
1219 // translate the word "Index" to the German "Stichwortverzeichnis".
1220 // For more infos why this place was chosen, see
1221 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1222 // If you encounter problems, you can shift babel to its old place behind
1223 // the user-defined preamble. But in this case you must change the Vietnamese
1224 // support from currently "\usepackage[vietnamese]{babel}" to:
1225 // \usepackage{vietnamese}
1226 // \usepackage{babel}
1227 // because vietnamese must be loaded before hyperref
1228 if (use_babel && !features.isRequired("jurabib")) {
1230 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1231 lyxpreamble += from_utf8(features.getBabelOptions());
1234 // When the language "japanese-plain" is used, the package "japanese" must
1235 // be loaded behind babel (it provides babel support for Japanese) but before
1237 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1238 if (language->lang() == "japanese-plain" &&
1239 !getTextClass().provides("japanese")) {
1240 //load babel in case it was not loaded due to an empty language list
1241 if (language_options.str().empty())
1242 lyxpreamble += "\\usepackage{babel}\n";
1243 lyxpreamble += "\\usepackage{japanese}\n";
1247 // * Hyperref manual: "Make sure it comes last of your loaded
1248 // packages, to give it a fighting chance of not being over-written,
1249 // since its job is to redefine many LATEX commands."
1250 // * Email from Heiko Oberdiek: "It is usually better to load babel
1251 // before hyperref. Then hyperref has a chance to detect babel.
1252 // * Has to be loaded before the "LyX specific LaTeX commands" to
1253 // avoid errors with algorithm floats.
1254 // use hyperref explicitely when it is required
1255 if (features.isRequired("hyperref")) {
1256 odocstringstream oss;
1257 pdfoptions().writeLaTeX(oss, getTextClass().provides("hyperref"));
1258 lyxpreamble += oss.str();
1261 // this might be useful...
1262 lyxpreamble += "\n\\makeatletter\n";
1264 // Some macros LyX will need
1265 docstring tmppreamble(from_ascii(features.getMacros()));
1267 if (!tmppreamble.empty()) {
1268 lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1269 "LyX specific LaTeX commands.\n"
1270 + tmppreamble + '\n';
1273 // the text class specific preamble
1274 tmppreamble = features.getTClassPreamble();
1275 if (!tmppreamble.empty()) {
1276 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1277 "Textclass specific LaTeX commands.\n"
1278 + tmppreamble + '\n';
1281 /* the user-defined preamble */
1282 if (!preamble.empty()) {
1284 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1285 "User specified LaTeX commands.\n"
1286 + from_utf8(preamble) + '\n';
1289 // Itemize bullet settings need to be last in case the user
1290 // defines their own bullets that use a package included
1291 // in the user-defined preamble -- ARRae
1292 // Actually it has to be done much later than that
1293 // since some packages like frenchb make modifications
1294 // at \begin{document} time -- JMarc
1295 docstring bullets_def;
1296 for (int i = 0; i < 4; ++i) {
1297 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1298 if (bullets_def.empty())
1299 bullets_def += "\\AtBeginDocument{\n";
1300 bullets_def += " \\def\\labelitemi";
1302 // `i' is one less than the item to modify
1309 bullets_def += "ii";
1315 bullets_def += '{' +
1316 user_defined_bullet(i).getText()
1321 if (!bullets_def.empty())
1322 lyxpreamble += bullets_def + "}\n\n";
1324 lyxpreamble += "\\makeatother\n\n";
1327 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1328 for (int j = 0; j != nlines; ++j) {
1337 void BufferParams::useClassDefaults()
1339 TextClass const & tclass = textclasslist[baseClass_];
1341 sides = tclass.sides();
1342 columns = tclass.columns();
1343 pagestyle = tclass.pagestyle();
1344 options = tclass.options();
1345 // Only if class has a ToC hierarchy
1346 if (tclass.hasTocLevels()) {
1347 secnumdepth = tclass.secnumdepth();
1348 tocdepth = tclass.tocdepth();
1353 bool BufferParams::hasClassDefaults() const
1355 TextClass const & tclass = textclasslist[baseClass_];
1357 return (sides == tclass.sides()
1358 && columns == tclass.columns()
1359 && pagestyle == tclass.pagestyle()
1360 && options == tclass.options()
1361 && secnumdepth == tclass.secnumdepth()
1362 && tocdepth == tclass.tocdepth());
1366 TextClass const & BufferParams::getTextClass() const
1372 TextClassPtr BufferParams::getTextClassPtr() const {
1377 void BufferParams::setTextClass(TextClassPtr tc) {
1382 bool BufferParams::setBaseClass(textclass_type tc)
1384 if (textclasslist[tc].load()) {
1390 bformat(_("The document class %1$s could not be loaded."),
1391 from_utf8(textclasslist[tc].name()));
1392 frontend::Alert::error(_("Could not load class"), s);
1397 textclass_type BufferParams::getBaseClass() const
1403 void BufferParams::makeTextClass()
1405 textClass_.reset(new TextClass(textclasslist[getBaseClass()]));
1407 //FIXME It might be worth loading the children's modules here,
1408 //just as we load their bibliographies and such, instead of just
1409 //doing a check in InsetInclude.
1410 LayoutModuleList::const_iterator it = layoutModules_.begin();
1411 for (; it != layoutModules_.end(); it++) {
1412 string const modName = *it;
1413 LyXModule * lm = moduleList[modName];
1415 docstring const msg =
1416 bformat(_("The module %1$s has been requested by\n"
1417 "this document but has not been found in the list of\n"
1418 "available modules. If you recently installed it, you\n"
1419 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1420 frontend::Alert::warning(_("Module not available"),
1421 msg + _("Some layouts may not be available."));
1422 lyxerr << "BufferParams::makeTextClass(): Module " <<
1423 modName << " requested but not found in module list." <<
1427 if (!lm->isAvailable()) {
1428 docstring const msg =
1429 bformat(_("The module %1$s requires a package that is\n"
1430 "not available in your LaTeX installation. LaTeX output\n"
1431 "may not be possible.\n"), from_utf8(modName));
1432 frontend::Alert::warning(_("Package not available"), msg);
1434 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1435 if (!textClass_->read(layout_file, TextClass::MODULE)) {
1436 docstring const msg =
1437 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1438 frontend::Alert::warning(_("Read Error"), msg);
1444 vector<string> const & BufferParams::getModules() const {
1445 return layoutModules_;
1450 bool BufferParams::addLayoutModule(string const & modName) {
1451 LayoutModuleList::const_iterator it = layoutModules_.begin();
1452 LayoutModuleList::const_iterator end = layoutModules_.end();
1453 for (; it != end; it++) {
1457 if (it != layoutModules_.end())
1459 layoutModules_.push_back(modName);
1464 void BufferParams::clearLayoutModules() {
1465 layoutModules_.clear();
1469 Font const BufferParams::getFont() const
1471 FontInfo f = getTextClass().defaultfont();
1472 if (fontsDefaultFamily == "rmdefault")
1473 f.setFamily(ROMAN_FAMILY);
1474 else if (fontsDefaultFamily == "sfdefault")
1475 f.setFamily(SANS_FAMILY);
1476 else if (fontsDefaultFamily == "ttdefault")
1477 f.setFamily(TYPEWRITER_FAMILY);
1478 return Font(f, language);
1482 void BufferParams::readPreamble(Lexer & lex)
1484 if (lex.getString() != "\\begin_preamble")
1485 lyxerr << "Error (BufferParams::readPreamble):"
1486 "consistency check failed." << endl;
1488 preamble = lex.getLongString("\\end_preamble");
1492 void BufferParams::readLanguage(Lexer & lex)
1494 if (!lex.next()) return;
1496 string const tmptok = lex.getString();
1498 // check if tmptok is part of tex_babel in tex-defs.h
1499 language = languages.getLanguage(tmptok);
1501 // Language tmptok was not found
1502 language = default_language;
1503 lyxerr << "Warning: Setting language `"
1504 << tmptok << "' to `" << language->lang()
1510 void BufferParams::readGraphicsDriver(Lexer & lex)
1512 if (!lex.next()) return;
1514 string const tmptok = lex.getString();
1515 // check if tmptok is part of tex_graphics in tex_defs.h
1518 string const test = tex_graphics[n++];
1520 if (test == tmptok) {
1521 graphicsDriver = tmptok;
1523 } else if (test == "") {
1525 "Warning: graphics driver `$$Token' not recognized!\n"
1526 " Setting graphics driver to `default'.\n");
1527 graphicsDriver = "default";
1534 void BufferParams::readBullets(Lexer & lex)
1536 if (!lex.next()) return;
1538 int const index = lex.getInteger();
1540 int temp_int = lex.getInteger();
1541 user_defined_bullet(index).setFont(temp_int);
1542 temp_bullet(index).setFont(temp_int);
1544 user_defined_bullet(index).setCharacter(temp_int);
1545 temp_bullet(index).setCharacter(temp_int);
1547 user_defined_bullet(index).setSize(temp_int);
1548 temp_bullet(index).setSize(temp_int);
1552 void BufferParams::readBulletsLaTeX(Lexer & lex)
1554 // The bullet class should be able to read this.
1555 if (!lex.next()) return;
1556 int const index = lex.getInteger();
1558 docstring const temp_str = lex.getDocString();
1560 user_defined_bullet(index).setText(temp_str);
1561 temp_bullet(index).setText(temp_str);
1565 void BufferParams::readModules(Lexer & lex)
1567 if (!lex.eatLine()) {
1568 lyxerr << "Error (BufferParams::readModules):"
1569 "Unexpected end of input." << endl;
1573 string mod = lex.getString();
1574 if (mod == "\\end_modules")
1576 addLayoutModule(mod);
1582 string const BufferParams::paperSizeName(Papersize_Purpose const & purpose) const
1584 char real_papersize = papersize;
1585 if (real_papersize == PAPER_DEFAULT)
1586 real_papersize = lyxrc.default_papersize;
1588 switch (real_papersize) {
1590 // could be anything, so don't guess
1592 case PAPER_CUSTOM: {
1593 if (purpose == XDVI && !paperwidth.empty() &&
1594 !paperheight.empty()) {
1595 // heightxwidth<unit>
1596 string first = paperwidth;
1597 string second = paperheight;
1598 if (orientation == ORIENTATION_LANDSCAPE)
1601 return first.erase(first.length() - 2)
1613 // dvips and dvipdfm do not know this
1614 if (purpose == DVIPS || purpose == DVIPDFM)
1618 // dvipdfm does not know this
1619 if (purpose == DVIPDFM)
1623 // dvipdfm does not know this
1624 if (purpose == DVIPDFM)
1627 case PAPER_USEXECUTIVE:
1628 // dvipdfm does not know this
1629 if (purpose == DVIPDFM)
1634 case PAPER_USLETTER:
1636 if (purpose == XDVI)
1643 string const BufferParams::dvips_options() const
1648 && papersize == PAPER_CUSTOM
1649 && !lyxrc.print_paper_dimension_flag.empty()
1650 && !paperwidth.empty()
1651 && !paperheight.empty()) {
1652 // using a custom papersize
1653 result = lyxrc.print_paper_dimension_flag;
1654 result += ' ' + paperwidth;
1655 result += ',' + paperheight;
1657 string const paper_option = paperSizeName(DVIPS);
1658 if (!paper_option.empty() && (paper_option != "letter" ||
1659 orientation != ORIENTATION_LANDSCAPE)) {
1660 // dvips won't accept -t letter -t landscape.
1661 // In all other cases, include the paper size
1663 result = lyxrc.print_paper_flag;
1664 result += ' ' + paper_option;
1667 if (orientation == ORIENTATION_LANDSCAPE &&
1668 papersize != PAPER_CUSTOM)
1669 result += ' ' + lyxrc.print_landscape_flag;
1674 string const BufferParams::babelCall(string const & lang_opts) const
1676 string lang_pack = lyxrc.language_package;
1677 if (lang_pack != "\\usepackage{babel}")
1679 // suppress the babel call when there is no babel language defined
1680 // for the document language in the lib/languages file and if no
1681 // other languages are used (lang_opts is then empty)
1682 if (lang_opts.empty())
1684 // when Vietnamese is used, babel must directly be loaded with the
1685 // language options, see
1686 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1687 size_t viet = lang_opts.find("vietnam");
1688 // viet = string::npos when not found
1689 if (!lyxrc.language_global_options || viet != string::npos)
1690 return "\\usepackage[" + lang_opts + "]{babel}";
1695 void BufferParams::writeEncodingPreamble(odocstream & os,
1696 LaTeXFeatures & features, TexRow & texrow) const
1698 if (inputenc == "auto") {
1699 string const doc_encoding =
1700 language->encoding()->latexName();
1701 Encoding::Package const package =
1702 language->encoding()->package();
1704 // Create a list with all the input encodings used
1706 set<string> encodings =
1707 features.getEncodingSet(doc_encoding);
1709 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1710 // package inputenc must be omitted. Therefore set the encoding to empty.
1711 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1712 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1713 doc_encoding == "SJIS-plain")
1716 if (!encodings.empty() || package == Encoding::inputenc) {
1717 os << "\\usepackage[";
1718 set<string>::const_iterator it = encodings.begin();
1719 set<string>::const_iterator const end = encodings.end();
1721 os << from_ascii(*it);
1724 for (; it != end; ++it)
1725 os << ',' << from_ascii(*it);
1726 if (package == Encoding::inputenc) {
1727 if (!encodings.empty())
1729 os << from_ascii(doc_encoding);
1731 os << "]{inputenc}\n";
1734 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1735 os << "\\usepackage{CJK}\n";
1738 } else if (inputenc != "default") {
1739 switch (encoding().package()) {
1740 case Encoding::none:
1742 case Encoding::inputenc:
1743 os << "\\usepackage[" << from_ascii(inputenc)
1748 os << "\\usepackage{CJK}\n";
1754 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1755 // armscii8 is used for Armenian.
1756 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1757 os << "\\usepackage{armtex}\n";
1763 string const BufferParams::loadFonts(string const & rm,
1764 string const & sf, string const & tt,
1765 bool const & sc, bool const & osf,
1766 int const & sfscale, int const & ttscale) const
1768 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1769 several packages have been replaced by others, that might not
1770 be installed on every system. We have to take care for that
1771 (see psnfss.pdf). We try to support all psnfss fonts as well
1772 as the fonts that have become de facto standard in the LaTeX
1773 world (e.g. Latin Modern). We do not support obsolete fonts
1774 (like PSLatex). In general, it should be possible to mix any
1775 rm font with any sf or tt font, respectively. (JSpitzm)
1777 -- separate math fonts.
1780 if (rm == "default" && sf == "default" && tt == "default")
1787 // Computer Modern (must be explicitely selectable -- there might be classes
1788 // that define a different default font!
1790 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1791 // osf for Computer Modern needs eco.sty
1793 os << "\\usepackage{eco}\n";
1795 // Latin Modern Roman
1796 else if (rm == "lmodern")
1797 os << "\\usepackage{lmodern}\n";
1799 else if (rm == "ae") {
1800 // not needed when using OT1 font encoding.
1801 if (lyxrc.fontenc != "default")
1802 os << "\\usepackage{ae,aecompl}\n";
1805 else if (rm == "times") {
1806 // try to load the best available package
1807 if (LaTeXFeatures::isAvailable("mathptmx"))
1808 os << "\\usepackage{mathptmx}\n";
1809 else if (LaTeXFeatures::isAvailable("mathptm"))
1810 os << "\\usepackage{mathptm}\n";
1812 os << "\\usepackage{times}\n";
1815 else if (rm == "palatino") {
1816 // try to load the best available package
1817 if (LaTeXFeatures::isAvailable("mathpazo")) {
1818 os << "\\usepackage";
1824 // "osf" includes "sc"!
1828 os << "{mathpazo}\n";
1830 else if (LaTeXFeatures::isAvailable("mathpple"))
1831 os << "\\usepackage{mathpple}\n";
1833 os << "\\usepackage{palatino}\n";
1836 else if (rm == "utopia") {
1837 // fourier supersedes utopia.sty, but does
1838 // not work with OT1 encoding.
1839 if (LaTeXFeatures::isAvailable("fourier")
1840 && lyxrc.fontenc != "default") {
1841 os << "\\usepackage";
1852 os << "{fourier}\n";
1855 os << "\\usepackage{utopia}\n";
1857 // Bera (complete fontset)
1858 else if (rm == "bera" && sf == "default" && tt == "default")
1859 os << "\\usepackage{bera}\n";
1861 else if (rm != "default")
1862 os << "\\usepackage" << "{" << rm << "}\n";
1865 // Helvetica, Bera Sans
1866 if (sf == "helvet" || sf == "berasans") {
1868 os << "\\usepackage[scaled=" << float(sfscale) / 100
1869 << "]{" << sf << "}\n";
1871 os << "\\usepackage{" << sf << "}\n";
1874 else if (sf == "avant")
1875 os << "\\usepackage{" << sf << "}\n";
1876 // Computer Modern, Latin Modern, CM Bright
1877 else if (sf != "default")
1878 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1880 // monospaced/typewriter
1881 // Courier, LuxiMono
1882 if (tt == "luximono" || tt == "beramono") {
1884 os << "\\usepackage[scaled=" << float(ttscale) / 100
1885 << "]{" << tt << "}\n";
1887 os << "\\usepackage{" << tt << "}\n";
1890 else if (tt == "courier" )
1891 os << "\\usepackage{" << tt << "}\n";
1892 // Computer Modern, Latin Modern, CM Bright
1893 else if (tt != "default")
1894 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1900 Encoding const & BufferParams::encoding() const
1902 if (inputenc == "auto" || inputenc == "default")
1903 return *(language->encoding());
1904 Encoding const * const enc =
1905 encodings.getFromLaTeXName(inputenc);
1908 lyxerr << "Unknown inputenc value `" << inputenc
1909 << "'. Using `auto' instead." << endl;
1910 return *(language->encoding());
1914 biblio::CiteEngine BufferParams::getEngine() const
1916 // FIXME the class should provide the numerical/
1917 // authoryear choice
1918 if (getTextClass().provides("natbib")
1919 && cite_engine_ != biblio::ENGINE_NATBIB_NUMERICAL)
1920 return biblio::ENGINE_NATBIB_AUTHORYEAR;
1921 return cite_engine_;
1925 void BufferParams::setCiteEngine(biblio::CiteEngine const cite_engine)
1927 cite_engine_ = cite_engine;