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, biblio::CiteEngine> CiteEngineTranslator;
231 CiteEngineTranslator const init_citeenginetranslator()
233 CiteEngineTranslator translator("basic", biblio::ENGINE_BASIC);
234 translator.addPair("natbib_numerical", biblio::ENGINE_NATBIB_NUMERICAL);
235 translator.addPair("natbib_authoryear", biblio::ENGINE_NATBIB_AUTHORYEAR);
236 translator.addPair("jurabib", biblio::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 vector<string> extraEmbeddedFiles;
281 Bullet temp_bullets[4];
282 Bullet user_defined_bullets[4];
284 /** This is the amount of space used for paragraph_separation "skip",
285 * and for detached paragraphs in "indented" documents.
288 PDFOptions pdfoptions;
289 LayoutFileIndex baseClass_;
293 BufferParams::Impl::Impl()
294 : defskip(VSpace::MEDSKIP), baseClass_(string(""))
296 // set initial author
298 authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
303 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
307 return new BufferParams::Impl(*ptr);
311 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
317 BufferParams::BufferParams()
320 setBaseClass(defaultBaseclass());
322 paragraph_separation = ParagraphIndentSeparation;
323 quotes_language = InsetQuotes::EnglishQuotes;
324 fontsize = "default";
327 papersize = PAPER_DEFAULT;
328 orientation = ORIENTATION_PORTRAIT;
329 use_geometry = false;
330 use_amsmath = package_auto;
331 use_esint = package_auto;
332 cite_engine_ = biblio::ENGINE_BASIC;
333 use_bibtopic = false;
334 trackChanges = false;
335 outputChanges = false;
338 language = default_language;
339 fontsRoman = "default";
340 fontsSans = "default";
341 fontsTypewriter = "default";
342 fontsDefaultFamily = "default";
345 fontsSansScale = 100;
346 fontsTypewriterScale = 100;
348 graphicsDriver = "default";
351 listings_params = string();
352 pagestyle = "default";
354 embedded = lyxrc.use_bundled_format;
355 for (int iter = 0; iter < 4; ++iter) {
356 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
357 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
362 docstring BufferParams::B_(string const & l10n) const
364 LASSERT(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 vector<string> & BufferParams::extraEmbeddedFiles()
383 return pimpl_->extraEmbeddedFiles;
387 vector<string> const & BufferParams::extraEmbeddedFiles() const
389 return pimpl_->extraEmbeddedFiles;
393 BranchList & BufferParams::branchlist()
395 return pimpl_->branchlist;
399 BranchList const & BufferParams::branchlist() const
401 return pimpl_->branchlist;
405 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
407 LASSERT(index < 4, /**/);
408 return pimpl_->temp_bullets[index];
412 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
414 LASSERT(index < 4, /**/);
415 return pimpl_->temp_bullets[index];
419 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
421 LASSERT(index < 4, /**/);
422 return pimpl_->user_defined_bullets[index];
426 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
428 LASSERT(index < 4, /**/);
429 return pimpl_->user_defined_bullets[index];
433 Spacing & BufferParams::spacing()
435 return pimpl_->spacing;
439 Spacing const & BufferParams::spacing() const
441 return pimpl_->spacing;
445 PDFOptions & BufferParams::pdfoptions()
447 return pimpl_->pdfoptions;
451 PDFOptions const & BufferParams::pdfoptions() const
453 return pimpl_->pdfoptions;
457 VSpace const & BufferParams::getDefSkip() const
459 return pimpl_->defskip;
463 void BufferParams::setDefSkip(VSpace const & vs)
465 pimpl_->defskip = vs;
469 string BufferParams::readToken(Lexer & lex, string const & token,
470 FileName const & filepath, FileName const & temppath)
472 if (token == "\\textclass") {
474 string const classname = lex.getString();
475 // if there exists a local layout file, ignore the system one
476 // NOTE: in this case, the textclass (.cls file) is assumed to be available.
478 LayoutFileList & bcl = LayoutFileList::get();
479 if (!temppath.empty())
480 tcp = bcl.addLayoutFile(classname, temppath.absFilename(), LayoutFileList::Embedded);
481 if (tcp.empty() && !filepath.empty())
482 tcp = bcl.addLayoutFile(classname, filepath.absFilename(), LayoutFileList::Local);
485 else if (bcl.haveClass(classname)) {
486 setBaseClass(classname);
488 // a warning will be given for unknown class
489 setBaseClass(defaultBaseclass());
492 // FIXME: this warning will be given even if there exists a local .cls
493 // file. Even worse, the .lyx file can not be compiled or exported
494 // because the textclass is marked as unavilable.
495 if (!baseClass()->isTeXClassAvailable()) {
496 docstring const msg =
497 bformat(_("The layout file requested by this document,\n"
499 "is not usable. This is probably because a LaTeX\n"
500 "class or style file required by it is not\n"
501 "available. See the Customization documentation\n"
502 "for more information.\n"), from_utf8(classname));
503 frontend::Alert::warning(_("Document class not available"),
504 msg + _("LyX will not be able to produce output."));
507 } else if (token == "\\begin_preamble") {
509 } else if (token == "\\begin_local_layout") {
510 readLocalLayout(lex);
511 } else if (token == "\\begin_modules") {
513 } else if (token == "\\options") {
515 options = lex.getString();
516 } else if (token == "\\language") {
518 } else if (token == "\\inputencoding") {
520 } else if (token == "\\graphics") {
521 readGraphicsDriver(lex);
522 } else if (token == "\\font_roman") {
524 } else if (token == "\\font_sans") {
526 } else if (token == "\\font_typewriter") {
527 lex >> fontsTypewriter;
528 } else if (token == "\\font_default_family") {
529 lex >> fontsDefaultFamily;
530 } else if (token == "\\font_sc") {
532 } else if (token == "\\font_osf") {
534 } else if (token == "\\font_sf_scale") {
535 lex >> fontsSansScale;
536 } else if (token == "\\font_tt_scale") {
537 lex >> fontsTypewriterScale;
538 } else if (token == "\\paragraph_separation") {
541 paragraph_separation = parseptranslator().find(parsep);
542 } else if (token == "\\defskip") {
544 string defskip = lex.getString();
545 if (defskip == "defskip")
548 pimpl_->defskip = VSpace(defskip);
549 } else if (token == "\\quotes_language") {
552 quotes_language = quoteslangtranslator().find(quotes_lang);
553 } else if (token == "\\papersize") {
556 papersize = papersizetranslator().find(ppsize);
557 } else if (token == "\\use_geometry") {
559 } else if (token == "\\use_amsmath") {
562 use_amsmath = packagetranslator().find(use_ams);
563 } else if (token == "\\use_esint") {
566 use_esint = packagetranslator().find(useesint);
567 } else if (token == "\\cite_engine") {
570 cite_engine_ = citeenginetranslator().find(engine);
571 } else if (token == "\\use_bibtopic") {
573 } else if (token == "\\tracking_changes") {
575 } else if (token == "\\output_changes") {
576 lex >> outputChanges;
577 } else if (token == "\\branch") {
579 docstring branch = lex.getDocString();
580 branchlist().add(branch);
583 string const tok = lex.getString();
584 if (tok == "\\end_branch")
586 Branch * branch_ptr = branchlist().find(branch);
587 if (tok == "\\selected") {
590 branch_ptr->setSelected(lex.getInteger());
592 // not yet operational
593 if (tok == "\\color") {
595 string color = lex.getString();
597 branch_ptr->setColor(color);
598 // Update also the Color table:
600 color = lcolor.getX11Name(Color_background);
602 lcolor.setColor(to_utf8(branch), color);
606 } else if (token == "\\author") {
608 istringstream ss(lex.getString());
611 author_map.push_back(pimpl_->authorlist.record(a));
612 } else if (token == "\\paperorientation") {
615 orientation = paperorientationtranslator().find(orient);
616 } else if (token == "\\paperwidth") {
618 } else if (token == "\\paperheight") {
620 } else if (token == "\\leftmargin") {
622 } else if (token == "\\topmargin") {
624 } else if (token == "\\rightmargin") {
626 } else if (token == "\\bottommargin") {
628 } else if (token == "\\headheight") {
630 } else if (token == "\\headsep") {
632 } else if (token == "\\footskip") {
634 } else if (token == "\\columnsep") {
636 } else if (token == "\\paperfontsize") {
638 } else if (token == "\\papercolumns") {
640 } else if (token == "\\listings_params") {
643 listings_params = InsetListingsParams(par).params();
644 } else if (token == "\\papersides") {
647 sides = sidestranslator().find(psides);
648 } else if (token == "\\paperpagestyle") {
650 } else if (token == "\\bullet") {
652 } else if (token == "\\bulletLaTeX") {
653 readBulletsLaTeX(lex);
654 } else if (token == "\\secnumdepth") {
656 } else if (token == "\\tocdepth") {
658 } else if (token == "\\spacing") {
662 if (nspacing == "other") {
665 spacing().set(spacetranslator().find(nspacing), tmp_val);
666 } else if (token == "\\float_placement") {
667 lex >> float_placement;
669 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
670 string toktmp = pdfoptions().readToken(lex, token);
671 if (!toktmp.empty()) {
672 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
676 } else if (token == "\\extra_embedded_files") {
677 extraEmbeddedFiles().clear();
681 par = split(par, tmp, ',');
682 while (!tmp.empty()) {
683 extraEmbeddedFiles().push_back(tmp);
684 par = split(par, tmp, ',');
687 lyxerr << "BufferParams::readToken(): Unknown token: " <<
696 void BufferParams::writeFile(ostream & os) const
698 // The top of the file is written by the buffer.
699 // Prints out the buffer info into the .lyx file given by file
702 os << "\\textclass " << baseClass()->name() << '\n';
705 if (!preamble.empty()) {
706 // remove '\n' from the end of preamble
707 string const tmppreamble = rtrim(preamble, "\n");
708 os << "\\begin_preamble\n"
710 << "\n\\end_preamble\n";
714 if (!options.empty()) {
715 os << "\\options " << options << '\n';
719 if (!layoutModules_.empty()) {
720 os << "\\begin_modules" << '\n';
721 LayoutModuleList::const_iterator it = layoutModules_.begin();
722 for (; it != layoutModules_.end(); it++)
724 os << "\\end_modules" << '\n';
727 // local layout information
728 if (!local_layout.empty()) {
729 // remove '\n' from the end
730 string const tmplocal = rtrim(local_layout, "\n");
731 os << "\\begin_local_layout\n"
733 << "\n\\end_local_layout\n";
736 // then the text parameters
737 if (language != ignore_language)
738 os << "\\language " << language->lang() << '\n';
739 os << "\\inputencoding " << inputenc
740 << "\n\\font_roman " << fontsRoman
741 << "\n\\font_sans " << fontsSans
742 << "\n\\font_typewriter " << fontsTypewriter
743 << "\n\\font_default_family " << fontsDefaultFamily
744 << "\n\\font_sc " << convert<string>(fontsSC)
745 << "\n\\font_osf " << convert<string>(fontsOSF)
746 << "\n\\font_sf_scale " << fontsSansScale
747 << "\n\\font_tt_scale " << fontsTypewriterScale
748 << "\n\\graphics " << graphicsDriver << '\n';
750 if (!float_placement.empty()) {
751 os << "\\float_placement " << float_placement << '\n';
753 os << "\\paperfontsize " << fontsize << '\n';
755 spacing().writeFile(os);
756 pdfoptions().writeFile(os);
758 os << "\\papersize " << string_papersize[papersize]
759 << "\n\\use_geometry " << convert<string>(use_geometry)
760 << "\n\\use_amsmath " << use_amsmath
761 << "\n\\use_esint " << use_esint
762 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
763 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
764 << "\n\\paperorientation " << string_orientation[orientation]
767 BranchList::const_iterator it = branchlist().begin();
768 BranchList::const_iterator end = branchlist().end();
769 for (; it != end; ++it) {
770 os << "\\branch " << to_utf8(it->getBranch())
771 << "\n\\selected " << it->getSelected()
772 << "\n\\color " << lyx::X11hexname(it->getColor())
777 if (!paperwidth.empty())
778 os << "\\paperwidth "
779 << VSpace(paperwidth).asLyXCommand() << '\n';
780 if (!paperheight.empty())
781 os << "\\paperheight "
782 << VSpace(paperheight).asLyXCommand() << '\n';
783 if (!leftmargin.empty())
784 os << "\\leftmargin "
785 << VSpace(leftmargin).asLyXCommand() << '\n';
786 if (!topmargin.empty())
788 << VSpace(topmargin).asLyXCommand() << '\n';
789 if (!rightmargin.empty())
790 os << "\\rightmargin "
791 << VSpace(rightmargin).asLyXCommand() << '\n';
792 if (!bottommargin.empty())
793 os << "\\bottommargin "
794 << VSpace(bottommargin).asLyXCommand() << '\n';
795 if (!headheight.empty())
796 os << "\\headheight "
797 << VSpace(headheight).asLyXCommand() << '\n';
798 if (!headsep.empty())
800 << VSpace(headsep).asLyXCommand() << '\n';
801 if (!footskip.empty())
803 << VSpace(footskip).asLyXCommand() << '\n';
804 if (!columnsep.empty())
806 << VSpace(columnsep).asLyXCommand() << '\n';
807 os << "\\secnumdepth " << secnumdepth
808 << "\n\\tocdepth " << tocdepth
809 << "\n\\paragraph_separation "
810 << string_paragraph_separation[paragraph_separation]
811 << "\n\\defskip " << getDefSkip().asLyXCommand()
812 << "\n\\quotes_language "
813 << string_quotes_language[quotes_language]
814 << "\n\\papercolumns " << columns
815 << "\n\\papersides " << sides
816 << "\n\\paperpagestyle " << pagestyle << '\n';
817 if (!listings_params.empty())
818 os << "\\listings_params \"" <<
819 InsetListingsParams(listings_params).encodedString() << "\"\n";
820 for (int i = 0; i < 4; ++i) {
821 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
822 if (user_defined_bullet(i).getFont() != -1) {
823 os << "\\bullet " << i << " "
824 << user_defined_bullet(i).getFont() << " "
825 << user_defined_bullet(i).getCharacter() << " "
826 << user_defined_bullet(i).getSize() << "\n";
830 os << "\\bulletLaTeX " << i << " \""
831 << lyx::to_ascii(user_defined_bullet(i).getText())
837 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
838 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
840 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
841 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
842 for (; a_it != a_end; ++a_it) {
843 if (a_it->second.used())
844 os << "\\author " << a_it->second << "\n";
846 os << "\\author " << Author() << "\n";
851 void BufferParams::validate(LaTeXFeatures & features) const
853 features.require(documentClass().requires());
856 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
857 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
858 LaTeXFeatures::isAvailable("xcolor");
860 switch (features.runparams().flavor) {
861 case OutputParams::LATEX:
863 features.require("ct-dvipost");
864 features.require("dvipost");
865 } else if (xcolorsoul) {
866 features.require("ct-xcolor-soul");
867 features.require("soul");
868 features.require("xcolor");
870 features.require("ct-none");
873 case OutputParams::PDFLATEX:
875 features.require("ct-xcolor-soul");
876 features.require("soul");
877 features.require("xcolor");
878 // improves color handling in PDF output
879 features.require("pdfcolmk");
881 features.require("ct-none");
889 // Floats with 'Here definitely' as default setting.
890 if (float_placement.find('H') != string::npos)
891 features.require("float");
893 // AMS Style is at document level
894 if (use_amsmath == package_on
895 || documentClass().provides("amsmath"))
896 features.require("amsmath");
897 if (use_esint == package_on)
898 features.require("esint");
900 // Document-level line spacing
901 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
902 features.require("setspace");
904 // the bullet shapes are buffer level not paragraph level
905 // so they are tested here
906 for (int i = 0; i < 4; ++i) {
907 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
909 int const font = user_defined_bullet(i).getFont();
911 int const c = user_defined_bullet(i).getCharacter();
917 features.require("latexsym");
919 } else if (font == 1) {
920 features.require("amssymb");
921 } else if (font >= 2 && font <= 5) {
922 features.require("pifont");
926 if (pdfoptions().use_hyperref)
927 features.require("hyperref");
931 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
932 TexRow & texrow) const
934 os << "\\documentclass";
936 DocumentClass const & tclass = documentClass();
938 ostringstream clsoptions; // the document class options.
940 if (tokenPos(tclass.opt_fontsize(),
941 '|', fontsize) >= 0) {
942 // only write if existing in list (and not default)
943 clsoptions << fontsize << "pt,";
946 // custom, A3, B3 and B4 paper sizes need geometry
947 bool nonstandard_papersize = papersize == PAPER_B3
948 || papersize == PAPER_B4
949 || papersize == PAPER_A3
950 || papersize == PAPER_CUSTOM;
955 clsoptions << "a4paper,";
958 clsoptions << "letterpaper,";
961 clsoptions << "a5paper,";
964 clsoptions << "b5paper,";
966 case PAPER_USEXECUTIVE:
967 clsoptions << "executivepaper,";
970 clsoptions << "legalpaper,";
982 if (sides != tclass.sides()) {
985 clsoptions << "oneside,";
988 clsoptions << "twoside,";
994 if (columns != tclass.columns()) {
996 clsoptions << "twocolumn,";
998 clsoptions << "onecolumn,";
1002 && orientation == ORIENTATION_LANDSCAPE)
1003 clsoptions << "landscape,";
1005 // language should be a parameter to \documentclass
1006 if (language->babel() == "hebrew"
1007 && default_language->babel() != "hebrew")
1008 // This seems necessary
1009 features.useLanguage(default_language);
1011 ostringstream language_options;
1012 bool const use_babel = features.useBabel();
1014 language_options << features.getLanguages();
1015 if (!language->babel().empty()) {
1016 if (!language_options.str().empty())
1017 language_options << ',';
1018 language_options << language->babel();
1020 // when Vietnamese is used, babel must directly be loaded with the
1021 // language options, not in the class options, see
1022 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1023 size_t viet = language_options.str().find("vietnam");
1024 // viet = string::npos when not found
1025 // when Japanese is used, babel must directly be loaded with the
1026 // language options, not in the class options, see
1027 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1028 size_t japan = language_options.str().find("japanese");
1029 // japan = string::npos when not found
1030 if (lyxrc.language_global_options && !language_options.str().empty()
1031 && viet == string::npos && japan == string::npos)
1032 clsoptions << language_options.str() << ',';
1035 // the user-defined options
1036 if (!options.empty()) {
1037 clsoptions << options << ',';
1040 string strOptions(clsoptions.str());
1041 if (!strOptions.empty()) {
1042 strOptions = rtrim(strOptions, ",");
1044 os << '[' << from_utf8(strOptions) << ']';
1047 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1049 // end of \documentclass defs
1051 // font selection must be done before loading fontenc.sty
1052 string const fonts =
1053 loadFonts(fontsRoman, fontsSans,
1054 fontsTypewriter, fontsSC, fontsOSF,
1055 fontsSansScale, fontsTypewriterScale);
1056 if (!fonts.empty()) {
1057 os << from_ascii(fonts);
1060 if (fontsDefaultFamily != "default")
1061 os << "\\renewcommand{\\familydefault}{\\"
1062 << from_ascii(fontsDefaultFamily) << "}\n";
1064 // set font encoding
1065 // this one is not per buffer
1066 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1067 if (lyxrc.fontenc != "default") {
1068 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1069 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1070 << ",LFE,LAE]{fontenc}\n";
1073 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1079 // handle inputenc etc.
1080 writeEncodingPreamble(os, features, texrow);
1082 if (!listings_params.empty()) {
1083 os << "\\usepackage{listings}\n";
1086 // do not test validity because listings_params is supposed to be valid
1087 string par = InsetListingsParams(listings_params).separatedParams(true);
1088 os << from_ascii(par);
1089 // count the number of newlines
1090 for (size_t i = 0; i < par.size(); ++i)
1096 if (use_geometry || nonstandard_papersize) {
1097 os << "\\usepackage{geometry}\n";
1099 os << "\\geometry{verbose";
1100 if (orientation == ORIENTATION_LANDSCAPE)
1102 switch (papersize) {
1104 if (!paperwidth.empty())
1105 os << ",paperwidth="
1106 << from_ascii(paperwidth);
1107 if (!paperheight.empty())
1108 os << ",paperheight="
1109 << from_ascii(paperheight);
1111 case PAPER_USLETTER:
1112 os << ",letterpaper";
1115 os << ",legalpaper";
1117 case PAPER_USEXECUTIVE:
1118 os << ",executivepaper";
1139 // default papersize ie PAPER_DEFAULT
1140 switch (lyxrc.default_papersize) {
1141 case PAPER_DEFAULT: // keep compiler happy
1142 case PAPER_USLETTER:
1143 os << ",letterpaper";
1146 os << ",legalpaper";
1148 case PAPER_USEXECUTIVE:
1149 os << ",executivepaper";
1169 if (!topmargin.empty())
1170 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1171 if (!bottommargin.empty())
1172 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1173 if (!leftmargin.empty())
1174 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1175 if (!rightmargin.empty())
1176 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1177 if (!headheight.empty())
1178 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1179 if (!headsep.empty())
1180 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1181 if (!footskip.empty())
1182 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1183 if (!columnsep.empty())
1184 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1189 if (tokenPos(tclass.opt_pagestyle(),
1190 '|', pagestyle) >= 0) {
1191 if (pagestyle == "fancy") {
1192 os << "\\usepackage{fancyhdr}\n";
1195 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1199 // Only if class has a ToC hierarchy
1200 if (tclass.hasTocLevels()) {
1201 if (secnumdepth != tclass.secnumdepth()) {
1202 os << "\\setcounter{secnumdepth}{"
1207 if (tocdepth != tclass.tocdepth()) {
1208 os << "\\setcounter{tocdepth}{"
1215 if (paragraph_separation) {
1216 switch (getDefSkip().kind()) {
1217 case VSpace::SMALLSKIP:
1218 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1220 case VSpace::MEDSKIP:
1221 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1223 case VSpace::BIGSKIP:
1224 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1226 case VSpace::LENGTH:
1227 os << "\\setlength{\\parskip}{"
1228 << from_utf8(getDefSkip().length().asLatexString())
1231 default: // should never happen // Then delete it.
1232 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1237 os << "\\setlength{\\parindent}{0pt}\n";
1241 // If we use jurabib, we have to call babel here.
1242 if (use_babel && features.isRequired("jurabib")) {
1243 os << from_ascii(babelCall(language_options.str()))
1245 << from_ascii(features.getBabelOptions());
1249 // Now insert the LyX specific LaTeX commands...
1251 // The optional packages;
1252 docstring lyxpreamble(from_ascii(features.getPackages()));
1255 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1257 // We try to load babel late, in case it interferes
1258 // with other packages. But some packages also need babel to be loaded
1259 // before, e.g. jurabib has to be called after babel.
1260 // So load babel after the optional packages but before the user-defined
1261 // preamble. This allows the users to redefine babel commands, e.g. to
1262 // translate the word "Index" to the German "Stichwortverzeichnis".
1263 // For more infos why this place was chosen, see
1264 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1265 // If you encounter problems, you can shift babel to its old place behind
1266 // the user-defined preamble. But in this case you must change the Vietnamese
1267 // support from currently "\usepackage[vietnamese]{babel}" to:
1268 // \usepackage{vietnamese}
1269 // \usepackage{babel}
1270 // because vietnamese must be loaded before hyperref
1271 if (use_babel && !features.isRequired("jurabib")) {
1273 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1274 lyxpreamble += from_utf8(features.getBabelOptions());
1278 // * Hyperref manual: "Make sure it comes last of your loaded
1279 // packages, to give it a fighting chance of not being over-written,
1280 // since its job is to redefine many LATEX commands."
1281 // * Email from Heiko Oberdiek: "It is usually better to load babel
1282 // before hyperref. Then hyperref has a chance to detect babel.
1283 // * Has to be loaded before the "LyX specific LaTeX commands" to
1284 // avoid errors with algorithm floats.
1285 // use hyperref explicitely when it is required
1286 if (features.isRequired("hyperref")) {
1287 odocstringstream oss;
1288 pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
1289 lyxpreamble += oss.str();
1292 // only add \makeatletter and \makeatother when actually needed
1293 bool makeatletter = false;
1295 // Some macros LyX will need
1296 docstring tmppreamble(from_ascii(features.getMacros()));
1298 if (!tmppreamble.empty()) {
1299 if (!makeatletter) {
1300 lyxpreamble += "\n\\makeatletter\n";
1301 makeatletter = true;
1303 lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1304 "LyX specific LaTeX commands.\n"
1305 + tmppreamble + '\n';
1308 // the text class specific preamble
1309 tmppreamble = features.getTClassPreamble();
1310 if (!tmppreamble.empty()) {
1311 if (!makeatletter) {
1312 lyxpreamble += "\n\\makeatletter\n";
1313 makeatletter = true;
1315 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1316 "Textclass specific LaTeX commands.\n"
1317 + tmppreamble + '\n';
1320 /* the user-defined preamble */
1321 if (!preamble.empty()) {
1322 if (!makeatletter) {
1323 lyxpreamble += "\n\\makeatletter\n";
1324 makeatletter = true;
1327 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1328 "User specified LaTeX commands.\n"
1329 + from_utf8(preamble) + '\n';
1332 // Itemize bullet settings need to be last in case the user
1333 // defines their own bullets that use a package included
1334 // in the user-defined preamble -- ARRae
1335 // Actually it has to be done much later than that
1336 // since some packages like frenchb make modifications
1337 // at \begin{document} time -- JMarc
1338 docstring bullets_def;
1339 for (int i = 0; i < 4; ++i) {
1340 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1341 if (bullets_def.empty())
1342 bullets_def += "\\AtBeginDocument{\n";
1343 bullets_def += " \\def\\labelitemi";
1345 // `i' is one less than the item to modify
1352 bullets_def += "ii";
1358 bullets_def += '{' +
1359 user_defined_bullet(i).getText()
1364 if (!bullets_def.empty()) {
1365 if (!makeatletter) {
1366 lyxpreamble += "\n\\makeatletter\n";
1367 makeatletter = true;
1369 lyxpreamble += bullets_def + "}\n\n";
1373 lyxpreamble += "\\makeatother\n\n";
1376 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1377 for (int j = 0; j != nlines; ++j) {
1386 void BufferParams::useClassDefaults()
1388 DocumentClass const & tclass = documentClass();
1390 sides = tclass.sides();
1391 columns = tclass.columns();
1392 pagestyle = tclass.pagestyle();
1393 options = tclass.options();
1394 // Only if class has a ToC hierarchy
1395 if (tclass.hasTocLevels()) {
1396 secnumdepth = tclass.secnumdepth();
1397 tocdepth = tclass.tocdepth();
1402 bool BufferParams::hasClassDefaults() const
1404 DocumentClass const & tclass = documentClass();
1406 return sides == tclass.sides()
1407 && columns == tclass.columns()
1408 && pagestyle == tclass.pagestyle()
1409 && options == tclass.options()
1410 && secnumdepth == tclass.secnumdepth()
1411 && tocdepth == tclass.tocdepth();
1415 DocumentClass const & BufferParams::documentClass() const
1421 DocumentClass * BufferParams::documentClassPtr() const {
1426 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1427 // evil, but this function is evil
1428 doc_class_ = const_cast<DocumentClass *>(tc);
1432 bool BufferParams::setBaseClass(string const & classname)
1434 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1435 LayoutFileList const & bcl = LayoutFileList::get();
1436 if (!bcl.haveClass(classname)) {
1438 bformat(_("The document class %1$s could not be found."),
1439 from_utf8(classname));
1440 frontend::Alert::error(_("Class not found"), s);
1444 if (bcl[classname].load()) {
1445 pimpl_->baseClass_ = classname;
1450 bformat(_("The document class %1$s could not be loaded."),
1451 from_utf8(classname));
1452 frontend::Alert::error(_("Could not load class"), s);
1457 LayoutFile const * BufferParams::baseClass() const
1459 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
1460 return &(LayoutFileList::get()[pimpl_->baseClass_]);
1466 LayoutFileIndex const & BufferParams::baseClassID() const
1468 return pimpl_->baseClass_;
1472 void BufferParams::makeDocumentClass()
1477 doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass()));
1479 //FIXME It might be worth loading the children's modules here,
1480 //just as we load their bibliographies and such, instead of just
1481 //doing a check in InsetInclude.
1482 LayoutModuleList::const_iterator it = layoutModules_.begin();
1483 for (; it != layoutModules_.end(); it++) {
1484 string const modName = *it;
1485 LyXModule * lm = moduleList[modName];
1487 docstring const msg =
1488 bformat(_("The module %1$s has been requested by\n"
1489 "this document but has not been found in the list of\n"
1490 "available modules. If you recently installed it, you\n"
1491 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1492 frontend::Alert::warning(_("Module not available"),
1493 msg + _("Some layouts may not be available."));
1494 lyxerr << "BufferParams::makeDocumentClass(): Module " <<
1495 modName << " requested but not found in module list." <<
1499 if (!lm->isAvailable()) {
1500 docstring const msg =
1501 bformat(_("The module %1$s requires a package that is\n"
1502 "not available in your LaTeX installation. LaTeX output\n"
1503 "may not be possible.\n"), from_utf8(modName));
1504 frontend::Alert::warning(_("Package not available"), msg);
1506 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1507 if (!doc_class_->read(layout_file, TextClass::MODULE)) {
1508 docstring const msg =
1509 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1510 frontend::Alert::warning(_("Read Error"), msg);
1513 if (!local_layout.empty()) {
1514 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
1515 docstring const msg = _("Error reading internal layout information");
1516 frontend::Alert::warning(_("Read Error"), msg);
1522 vector<string> const & BufferParams::getModules() const
1524 return layoutModules_;
1529 bool BufferParams::addLayoutModule(string const & modName)
1531 LayoutModuleList::const_iterator it = layoutModules_.begin();
1532 LayoutModuleList::const_iterator end = layoutModules_.end();
1533 for (; it != end; it++) {
1537 if (it != layoutModules_.end())
1539 layoutModules_.push_back(modName);
1544 void BufferParams::clearLayoutModules()
1546 layoutModules_.clear();
1550 Font const BufferParams::getFont() const
1552 FontInfo f = documentClass().defaultfont();
1553 if (fontsDefaultFamily == "rmdefault")
1554 f.setFamily(ROMAN_FAMILY);
1555 else if (fontsDefaultFamily == "sfdefault")
1556 f.setFamily(SANS_FAMILY);
1557 else if (fontsDefaultFamily == "ttdefault")
1558 f.setFamily(TYPEWRITER_FAMILY);
1559 return Font(f, language);
1563 void BufferParams::readPreamble(Lexer & lex)
1565 if (lex.getString() != "\\begin_preamble")
1566 lyxerr << "Error (BufferParams::readPreamble):"
1567 "consistency check failed." << endl;
1569 preamble = lex.getLongString("\\end_preamble");
1573 void BufferParams::readLocalLayout(Lexer & lex)
1575 if (lex.getString() != "\\begin_local_layout")
1576 lyxerr << "Error (BufferParams::readLocalLayout):"
1577 "consistency check failed." << endl;
1579 local_layout = lex.getLongString("\\end_local_layout");
1583 void BufferParams::readLanguage(Lexer & lex)
1585 if (!lex.next()) return;
1587 string const tmptok = lex.getString();
1589 // check if tmptok is part of tex_babel in tex-defs.h
1590 language = languages.getLanguage(tmptok);
1592 // Language tmptok was not found
1593 language = default_language;
1594 lyxerr << "Warning: Setting language `"
1595 << tmptok << "' to `" << language->lang()
1601 void BufferParams::readGraphicsDriver(Lexer & lex)
1606 string const tmptok = lex.getString();
1607 // check if tmptok is part of tex_graphics in tex_defs.h
1610 string const test = tex_graphics[n++];
1612 if (test == tmptok) {
1613 graphicsDriver = tmptok;
1618 "Warning: graphics driver `$$Token' not recognized!\n"
1619 " Setting graphics driver to `default'.\n");
1620 graphicsDriver = "default";
1627 void BufferParams::readBullets(Lexer & lex)
1632 int const index = lex.getInteger();
1634 int temp_int = lex.getInteger();
1635 user_defined_bullet(index).setFont(temp_int);
1636 temp_bullet(index).setFont(temp_int);
1638 user_defined_bullet(index).setCharacter(temp_int);
1639 temp_bullet(index).setCharacter(temp_int);
1641 user_defined_bullet(index).setSize(temp_int);
1642 temp_bullet(index).setSize(temp_int);
1646 void BufferParams::readBulletsLaTeX(Lexer & lex)
1648 // The bullet class should be able to read this.
1651 int const index = lex.getInteger();
1653 docstring const temp_str = lex.getDocString();
1655 user_defined_bullet(index).setText(temp_str);
1656 temp_bullet(index).setText(temp_str);
1660 void BufferParams::readModules(Lexer & lex)
1662 if (!lex.eatLine()) {
1663 lyxerr << "Error (BufferParams::readModules):"
1664 "Unexpected end of input." << endl;
1668 string mod = lex.getString();
1669 if (mod == "\\end_modules")
1671 addLayoutModule(mod);
1677 string BufferParams::paperSizeName(PapersizePurpose purpose) const
1679 char real_papersize = papersize;
1680 if (real_papersize == PAPER_DEFAULT)
1681 real_papersize = lyxrc.default_papersize;
1683 switch (real_papersize) {
1685 // could be anything, so don't guess
1687 case PAPER_CUSTOM: {
1688 if (purpose == XDVI && !paperwidth.empty() &&
1689 !paperheight.empty()) {
1690 // heightxwidth<unit>
1691 string first = paperwidth;
1692 string second = paperheight;
1693 if (orientation == ORIENTATION_LANDSCAPE)
1696 return first.erase(first.length() - 2)
1708 // dvips and dvipdfm do not know this
1709 if (purpose == DVIPS || purpose == DVIPDFM)
1713 // dvipdfm does not know this
1714 if (purpose == DVIPDFM)
1718 // dvipdfm does not know this
1719 if (purpose == DVIPDFM)
1722 case PAPER_USEXECUTIVE:
1723 // dvipdfm does not know this
1724 if (purpose == DVIPDFM)
1729 case PAPER_USLETTER:
1731 if (purpose == XDVI)
1738 string const BufferParams::dvips_options() const
1743 && papersize == PAPER_CUSTOM
1744 && !lyxrc.print_paper_dimension_flag.empty()
1745 && !paperwidth.empty()
1746 && !paperheight.empty()) {
1747 // using a custom papersize
1748 result = lyxrc.print_paper_dimension_flag;
1749 result += ' ' + paperwidth;
1750 result += ',' + paperheight;
1752 string const paper_option = paperSizeName(DVIPS);
1753 if (!paper_option.empty() && (paper_option != "letter" ||
1754 orientation != ORIENTATION_LANDSCAPE)) {
1755 // dvips won't accept -t letter -t landscape.
1756 // In all other cases, include the paper size
1758 result = lyxrc.print_paper_flag;
1759 result += ' ' + paper_option;
1762 if (orientation == ORIENTATION_LANDSCAPE &&
1763 papersize != PAPER_CUSTOM)
1764 result += ' ' + lyxrc.print_landscape_flag;
1769 string BufferParams::babelCall(string const & lang_opts) const
1771 string lang_pack = lyxrc.language_package;
1772 if (lang_pack != "\\usepackage{babel}")
1774 // suppress the babel call when there is no babel language defined
1775 // for the document language in the lib/languages file and if no
1776 // other languages are used (lang_opts is then empty)
1777 if (lang_opts.empty())
1779 // when Vietnamese is used, babel must directly be loaded with the
1780 // language options, see
1781 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1782 size_t viet = lang_opts.find("vietnam");
1783 // viet = string::npos when not found
1784 // when Japanese is used, babel must directly be loaded with the
1785 // language options, see
1786 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1787 size_t japan = lang_opts.find("japanese");
1788 // japan = string::npos when not found
1789 if (!lyxrc.language_global_options || viet != string::npos || japan != string::npos)
1790 return "\\usepackage[" + lang_opts + "]{babel}";
1795 void BufferParams::writeEncodingPreamble(odocstream & os,
1796 LaTeXFeatures & features, TexRow & texrow) const
1798 if (inputenc == "auto") {
1799 string const doc_encoding =
1800 language->encoding()->latexName();
1801 Encoding::Package const package =
1802 language->encoding()->package();
1804 // Create a list with all the input encodings used
1806 set<string> encodings =
1807 features.getEncodingSet(doc_encoding);
1809 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1810 // package inputenc must be omitted. Therefore set the encoding to empty.
1811 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1812 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1813 doc_encoding == "SJIS-plain")
1816 if (!encodings.empty() || package == Encoding::inputenc) {
1817 os << "\\usepackage[";
1818 set<string>::const_iterator it = encodings.begin();
1819 set<string>::const_iterator const end = encodings.end();
1821 os << from_ascii(*it);
1824 for (; it != end; ++it)
1825 os << ',' << from_ascii(*it);
1826 if (package == Encoding::inputenc) {
1827 if (!encodings.empty())
1829 os << from_ascii(doc_encoding);
1831 os << "]{inputenc}\n";
1834 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1835 os << "\\usepackage{CJK}\n";
1838 } else if (inputenc != "default") {
1839 switch (encoding().package()) {
1840 case Encoding::none:
1842 case Encoding::inputenc:
1843 os << "\\usepackage[" << from_ascii(inputenc)
1848 os << "\\usepackage{CJK}\n";
1854 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1855 // armscii8 is used for Armenian.
1856 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1857 os << "\\usepackage{armtex}\n";
1863 string const BufferParams::loadFonts(string const & rm,
1864 string const & sf, string const & tt,
1865 bool const & sc, bool const & osf,
1866 int const & sfscale, int const & ttscale) const
1868 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1869 several packages have been replaced by others, that might not
1870 be installed on every system. We have to take care for that
1871 (see psnfss.pdf). We try to support all psnfss fonts as well
1872 as the fonts that have become de facto standard in the LaTeX
1873 world (e.g. Latin Modern). We do not support obsolete fonts
1874 (like PSLatex). In general, it should be possible to mix any
1875 rm font with any sf or tt font, respectively. (JSpitzm)
1877 -- separate math fonts.
1880 if (rm == "default" && sf == "default" && tt == "default")
1887 // Computer Modern (must be explicitely selectable -- there might be classes
1888 // that define a different default font!
1890 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1891 // osf for Computer Modern needs eco.sty
1893 os << "\\usepackage{eco}\n";
1895 // Latin Modern Roman
1896 else if (rm == "lmodern")
1897 os << "\\usepackage{lmodern}\n";
1899 else if (rm == "ae") {
1900 // not needed when using OT1 font encoding.
1901 if (lyxrc.fontenc != "default")
1902 os << "\\usepackage{ae,aecompl}\n";
1905 else if (rm == "times") {
1906 // try to load the best available package
1907 if (LaTeXFeatures::isAvailable("mathptmx"))
1908 os << "\\usepackage{mathptmx}\n";
1909 else if (LaTeXFeatures::isAvailable("mathptm"))
1910 os << "\\usepackage{mathptm}\n";
1912 os << "\\usepackage{times}\n";
1915 else if (rm == "palatino") {
1916 // try to load the best available package
1917 if (LaTeXFeatures::isAvailable("mathpazo")) {
1918 os << "\\usepackage";
1924 // "osf" includes "sc"!
1928 os << "{mathpazo}\n";
1930 else if (LaTeXFeatures::isAvailable("mathpple"))
1931 os << "\\usepackage{mathpple}\n";
1933 os << "\\usepackage{palatino}\n";
1936 else if (rm == "utopia") {
1937 // fourier supersedes utopia.sty, but does
1938 // not work with OT1 encoding.
1939 if (LaTeXFeatures::isAvailable("fourier")
1940 && lyxrc.fontenc != "default") {
1941 os << "\\usepackage";
1952 os << "{fourier}\n";
1955 os << "\\usepackage{utopia}\n";
1957 // Bera (complete fontset)
1958 else if (rm == "bera" && sf == "default" && tt == "default")
1959 os << "\\usepackage{bera}\n";
1961 else if (rm != "default")
1962 os << "\\usepackage" << "{" << rm << "}\n";
1965 // Helvetica, Bera Sans
1966 if (sf == "helvet" || sf == "berasans") {
1968 os << "\\usepackage[scaled=" << float(sfscale) / 100
1969 << "]{" << sf << "}\n";
1971 os << "\\usepackage{" << sf << "}\n";
1974 else if (sf == "avant")
1975 os << "\\usepackage{" << sf << "}\n";
1976 // Computer Modern, Latin Modern, CM Bright
1977 else if (sf != "default")
1978 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1980 // monospaced/typewriter
1981 // Courier, LuxiMono
1982 if (tt == "luximono" || tt == "beramono") {
1984 os << "\\usepackage[scaled=" << float(ttscale) / 100
1985 << "]{" << tt << "}\n";
1987 os << "\\usepackage{" << tt << "}\n";
1990 else if (tt == "courier" )
1991 os << "\\usepackage{" << tt << "}\n";
1992 // Computer Modern, Latin Modern, CM Bright
1993 else if (tt != "default")
1994 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
2000 Encoding const & BufferParams::encoding() const
2002 if (inputenc == "auto" || inputenc == "default")
2003 return *language->encoding();
2004 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
2007 LYXERR0("Unknown inputenc value `" << inputenc
2008 << "'. Using `auto' instead.");
2009 return *language->encoding();
2013 biblio::CiteEngine BufferParams::citeEngine() const
2015 // FIXME the class should provide the numerical/
2016 // authoryear choice
2017 if (documentClass().provides("natbib")
2018 && cite_engine_ != biblio::ENGINE_NATBIB_NUMERICAL)
2019 return biblio::ENGINE_NATBIB_AUTHORYEAR;
2020 return cite_engine_;
2024 void BufferParams::setCiteEngine(biblio::CiteEngine cite_engine)
2026 cite_engine_ = cite_engine;