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 pimpl_->defskip = VSpace(lex.getString());
533 } else if (token == "\\quotes_language") {
536 quotes_language = quoteslangtranslator().find(quotes_lang);
537 } else if (token == "\\papersize") {
540 papersize = papersizetranslator().find(ppsize);
541 } else if (token == "\\use_geometry") {
543 } else if (token == "\\use_amsmath") {
546 use_amsmath = packagetranslator().find(use_ams);
547 } else if (token == "\\use_esint") {
550 use_esint = packagetranslator().find(useesint);
551 } else if (token == "\\cite_engine") {
554 cite_engine_ = citeenginetranslator().find(engine);
555 } else if (token == "\\use_bibtopic") {
557 } else if (token == "\\tracking_changes") {
559 } else if (token == "\\output_changes") {
560 lex >> outputChanges;
561 } else if (token == "\\branch") {
563 docstring branch = lex.getDocString();
564 branchlist().add(branch);
567 string const tok = lex.getString();
568 if (tok == "\\end_branch")
570 Branch * branch_ptr = branchlist().find(branch);
571 if (tok == "\\selected") {
574 branch_ptr->setSelected(lex.getInteger());
576 // not yet operational
577 if (tok == "\\color") {
579 string color = lex.getString();
581 branch_ptr->setColor(color);
582 // Update also the Color table:
584 color = lcolor.getX11Name(Color_background);
586 lcolor.setColor(to_utf8(branch), color);
590 } else if (token == "\\author") {
592 istringstream ss(lex.getString());
595 author_map.push_back(pimpl_->authorlist.record(a));
596 } else if (token == "\\paperorientation") {
599 orientation = paperorientationtranslator().find(orient);
600 } else if (token == "\\paperwidth") {
602 } else if (token == "\\paperheight") {
604 } else if (token == "\\leftmargin") {
606 } else if (token == "\\topmargin") {
608 } else if (token == "\\rightmargin") {
610 } else if (token == "\\bottommargin") {
612 } else if (token == "\\headheight") {
614 } else if (token == "\\headsep") {
616 } else if (token == "\\footskip") {
618 } else if (token == "\\paperfontsize") {
620 } else if (token == "\\papercolumns") {
622 } else if (token == "\\listings_params") {
625 listings_params = InsetListingsParams(par).params();
626 } else if (token == "\\papersides") {
629 sides = sidestranslator().find(psides);
630 } else if (token == "\\paperpagestyle") {
632 } else if (token == "\\bullet") {
634 } else if (token == "\\bulletLaTeX") {
635 readBulletsLaTeX(lex);
636 } else if (token == "\\secnumdepth") {
638 } else if (token == "\\tocdepth") {
640 } else if (token == "\\spacing") {
644 if (nspacing == "other") {
647 spacing().set(spacetranslator().find(nspacing), tmp_val);
648 } else if (token == "\\float_placement") {
649 lex >> float_placement;
651 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
652 string toktmp = pdfoptions().readToken(lex, token);
653 if (!toktmp.empty()) {
654 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
659 lyxerr << "BufferParams::readToken(): Unknown token: " <<
668 void BufferParams::writeFile(ostream & os) const
670 // The top of the file is written by the buffer.
671 // Prints out the buffer info into the .lyx file given by file
674 os << "\\textclass " << textclasslist[baseClass_].name() << '\n';
677 if (!preamble.empty()) {
678 // remove '\n' from the end of preamble
679 string const tmppreamble = rtrim(preamble, "\n");
680 os << "\\begin_preamble\n"
682 << "\n\\end_preamble\n";
686 if (!options.empty()) {
687 os << "\\options " << options << '\n';
691 if (!layoutModules_.empty()) {
692 os << "\\begin_modules" << '\n';
693 LayoutModuleList::const_iterator it = layoutModules_.begin();
694 for (; it != layoutModules_.end(); it++)
696 os << "\\end_modules" << '\n';
699 // then the text parameters
700 if (language != ignore_language)
701 os << "\\language " << language->lang() << '\n';
702 os << "\\inputencoding " << inputenc
703 << "\n\\font_roman " << fontsRoman
704 << "\n\\font_sans " << fontsSans
705 << "\n\\font_typewriter " << fontsTypewriter
706 << "\n\\font_default_family " << fontsDefaultFamily
707 << "\n\\font_sc " << convert<string>(fontsSC)
708 << "\n\\font_osf " << convert<string>(fontsOSF)
709 << "\n\\font_sf_scale " << fontsSansScale
710 << "\n\\font_tt_scale " << fontsTypewriterScale
711 << "\n\\graphics " << graphicsDriver << '\n';
713 if (!float_placement.empty()) {
714 os << "\\float_placement " << float_placement << '\n';
716 os << "\\paperfontsize " << fontsize << '\n';
718 spacing().writeFile(os);
719 pdfoptions().writeFile(os);
721 os << "\\papersize " << string_papersize[papersize]
722 << "\n\\use_geometry " << convert<string>(use_geometry)
723 << "\n\\use_amsmath " << use_amsmath
724 << "\n\\use_esint " << use_esint
725 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
726 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
727 << "\n\\paperorientation " << string_orientation[orientation]
730 BranchList::const_iterator it = branchlist().begin();
731 BranchList::const_iterator end = branchlist().end();
732 for (; it != end; ++it) {
733 os << "\\branch " << to_utf8(it->getBranch())
734 << "\n\\selected " << it->getSelected()
735 << "\n\\color " << lyx::X11hexname(it->getColor())
740 if (!paperwidth.empty())
741 os << "\\paperwidth "
742 << VSpace(paperwidth).asLyXCommand() << '\n';
743 if (!paperheight.empty())
744 os << "\\paperheight "
745 << VSpace(paperheight).asLyXCommand() << '\n';
746 if (!leftmargin.empty())
747 os << "\\leftmargin "
748 << VSpace(leftmargin).asLyXCommand() << '\n';
749 if (!topmargin.empty())
751 << VSpace(topmargin).asLyXCommand() << '\n';
752 if (!rightmargin.empty())
753 os << "\\rightmargin "
754 << VSpace(rightmargin).asLyXCommand() << '\n';
755 if (!bottommargin.empty())
756 os << "\\bottommargin "
757 << VSpace(bottommargin).asLyXCommand() << '\n';
758 if (!headheight.empty())
759 os << "\\headheight "
760 << VSpace(headheight).asLyXCommand() << '\n';
761 if (!headsep.empty())
763 << VSpace(headsep).asLyXCommand() << '\n';
764 if (!footskip.empty())
766 << VSpace(footskip).asLyXCommand() << '\n';
767 os << "\\secnumdepth " << secnumdepth
768 << "\n\\tocdepth " << tocdepth
769 << "\n\\paragraph_separation "
770 << string_paragraph_separation[paragraph_separation]
771 << "\n\\defskip " << getDefSkip().asLyXCommand()
772 << "\n\\quotes_language "
773 << string_quotes_language[quotes_language]
774 << "\n\\papercolumns " << columns
775 << "\n\\papersides " << sides
776 << "\n\\paperpagestyle " << pagestyle << '\n';
777 if (!listings_params.empty())
778 os << "\\listings_params \"" <<
779 InsetListingsParams(listings_params).encodedString() << "\"\n";
780 for (int i = 0; i < 4; ++i) {
781 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
782 if (user_defined_bullet(i).getFont() != -1) {
783 os << "\\bullet " << i << " "
784 << user_defined_bullet(i).getFont() << " "
785 << user_defined_bullet(i).getCharacter() << " "
786 << user_defined_bullet(i).getSize() << "\n";
790 os << "\\bulletLaTeX " << i << " \""
791 << lyx::to_ascii(user_defined_bullet(i).getText())
797 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
798 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
800 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
801 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
802 for (; a_it != a_end; ++a_it) {
803 if (a_it->second.used())
804 os << "\\author " << a_it->second << "\n";
806 os << "\\author " << Author() << "\n";
811 void BufferParams::validate(LaTeXFeatures & features) const
813 features.require(getTextClass().requires());
816 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
817 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
818 LaTeXFeatures::isAvailable("xcolor");
820 switch (features.runparams().flavor) {
821 case OutputParams::LATEX:
823 features.require("ct-dvipost");
824 features.require("dvipost");
825 } else if (xcolorsoul) {
826 features.require("ct-xcolor-soul");
827 features.require("soul");
828 features.require("xcolor");
830 features.require("ct-none");
833 case OutputParams::PDFLATEX:
835 features.require("ct-xcolor-soul");
836 features.require("soul");
837 features.require("xcolor");
838 // improves color handling in PDF output
839 features.require("pdfcolmk");
841 features.require("ct-none");
849 // Floats with 'Here definitely' as default setting.
850 if (float_placement.find('H') != string::npos)
851 features.require("float");
853 // AMS Style is at document level
854 if (use_amsmath == package_on
855 || getTextClass().provides("amsmath"))
856 features.require("amsmath");
857 if (use_esint == package_on)
858 features.require("esint");
860 // Document-level line spacing
861 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
862 features.require("setspace");
864 // the bullet shapes are buffer level not paragraph level
865 // so they are tested here
866 for (int i = 0; i < 4; ++i) {
867 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
869 int const font = user_defined_bullet(i).getFont();
871 int const c = user_defined_bullet(i).getCharacter();
877 features.require("latexsym");
879 } else if (font == 1) {
880 features.require("amssymb");
881 } else if (font >= 2 && font <= 5) {
882 features.require("pifont");
886 if (pdfoptions().use_hyperref)
887 features.require("hyperref");
891 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
892 TexRow & texrow) const
894 os << "\\documentclass";
896 TextClass const & tclass = getTextClass();
898 ostringstream clsoptions; // the document class options.
900 if (tokenPos(tclass.opt_fontsize(),
901 '|', fontsize) >= 0) {
902 // only write if existing in list (and not default)
903 clsoptions << fontsize << "pt,";
906 // custom, A3, B3 and B4 paper sizes need geometry
907 bool nonstandard_papersize = papersize == PAPER_B3
908 || papersize == PAPER_B4
909 || papersize == PAPER_A3
910 || papersize == PAPER_CUSTOM;
915 clsoptions << "a4paper,";
918 clsoptions << "letterpaper,";
921 clsoptions << "a5paper,";
924 clsoptions << "b5paper,";
926 case PAPER_USEXECUTIVE:
927 clsoptions << "executivepaper,";
930 clsoptions << "legalpaper,";
942 if (sides != tclass.sides()) {
945 clsoptions << "oneside,";
948 clsoptions << "twoside,";
954 if (columns != tclass.columns()) {
956 clsoptions << "twocolumn,";
958 clsoptions << "onecolumn,";
962 && orientation == ORIENTATION_LANDSCAPE)
963 clsoptions << "landscape,";
965 // language should be a parameter to \documentclass
966 if (language->babel() == "hebrew"
967 && default_language->babel() != "hebrew")
968 // This seems necessary
969 features.useLanguage(default_language);
971 ostringstream language_options;
972 bool const use_babel = features.useBabel();
974 language_options << features.getLanguages();
975 if (!language->babel().empty()) {
976 if (!language_options.str().empty())
977 language_options << ',';
978 language_options << language->babel();
980 // when Vietnamese is used, babel must directly be loaded with the
981 // language options, not in the class options, see
982 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
983 size_t viet = language_options.str().find("vietnam");
984 // viet = string::npos when not found
985 if (lyxrc.language_global_options && !language_options.str().empty()
986 && viet == string::npos)
987 clsoptions << language_options.str() << ',';
990 // the user-defined options
991 if (!options.empty()) {
992 clsoptions << options << ',';
995 string strOptions(clsoptions.str());
996 if (!strOptions.empty()) {
997 strOptions = rtrim(strOptions, ",");
999 os << '[' << from_utf8(strOptions) << ']';
1002 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1004 // end of \documentclass defs
1006 // font selection must be done before loading fontenc.sty
1007 string const fonts =
1008 loadFonts(fontsRoman, fontsSans,
1009 fontsTypewriter, fontsSC, fontsOSF,
1010 fontsSansScale, fontsTypewriterScale);
1011 if (!fonts.empty()) {
1012 os << from_ascii(fonts);
1015 if (fontsDefaultFamily != "default")
1016 os << "\\renewcommand{\\familydefault}{\\"
1017 << from_ascii(fontsDefaultFamily) << "}\n";
1019 // set font encoding
1020 // this one is not per buffer
1021 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1022 if (lyxrc.fontenc != "default") {
1023 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1024 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1025 << ",LFE,LAE]{fontenc}\n";
1028 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1034 // handle inputenc etc.
1035 writeEncodingPreamble(os, features, texrow);
1037 if (!listings_params.empty()) {
1038 os << "\\usepackage{listings}\n";
1041 // do not test validity because listings_params is supposed to be valid
1042 string par = InsetListingsParams(listings_params).separatedParams(true);
1043 os << from_ascii(par);
1044 // count the number of newlines
1045 for (size_t i = 0; i < par.size(); ++i)
1051 if (use_geometry || nonstandard_papersize) {
1052 os << "\\usepackage{geometry}\n";
1054 os << "\\geometry{verbose";
1055 if (orientation == ORIENTATION_LANDSCAPE)
1057 switch (papersize) {
1059 if (!paperwidth.empty())
1060 os << ",paperwidth="
1061 << from_ascii(paperwidth);
1062 if (!paperheight.empty())
1063 os << ",paperheight="
1064 << from_ascii(paperheight);
1066 case PAPER_USLETTER:
1067 os << ",letterpaper";
1070 os << ",legalpaper";
1072 case PAPER_USEXECUTIVE:
1073 os << ",executivepaper";
1094 // default papersize ie PAPER_DEFAULT
1095 switch (lyxrc.default_papersize) {
1096 case PAPER_DEFAULT: // keep compiler happy
1097 case PAPER_USLETTER:
1098 os << ",letterpaper";
1101 os << ",legalpaper";
1103 case PAPER_USEXECUTIVE:
1104 os << ",executivepaper";
1124 if (!topmargin.empty())
1125 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1126 if (!bottommargin.empty())
1127 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1128 if (!leftmargin.empty())
1129 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1130 if (!rightmargin.empty())
1131 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1132 if (!headheight.empty())
1133 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1134 if (!headsep.empty())
1135 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1136 if (!footskip.empty())
1137 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1142 if (tokenPos(tclass.opt_pagestyle(),
1143 '|', pagestyle) >= 0) {
1144 if (pagestyle == "fancy") {
1145 os << "\\usepackage{fancyhdr}\n";
1148 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1152 // Only if class has a ToC hierarchy
1153 if (tclass.hasTocLevels()) {
1154 if (secnumdepth != tclass.secnumdepth()) {
1155 os << "\\setcounter{secnumdepth}{"
1160 if (tocdepth != tclass.tocdepth()) {
1161 os << "\\setcounter{tocdepth}{"
1168 if (paragraph_separation) {
1169 switch (getDefSkip().kind()) {
1170 case VSpace::SMALLSKIP:
1171 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1173 case VSpace::MEDSKIP:
1174 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1176 case VSpace::BIGSKIP:
1177 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1179 case VSpace::LENGTH:
1180 os << "\\setlength{\\parskip}{"
1181 << from_utf8(getDefSkip().length().asLatexString())
1184 default: // should never happen // Then delete it.
1185 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1190 os << "\\setlength{\\parindent}{0pt}\n";
1194 // If we use jurabib, we have to call babel here.
1195 if (use_babel && features.isRequired("jurabib")) {
1196 os << from_ascii(babelCall(language_options.str()))
1198 << from_ascii(features.getBabelOptions());
1202 // Now insert the LyX specific LaTeX commands...
1204 // The optional packages;
1205 docstring lyxpreamble(from_ascii(features.getPackages()));
1208 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1210 // We try to load babel late, in case it interferes
1211 // with other packages. But some packages also need babel to be loaded
1212 // before, e.g. jurabib has to be called after babel.
1213 // So load babel after the optional packages but before the user-defined
1214 // preamble. This allows the users to redefine babel commands, e.g. to
1215 // translate the word "Index" to the German "Stichwortverzeichnis".
1216 // For more infos why this place was chosen, see
1217 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1218 // If you encounter problems, you can shift babel to its old place behind
1219 // the user-defined preamble. But in this case you must change the Vietnamese
1220 // support from currently "\usepackage[vietnamese]{babel}" to:
1221 // \usepackage{vietnamese}
1222 // \usepackage{babel}
1223 // because vietnamese must be loaded before hyperref
1224 if (use_babel && !features.isRequired("jurabib")) {
1226 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1227 lyxpreamble += from_utf8(features.getBabelOptions());
1230 // When the language "japanese-plain" is used, the package "japanese" must
1231 // be loaded behind babel (it provides babel support for Japanese) but before
1233 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1234 if (language->lang() == "japanese-plain" &&
1235 !getTextClass().provides("japanese")) {
1236 //load babel in case it was not loaded due to an empty language list
1237 if (language_options.str().empty())
1238 lyxpreamble += "\\usepackage{babel}\n";
1239 lyxpreamble += "\\usepackage{japanese}\n";
1243 // * Hyperref manual: "Make sure it comes last of your loaded
1244 // packages, to give it a fighting chance of not being over-written,
1245 // since its job is to redefine many LATEX commands."
1246 // * Email from Heiko Oberdiek: "It is usually better to load babel
1247 // before hyperref. Then hyperref has a chance to detect babel.
1248 // * Has to be loaded before the "LyX specific LaTeX commands" to
1249 // avoid errors with algorithm floats.
1250 // use hyperref explicitely when it is required
1251 if (features.isRequired("hyperref")) {
1252 odocstringstream oss;
1253 pdfoptions().writeLaTeX(oss, getTextClass().provides("hyperref"));
1254 lyxpreamble += oss.str();
1257 // this might be useful...
1258 lyxpreamble += "\n\\makeatletter\n";
1260 // Some macros LyX will need
1261 docstring tmppreamble(from_ascii(features.getMacros()));
1263 if (!tmppreamble.empty()) {
1264 lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1265 "LyX specific LaTeX commands.\n"
1266 + tmppreamble + '\n';
1269 // the text class specific preamble
1270 tmppreamble = features.getTClassPreamble();
1271 if (!tmppreamble.empty()) {
1272 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1273 "Textclass specific LaTeX commands.\n"
1274 + tmppreamble + '\n';
1277 /* the user-defined preamble */
1278 if (!preamble.empty()) {
1280 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1281 "User specified LaTeX commands.\n"
1282 + from_utf8(preamble) + '\n';
1285 // Itemize bullet settings need to be last in case the user
1286 // defines their own bullets that use a package included
1287 // in the user-defined preamble -- ARRae
1288 // Actually it has to be done much later than that
1289 // since some packages like frenchb make modifications
1290 // at \begin{document} time -- JMarc
1291 docstring bullets_def;
1292 for (int i = 0; i < 4; ++i) {
1293 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1294 if (bullets_def.empty())
1295 bullets_def += "\\AtBeginDocument{\n";
1296 bullets_def += " \\def\\labelitemi";
1298 // `i' is one less than the item to modify
1305 bullets_def += "ii";
1311 bullets_def += '{' +
1312 user_defined_bullet(i).getText()
1317 if (!bullets_def.empty())
1318 lyxpreamble += bullets_def + "}\n\n";
1320 lyxpreamble += "\\makeatother\n\n";
1323 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1324 for (int j = 0; j != nlines; ++j) {
1333 void BufferParams::useClassDefaults()
1335 TextClass const & tclass = textclasslist[baseClass_];
1337 sides = tclass.sides();
1338 columns = tclass.columns();
1339 pagestyle = tclass.pagestyle();
1340 options = tclass.options();
1341 // Only if class has a ToC hierarchy
1342 if (tclass.hasTocLevels()) {
1343 secnumdepth = tclass.secnumdepth();
1344 tocdepth = tclass.tocdepth();
1349 bool BufferParams::hasClassDefaults() const
1351 TextClass const & tclass = textclasslist[baseClass_];
1353 return (sides == tclass.sides()
1354 && columns == tclass.columns()
1355 && pagestyle == tclass.pagestyle()
1356 && options == tclass.options()
1357 && secnumdepth == tclass.secnumdepth()
1358 && tocdepth == tclass.tocdepth());
1362 TextClass const & BufferParams::getTextClass() const
1368 TextClassPtr BufferParams::getTextClassPtr() const {
1373 void BufferParams::setTextClass(TextClassPtr tc) {
1378 bool BufferParams::setBaseClass(textclass_type tc)
1380 if (textclasslist[tc].load()) {
1386 bformat(_("The document class %1$s could not be loaded."),
1387 from_utf8(textclasslist[tc].name()));
1388 frontend::Alert::error(_("Could not load class"), s);
1393 textclass_type BufferParams::getBaseClass() const
1399 void BufferParams::makeTextClass()
1401 textClass_.reset(new TextClass(textclasslist[getBaseClass()]));
1403 //FIXME It might be worth loading the children's modules here,
1404 //just as we load their bibliographies and such, instead of just
1405 //doing a check in InsetInclude.
1406 LayoutModuleList::const_iterator it = layoutModules_.begin();
1407 for (; it != layoutModules_.end(); it++) {
1408 string const modName = *it;
1409 LyXModule * lm = moduleList[modName];
1411 docstring const msg =
1412 bformat(_("The module %1$s has been requested by\n"
1413 "this document but has not been found in the list of\n"
1414 "available modules. If you recently installed it, you\n"
1415 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1416 frontend::Alert::warning(_("Module not available"),
1417 msg + _("Some layouts may not be available."));
1418 lyxerr << "BufferParams::makeTextClass(): Module " <<
1419 modName << " requested but not found in module list." <<
1423 if (!lm->isAvailable()) {
1424 docstring const msg =
1425 bformat(_("The module %1$s requires a package that is\n"
1426 "not available in your LaTeX installation. LaTeX output\n"
1427 "may not be possible.\n"), from_utf8(modName));
1428 frontend::Alert::warning(_("Package not available"), msg);
1430 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1431 if (!textClass_->read(layout_file, TextClass::MODULE)) {
1432 docstring const msg =
1433 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1434 frontend::Alert::warning(_("Read Error"), msg);
1440 vector<string> const & BufferParams::getModules() const {
1441 return layoutModules_;
1446 bool BufferParams::addLayoutModule(string const & modName) {
1447 LayoutModuleList::const_iterator it = layoutModules_.begin();
1448 LayoutModuleList::const_iterator end = layoutModules_.end();
1449 for (; it != end; it++) {
1453 if (it != layoutModules_.end())
1455 layoutModules_.push_back(modName);
1460 void BufferParams::clearLayoutModules() {
1461 layoutModules_.clear();
1465 Font const BufferParams::getFont() const
1467 FontInfo f = getTextClass().defaultfont();
1468 if (fontsDefaultFamily == "rmdefault")
1469 f.setFamily(ROMAN_FAMILY);
1470 else if (fontsDefaultFamily == "sfdefault")
1471 f.setFamily(SANS_FAMILY);
1472 else if (fontsDefaultFamily == "ttdefault")
1473 f.setFamily(TYPEWRITER_FAMILY);
1474 return Font(f, language);
1478 void BufferParams::readPreamble(Lexer & lex)
1480 if (lex.getString() != "\\begin_preamble")
1481 lyxerr << "Error (BufferParams::readPreamble):"
1482 "consistency check failed." << endl;
1484 preamble = lex.getLongString("\\end_preamble");
1488 void BufferParams::readLanguage(Lexer & lex)
1490 if (!lex.next()) return;
1492 string const tmptok = lex.getString();
1494 // check if tmptok is part of tex_babel in tex-defs.h
1495 language = languages.getLanguage(tmptok);
1497 // Language tmptok was not found
1498 language = default_language;
1499 lyxerr << "Warning: Setting language `"
1500 << tmptok << "' to `" << language->lang()
1506 void BufferParams::readGraphicsDriver(Lexer & lex)
1508 if (!lex.next()) return;
1510 string const tmptok = lex.getString();
1511 // check if tmptok is part of tex_graphics in tex_defs.h
1514 string const test = tex_graphics[n++];
1516 if (test == tmptok) {
1517 graphicsDriver = tmptok;
1519 } else if (test == "") {
1521 "Warning: graphics driver `$$Token' not recognized!\n"
1522 " Setting graphics driver to `default'.\n");
1523 graphicsDriver = "default";
1530 void BufferParams::readBullets(Lexer & lex)
1532 if (!lex.next()) return;
1534 int const index = lex.getInteger();
1536 int temp_int = lex.getInteger();
1537 user_defined_bullet(index).setFont(temp_int);
1538 temp_bullet(index).setFont(temp_int);
1540 user_defined_bullet(index).setCharacter(temp_int);
1541 temp_bullet(index).setCharacter(temp_int);
1543 user_defined_bullet(index).setSize(temp_int);
1544 temp_bullet(index).setSize(temp_int);
1548 void BufferParams::readBulletsLaTeX(Lexer & lex)
1550 // The bullet class should be able to read this.
1551 if (!lex.next()) return;
1552 int const index = lex.getInteger();
1554 docstring const temp_str = lex.getDocString();
1556 user_defined_bullet(index).setText(temp_str);
1557 temp_bullet(index).setText(temp_str);
1561 void BufferParams::readModules(Lexer & lex)
1563 if (!lex.eatLine()) {
1564 lyxerr << "Error (BufferParams::readModules):"
1565 "Unexpected end of input." << endl;
1569 string mod = lex.getString();
1570 if (mod == "\\end_modules")
1572 addLayoutModule(mod);
1578 string const BufferParams::paperSizeName(Papersize_Purpose const & purpose) const
1580 char real_papersize = papersize;
1581 if (real_papersize == PAPER_DEFAULT)
1582 real_papersize = lyxrc.default_papersize;
1584 switch (real_papersize) {
1586 // could be anything, so don't guess
1588 case PAPER_CUSTOM: {
1589 if (purpose == XDVI && !paperwidth.empty() &&
1590 !paperheight.empty()) {
1591 // heightxwidth<unit>
1592 string first = paperwidth;
1593 string second = paperheight;
1594 if (orientation == ORIENTATION_LANDSCAPE)
1597 return first.erase(first.length() - 2)
1609 // dvips and dvipdfm do not know this
1610 if (purpose == DVIPS || purpose == DVIPDFM)
1614 // dvipdfm does not know this
1615 if (purpose == DVIPDFM)
1619 // dvipdfm does not know this
1620 if (purpose == DVIPDFM)
1623 case PAPER_USEXECUTIVE:
1624 // dvipdfm does not know this
1625 if (purpose == DVIPDFM)
1630 case PAPER_USLETTER:
1632 if (purpose == XDVI)
1639 string const BufferParams::dvips_options() const
1644 && papersize == PAPER_CUSTOM
1645 && !lyxrc.print_paper_dimension_flag.empty()
1646 && !paperwidth.empty()
1647 && !paperheight.empty()) {
1648 // using a custom papersize
1649 result = lyxrc.print_paper_dimension_flag;
1650 result += ' ' + paperwidth;
1651 result += ',' + paperheight;
1653 string const paper_option = paperSizeName(DVIPS);
1654 if (!paper_option.empty() && (paper_option != "letter" ||
1655 orientation != ORIENTATION_LANDSCAPE)) {
1656 // dvips won't accept -t letter -t landscape.
1657 // In all other cases, include the paper size
1659 result = lyxrc.print_paper_flag;
1660 result += ' ' + paper_option;
1663 if (orientation == ORIENTATION_LANDSCAPE &&
1664 papersize != PAPER_CUSTOM)
1665 result += ' ' + lyxrc.print_landscape_flag;
1670 string const BufferParams::babelCall(string const & lang_opts) const
1672 string lang_pack = lyxrc.language_package;
1673 if (lang_pack != "\\usepackage{babel}")
1675 // suppress the babel call when there is no babel language defined
1676 // for the document language in the lib/languages file and if no
1677 // other languages are used (lang_opts is then empty)
1678 if (lang_opts.empty())
1680 // when Vietnamese is used, babel must directly be loaded with the
1681 // language options, see
1682 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1683 size_t viet = lang_opts.find("vietnam");
1684 // viet = string::npos when not found
1685 if (!lyxrc.language_global_options || viet != string::npos)
1686 return "\\usepackage[" + lang_opts + "]{babel}";
1691 void BufferParams::writeEncodingPreamble(odocstream & os,
1692 LaTeXFeatures & features, TexRow & texrow) const
1694 if (inputenc == "auto") {
1695 string const doc_encoding =
1696 language->encoding()->latexName();
1697 Encoding::Package const package =
1698 language->encoding()->package();
1700 // Create a list with all the input encodings used
1702 set<string> encodings =
1703 features.getEncodingSet(doc_encoding);
1705 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1706 // package inputenc must be omitted. Therefore set the encoding to empty.
1707 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1708 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1709 doc_encoding == "SJIS-plain")
1712 if (!encodings.empty() || package == Encoding::inputenc) {
1713 os << "\\usepackage[";
1714 set<string>::const_iterator it = encodings.begin();
1715 set<string>::const_iterator const end = encodings.end();
1717 os << from_ascii(*it);
1720 for (; it != end; ++it)
1721 os << ',' << from_ascii(*it);
1722 if (package == Encoding::inputenc) {
1723 if (!encodings.empty())
1725 os << from_ascii(doc_encoding);
1727 os << "]{inputenc}\n";
1730 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1731 os << "\\usepackage{CJK}\n";
1734 } else if (inputenc != "default") {
1735 switch (encoding().package()) {
1736 case Encoding::none:
1738 case Encoding::inputenc:
1739 os << "\\usepackage[" << from_ascii(inputenc)
1744 os << "\\usepackage{CJK}\n";
1750 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1751 // armscii8 is used for Armenian.
1752 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1753 os << "\\usepackage{armtex}\n";
1759 string const BufferParams::loadFonts(string const & rm,
1760 string const & sf, string const & tt,
1761 bool const & sc, bool const & osf,
1762 int const & sfscale, int const & ttscale) const
1764 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1765 several packages have been replaced by others, that might not
1766 be installed on every system. We have to take care for that
1767 (see psnfss.pdf). We try to support all psnfss fonts as well
1768 as the fonts that have become de facto standard in the LaTeX
1769 world (e.g. Latin Modern). We do not support obsolete fonts
1770 (like PSLatex). In general, it should be possible to mix any
1771 rm font with any sf or tt font, respectively. (JSpitzm)
1773 -- separate math fonts.
1776 if (rm == "default" && sf == "default" && tt == "default")
1783 // Computer Modern (must be explicitely selectable -- there might be classes
1784 // that define a different default font!
1786 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1787 // osf for Computer Modern needs eco.sty
1789 os << "\\usepackage{eco}\n";
1791 // Latin Modern Roman
1792 else if (rm == "lmodern")
1793 os << "\\usepackage{lmodern}\n";
1795 else if (rm == "ae") {
1796 // not needed when using OT1 font encoding.
1797 if (lyxrc.fontenc != "default")
1798 os << "\\usepackage{ae,aecompl}\n";
1801 else if (rm == "times") {
1802 // try to load the best available package
1803 if (LaTeXFeatures::isAvailable("mathptmx"))
1804 os << "\\usepackage{mathptmx}\n";
1805 else if (LaTeXFeatures::isAvailable("mathptm"))
1806 os << "\\usepackage{mathptm}\n";
1808 os << "\\usepackage{times}\n";
1811 else if (rm == "palatino") {
1812 // try to load the best available package
1813 if (LaTeXFeatures::isAvailable("mathpazo")) {
1814 os << "\\usepackage";
1820 // "osf" includes "sc"!
1824 os << "{mathpazo}\n";
1826 else if (LaTeXFeatures::isAvailable("mathpple"))
1827 os << "\\usepackage{mathpple}\n";
1829 os << "\\usepackage{palatino}\n";
1832 else if (rm == "utopia") {
1833 // fourier supersedes utopia.sty, but does
1834 // not work with OT1 encoding.
1835 if (LaTeXFeatures::isAvailable("fourier")
1836 && lyxrc.fontenc != "default") {
1837 os << "\\usepackage";
1848 os << "{fourier}\n";
1851 os << "\\usepackage{utopia}\n";
1853 // Bera (complete fontset)
1854 else if (rm == "bera" && sf == "default" && tt == "default")
1855 os << "\\usepackage{bera}\n";
1857 else if (rm != "default")
1858 os << "\\usepackage" << "{" << rm << "}\n";
1861 // Helvetica, Bera Sans
1862 if (sf == "helvet" || sf == "berasans") {
1864 os << "\\usepackage[scaled=" << float(sfscale) / 100
1865 << "]{" << sf << "}\n";
1867 os << "\\usepackage{" << sf << "}\n";
1870 else if (sf == "avant")
1871 os << "\\usepackage{" << sf << "}\n";
1872 // Computer Modern, Latin Modern, CM Bright
1873 else if (sf != "default")
1874 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1876 // monospaced/typewriter
1877 // Courier, LuxiMono
1878 if (tt == "luximono" || tt == "beramono") {
1880 os << "\\usepackage[scaled=" << float(ttscale) / 100
1881 << "]{" << tt << "}\n";
1883 os << "\\usepackage{" << tt << "}\n";
1886 else if (tt == "courier" )
1887 os << "\\usepackage{" << tt << "}\n";
1888 // Computer Modern, Latin Modern, CM Bright
1889 else if (tt != "default")
1890 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1896 Encoding const & BufferParams::encoding() const
1898 if (inputenc == "auto" || inputenc == "default")
1899 return *(language->encoding());
1900 Encoding const * const enc =
1901 encodings.getFromLaTeXName(inputenc);
1904 lyxerr << "Unknown inputenc value `" << inputenc
1905 << "'. Using `auto' instead." << endl;
1906 return *(language->encoding());
1910 biblio::CiteEngine BufferParams::getEngine() const
1912 // FIXME the class should provide the numerical/
1913 // authoryear choice
1914 if (getTextClass().provides("natbib")
1915 && cite_engine_ != biblio::ENGINE_NATBIB_NUMERICAL)
1916 return biblio::ENGINE_NATBIB_AUTHORYEAR;
1917 return cite_engine_;
1921 void BufferParams::setCiteEngine(biblio::CiteEngine const cite_engine)
1923 cite_engine_ = cite_engine;