2 * \file BufferParams.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Alfredo Braunstein
7 * \author Lars Gullik Bjønnes
8 * \author Jean-Marc Lasgouttes
10 * \author André Pönitz
11 * \author Martin Vermeer
13 * Full author contact details are available in file CREDITS.
18 #include "BufferParams.h"
21 #include "LayoutFile.h"
22 #include "BranchList.h"
23 #include "buffer_funcs.h"
28 #include "LaTeXFeatures.h"
29 #include "ModuleList.h"
33 #include "OutputParams.h"
37 #include "PDFOptions.h"
39 #include "frontends/alert.h"
41 #include "insets/InsetListingsParams.h"
43 #include "support/convert.h"
44 #include "support/debug.h"
45 #include "support/docstream.h"
46 #include "support/FileName.h"
47 #include "support/filetools.h"
48 #include "support/gettext.h"
49 #include "support/Messages.h"
50 #include "support/Translator.h"
51 #include "support/lstrings.h"
57 using namespace lyx::support;
60 static char const * const string_paragraph_separation[] = {
65 static char const * const string_quotes_language[] = {
66 "english", "swedish", "german", "polish", "french", "danish", ""
70 static char const * const string_papersize[] = {
71 "default", "custom", "letterpaper", "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::ParagraphSeparation> ParSepTranslator;
101 ParSepTranslator const init_parseptranslator()
103 ParSepTranslator translator
104 (string_paragraph_separation[0], BufferParams::ParagraphIndentSeparation);
105 translator.addPair(string_paragraph_separation[1], BufferParams::ParagraphSkipSeparation);
110 ParSepTranslator const & parseptranslator()
112 static ParSepTranslator translator = init_parseptranslator();
118 typedef Translator<string, InsetQuotes::QuoteLanguage> QuotesLangTranslator;
121 QuotesLangTranslator const init_quoteslangtranslator()
123 QuotesLangTranslator translator
124 (string_quotes_language[0], InsetQuotes::EnglishQuotes);
125 translator.addPair(string_quotes_language[1], InsetQuotes::SwedishQuotes);
126 translator.addPair(string_quotes_language[2], InsetQuotes::GermanQuotes);
127 translator.addPair(string_quotes_language[3], InsetQuotes::PolishQuotes);
128 translator.addPair(string_quotes_language[4], InsetQuotes::FrenchQuotes);
129 translator.addPair(string_quotes_language[5], InsetQuotes::DanishQuotes);
134 QuotesLangTranslator const & quoteslangtranslator()
136 static QuotesLangTranslator translator = init_quoteslangtranslator();
142 typedef Translator<string, PAPER_SIZE> PaperSizeTranslator;
145 static PaperSizeTranslator initPaperSizeTranslator()
147 PaperSizeTranslator translator(string_papersize[0], PAPER_DEFAULT);
148 translator.addPair(string_papersize[1], PAPER_CUSTOM);
149 translator.addPair(string_papersize[2], PAPER_USLETTER);
150 translator.addPair(string_papersize[3], PAPER_USLEGAL);
151 translator.addPair(string_papersize[4], PAPER_USEXECUTIVE);
152 translator.addPair(string_papersize[5], PAPER_A3);
153 translator.addPair(string_papersize[6], PAPER_A4);
154 translator.addPair(string_papersize[7], PAPER_A5);
155 translator.addPair(string_papersize[8], PAPER_B3);
156 translator.addPair(string_papersize[9], PAPER_B4);
157 translator.addPair(string_papersize[10], PAPER_B5);
162 PaperSizeTranslator const & papersizetranslator()
164 static PaperSizeTranslator translator = initPaperSizeTranslator();
170 typedef Translator<string, PAPER_ORIENTATION> PaperOrientationTranslator;
173 PaperOrientationTranslator const init_paperorientationtranslator()
175 PaperOrientationTranslator translator(string_orientation[0], ORIENTATION_PORTRAIT);
176 translator.addPair(string_orientation[1], ORIENTATION_LANDSCAPE);
181 PaperOrientationTranslator const & paperorientationtranslator()
183 static PaperOrientationTranslator translator = init_paperorientationtranslator();
189 typedef Translator<int, PageSides> SidesTranslator;
192 SidesTranslator const init_sidestranslator()
194 SidesTranslator translator(1, OneSide);
195 translator.addPair(2, TwoSides);
200 SidesTranslator const & sidestranslator()
202 static SidesTranslator translator = init_sidestranslator();
208 typedef Translator<int, BufferParams::Package> PackageTranslator;
211 PackageTranslator const init_packagetranslator()
213 PackageTranslator translator(0, BufferParams::package_off);
214 translator.addPair(1, BufferParams::package_auto);
215 translator.addPair(2, BufferParams::package_on);
220 PackageTranslator const & packagetranslator()
222 static PackageTranslator translator = init_packagetranslator();
228 typedef Translator<string, CiteEngine> CiteEngineTranslator;
231 CiteEngineTranslator const init_citeenginetranslator()
233 CiteEngineTranslator translator("basic", ENGINE_BASIC);
234 translator.addPair("natbib_numerical", ENGINE_NATBIB_NUMERICAL);
235 translator.addPair("natbib_authoryear", ENGINE_NATBIB_AUTHORYEAR);
236 translator.addPair("jurabib", ENGINE_JURABIB);
241 CiteEngineTranslator const & citeenginetranslator()
243 static CiteEngineTranslator translator = init_citeenginetranslator();
249 typedef Translator<string, Spacing::Space> SpaceTranslator;
252 SpaceTranslator const init_spacetranslator()
254 SpaceTranslator translator("default", Spacing::Default);
255 translator.addPair("single", Spacing::Single);
256 translator.addPair("onehalf", Spacing::Onehalf);
257 translator.addPair("double", Spacing::Double);
258 translator.addPair("other", Spacing::Other);
263 SpaceTranslator const & spacetranslator()
265 static SpaceTranslator translator = init_spacetranslator();
273 class BufferParams::Impl
278 AuthorList authorlist;
279 BranchList branchlist;
280 Bullet temp_bullets[4];
281 Bullet user_defined_bullets[4];
283 /** This is the amount of space used for paragraph_separation "skip",
284 * and for detached paragraphs in "indented" documents.
287 PDFOptions pdfoptions;
288 LayoutFileIndex baseClass_;
292 BufferParams::Impl::Impl()
293 : defskip(VSpace::MEDSKIP), baseClass_(string(""))
295 // set initial author
297 authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
302 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
306 return new BufferParams::Impl(*ptr);
310 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
316 BufferParams::BufferParams()
319 setBaseClass(defaultBaseclass());
321 paragraph_separation = ParagraphIndentSeparation;
322 quotes_language = InsetQuotes::EnglishQuotes;
323 fontsize = "default";
326 papersize = PAPER_DEFAULT;
327 orientation = ORIENTATION_PORTRAIT;
328 use_geometry = false;
329 use_amsmath = package_auto;
330 use_esint = package_auto;
331 cite_engine_ = ENGINE_BASIC;
332 use_bibtopic = false;
333 trackChanges = false;
334 outputChanges = false;
337 language = default_language;
338 fontsRoman = "default";
339 fontsSans = "default";
340 fontsTypewriter = "default";
341 fontsDefaultFamily = "default";
344 fontsSansScale = 100;
345 fontsTypewriterScale = 100;
347 graphicsDriver = "default";
350 listings_params = string();
351 pagestyle = "default";
353 for (int iter = 0; iter < 4; ++iter) {
354 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
355 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
360 docstring BufferParams::B_(string const & l10n) const
362 LASSERT(language, /**/);
363 return getMessages(language->code()).get(l10n);
367 AuthorList & BufferParams::authors()
369 return pimpl_->authorlist;
373 AuthorList const & BufferParams::authors() const
375 return pimpl_->authorlist;
379 BranchList & BufferParams::branchlist()
381 return pimpl_->branchlist;
385 BranchList const & BufferParams::branchlist() const
387 return pimpl_->branchlist;
391 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
393 LASSERT(index < 4, /**/);
394 return pimpl_->temp_bullets[index];
398 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
400 LASSERT(index < 4, /**/);
401 return pimpl_->temp_bullets[index];
405 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
407 LASSERT(index < 4, /**/);
408 return pimpl_->user_defined_bullets[index];
412 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
414 LASSERT(index < 4, /**/);
415 return pimpl_->user_defined_bullets[index];
419 Spacing & BufferParams::spacing()
421 return pimpl_->spacing;
425 Spacing const & BufferParams::spacing() const
427 return pimpl_->spacing;
431 PDFOptions & BufferParams::pdfoptions()
433 return pimpl_->pdfoptions;
437 PDFOptions const & BufferParams::pdfoptions() const
439 return pimpl_->pdfoptions;
443 VSpace const & BufferParams::getDefSkip() const
445 return pimpl_->defskip;
449 void BufferParams::setDefSkip(VSpace const & vs)
451 pimpl_->defskip = vs;
455 string BufferParams::readToken(Lexer & lex, string const & token,
456 FileName const & filepath)
458 if (token == "\\textclass") {
460 string const classname = lex.getString();
461 // if there exists a local layout file, ignore the system one
462 // NOTE: in this case, the textclass (.cls file) is assumed to be available.
464 LayoutFileList & bcl = LayoutFileList::get();
465 if (tcp.empty() && !filepath.empty())
466 tcp = bcl.addLayoutFile(classname, filepath.absFilename(), LayoutFileList::Local);
469 else if (bcl.haveClass(classname)) {
470 setBaseClass(classname);
472 // a warning will be given for unknown class
473 setBaseClass(defaultBaseclass());
476 // FIXME: this warning will be given even if there exists a local .cls
477 // file. Even worse, the .lyx file can not be compiled or exported
478 // because the textclass is marked as unavilable.
479 if (!baseClass()->isTeXClassAvailable()) {
480 docstring const msg =
481 bformat(_("The layout file requested by this document,\n"
483 "is not usable. This is probably because a LaTeX\n"
484 "class or style file required by it is not\n"
485 "available. See the Customization documentation\n"
486 "for more information.\n"), from_utf8(classname));
487 frontend::Alert::warning(_("Document class not available"),
488 msg + _("LyX will not be able to produce output."));
491 } else if (token == "\\begin_preamble") {
493 } else if (token == "\\begin_local_layout") {
494 readLocalLayout(lex);
495 } else if (token == "\\begin_modules") {
497 } else if (token == "\\options") {
499 options = lex.getString();
500 } else if (token == "\\language") {
502 } else if (token == "\\inputencoding") {
504 } else if (token == "\\graphics") {
505 readGraphicsDriver(lex);
506 } else if (token == "\\font_roman") {
508 } else if (token == "\\font_sans") {
510 } else if (token == "\\font_typewriter") {
511 lex >> fontsTypewriter;
512 } else if (token == "\\font_default_family") {
513 lex >> fontsDefaultFamily;
514 } else if (token == "\\font_sc") {
516 } else if (token == "\\font_osf") {
518 } else if (token == "\\font_sf_scale") {
519 lex >> fontsSansScale;
520 } else if (token == "\\font_tt_scale") {
521 lex >> fontsTypewriterScale;
522 } else if (token == "\\paragraph_separation") {
525 paragraph_separation = parseptranslator().find(parsep);
526 } else if (token == "\\defskip") {
528 string defskip = lex.getString();
529 if (defskip == "defskip")
532 pimpl_->defskip = VSpace(defskip);
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 == "\\columnsep") {
620 } else if (token == "\\paperfontsize") {
622 } else if (token == "\\papercolumns") {
624 } else if (token == "\\listings_params") {
627 listings_params = InsetListingsParams(par).params();
628 } else if (token == "\\papersides") {
631 sides = sidestranslator().find(psides);
632 } else if (token == "\\paperpagestyle") {
634 } else if (token == "\\bullet") {
636 } else if (token == "\\bulletLaTeX") {
637 readBulletsLaTeX(lex);
638 } else if (token == "\\secnumdepth") {
640 } else if (token == "\\tocdepth") {
642 } else if (token == "\\spacing") {
646 if (nspacing == "other") {
649 spacing().set(spacetranslator().find(nspacing), tmp_val);
650 } else if (token == "\\float_placement") {
651 lex >> float_placement;
653 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
654 string toktmp = pdfoptions().readToken(lex, token);
655 if (!toktmp.empty()) {
656 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
661 lyxerr << "BufferParams::readToken(): Unknown token: " <<
670 void BufferParams::writeFile(ostream & os) const
672 // The top of the file is written by the buffer.
673 // Prints out the buffer info into the .lyx file given by file
676 os << "\\textclass " << baseClass()->name() << '\n';
679 if (!preamble.empty()) {
680 // remove '\n' from the end of preamble
681 string const tmppreamble = rtrim(preamble, "\n");
682 os << "\\begin_preamble\n"
684 << "\n\\end_preamble\n";
688 if (!options.empty()) {
689 os << "\\options " << options << '\n';
693 if (!layoutModules_.empty()) {
694 os << "\\begin_modules" << '\n';
695 LayoutModuleList::const_iterator it = layoutModules_.begin();
696 for (; it != layoutModules_.end(); it++)
698 os << "\\end_modules" << '\n';
701 // local layout information
702 if (!local_layout.empty()) {
703 // remove '\n' from the end
704 string const tmplocal = rtrim(local_layout, "\n");
705 os << "\\begin_local_layout\n"
707 << "\n\\end_local_layout\n";
710 // then the text parameters
711 if (language != ignore_language)
712 os << "\\language " << language->lang() << '\n';
713 os << "\\inputencoding " << inputenc
714 << "\n\\font_roman " << fontsRoman
715 << "\n\\font_sans " << fontsSans
716 << "\n\\font_typewriter " << fontsTypewriter
717 << "\n\\font_default_family " << fontsDefaultFamily
718 << "\n\\font_sc " << convert<string>(fontsSC)
719 << "\n\\font_osf " << convert<string>(fontsOSF)
720 << "\n\\font_sf_scale " << fontsSansScale
721 << "\n\\font_tt_scale " << fontsTypewriterScale
722 << "\n\\graphics " << graphicsDriver << '\n';
724 if (!float_placement.empty()) {
725 os << "\\float_placement " << float_placement << '\n';
727 os << "\\paperfontsize " << fontsize << '\n';
729 spacing().writeFile(os);
730 pdfoptions().writeFile(os);
732 os << "\\papersize " << string_papersize[papersize]
733 << "\n\\use_geometry " << convert<string>(use_geometry)
734 << "\n\\use_amsmath " << use_amsmath
735 << "\n\\use_esint " << use_esint
736 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
737 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
738 << "\n\\paperorientation " << string_orientation[orientation]
741 BranchList::const_iterator it = branchlist().begin();
742 BranchList::const_iterator end = branchlist().end();
743 for (; it != end; ++it) {
744 os << "\\branch " << to_utf8(it->getBranch())
745 << "\n\\selected " << it->getSelected()
746 << "\n\\color " << lyx::X11hexname(it->getColor())
751 if (!paperwidth.empty())
752 os << "\\paperwidth "
753 << VSpace(paperwidth).asLyXCommand() << '\n';
754 if (!paperheight.empty())
755 os << "\\paperheight "
756 << VSpace(paperheight).asLyXCommand() << '\n';
757 if (!leftmargin.empty())
758 os << "\\leftmargin "
759 << VSpace(leftmargin).asLyXCommand() << '\n';
760 if (!topmargin.empty())
762 << VSpace(topmargin).asLyXCommand() << '\n';
763 if (!rightmargin.empty())
764 os << "\\rightmargin "
765 << VSpace(rightmargin).asLyXCommand() << '\n';
766 if (!bottommargin.empty())
767 os << "\\bottommargin "
768 << VSpace(bottommargin).asLyXCommand() << '\n';
769 if (!headheight.empty())
770 os << "\\headheight "
771 << VSpace(headheight).asLyXCommand() << '\n';
772 if (!headsep.empty())
774 << VSpace(headsep).asLyXCommand() << '\n';
775 if (!footskip.empty())
777 << VSpace(footskip).asLyXCommand() << '\n';
778 if (!columnsep.empty())
780 << VSpace(columnsep).asLyXCommand() << '\n';
781 os << "\\secnumdepth " << secnumdepth
782 << "\n\\tocdepth " << tocdepth
783 << "\n\\paragraph_separation "
784 << string_paragraph_separation[paragraph_separation]
785 << "\n\\defskip " << getDefSkip().asLyXCommand()
786 << "\n\\quotes_language "
787 << string_quotes_language[quotes_language]
788 << "\n\\papercolumns " << columns
789 << "\n\\papersides " << sides
790 << "\n\\paperpagestyle " << pagestyle << '\n';
791 if (!listings_params.empty())
792 os << "\\listings_params \"" <<
793 InsetListingsParams(listings_params).encodedString() << "\"\n";
794 for (int i = 0; i < 4; ++i) {
795 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
796 if (user_defined_bullet(i).getFont() != -1) {
797 os << "\\bullet " << i << " "
798 << user_defined_bullet(i).getFont() << " "
799 << user_defined_bullet(i).getCharacter() << " "
800 << user_defined_bullet(i).getSize() << "\n";
804 os << "\\bulletLaTeX " << i << " \""
805 << lyx::to_ascii(user_defined_bullet(i).getText())
811 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
812 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
814 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
815 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
816 for (; a_it != a_end; ++a_it) {
817 if (a_it->second.used())
818 os << "\\author " << a_it->second << "\n";
820 os << "\\author " << Author() << "\n";
825 void BufferParams::validate(LaTeXFeatures & features) const
827 features.require(documentClass().requires());
830 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
831 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
832 LaTeXFeatures::isAvailable("xcolor");
834 switch (features.runparams().flavor) {
835 case OutputParams::LATEX:
837 features.require("ct-dvipost");
838 features.require("dvipost");
839 } else if (xcolorsoul) {
840 features.require("ct-xcolor-soul");
841 features.require("soul");
842 features.require("xcolor");
844 features.require("ct-none");
847 case OutputParams::PDFLATEX:
849 features.require("ct-xcolor-soul");
850 features.require("soul");
851 features.require("xcolor");
852 // improves color handling in PDF output
853 features.require("pdfcolmk");
855 features.require("ct-none");
863 // Floats with 'Here definitely' as default setting.
864 if (float_placement.find('H') != string::npos)
865 features.require("float");
867 // AMS Style is at document level
868 if (use_amsmath == package_on
869 || documentClass().provides("amsmath"))
870 features.require("amsmath");
871 if (use_esint == package_on)
872 features.require("esint");
874 // Document-level line spacing
875 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
876 features.require("setspace");
878 // the bullet shapes are buffer level not paragraph level
879 // so they are tested here
880 for (int i = 0; i < 4; ++i) {
881 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
883 int const font = user_defined_bullet(i).getFont();
885 int const c = user_defined_bullet(i).getCharacter();
891 features.require("latexsym");
893 } else if (font == 1) {
894 features.require("amssymb");
895 } else if (font >= 2 && font <= 5) {
896 features.require("pifont");
900 if (pdfoptions().use_hyperref)
901 features.require("hyperref");
905 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
906 TexRow & texrow) const
908 os << "\\documentclass";
910 DocumentClass const & tclass = documentClass();
912 ostringstream clsoptions; // the document class options.
914 if (tokenPos(tclass.opt_fontsize(),
915 '|', fontsize) >= 0) {
916 // only write if existing in list (and not default)
917 clsoptions << fontsize << "pt,";
920 // custom, A3, B3 and B4 paper sizes need geometry
921 bool nonstandard_papersize = papersize == PAPER_B3
922 || papersize == PAPER_B4
923 || papersize == PAPER_A3
924 || papersize == PAPER_CUSTOM;
929 clsoptions << "a4paper,";
932 clsoptions << "letterpaper,";
935 clsoptions << "a5paper,";
938 clsoptions << "b5paper,";
940 case PAPER_USEXECUTIVE:
941 clsoptions << "executivepaper,";
944 clsoptions << "legalpaper,";
956 if (sides != tclass.sides()) {
959 clsoptions << "oneside,";
962 clsoptions << "twoside,";
968 if (columns != tclass.columns()) {
970 clsoptions << "twocolumn,";
972 clsoptions << "onecolumn,";
976 && orientation == ORIENTATION_LANDSCAPE)
977 clsoptions << "landscape,";
979 // language should be a parameter to \documentclass
980 if (language->babel() == "hebrew"
981 && default_language->babel() != "hebrew")
982 // This seems necessary
983 features.useLanguage(default_language);
985 ostringstream language_options;
986 bool const use_babel = features.useBabel();
988 language_options << features.getLanguages();
989 if (!language->babel().empty()) {
990 if (!language_options.str().empty())
991 language_options << ',';
992 language_options << language->babel();
994 // when Vietnamese is used, babel must directly be loaded with the
995 // language options, not in the class options, see
996 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
997 size_t viet = language_options.str().find("vietnam");
998 // viet = string::npos when not found
999 // when Japanese is used, babel must directly be loaded with the
1000 // language options, not in the class options, see
1001 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1002 size_t japan = language_options.str().find("japanese");
1003 // japan = string::npos when not found
1004 if (lyxrc.language_global_options && !language_options.str().empty()
1005 && viet == string::npos && japan == string::npos)
1006 clsoptions << language_options.str() << ',';
1009 // the user-defined options
1010 if (!options.empty()) {
1011 clsoptions << options << ',';
1014 string strOptions(clsoptions.str());
1015 if (!strOptions.empty()) {
1016 strOptions = rtrim(strOptions, ",");
1018 os << '[' << from_utf8(strOptions) << ']';
1021 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1023 // end of \documentclass defs
1025 // font selection must be done before loading fontenc.sty
1026 string const fonts =
1027 loadFonts(fontsRoman, fontsSans,
1028 fontsTypewriter, fontsSC, fontsOSF,
1029 fontsSansScale, fontsTypewriterScale);
1030 if (!fonts.empty()) {
1031 os << from_ascii(fonts);
1034 if (fontsDefaultFamily != "default")
1035 os << "\\renewcommand{\\familydefault}{\\"
1036 << from_ascii(fontsDefaultFamily) << "}\n";
1038 // set font encoding
1039 // this one is not per buffer
1040 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1041 if (lyxrc.fontenc != "default") {
1042 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1043 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1044 << ",LFE,LAE]{fontenc}\n";
1047 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1053 // handle inputenc etc.
1054 writeEncodingPreamble(os, features, texrow);
1056 if (!listings_params.empty()) {
1057 os << "\\usepackage{listings}\n";
1060 // do not test validity because listings_params is supposed to be valid
1061 string par = InsetListingsParams(listings_params).separatedParams(true);
1062 os << from_ascii(par);
1063 // count the number of newlines
1064 for (size_t i = 0; i < par.size(); ++i)
1070 if (use_geometry || nonstandard_papersize) {
1071 os << "\\usepackage{geometry}\n";
1073 os << "\\geometry{verbose";
1074 if (orientation == ORIENTATION_LANDSCAPE)
1076 switch (papersize) {
1078 if (!paperwidth.empty())
1079 os << ",paperwidth="
1080 << from_ascii(paperwidth);
1081 if (!paperheight.empty())
1082 os << ",paperheight="
1083 << from_ascii(paperheight);
1085 case PAPER_USLETTER:
1086 os << ",letterpaper";
1089 os << ",legalpaper";
1091 case PAPER_USEXECUTIVE:
1092 os << ",executivepaper";
1113 // default papersize ie PAPER_DEFAULT
1114 switch (lyxrc.default_papersize) {
1115 case PAPER_DEFAULT: // keep compiler happy
1116 case PAPER_USLETTER:
1117 os << ",letterpaper";
1120 os << ",legalpaper";
1122 case PAPER_USEXECUTIVE:
1123 os << ",executivepaper";
1143 if (!topmargin.empty())
1144 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1145 if (!bottommargin.empty())
1146 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1147 if (!leftmargin.empty())
1148 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1149 if (!rightmargin.empty())
1150 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1151 if (!headheight.empty())
1152 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1153 if (!headsep.empty())
1154 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1155 if (!footskip.empty())
1156 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1157 if (!columnsep.empty())
1158 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1163 if (tokenPos(tclass.opt_pagestyle(),
1164 '|', pagestyle) >= 0) {
1165 if (pagestyle == "fancy") {
1166 os << "\\usepackage{fancyhdr}\n";
1169 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1173 // Only if class has a ToC hierarchy
1174 if (tclass.hasTocLevels()) {
1175 if (secnumdepth != tclass.secnumdepth()) {
1176 os << "\\setcounter{secnumdepth}{"
1181 if (tocdepth != tclass.tocdepth()) {
1182 os << "\\setcounter{tocdepth}{"
1189 if (paragraph_separation) {
1190 switch (getDefSkip().kind()) {
1191 case VSpace::SMALLSKIP:
1192 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1194 case VSpace::MEDSKIP:
1195 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1197 case VSpace::BIGSKIP:
1198 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1200 case VSpace::LENGTH:
1201 os << "\\setlength{\\parskip}{"
1202 << from_utf8(getDefSkip().length().asLatexString())
1205 default: // should never happen // Then delete it.
1206 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1211 os << "\\setlength{\\parindent}{0pt}\n";
1215 // If we use jurabib, we have to call babel here.
1216 if (use_babel && features.isRequired("jurabib")) {
1217 os << from_ascii(babelCall(language_options.str()))
1219 << from_ascii(features.getBabelOptions());
1223 // Now insert the LyX specific LaTeX commands...
1225 // The optional packages;
1226 docstring lyxpreamble(from_ascii(features.getPackages()));
1229 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1231 // We try to load babel late, in case it interferes
1232 // with other packages. But some packages also need babel to be loaded
1233 // before, e.g. jurabib has to be called after babel.
1234 // So load babel after the optional packages but before the user-defined
1235 // preamble. This allows the users to redefine babel commands, e.g. to
1236 // translate the word "Index" to the German "Stichwortverzeichnis".
1237 // For more infos why this place was chosen, see
1238 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1239 // If you encounter problems, you can shift babel to its old place behind
1240 // the user-defined preamble. But in this case you must change the Vietnamese
1241 // support from currently "\usepackage[vietnamese]{babel}" to:
1242 // \usepackage{vietnamese}
1243 // \usepackage{babel}
1244 // because vietnamese must be loaded before hyperref
1245 if (use_babel && !features.isRequired("jurabib")) {
1247 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1248 lyxpreamble += from_utf8(features.getBabelOptions());
1252 // * Hyperref manual: "Make sure it comes last of your loaded
1253 // packages, to give it a fighting chance of not being over-written,
1254 // since its job is to redefine many LATEX commands."
1255 // * Email from Heiko Oberdiek: "It is usually better to load babel
1256 // before hyperref. Then hyperref has a chance to detect babel.
1257 // * Has to be loaded before the "LyX specific LaTeX commands" to
1258 // avoid errors with algorithm floats.
1259 // use hyperref explicitely when it is required
1260 if (features.isRequired("hyperref")) {
1261 odocstringstream oss;
1262 pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
1263 lyxpreamble += oss.str();
1266 // only add \makeatletter and \makeatother when actually needed
1267 bool makeatletter = false;
1269 // Some macros LyX will need
1270 docstring tmppreamble(from_ascii(features.getMacros()));
1272 if (!tmppreamble.empty()) {
1273 if (!makeatletter) {
1274 lyxpreamble += "\n\\makeatletter\n";
1275 makeatletter = true;
1277 lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1278 "LyX specific LaTeX commands.\n"
1279 + tmppreamble + '\n';
1282 // the text class specific preamble
1283 tmppreamble = features.getTClassPreamble();
1284 if (!tmppreamble.empty()) {
1285 if (!makeatletter) {
1286 lyxpreamble += "\n\\makeatletter\n";
1287 makeatletter = true;
1289 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1290 "Textclass specific LaTeX commands.\n"
1291 + tmppreamble + '\n';
1294 /* the user-defined preamble */
1295 if (!preamble.empty()) {
1296 if (!makeatletter) {
1297 lyxpreamble += "\n\\makeatletter\n";
1298 makeatletter = true;
1301 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1302 "User specified LaTeX commands.\n"
1303 + from_utf8(preamble) + '\n';
1306 // Itemize bullet settings need to be last in case the user
1307 // defines their own bullets that use a package included
1308 // in the user-defined preamble -- ARRae
1309 // Actually it has to be done much later than that
1310 // since some packages like frenchb make modifications
1311 // at \begin{document} time -- JMarc
1312 docstring bullets_def;
1313 for (int i = 0; i < 4; ++i) {
1314 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1315 if (bullets_def.empty())
1316 bullets_def += "\\AtBeginDocument{\n";
1317 bullets_def += " \\def\\labelitemi";
1319 // `i' is one less than the item to modify
1326 bullets_def += "ii";
1332 bullets_def += '{' +
1333 user_defined_bullet(i).getText()
1338 if (!bullets_def.empty()) {
1339 if (!makeatletter) {
1340 lyxpreamble += "\n\\makeatletter\n";
1341 makeatletter = true;
1343 lyxpreamble += bullets_def + "}\n\n";
1347 lyxpreamble += "\\makeatother\n\n";
1350 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1351 for (int j = 0; j != nlines; ++j) {
1360 void BufferParams::useClassDefaults()
1362 DocumentClass const & tclass = documentClass();
1364 sides = tclass.sides();
1365 columns = tclass.columns();
1366 pagestyle = tclass.pagestyle();
1367 options = tclass.options();
1368 // Only if class has a ToC hierarchy
1369 if (tclass.hasTocLevels()) {
1370 secnumdepth = tclass.secnumdepth();
1371 tocdepth = tclass.tocdepth();
1376 bool BufferParams::hasClassDefaults() const
1378 DocumentClass const & tclass = documentClass();
1380 return sides == tclass.sides()
1381 && columns == tclass.columns()
1382 && pagestyle == tclass.pagestyle()
1383 && options == tclass.options()
1384 && secnumdepth == tclass.secnumdepth()
1385 && tocdepth == tclass.tocdepth();
1389 DocumentClass const & BufferParams::documentClass() const
1395 DocumentClass * BufferParams::documentClassPtr() const {
1400 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1401 // evil, but this function is evil
1402 doc_class_ = const_cast<DocumentClass *>(tc);
1406 bool BufferParams::setBaseClass(string const & classname)
1408 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1409 LayoutFileList const & bcl = LayoutFileList::get();
1410 if (!bcl.haveClass(classname)) {
1412 bformat(_("The document class %1$s could not be found."),
1413 from_utf8(classname));
1414 frontend::Alert::error(_("Class not found"), s);
1418 if (bcl[classname].load()) {
1419 pimpl_->baseClass_ = classname;
1424 bformat(_("The document class %1$s could not be loaded."),
1425 from_utf8(classname));
1426 frontend::Alert::error(_("Could not load class"), s);
1431 LayoutFile const * BufferParams::baseClass() const
1433 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
1434 return &(LayoutFileList::get()[pimpl_->baseClass_]);
1440 LayoutFileIndex const & BufferParams::baseClassID() const
1442 return pimpl_->baseClass_;
1446 void BufferParams::makeDocumentClass()
1451 doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass()));
1453 //FIXME It might be worth loading the children's modules here,
1454 //just as we load their bibliographies and such, instead of just
1455 //doing a check in InsetInclude.
1456 LayoutModuleList::const_iterator it = layoutModules_.begin();
1457 for (; it != layoutModules_.end(); it++) {
1458 string const modName = *it;
1459 LyXModule * lm = moduleList[modName];
1461 docstring const msg =
1462 bformat(_("The module %1$s has been requested by\n"
1463 "this document but has not been found in the list of\n"
1464 "available modules. If you recently installed it, you\n"
1465 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1466 frontend::Alert::warning(_("Module not available"),
1467 msg + _("Some layouts may not be available."));
1468 LYXERR0("BufferParams::makeDocumentClass(): Module " <<
1469 modName << " requested but not found in module list.");
1472 if (!lm->isAvailable()) {
1473 docstring const msg =
1474 bformat(_("The module %1$s requires a package that is\n"
1475 "not available in your LaTeX installation. LaTeX output\n"
1476 "may not be possible.\n"), from_utf8(modName));
1477 frontend::Alert::warning(_("Package not available"), msg);
1479 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1480 if (!doc_class_->read(layout_file, TextClass::MODULE)) {
1481 docstring const msg =
1482 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1483 frontend::Alert::warning(_("Read Error"), msg);
1486 if (!local_layout.empty()) {
1487 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
1488 docstring const msg = _("Error reading internal layout information");
1489 frontend::Alert::warning(_("Read Error"), msg);
1495 vector<string> const & BufferParams::getModules() const
1497 return layoutModules_;
1502 bool BufferParams::addLayoutModule(string const & modName)
1504 LayoutModuleList::const_iterator it = layoutModules_.begin();
1505 LayoutModuleList::const_iterator end = layoutModules_.end();
1506 for (; it != end; it++)
1509 layoutModules_.push_back(modName);
1514 void BufferParams::clearLayoutModules()
1516 layoutModules_.clear();
1520 Font const BufferParams::getFont() const
1522 FontInfo f = documentClass().defaultfont();
1523 if (fontsDefaultFamily == "rmdefault")
1524 f.setFamily(ROMAN_FAMILY);
1525 else if (fontsDefaultFamily == "sfdefault")
1526 f.setFamily(SANS_FAMILY);
1527 else if (fontsDefaultFamily == "ttdefault")
1528 f.setFamily(TYPEWRITER_FAMILY);
1529 return Font(f, language);
1533 void BufferParams::readPreamble(Lexer & lex)
1535 if (lex.getString() != "\\begin_preamble")
1536 lyxerr << "Error (BufferParams::readPreamble):"
1537 "consistency check failed." << endl;
1539 preamble = lex.getLongString("\\end_preamble");
1543 void BufferParams::readLocalLayout(Lexer & lex)
1545 if (lex.getString() != "\\begin_local_layout")
1546 lyxerr << "Error (BufferParams::readLocalLayout):"
1547 "consistency check failed." << endl;
1549 local_layout = lex.getLongString("\\end_local_layout");
1553 void BufferParams::readLanguage(Lexer & lex)
1555 if (!lex.next()) return;
1557 string const tmptok = lex.getString();
1559 // check if tmptok is part of tex_babel in tex-defs.h
1560 language = languages.getLanguage(tmptok);
1562 // Language tmptok was not found
1563 language = default_language;
1564 lyxerr << "Warning: Setting language `"
1565 << tmptok << "' to `" << language->lang()
1571 void BufferParams::readGraphicsDriver(Lexer & lex)
1576 string const tmptok = lex.getString();
1577 // check if tmptok is part of tex_graphics in tex_defs.h
1580 string const test = tex_graphics[n++];
1582 if (test == tmptok) {
1583 graphicsDriver = tmptok;
1588 "Warning: graphics driver `$$Token' not recognized!\n"
1589 " Setting graphics driver to `default'.\n");
1590 graphicsDriver = "default";
1597 void BufferParams::readBullets(Lexer & lex)
1602 int const index = lex.getInteger();
1604 int temp_int = lex.getInteger();
1605 user_defined_bullet(index).setFont(temp_int);
1606 temp_bullet(index).setFont(temp_int);
1608 user_defined_bullet(index).setCharacter(temp_int);
1609 temp_bullet(index).setCharacter(temp_int);
1611 user_defined_bullet(index).setSize(temp_int);
1612 temp_bullet(index).setSize(temp_int);
1616 void BufferParams::readBulletsLaTeX(Lexer & lex)
1618 // The bullet class should be able to read this.
1621 int const index = lex.getInteger();
1623 docstring const temp_str = lex.getDocString();
1625 user_defined_bullet(index).setText(temp_str);
1626 temp_bullet(index).setText(temp_str);
1630 void BufferParams::readModules(Lexer & lex)
1632 if (!lex.eatLine()) {
1633 lyxerr << "Error (BufferParams::readModules):"
1634 "Unexpected end of input." << endl;
1638 string mod = lex.getString();
1639 if (mod == "\\end_modules")
1641 addLayoutModule(mod);
1647 string BufferParams::paperSizeName(PapersizePurpose purpose) const
1649 char real_papersize = papersize;
1650 if (real_papersize == PAPER_DEFAULT)
1651 real_papersize = lyxrc.default_papersize;
1653 switch (real_papersize) {
1655 // could be anything, so don't guess
1657 case PAPER_CUSTOM: {
1658 if (purpose == XDVI && !paperwidth.empty() &&
1659 !paperheight.empty()) {
1660 // heightxwidth<unit>
1661 string first = paperwidth;
1662 string second = paperheight;
1663 if (orientation == ORIENTATION_LANDSCAPE)
1666 return first.erase(first.length() - 2)
1678 // dvips and dvipdfm do not know this
1679 if (purpose == DVIPS || purpose == DVIPDFM)
1683 // dvipdfm does not know this
1684 if (purpose == DVIPDFM)
1688 // dvipdfm does not know this
1689 if (purpose == DVIPDFM)
1692 case PAPER_USEXECUTIVE:
1693 // dvipdfm does not know this
1694 if (purpose == DVIPDFM)
1699 case PAPER_USLETTER:
1701 if (purpose == XDVI)
1708 string const BufferParams::dvips_options() const
1713 && papersize == PAPER_CUSTOM
1714 && !lyxrc.print_paper_dimension_flag.empty()
1715 && !paperwidth.empty()
1716 && !paperheight.empty()) {
1717 // using a custom papersize
1718 result = lyxrc.print_paper_dimension_flag;
1719 result += ' ' + paperwidth;
1720 result += ',' + paperheight;
1722 string const paper_option = paperSizeName(DVIPS);
1723 if (!paper_option.empty() && (paper_option != "letter" ||
1724 orientation != ORIENTATION_LANDSCAPE)) {
1725 // dvips won't accept -t letter -t landscape.
1726 // In all other cases, include the paper size
1728 result = lyxrc.print_paper_flag;
1729 result += ' ' + paper_option;
1732 if (orientation == ORIENTATION_LANDSCAPE &&
1733 papersize != PAPER_CUSTOM)
1734 result += ' ' + lyxrc.print_landscape_flag;
1739 string BufferParams::babelCall(string const & lang_opts) const
1741 string lang_pack = lyxrc.language_package;
1742 if (lang_pack != "\\usepackage{babel}")
1744 // suppress the babel call when there is no babel language defined
1745 // for the document language in the lib/languages file and if no
1746 // other languages are used (lang_opts is then empty)
1747 if (lang_opts.empty())
1749 // when Vietnamese is used, babel must directly be loaded with the
1750 // language options, see
1751 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1752 size_t viet = lang_opts.find("vietnam");
1753 // viet = string::npos when not found
1754 // when Japanese is used, babel must directly be loaded with the
1755 // language options, see
1756 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1757 size_t japan = lang_opts.find("japanese");
1758 // japan = string::npos when not found
1759 if (!lyxrc.language_global_options || viet != string::npos || japan != string::npos)
1760 return "\\usepackage[" + lang_opts + "]{babel}";
1765 void BufferParams::writeEncodingPreamble(odocstream & os,
1766 LaTeXFeatures & features, TexRow & texrow) const
1768 if (inputenc == "auto") {
1769 string const doc_encoding =
1770 language->encoding()->latexName();
1771 Encoding::Package const package =
1772 language->encoding()->package();
1774 // Create a list with all the input encodings used
1776 set<string> encodings =
1777 features.getEncodingSet(doc_encoding);
1779 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1780 // package inputenc must be omitted. Therefore set the encoding to empty.
1781 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1782 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1783 doc_encoding == "SJIS-plain")
1786 if (!encodings.empty() || package == Encoding::inputenc) {
1787 os << "\\usepackage[";
1788 set<string>::const_iterator it = encodings.begin();
1789 set<string>::const_iterator const end = encodings.end();
1791 os << from_ascii(*it);
1794 for (; it != end; ++it)
1795 os << ',' << from_ascii(*it);
1796 if (package == Encoding::inputenc) {
1797 if (!encodings.empty())
1799 os << from_ascii(doc_encoding);
1801 os << "]{inputenc}\n";
1804 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1805 os << "\\usepackage{CJK}\n";
1808 } else if (inputenc != "default") {
1809 switch (encoding().package()) {
1810 case Encoding::none:
1812 case Encoding::inputenc:
1813 os << "\\usepackage[" << from_ascii(inputenc)
1818 os << "\\usepackage{CJK}\n";
1824 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1825 // armscii8 is used for Armenian.
1826 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1827 os << "\\usepackage{armtex}\n";
1833 string const BufferParams::loadFonts(string const & rm,
1834 string const & sf, string const & tt,
1835 bool const & sc, bool const & osf,
1836 int const & sfscale, int const & ttscale) const
1838 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1839 several packages have been replaced by others, that might not
1840 be installed on every system. We have to take care for that
1841 (see psnfss.pdf). We try to support all psnfss fonts as well
1842 as the fonts that have become de facto standard in the LaTeX
1843 world (e.g. Latin Modern). We do not support obsolete fonts
1844 (like PSLatex). In general, it should be possible to mix any
1845 rm font with any sf or tt font, respectively. (JSpitzm)
1847 -- separate math fonts.
1850 if (rm == "default" && sf == "default" && tt == "default")
1857 // Computer Modern (must be explicitely selectable -- there might be classes
1858 // that define a different default font!
1860 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1861 // osf for Computer Modern needs eco.sty
1863 os << "\\usepackage{eco}\n";
1865 // Latin Modern Roman
1866 else if (rm == "lmodern")
1867 os << "\\usepackage{lmodern}\n";
1869 else if (rm == "ae") {
1870 // not needed when using OT1 font encoding.
1871 if (lyxrc.fontenc != "default")
1872 os << "\\usepackage{ae,aecompl}\n";
1875 else if (rm == "times") {
1876 // try to load the best available package
1877 if (LaTeXFeatures::isAvailable("mathptmx"))
1878 os << "\\usepackage{mathptmx}\n";
1879 else if (LaTeXFeatures::isAvailable("mathptm"))
1880 os << "\\usepackage{mathptm}\n";
1882 os << "\\usepackage{times}\n";
1885 else if (rm == "palatino") {
1886 // try to load the best available package
1887 if (LaTeXFeatures::isAvailable("mathpazo")) {
1888 os << "\\usepackage";
1894 // "osf" includes "sc"!
1898 os << "{mathpazo}\n";
1900 else if (LaTeXFeatures::isAvailable("mathpple"))
1901 os << "\\usepackage{mathpple}\n";
1903 os << "\\usepackage{palatino}\n";
1906 else if (rm == "utopia") {
1907 // fourier supersedes utopia.sty, but does
1908 // not work with OT1 encoding.
1909 if (LaTeXFeatures::isAvailable("fourier")
1910 && lyxrc.fontenc != "default") {
1911 os << "\\usepackage";
1922 os << "{fourier}\n";
1925 os << "\\usepackage{utopia}\n";
1927 // Bera (complete fontset)
1928 else if (rm == "bera" && sf == "default" && tt == "default")
1929 os << "\\usepackage{bera}\n";
1931 else if (rm != "default")
1932 os << "\\usepackage" << "{" << rm << "}\n";
1935 // Helvetica, Bera Sans
1936 if (sf == "helvet" || sf == "berasans") {
1938 os << "\\usepackage[scaled=" << float(sfscale) / 100
1939 << "]{" << sf << "}\n";
1941 os << "\\usepackage{" << sf << "}\n";
1944 else if (sf == "avant")
1945 os << "\\usepackage{" << sf << "}\n";
1946 // Computer Modern, Latin Modern, CM Bright
1947 else if (sf != "default")
1948 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1950 // monospaced/typewriter
1951 // Courier, LuxiMono
1952 if (tt == "luximono" || tt == "beramono") {
1954 os << "\\usepackage[scaled=" << float(ttscale) / 100
1955 << "]{" << tt << "}\n";
1957 os << "\\usepackage{" << tt << "}\n";
1960 else if (tt == "courier" )
1961 os << "\\usepackage{" << tt << "}\n";
1962 // Computer Modern, Latin Modern, CM Bright
1963 else if (tt != "default")
1964 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1970 Encoding const & BufferParams::encoding() const
1972 if (inputenc == "auto" || inputenc == "default")
1973 return *language->encoding();
1974 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
1977 LYXERR0("Unknown inputenc value `" << inputenc
1978 << "'. Using `auto' instead.");
1979 return *language->encoding();
1983 CiteEngine BufferParams::citeEngine() const
1985 // FIXME the class should provide the numerical/
1986 // authoryear choice
1987 if (documentClass().provides("natbib")
1988 && cite_engine_ != ENGINE_NATBIB_NUMERICAL)
1989 return ENGINE_NATBIB_AUTHORYEAR;
1990 return cite_engine_;
1994 void BufferParams::setCiteEngine(CiteEngine cite_engine)
1996 cite_engine_ = cite_engine;