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 == "\\columnsep") {
624 } else if (token == "\\paperfontsize") {
626 } else if (token == "\\papercolumns") {
628 } else if (token == "\\listings_params") {
631 listings_params = InsetListingsParams(par).params();
632 } else if (token == "\\papersides") {
635 sides = sidestranslator().find(psides);
636 } else if (token == "\\paperpagestyle") {
638 } else if (token == "\\bullet") {
640 } else if (token == "\\bulletLaTeX") {
641 readBulletsLaTeX(lex);
642 } else if (token == "\\secnumdepth") {
644 } else if (token == "\\tocdepth") {
646 } else if (token == "\\spacing") {
650 if (nspacing == "other") {
653 spacing().set(spacetranslator().find(nspacing), tmp_val);
654 } else if (token == "\\float_placement") {
655 lex >> float_placement;
657 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
658 string toktmp = pdfoptions().readToken(lex, token);
659 if (!toktmp.empty()) {
660 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
665 lyxerr << "BufferParams::readToken(): Unknown token: " <<
674 void BufferParams::writeFile(ostream & os) const
676 // The top of the file is written by the buffer.
677 // Prints out the buffer info into the .lyx file given by file
680 os << "\\textclass " << textclasslist[baseClass_].name() << '\n';
683 if (!preamble.empty()) {
684 // remove '\n' from the end of preamble
685 string const tmppreamble = rtrim(preamble, "\n");
686 os << "\\begin_preamble\n"
688 << "\n\\end_preamble\n";
692 if (!options.empty()) {
693 os << "\\options " << options << '\n';
697 if (!layoutModules_.empty()) {
698 os << "\\begin_modules" << '\n';
699 LayoutModuleList::const_iterator it = layoutModules_.begin();
700 for (; it != layoutModules_.end(); it++)
702 os << "\\end_modules" << '\n';
705 // then the text parameters
706 if (language != ignore_language)
707 os << "\\language " << language->lang() << '\n';
708 os << "\\inputencoding " << inputenc
709 << "\n\\font_roman " << fontsRoman
710 << "\n\\font_sans " << fontsSans
711 << "\n\\font_typewriter " << fontsTypewriter
712 << "\n\\font_default_family " << fontsDefaultFamily
713 << "\n\\font_sc " << convert<string>(fontsSC)
714 << "\n\\font_osf " << convert<string>(fontsOSF)
715 << "\n\\font_sf_scale " << fontsSansScale
716 << "\n\\font_tt_scale " << fontsTypewriterScale
717 << "\n\\graphics " << graphicsDriver << '\n';
719 if (!float_placement.empty()) {
720 os << "\\float_placement " << float_placement << '\n';
722 os << "\\paperfontsize " << fontsize << '\n';
724 spacing().writeFile(os);
725 pdfoptions().writeFile(os);
727 os << "\\papersize " << string_papersize[papersize]
728 << "\n\\use_geometry " << convert<string>(use_geometry)
729 << "\n\\use_amsmath " << use_amsmath
730 << "\n\\use_esint " << use_esint
731 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
732 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
733 << "\n\\paperorientation " << string_orientation[orientation]
736 BranchList::const_iterator it = branchlist().begin();
737 BranchList::const_iterator end = branchlist().end();
738 for (; it != end; ++it) {
739 os << "\\branch " << to_utf8(it->getBranch())
740 << "\n\\selected " << it->getSelected()
741 << "\n\\color " << lyx::X11hexname(it->getColor())
746 if (!paperwidth.empty())
747 os << "\\paperwidth "
748 << VSpace(paperwidth).asLyXCommand() << '\n';
749 if (!paperheight.empty())
750 os << "\\paperheight "
751 << VSpace(paperheight).asLyXCommand() << '\n';
752 if (!leftmargin.empty())
753 os << "\\leftmargin "
754 << VSpace(leftmargin).asLyXCommand() << '\n';
755 if (!topmargin.empty())
757 << VSpace(topmargin).asLyXCommand() << '\n';
758 if (!rightmargin.empty())
759 os << "\\rightmargin "
760 << VSpace(rightmargin).asLyXCommand() << '\n';
761 if (!bottommargin.empty())
762 os << "\\bottommargin "
763 << VSpace(bottommargin).asLyXCommand() << '\n';
764 if (!headheight.empty())
765 os << "\\headheight "
766 << VSpace(headheight).asLyXCommand() << '\n';
767 if (!headsep.empty())
769 << VSpace(headsep).asLyXCommand() << '\n';
770 if (!footskip.empty())
772 << VSpace(footskip).asLyXCommand() << '\n';
773 if (!columnsep.empty())
775 << VSpace(columnsep).asLyXCommand() << '\n';
776 os << "\\secnumdepth " << secnumdepth
777 << "\n\\tocdepth " << tocdepth
778 << "\n\\paragraph_separation "
779 << string_paragraph_separation[paragraph_separation]
780 << "\n\\defskip " << getDefSkip().asLyXCommand()
781 << "\n\\quotes_language "
782 << string_quotes_language[quotes_language]
783 << "\n\\papercolumns " << columns
784 << "\n\\papersides " << sides
785 << "\n\\paperpagestyle " << pagestyle << '\n';
786 if (!listings_params.empty())
787 os << "\\listings_params \"" <<
788 InsetListingsParams(listings_params).encodedString() << "\"\n";
789 for (int i = 0; i < 4; ++i) {
790 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
791 if (user_defined_bullet(i).getFont() != -1) {
792 os << "\\bullet " << i << " "
793 << user_defined_bullet(i).getFont() << " "
794 << user_defined_bullet(i).getCharacter() << " "
795 << user_defined_bullet(i).getSize() << "\n";
799 os << "\\bulletLaTeX " << i << " \""
800 << lyx::to_ascii(user_defined_bullet(i).getText())
806 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
807 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
809 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
810 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
811 for (; a_it != a_end; ++a_it) {
812 if (a_it->second.used())
813 os << "\\author " << a_it->second << "\n";
815 os << "\\author " << Author() << "\n";
820 void BufferParams::validate(LaTeXFeatures & features) const
822 features.require(getTextClass().requires());
825 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
826 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
827 LaTeXFeatures::isAvailable("xcolor");
829 switch (features.runparams().flavor) {
830 case OutputParams::LATEX:
832 features.require("ct-dvipost");
833 features.require("dvipost");
834 } else if (xcolorsoul) {
835 features.require("ct-xcolor-soul");
836 features.require("soul");
837 features.require("xcolor");
839 features.require("ct-none");
842 case OutputParams::PDFLATEX:
844 features.require("ct-xcolor-soul");
845 features.require("soul");
846 features.require("xcolor");
847 // improves color handling in PDF output
848 features.require("pdfcolmk");
850 features.require("ct-none");
858 // Floats with 'Here definitely' as default setting.
859 if (float_placement.find('H') != string::npos)
860 features.require("float");
862 // AMS Style is at document level
863 if (use_amsmath == package_on
864 || getTextClass().provides("amsmath"))
865 features.require("amsmath");
866 if (use_esint == package_on)
867 features.require("esint");
869 // Document-level line spacing
870 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
871 features.require("setspace");
873 // the bullet shapes are buffer level not paragraph level
874 // so they are tested here
875 for (int i = 0; i < 4; ++i) {
876 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
878 int const font = user_defined_bullet(i).getFont();
880 int const c = user_defined_bullet(i).getCharacter();
886 features.require("latexsym");
888 } else if (font == 1) {
889 features.require("amssymb");
890 } else if (font >= 2 && font <= 5) {
891 features.require("pifont");
895 if (pdfoptions().use_hyperref)
896 features.require("hyperref");
900 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
901 TexRow & texrow) const
903 os << "\\documentclass";
905 TextClass const & tclass = getTextClass();
907 ostringstream clsoptions; // the document class options.
909 if (tokenPos(tclass.opt_fontsize(),
910 '|', fontsize) >= 0) {
911 // only write if existing in list (and not default)
912 clsoptions << fontsize << "pt,";
915 // custom, A3, B3 and B4 paper sizes need geometry
916 bool nonstandard_papersize = papersize == PAPER_B3
917 || papersize == PAPER_B4
918 || papersize == PAPER_A3
919 || papersize == PAPER_CUSTOM;
924 clsoptions << "a4paper,";
927 clsoptions << "letterpaper,";
930 clsoptions << "a5paper,";
933 clsoptions << "b5paper,";
935 case PAPER_USEXECUTIVE:
936 clsoptions << "executivepaper,";
939 clsoptions << "legalpaper,";
951 if (sides != tclass.sides()) {
954 clsoptions << "oneside,";
957 clsoptions << "twoside,";
963 if (columns != tclass.columns()) {
965 clsoptions << "twocolumn,";
967 clsoptions << "onecolumn,";
971 && orientation == ORIENTATION_LANDSCAPE)
972 clsoptions << "landscape,";
974 // language should be a parameter to \documentclass
975 if (language->babel() == "hebrew"
976 && default_language->babel() != "hebrew")
977 // This seems necessary
978 features.useLanguage(default_language);
980 ostringstream language_options;
981 bool const use_babel = features.useBabel();
983 language_options << features.getLanguages();
984 if (!language->babel().empty()) {
985 if (!language_options.str().empty())
986 language_options << ',';
987 language_options << language->babel();
989 // when Vietnamese is used, babel must directly be loaded with the
990 // language options, not in the class options, see
991 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
992 size_t viet = language_options.str().find("vietnam");
993 // viet = string::npos when not found
994 if (lyxrc.language_global_options && !language_options.str().empty()
995 && viet == string::npos)
996 clsoptions << language_options.str() << ',';
999 // the user-defined options
1000 if (!options.empty()) {
1001 clsoptions << options << ',';
1004 string strOptions(clsoptions.str());
1005 if (!strOptions.empty()) {
1006 strOptions = rtrim(strOptions, ",");
1008 os << '[' << from_utf8(strOptions) << ']';
1011 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1013 // end of \documentclass defs
1015 // font selection must be done before loading fontenc.sty
1016 string const fonts =
1017 loadFonts(fontsRoman, fontsSans,
1018 fontsTypewriter, fontsSC, fontsOSF,
1019 fontsSansScale, fontsTypewriterScale);
1020 if (!fonts.empty()) {
1021 os << from_ascii(fonts);
1024 if (fontsDefaultFamily != "default")
1025 os << "\\renewcommand{\\familydefault}{\\"
1026 << from_ascii(fontsDefaultFamily) << "}\n";
1028 // set font encoding
1029 // this one is not per buffer
1030 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1031 if (lyxrc.fontenc != "default") {
1032 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1033 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1034 << ",LFE,LAE]{fontenc}\n";
1037 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1043 // handle inputenc etc.
1044 writeEncodingPreamble(os, features, texrow);
1046 if (!listings_params.empty()) {
1047 os << "\\usepackage{listings}\n";
1050 // do not test validity because listings_params is supposed to be valid
1051 string par = InsetListingsParams(listings_params).separatedParams(true);
1052 os << from_ascii(par);
1053 // count the number of newlines
1054 for (size_t i = 0; i < par.size(); ++i)
1060 if (use_geometry || nonstandard_papersize) {
1061 os << "\\usepackage{geometry}\n";
1063 os << "\\geometry{verbose";
1064 if (orientation == ORIENTATION_LANDSCAPE)
1066 switch (papersize) {
1068 if (!paperwidth.empty())
1069 os << ",paperwidth="
1070 << from_ascii(paperwidth);
1071 if (!paperheight.empty())
1072 os << ",paperheight="
1073 << from_ascii(paperheight);
1075 case PAPER_USLETTER:
1076 os << ",letterpaper";
1079 os << ",legalpaper";
1081 case PAPER_USEXECUTIVE:
1082 os << ",executivepaper";
1103 // default papersize ie PAPER_DEFAULT
1104 switch (lyxrc.default_papersize) {
1105 case PAPER_DEFAULT: // keep compiler happy
1106 case PAPER_USLETTER:
1107 os << ",letterpaper";
1110 os << ",legalpaper";
1112 case PAPER_USEXECUTIVE:
1113 os << ",executivepaper";
1133 if (!topmargin.empty())
1134 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1135 if (!bottommargin.empty())
1136 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1137 if (!leftmargin.empty())
1138 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1139 if (!rightmargin.empty())
1140 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1141 if (!headheight.empty())
1142 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1143 if (!headsep.empty())
1144 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1145 if (!footskip.empty())
1146 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1147 if (!columnsep.empty())
1148 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1153 if (tokenPos(tclass.opt_pagestyle(),
1154 '|', pagestyle) >= 0) {
1155 if (pagestyle == "fancy") {
1156 os << "\\usepackage{fancyhdr}\n";
1159 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1163 // Only if class has a ToC hierarchy
1164 if (tclass.hasTocLevels()) {
1165 if (secnumdepth != tclass.secnumdepth()) {
1166 os << "\\setcounter{secnumdepth}{"
1171 if (tocdepth != tclass.tocdepth()) {
1172 os << "\\setcounter{tocdepth}{"
1179 if (paragraph_separation) {
1180 switch (getDefSkip().kind()) {
1181 case VSpace::SMALLSKIP:
1182 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1184 case VSpace::MEDSKIP:
1185 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1187 case VSpace::BIGSKIP:
1188 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1190 case VSpace::LENGTH:
1191 os << "\\setlength{\\parskip}{"
1192 << from_utf8(getDefSkip().length().asLatexString())
1195 default: // should never happen // Then delete it.
1196 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1201 os << "\\setlength{\\parindent}{0pt}\n";
1205 // If we use jurabib, we have to call babel here.
1206 if (use_babel && features.isRequired("jurabib")) {
1207 os << from_ascii(babelCall(language_options.str()))
1209 << from_ascii(features.getBabelOptions());
1213 // Now insert the LyX specific LaTeX commands...
1215 // The optional packages;
1216 docstring lyxpreamble(from_ascii(features.getPackages()));
1219 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1221 // We try to load babel late, in case it interferes
1222 // with other packages. But some packages also need babel to be loaded
1223 // before, e.g. jurabib has to be called after babel.
1224 // So load babel after the optional packages but before the user-defined
1225 // preamble. This allows the users to redefine babel commands, e.g. to
1226 // translate the word "Index" to the German "Stichwortverzeichnis".
1227 // For more infos why this place was chosen, see
1228 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1229 // If you encounter problems, you can shift babel to its old place behind
1230 // the user-defined preamble. But in this case you must change the Vietnamese
1231 // support from currently "\usepackage[vietnamese]{babel}" to:
1232 // \usepackage{vietnamese}
1233 // \usepackage{babel}
1234 // because vietnamese must be loaded before hyperref
1235 if (use_babel && !features.isRequired("jurabib")) {
1237 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1238 lyxpreamble += from_utf8(features.getBabelOptions());
1241 // When the language "japanese-plain" is used, the package "japanese" must
1242 // be loaded behind babel (it provides babel support for Japanese) but before
1244 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1245 if (language->lang() == "japanese-plain" &&
1246 !getTextClass().provides("japanese")) {
1247 //load babel in case it was not loaded due to an empty language list
1248 if (language_options.str().empty())
1249 lyxpreamble += "\\usepackage{babel}\n";
1250 lyxpreamble += "\\usepackage{japanese}\n";
1254 // * Hyperref manual: "Make sure it comes last of your loaded
1255 // packages, to give it a fighting chance of not being over-written,
1256 // since its job is to redefine many LATEX commands."
1257 // * Email from Heiko Oberdiek: "It is usually better to load babel
1258 // before hyperref. Then hyperref has a chance to detect babel.
1259 // * Has to be loaded before the "LyX specific LaTeX commands" to
1260 // avoid errors with algorithm floats.
1261 // use hyperref explicitely when it is required
1262 if (features.isRequired("hyperref")) {
1263 odocstringstream oss;
1264 pdfoptions().writeLaTeX(oss, getTextClass().provides("hyperref"));
1265 lyxpreamble += oss.str();
1268 // this might be useful...
1269 lyxpreamble += "\n\\makeatletter\n";
1271 // Some macros LyX will need
1272 docstring tmppreamble(from_ascii(features.getMacros()));
1274 if (!tmppreamble.empty()) {
1275 lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1276 "LyX specific LaTeX commands.\n"
1277 + tmppreamble + '\n';
1280 // the text class specific preamble
1281 tmppreamble = features.getTClassPreamble();
1282 if (!tmppreamble.empty()) {
1283 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1284 "Textclass specific LaTeX commands.\n"
1285 + tmppreamble + '\n';
1288 /* the user-defined preamble */
1289 if (!preamble.empty()) {
1291 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1292 "User specified LaTeX commands.\n"
1293 + from_utf8(preamble) + '\n';
1296 // Itemize bullet settings need to be last in case the user
1297 // defines their own bullets that use a package included
1298 // in the user-defined preamble -- ARRae
1299 // Actually it has to be done much later than that
1300 // since some packages like frenchb make modifications
1301 // at \begin{document} time -- JMarc
1302 docstring bullets_def;
1303 for (int i = 0; i < 4; ++i) {
1304 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1305 if (bullets_def.empty())
1306 bullets_def += "\\AtBeginDocument{\n";
1307 bullets_def += " \\def\\labelitemi";
1309 // `i' is one less than the item to modify
1316 bullets_def += "ii";
1322 bullets_def += '{' +
1323 user_defined_bullet(i).getText()
1328 if (!bullets_def.empty())
1329 lyxpreamble += bullets_def + "}\n\n";
1331 lyxpreamble += "\\makeatother\n\n";
1334 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1335 for (int j = 0; j != nlines; ++j) {
1344 void BufferParams::useClassDefaults()
1346 TextClass const & tclass = textclasslist[baseClass_];
1348 sides = tclass.sides();
1349 columns = tclass.columns();
1350 pagestyle = tclass.pagestyle();
1351 options = tclass.options();
1352 // Only if class has a ToC hierarchy
1353 if (tclass.hasTocLevels()) {
1354 secnumdepth = tclass.secnumdepth();
1355 tocdepth = tclass.tocdepth();
1360 bool BufferParams::hasClassDefaults() const
1362 TextClass const & tclass = textclasslist[baseClass_];
1364 return (sides == tclass.sides()
1365 && columns == tclass.columns()
1366 && pagestyle == tclass.pagestyle()
1367 && options == tclass.options()
1368 && secnumdepth == tclass.secnumdepth()
1369 && tocdepth == tclass.tocdepth());
1373 TextClass const & BufferParams::getTextClass() const
1379 TextClassPtr BufferParams::getTextClassPtr() const {
1384 void BufferParams::setTextClass(TextClassPtr tc) {
1389 bool BufferParams::setBaseClass(textclass_type tc)
1391 if (textclasslist[tc].load()) {
1397 bformat(_("The document class %1$s could not be loaded."),
1398 from_utf8(textclasslist[tc].name()));
1399 frontend::Alert::error(_("Could not load class"), s);
1404 textclass_type BufferParams::getBaseClass() const
1410 void BufferParams::makeTextClass()
1412 textClass_.reset(new TextClass(textclasslist[getBaseClass()]));
1414 //FIXME It might be worth loading the children's modules here,
1415 //just as we load their bibliographies and such, instead of just
1416 //doing a check in InsetInclude.
1417 LayoutModuleList::const_iterator it = layoutModules_.begin();
1418 for (; it != layoutModules_.end(); it++) {
1419 string const modName = *it;
1420 LyXModule * lm = moduleList[modName];
1422 docstring const msg =
1423 bformat(_("The module %1$s has been requested by\n"
1424 "this document but has not been found in the list of\n"
1425 "available modules. If you recently installed it, you\n"
1426 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1427 frontend::Alert::warning(_("Module not available"),
1428 msg + _("Some layouts may not be available."));
1429 lyxerr << "BufferParams::makeTextClass(): Module " <<
1430 modName << " requested but not found in module list." <<
1434 if (!lm->isAvailable()) {
1435 docstring const msg =
1436 bformat(_("The module %1$s requires a package that is\n"
1437 "not available in your LaTeX installation. LaTeX output\n"
1438 "may not be possible.\n"), from_utf8(modName));
1439 frontend::Alert::warning(_("Package not available"), msg);
1441 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1442 if (!textClass_->read(layout_file, TextClass::MODULE)) {
1443 docstring const msg =
1444 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1445 frontend::Alert::warning(_("Read Error"), msg);
1451 vector<string> const & BufferParams::getModules() const {
1452 return layoutModules_;
1457 bool BufferParams::addLayoutModule(string const & modName) {
1458 LayoutModuleList::const_iterator it = layoutModules_.begin();
1459 LayoutModuleList::const_iterator end = layoutModules_.end();
1460 for (; it != end; it++) {
1464 if (it != layoutModules_.end())
1466 layoutModules_.push_back(modName);
1471 void BufferParams::clearLayoutModules() {
1472 layoutModules_.clear();
1476 Font const BufferParams::getFont() const
1478 FontInfo f = getTextClass().defaultfont();
1479 if (fontsDefaultFamily == "rmdefault")
1480 f.setFamily(ROMAN_FAMILY);
1481 else if (fontsDefaultFamily == "sfdefault")
1482 f.setFamily(SANS_FAMILY);
1483 else if (fontsDefaultFamily == "ttdefault")
1484 f.setFamily(TYPEWRITER_FAMILY);
1485 return Font(f, language);
1489 void BufferParams::readPreamble(Lexer & lex)
1491 if (lex.getString() != "\\begin_preamble")
1492 lyxerr << "Error (BufferParams::readPreamble):"
1493 "consistency check failed." << endl;
1495 preamble = lex.getLongString("\\end_preamble");
1499 void BufferParams::readLanguage(Lexer & lex)
1501 if (!lex.next()) return;
1503 string const tmptok = lex.getString();
1505 // check if tmptok is part of tex_babel in tex-defs.h
1506 language = languages.getLanguage(tmptok);
1508 // Language tmptok was not found
1509 language = default_language;
1510 lyxerr << "Warning: Setting language `"
1511 << tmptok << "' to `" << language->lang()
1517 void BufferParams::readGraphicsDriver(Lexer & lex)
1519 if (!lex.next()) return;
1521 string const tmptok = lex.getString();
1522 // check if tmptok is part of tex_graphics in tex_defs.h
1525 string const test = tex_graphics[n++];
1527 if (test == tmptok) {
1528 graphicsDriver = tmptok;
1530 } else if (test == "") {
1532 "Warning: graphics driver `$$Token' not recognized!\n"
1533 " Setting graphics driver to `default'.\n");
1534 graphicsDriver = "default";
1541 void BufferParams::readBullets(Lexer & lex)
1543 if (!lex.next()) return;
1545 int const index = lex.getInteger();
1547 int temp_int = lex.getInteger();
1548 user_defined_bullet(index).setFont(temp_int);
1549 temp_bullet(index).setFont(temp_int);
1551 user_defined_bullet(index).setCharacter(temp_int);
1552 temp_bullet(index).setCharacter(temp_int);
1554 user_defined_bullet(index).setSize(temp_int);
1555 temp_bullet(index).setSize(temp_int);
1559 void BufferParams::readBulletsLaTeX(Lexer & lex)
1561 // The bullet class should be able to read this.
1562 if (!lex.next()) return;
1563 int const index = lex.getInteger();
1565 docstring const temp_str = lex.getDocString();
1567 user_defined_bullet(index).setText(temp_str);
1568 temp_bullet(index).setText(temp_str);
1572 void BufferParams::readModules(Lexer & lex)
1574 if (!lex.eatLine()) {
1575 lyxerr << "Error (BufferParams::readModules):"
1576 "Unexpected end of input." << endl;
1580 string mod = lex.getString();
1581 if (mod == "\\end_modules")
1583 addLayoutModule(mod);
1589 string const BufferParams::paperSizeName(Papersize_Purpose const & purpose) const
1591 char real_papersize = papersize;
1592 if (real_papersize == PAPER_DEFAULT)
1593 real_papersize = lyxrc.default_papersize;
1595 switch (real_papersize) {
1597 // could be anything, so don't guess
1599 case PAPER_CUSTOM: {
1600 if (purpose == XDVI && !paperwidth.empty() &&
1601 !paperheight.empty()) {
1602 // heightxwidth<unit>
1603 string first = paperwidth;
1604 string second = paperheight;
1605 if (orientation == ORIENTATION_LANDSCAPE)
1608 return first.erase(first.length() - 2)
1620 // dvips and dvipdfm do not know this
1621 if (purpose == DVIPS || purpose == DVIPDFM)
1625 // dvipdfm does not know this
1626 if (purpose == DVIPDFM)
1630 // dvipdfm does not know this
1631 if (purpose == DVIPDFM)
1634 case PAPER_USEXECUTIVE:
1635 // dvipdfm does not know this
1636 if (purpose == DVIPDFM)
1641 case PAPER_USLETTER:
1643 if (purpose == XDVI)
1650 string const BufferParams::dvips_options() const
1655 && papersize == PAPER_CUSTOM
1656 && !lyxrc.print_paper_dimension_flag.empty()
1657 && !paperwidth.empty()
1658 && !paperheight.empty()) {
1659 // using a custom papersize
1660 result = lyxrc.print_paper_dimension_flag;
1661 result += ' ' + paperwidth;
1662 result += ',' + paperheight;
1664 string const paper_option = paperSizeName(DVIPS);
1665 if (!paper_option.empty() && (paper_option != "letter" ||
1666 orientation != ORIENTATION_LANDSCAPE)) {
1667 // dvips won't accept -t letter -t landscape.
1668 // In all other cases, include the paper size
1670 result = lyxrc.print_paper_flag;
1671 result += ' ' + paper_option;
1674 if (orientation == ORIENTATION_LANDSCAPE &&
1675 papersize != PAPER_CUSTOM)
1676 result += ' ' + lyxrc.print_landscape_flag;
1681 string const BufferParams::babelCall(string const & lang_opts) const
1683 string lang_pack = lyxrc.language_package;
1684 if (lang_pack != "\\usepackage{babel}")
1686 // suppress the babel call when there is no babel language defined
1687 // for the document language in the lib/languages file and if no
1688 // other languages are used (lang_opts is then empty)
1689 if (lang_opts.empty())
1691 // when Vietnamese is used, babel must directly be loaded with the
1692 // language options, see
1693 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1694 size_t viet = lang_opts.find("vietnam");
1695 // viet = string::npos when not found
1696 if (!lyxrc.language_global_options || viet != string::npos)
1697 return "\\usepackage[" + lang_opts + "]{babel}";
1702 void BufferParams::writeEncodingPreamble(odocstream & os,
1703 LaTeXFeatures & features, TexRow & texrow) const
1705 if (inputenc == "auto") {
1706 string const doc_encoding =
1707 language->encoding()->latexName();
1708 Encoding::Package const package =
1709 language->encoding()->package();
1711 // Create a list with all the input encodings used
1713 set<string> encodings =
1714 features.getEncodingSet(doc_encoding);
1716 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1717 // package inputenc must be omitted. Therefore set the encoding to empty.
1718 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1719 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1720 doc_encoding == "SJIS-plain")
1723 if (!encodings.empty() || package == Encoding::inputenc) {
1724 os << "\\usepackage[";
1725 set<string>::const_iterator it = encodings.begin();
1726 set<string>::const_iterator const end = encodings.end();
1728 os << from_ascii(*it);
1731 for (; it != end; ++it)
1732 os << ',' << from_ascii(*it);
1733 if (package == Encoding::inputenc) {
1734 if (!encodings.empty())
1736 os << from_ascii(doc_encoding);
1738 os << "]{inputenc}\n";
1741 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1742 os << "\\usepackage{CJK}\n";
1745 } else if (inputenc != "default") {
1746 switch (encoding().package()) {
1747 case Encoding::none:
1749 case Encoding::inputenc:
1750 os << "\\usepackage[" << from_ascii(inputenc)
1755 os << "\\usepackage{CJK}\n";
1761 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1762 // armscii8 is used for Armenian.
1763 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1764 os << "\\usepackage{armtex}\n";
1770 string const BufferParams::loadFonts(string const & rm,
1771 string const & sf, string const & tt,
1772 bool const & sc, bool const & osf,
1773 int const & sfscale, int const & ttscale) const
1775 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1776 several packages have been replaced by others, that might not
1777 be installed on every system. We have to take care for that
1778 (see psnfss.pdf). We try to support all psnfss fonts as well
1779 as the fonts that have become de facto standard in the LaTeX
1780 world (e.g. Latin Modern). We do not support obsolete fonts
1781 (like PSLatex). In general, it should be possible to mix any
1782 rm font with any sf or tt font, respectively. (JSpitzm)
1784 -- separate math fonts.
1787 if (rm == "default" && sf == "default" && tt == "default")
1794 // Computer Modern (must be explicitely selectable -- there might be classes
1795 // that define a different default font!
1797 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1798 // osf for Computer Modern needs eco.sty
1800 os << "\\usepackage{eco}\n";
1802 // Latin Modern Roman
1803 else if (rm == "lmodern")
1804 os << "\\usepackage{lmodern}\n";
1806 else if (rm == "ae") {
1807 // not needed when using OT1 font encoding.
1808 if (lyxrc.fontenc != "default")
1809 os << "\\usepackage{ae,aecompl}\n";
1812 else if (rm == "times") {
1813 // try to load the best available package
1814 if (LaTeXFeatures::isAvailable("mathptmx"))
1815 os << "\\usepackage{mathptmx}\n";
1816 else if (LaTeXFeatures::isAvailable("mathptm"))
1817 os << "\\usepackage{mathptm}\n";
1819 os << "\\usepackage{times}\n";
1822 else if (rm == "palatino") {
1823 // try to load the best available package
1824 if (LaTeXFeatures::isAvailable("mathpazo")) {
1825 os << "\\usepackage";
1831 // "osf" includes "sc"!
1835 os << "{mathpazo}\n";
1837 else if (LaTeXFeatures::isAvailable("mathpple"))
1838 os << "\\usepackage{mathpple}\n";
1840 os << "\\usepackage{palatino}\n";
1843 else if (rm == "utopia") {
1844 // fourier supersedes utopia.sty, but does
1845 // not work with OT1 encoding.
1846 if (LaTeXFeatures::isAvailable("fourier")
1847 && lyxrc.fontenc != "default") {
1848 os << "\\usepackage";
1859 os << "{fourier}\n";
1862 os << "\\usepackage{utopia}\n";
1864 // Bera (complete fontset)
1865 else if (rm == "bera" && sf == "default" && tt == "default")
1866 os << "\\usepackage{bera}\n";
1868 else if (rm != "default")
1869 os << "\\usepackage" << "{" << rm << "}\n";
1872 // Helvetica, Bera Sans
1873 if (sf == "helvet" || sf == "berasans") {
1875 os << "\\usepackage[scaled=" << float(sfscale) / 100
1876 << "]{" << sf << "}\n";
1878 os << "\\usepackage{" << sf << "}\n";
1881 else if (sf == "avant")
1882 os << "\\usepackage{" << sf << "}\n";
1883 // Computer Modern, Latin Modern, CM Bright
1884 else if (sf != "default")
1885 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1887 // monospaced/typewriter
1888 // Courier, LuxiMono
1889 if (tt == "luximono" || tt == "beramono") {
1891 os << "\\usepackage[scaled=" << float(ttscale) / 100
1892 << "]{" << tt << "}\n";
1894 os << "\\usepackage{" << tt << "}\n";
1897 else if (tt == "courier" )
1898 os << "\\usepackage{" << tt << "}\n";
1899 // Computer Modern, Latin Modern, CM Bright
1900 else if (tt != "default")
1901 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1907 Encoding const & BufferParams::encoding() const
1909 if (inputenc == "auto" || inputenc == "default")
1910 return *(language->encoding());
1911 Encoding const * const enc =
1912 encodings.getFromLaTeXName(inputenc);
1915 lyxerr << "Unknown inputenc value `" << inputenc
1916 << "'. Using `auto' instead." << endl;
1917 return *(language->encoding());
1921 biblio::CiteEngine BufferParams::getEngine() const
1923 // FIXME the class should provide the numerical/
1924 // authoryear choice
1925 if (getTextClass().provides("natbib")
1926 && cite_engine_ != biblio::ENGINE_NATBIB_NUMERICAL)
1927 return biblio::ENGINE_NATBIB_AUTHORYEAR;
1928 return cite_engine_;
1932 void BufferParams::setCiteEngine(biblio::CiteEngine const cite_engine)
1934 cite_engine_ = cite_engine;