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 BOOST_ASSERT(language);
365 return getMessages(language->code()).get(l10n);
369 AuthorList & BufferParams::authors()
371 return pimpl_->authorlist;
375 AuthorList const & BufferParams::authors() const
377 return pimpl_->authorlist;
381 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 BOOST_ASSERT(index < 4);
408 return pimpl_->temp_bullets[index];
412 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
414 BOOST_ASSERT(index < 4);
415 return pimpl_->temp_bullets[index];
419 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
421 BOOST_ASSERT(index < 4);
422 return pimpl_->user_defined_bullets[index];
426 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
428 BOOST_ASSERT(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";
849 vector<string>::const_iterator e_it = extraEmbeddedFiles().begin();
850 vector<string>::const_iterator e_end = extraEmbeddedFiles().end();
851 os << "\\extra_embedded_files \"";
853 for (; e_it != e_end; ++e_it) {
864 void BufferParams::validate(LaTeXFeatures & features) const
866 features.require(documentClass().requires());
869 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
870 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
871 LaTeXFeatures::isAvailable("xcolor");
873 switch (features.runparams().flavor) {
874 case OutputParams::LATEX:
876 features.require("ct-dvipost");
877 features.require("dvipost");
878 } else if (xcolorsoul) {
879 features.require("ct-xcolor-soul");
880 features.require("soul");
881 features.require("xcolor");
883 features.require("ct-none");
886 case OutputParams::PDFLATEX:
888 features.require("ct-xcolor-soul");
889 features.require("soul");
890 features.require("xcolor");
891 // improves color handling in PDF output
892 features.require("pdfcolmk");
894 features.require("ct-none");
902 // Floats with 'Here definitely' as default setting.
903 if (float_placement.find('H') != string::npos)
904 features.require("float");
906 // AMS Style is at document level
907 if (use_amsmath == package_on
908 || documentClass().provides("amsmath"))
909 features.require("amsmath");
910 if (use_esint == package_on)
911 features.require("esint");
913 // Document-level line spacing
914 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
915 features.require("setspace");
917 // the bullet shapes are buffer level not paragraph level
918 // so they are tested here
919 for (int i = 0; i < 4; ++i) {
920 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
922 int const font = user_defined_bullet(i).getFont();
924 int const c = user_defined_bullet(i).getCharacter();
930 features.require("latexsym");
932 } else if (font == 1) {
933 features.require("amssymb");
934 } else if (font >= 2 && font <= 5) {
935 features.require("pifont");
939 if (pdfoptions().use_hyperref)
940 features.require("hyperref");
944 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
945 TexRow & texrow) const
947 os << "\\documentclass";
949 DocumentClass const & tclass = documentClass();
951 ostringstream clsoptions; // the document class options.
953 if (tokenPos(tclass.opt_fontsize(),
954 '|', fontsize) >= 0) {
955 // only write if existing in list (and not default)
956 clsoptions << fontsize << "pt,";
959 // custom, A3, B3 and B4 paper sizes need geometry
960 bool nonstandard_papersize = papersize == PAPER_B3
961 || papersize == PAPER_B4
962 || papersize == PAPER_A3
963 || papersize == PAPER_CUSTOM;
968 clsoptions << "a4paper,";
971 clsoptions << "letterpaper,";
974 clsoptions << "a5paper,";
977 clsoptions << "b5paper,";
979 case PAPER_USEXECUTIVE:
980 clsoptions << "executivepaper,";
983 clsoptions << "legalpaper,";
995 if (sides != tclass.sides()) {
998 clsoptions << "oneside,";
1001 clsoptions << "twoside,";
1007 if (columns != tclass.columns()) {
1009 clsoptions << "twocolumn,";
1011 clsoptions << "onecolumn,";
1015 && orientation == ORIENTATION_LANDSCAPE)
1016 clsoptions << "landscape,";
1018 // language should be a parameter to \documentclass
1019 if (language->babel() == "hebrew"
1020 && default_language->babel() != "hebrew")
1021 // This seems necessary
1022 features.useLanguage(default_language);
1024 ostringstream language_options;
1025 bool const use_babel = features.useBabel();
1027 language_options << features.getLanguages();
1028 if (!language->babel().empty()) {
1029 if (!language_options.str().empty())
1030 language_options << ',';
1031 language_options << language->babel();
1033 // when Vietnamese is used, babel must directly be loaded with the
1034 // language options, not in the class options, see
1035 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1036 size_t viet = language_options.str().find("vietnam");
1037 // viet = string::npos when not found
1038 // when Japanese is used, babel must directly be loaded with the
1039 // language options, not in the class options, see
1040 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1041 size_t japan = language_options.str().find("japanese");
1042 // japan = string::npos when not found
1043 if (lyxrc.language_global_options && !language_options.str().empty()
1044 && viet == string::npos && japan == string::npos)
1045 clsoptions << language_options.str() << ',';
1048 // the user-defined options
1049 if (!options.empty()) {
1050 clsoptions << options << ',';
1053 string strOptions(clsoptions.str());
1054 if (!strOptions.empty()) {
1055 strOptions = rtrim(strOptions, ",");
1057 os << '[' << from_utf8(strOptions) << ']';
1060 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1062 // end of \documentclass defs
1064 // font selection must be done before loading fontenc.sty
1065 string const fonts =
1066 loadFonts(fontsRoman, fontsSans,
1067 fontsTypewriter, fontsSC, fontsOSF,
1068 fontsSansScale, fontsTypewriterScale);
1069 if (!fonts.empty()) {
1070 os << from_ascii(fonts);
1073 if (fontsDefaultFamily != "default")
1074 os << "\\renewcommand{\\familydefault}{\\"
1075 << from_ascii(fontsDefaultFamily) << "}\n";
1077 // set font encoding
1078 // this one is not per buffer
1079 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1080 if (lyxrc.fontenc != "default") {
1081 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1082 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1083 << ",LFE,LAE]{fontenc}\n";
1086 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1092 // handle inputenc etc.
1093 writeEncodingPreamble(os, features, texrow);
1095 if (!listings_params.empty()) {
1096 os << "\\usepackage{listings}\n";
1099 // do not test validity because listings_params is supposed to be valid
1100 string par = InsetListingsParams(listings_params).separatedParams(true);
1101 os << from_ascii(par);
1102 // count the number of newlines
1103 for (size_t i = 0; i < par.size(); ++i)
1109 if (use_geometry || nonstandard_papersize) {
1110 os << "\\usepackage{geometry}\n";
1112 os << "\\geometry{verbose";
1113 if (orientation == ORIENTATION_LANDSCAPE)
1115 switch (papersize) {
1117 if (!paperwidth.empty())
1118 os << ",paperwidth="
1119 << from_ascii(paperwidth);
1120 if (!paperheight.empty())
1121 os << ",paperheight="
1122 << from_ascii(paperheight);
1124 case PAPER_USLETTER:
1125 os << ",letterpaper";
1128 os << ",legalpaper";
1130 case PAPER_USEXECUTIVE:
1131 os << ",executivepaper";
1152 // default papersize ie PAPER_DEFAULT
1153 switch (lyxrc.default_papersize) {
1154 case PAPER_DEFAULT: // keep compiler happy
1155 case PAPER_USLETTER:
1156 os << ",letterpaper";
1159 os << ",legalpaper";
1161 case PAPER_USEXECUTIVE:
1162 os << ",executivepaper";
1182 if (!topmargin.empty())
1183 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1184 if (!bottommargin.empty())
1185 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1186 if (!leftmargin.empty())
1187 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1188 if (!rightmargin.empty())
1189 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1190 if (!headheight.empty())
1191 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1192 if (!headsep.empty())
1193 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1194 if (!footskip.empty())
1195 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1196 if (!columnsep.empty())
1197 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1202 if (tokenPos(tclass.opt_pagestyle(),
1203 '|', pagestyle) >= 0) {
1204 if (pagestyle == "fancy") {
1205 os << "\\usepackage{fancyhdr}\n";
1208 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1212 // Only if class has a ToC hierarchy
1213 if (tclass.hasTocLevels()) {
1214 if (secnumdepth != tclass.secnumdepth()) {
1215 os << "\\setcounter{secnumdepth}{"
1220 if (tocdepth != tclass.tocdepth()) {
1221 os << "\\setcounter{tocdepth}{"
1228 if (paragraph_separation) {
1229 switch (getDefSkip().kind()) {
1230 case VSpace::SMALLSKIP:
1231 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1233 case VSpace::MEDSKIP:
1234 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1236 case VSpace::BIGSKIP:
1237 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1239 case VSpace::LENGTH:
1240 os << "\\setlength{\\parskip}{"
1241 << from_utf8(getDefSkip().length().asLatexString())
1244 default: // should never happen // Then delete it.
1245 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1250 os << "\\setlength{\\parindent}{0pt}\n";
1254 // If we use jurabib, we have to call babel here.
1255 if (use_babel && features.isRequired("jurabib")) {
1256 os << from_ascii(babelCall(language_options.str()))
1258 << from_ascii(features.getBabelOptions());
1262 // Now insert the LyX specific LaTeX commands...
1264 // The optional packages;
1265 docstring lyxpreamble(from_ascii(features.getPackages()));
1268 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1270 // We try to load babel late, in case it interferes
1271 // with other packages. But some packages also need babel to be loaded
1272 // before, e.g. jurabib has to be called after babel.
1273 // So load babel after the optional packages but before the user-defined
1274 // preamble. This allows the users to redefine babel commands, e.g. to
1275 // translate the word "Index" to the German "Stichwortverzeichnis".
1276 // For more infos why this place was chosen, see
1277 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1278 // If you encounter problems, you can shift babel to its old place behind
1279 // the user-defined preamble. But in this case you must change the Vietnamese
1280 // support from currently "\usepackage[vietnamese]{babel}" to:
1281 // \usepackage{vietnamese}
1282 // \usepackage{babel}
1283 // because vietnamese must be loaded before hyperref
1284 if (use_babel && !features.isRequired("jurabib")) {
1286 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1287 lyxpreamble += from_utf8(features.getBabelOptions());
1291 // * Hyperref manual: "Make sure it comes last of your loaded
1292 // packages, to give it a fighting chance of not being over-written,
1293 // since its job is to redefine many LATEX commands."
1294 // * Email from Heiko Oberdiek: "It is usually better to load babel
1295 // before hyperref. Then hyperref has a chance to detect babel.
1296 // * Has to be loaded before the "LyX specific LaTeX commands" to
1297 // avoid errors with algorithm floats.
1298 // use hyperref explicitely when it is required
1299 if (features.isRequired("hyperref")) {
1300 odocstringstream oss;
1301 pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
1302 lyxpreamble += oss.str();
1305 // this might be useful...
1306 lyxpreamble += "\n\\makeatletter\n";
1308 // Some macros LyX will need
1309 docstring tmppreamble(from_ascii(features.getMacros()));
1311 if (!tmppreamble.empty()) {
1312 lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1313 "LyX specific LaTeX commands.\n"
1314 + tmppreamble + '\n';
1317 // the text class specific preamble
1318 tmppreamble = features.getTClassPreamble();
1319 if (!tmppreamble.empty()) {
1320 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1321 "Textclass specific LaTeX commands.\n"
1322 + tmppreamble + '\n';
1325 /* the user-defined preamble */
1326 if (!preamble.empty()) {
1328 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1329 "User specified LaTeX commands.\n"
1330 + from_utf8(preamble) + '\n';
1333 // Itemize bullet settings need to be last in case the user
1334 // defines their own bullets that use a package included
1335 // in the user-defined preamble -- ARRae
1336 // Actually it has to be done much later than that
1337 // since some packages like frenchb make modifications
1338 // at \begin{document} time -- JMarc
1339 docstring bullets_def;
1340 for (int i = 0; i < 4; ++i) {
1341 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1342 if (bullets_def.empty())
1343 bullets_def += "\\AtBeginDocument{\n";
1344 bullets_def += " \\def\\labelitemi";
1346 // `i' is one less than the item to modify
1353 bullets_def += "ii";
1359 bullets_def += '{' +
1360 user_defined_bullet(i).getText()
1365 if (!bullets_def.empty())
1366 lyxpreamble += bullets_def + "}\n\n";
1368 lyxpreamble += "\\makeatother\n\n";
1371 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1372 for (int j = 0; j != nlines; ++j) {
1381 void BufferParams::useClassDefaults()
1383 DocumentClass const & tclass = documentClass();
1385 sides = tclass.sides();
1386 columns = tclass.columns();
1387 pagestyle = tclass.pagestyle();
1388 options = tclass.options();
1389 // Only if class has a ToC hierarchy
1390 if (tclass.hasTocLevels()) {
1391 secnumdepth = tclass.secnumdepth();
1392 tocdepth = tclass.tocdepth();
1397 bool BufferParams::hasClassDefaults() const
1399 DocumentClass const & tclass = documentClass();
1401 return sides == tclass.sides()
1402 && columns == tclass.columns()
1403 && pagestyle == tclass.pagestyle()
1404 && options == tclass.options()
1405 && secnumdepth == tclass.secnumdepth()
1406 && tocdepth == tclass.tocdepth();
1410 DocumentClass const & BufferParams::documentClass() const
1416 DocumentClass * BufferParams::documentClassPtr() const {
1421 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1422 // evil, but this function is evil
1423 doc_class_ = const_cast<DocumentClass *>(tc);
1427 bool BufferParams::setBaseClass(string const & classname)
1429 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1430 LayoutFileList const & bcl = LayoutFileList::get();
1431 if (!bcl.haveClass(classname)) {
1433 bformat(_("The document class %1$s could not be found."),
1434 from_utf8(classname));
1435 frontend::Alert::error(_("Class not found"), s);
1439 if (bcl[classname].load()) {
1440 pimpl_->baseClass_ = classname;
1445 bformat(_("The document class %1$s could not be loaded."),
1446 from_utf8(classname));
1447 frontend::Alert::error(_("Could not load class"), s);
1452 LayoutFile const * BufferParams::baseClass() const
1454 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
1455 return &(LayoutFileList::get()[pimpl_->baseClass_]);
1461 LayoutFileIndex const & BufferParams::baseClassID() const
1463 return pimpl_->baseClass_;
1467 void BufferParams::makeDocumentClass()
1472 doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass()));
1474 //FIXME It might be worth loading the children's modules here,
1475 //just as we load their bibliographies and such, instead of just
1476 //doing a check in InsetInclude.
1477 LayoutModuleList::const_iterator it = layoutModules_.begin();
1478 for (; it != layoutModules_.end(); it++) {
1479 string const modName = *it;
1480 LyXModule * lm = moduleList[modName];
1482 docstring const msg =
1483 bformat(_("The module %1$s has been requested by\n"
1484 "this document but has not been found in the list of\n"
1485 "available modules. If you recently installed it, you\n"
1486 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1487 frontend::Alert::warning(_("Module not available"),
1488 msg + _("Some layouts may not be available."));
1489 lyxerr << "BufferParams::makeDocumentClass(): Module " <<
1490 modName << " requested but not found in module list." <<
1494 if (!lm->isAvailable()) {
1495 docstring const msg =
1496 bformat(_("The module %1$s requires a package that is\n"
1497 "not available in your LaTeX installation. LaTeX output\n"
1498 "may not be possible.\n"), from_utf8(modName));
1499 frontend::Alert::warning(_("Package not available"), msg);
1501 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1502 if (!doc_class_->read(layout_file, TextClass::MODULE)) {
1503 docstring const msg =
1504 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1505 frontend::Alert::warning(_("Read Error"), msg);
1508 if (!local_layout.empty()) {
1509 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
1510 docstring const msg = _("Error reading internal layout information");
1511 frontend::Alert::warning(_("Read Error"), msg);
1517 vector<string> const & BufferParams::getModules() const
1519 return layoutModules_;
1524 bool BufferParams::addLayoutModule(string const & modName)
1526 LayoutModuleList::const_iterator it = layoutModules_.begin();
1527 LayoutModuleList::const_iterator end = layoutModules_.end();
1528 for (; it != end; it++) {
1532 if (it != layoutModules_.end())
1534 layoutModules_.push_back(modName);
1539 void BufferParams::clearLayoutModules()
1541 layoutModules_.clear();
1545 Font const BufferParams::getFont() const
1547 FontInfo f = documentClass().defaultfont();
1548 if (fontsDefaultFamily == "rmdefault")
1549 f.setFamily(ROMAN_FAMILY);
1550 else if (fontsDefaultFamily == "sfdefault")
1551 f.setFamily(SANS_FAMILY);
1552 else if (fontsDefaultFamily == "ttdefault")
1553 f.setFamily(TYPEWRITER_FAMILY);
1554 return Font(f, language);
1558 void BufferParams::readPreamble(Lexer & lex)
1560 if (lex.getString() != "\\begin_preamble")
1561 lyxerr << "Error (BufferParams::readPreamble):"
1562 "consistency check failed." << endl;
1564 preamble = lex.getLongString("\\end_preamble");
1568 void BufferParams::readLocalLayout(Lexer & lex)
1570 if (lex.getString() != "\\begin_local_layout")
1571 lyxerr << "Error (BufferParams::readLocalLayout):"
1572 "consistency check failed." << endl;
1574 local_layout = lex.getLongString("\\end_local_layout");
1578 void BufferParams::readLanguage(Lexer & lex)
1580 if (!lex.next()) return;
1582 string const tmptok = lex.getString();
1584 // check if tmptok is part of tex_babel in tex-defs.h
1585 language = languages.getLanguage(tmptok);
1587 // Language tmptok was not found
1588 language = default_language;
1589 lyxerr << "Warning: Setting language `"
1590 << tmptok << "' to `" << language->lang()
1596 void BufferParams::readGraphicsDriver(Lexer & lex)
1601 string const tmptok = lex.getString();
1602 // check if tmptok is part of tex_graphics in tex_defs.h
1605 string const test = tex_graphics[n++];
1607 if (test == tmptok) {
1608 graphicsDriver = tmptok;
1610 } else if (test == "") {
1612 "Warning: graphics driver `$$Token' not recognized!\n"
1613 " Setting graphics driver to `default'.\n");
1614 graphicsDriver = "default";
1621 void BufferParams::readBullets(Lexer & lex)
1626 int const index = lex.getInteger();
1628 int temp_int = lex.getInteger();
1629 user_defined_bullet(index).setFont(temp_int);
1630 temp_bullet(index).setFont(temp_int);
1632 user_defined_bullet(index).setCharacter(temp_int);
1633 temp_bullet(index).setCharacter(temp_int);
1635 user_defined_bullet(index).setSize(temp_int);
1636 temp_bullet(index).setSize(temp_int);
1640 void BufferParams::readBulletsLaTeX(Lexer & lex)
1642 // The bullet class should be able to read this.
1645 int const index = lex.getInteger();
1647 docstring const temp_str = lex.getDocString();
1649 user_defined_bullet(index).setText(temp_str);
1650 temp_bullet(index).setText(temp_str);
1654 void BufferParams::readModules(Lexer & lex)
1656 if (!lex.eatLine()) {
1657 lyxerr << "Error (BufferParams::readModules):"
1658 "Unexpected end of input." << endl;
1662 string mod = lex.getString();
1663 if (mod == "\\end_modules")
1665 addLayoutModule(mod);
1671 string BufferParams::paperSizeName(PapersizePurpose purpose) const
1673 char real_papersize = papersize;
1674 if (real_papersize == PAPER_DEFAULT)
1675 real_papersize = lyxrc.default_papersize;
1677 switch (real_papersize) {
1679 // could be anything, so don't guess
1681 case PAPER_CUSTOM: {
1682 if (purpose == XDVI && !paperwidth.empty() &&
1683 !paperheight.empty()) {
1684 // heightxwidth<unit>
1685 string first = paperwidth;
1686 string second = paperheight;
1687 if (orientation == ORIENTATION_LANDSCAPE)
1690 return first.erase(first.length() - 2)
1702 // dvips and dvipdfm do not know this
1703 if (purpose == DVIPS || purpose == DVIPDFM)
1707 // dvipdfm does not know this
1708 if (purpose == DVIPDFM)
1712 // dvipdfm does not know this
1713 if (purpose == DVIPDFM)
1716 case PAPER_USEXECUTIVE:
1717 // dvipdfm does not know this
1718 if (purpose == DVIPDFM)
1723 case PAPER_USLETTER:
1725 if (purpose == XDVI)
1732 string const BufferParams::dvips_options() const
1737 && papersize == PAPER_CUSTOM
1738 && !lyxrc.print_paper_dimension_flag.empty()
1739 && !paperwidth.empty()
1740 && !paperheight.empty()) {
1741 // using a custom papersize
1742 result = lyxrc.print_paper_dimension_flag;
1743 result += ' ' + paperwidth;
1744 result += ',' + paperheight;
1746 string const paper_option = paperSizeName(DVIPS);
1747 if (!paper_option.empty() && (paper_option != "letter" ||
1748 orientation != ORIENTATION_LANDSCAPE)) {
1749 // dvips won't accept -t letter -t landscape.
1750 // In all other cases, include the paper size
1752 result = lyxrc.print_paper_flag;
1753 result += ' ' + paper_option;
1756 if (orientation == ORIENTATION_LANDSCAPE &&
1757 papersize != PAPER_CUSTOM)
1758 result += ' ' + lyxrc.print_landscape_flag;
1763 string BufferParams::babelCall(string const & lang_opts) const
1765 string lang_pack = lyxrc.language_package;
1766 if (lang_pack != "\\usepackage{babel}")
1768 // suppress the babel call when there is no babel language defined
1769 // for the document language in the lib/languages file and if no
1770 // other languages are used (lang_opts is then empty)
1771 if (lang_opts.empty())
1773 // when Vietnamese is used, babel must directly be loaded with the
1774 // language options, see
1775 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1776 size_t viet = lang_opts.find("vietnam");
1777 // viet = string::npos when not found
1778 // when Japanese is used, babel must directly be loaded with the
1779 // language options, see
1780 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1781 size_t japan = lang_opts.find("japanese");
1782 // japan = string::npos when not found
1783 if (!lyxrc.language_global_options || viet != string::npos || japan != string::npos)
1784 return "\\usepackage[" + lang_opts + "]{babel}";
1789 void BufferParams::writeEncodingPreamble(odocstream & os,
1790 LaTeXFeatures & features, TexRow & texrow) const
1792 if (inputenc == "auto") {
1793 string const doc_encoding =
1794 language->encoding()->latexName();
1795 Encoding::Package const package =
1796 language->encoding()->package();
1798 // Create a list with all the input encodings used
1800 set<string> encodings =
1801 features.getEncodingSet(doc_encoding);
1803 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1804 // package inputenc must be omitted. Therefore set the encoding to empty.
1805 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1806 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1807 doc_encoding == "SJIS-plain")
1810 if (!encodings.empty() || package == Encoding::inputenc) {
1811 os << "\\usepackage[";
1812 set<string>::const_iterator it = encodings.begin();
1813 set<string>::const_iterator const end = encodings.end();
1815 os << from_ascii(*it);
1818 for (; it != end; ++it)
1819 os << ',' << from_ascii(*it);
1820 if (package == Encoding::inputenc) {
1821 if (!encodings.empty())
1823 os << from_ascii(doc_encoding);
1825 os << "]{inputenc}\n";
1828 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1829 os << "\\usepackage{CJK}\n";
1832 } else if (inputenc != "default") {
1833 switch (encoding().package()) {
1834 case Encoding::none:
1836 case Encoding::inputenc:
1837 os << "\\usepackage[" << from_ascii(inputenc)
1842 os << "\\usepackage{CJK}\n";
1848 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1849 // armscii8 is used for Armenian.
1850 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1851 os << "\\usepackage{armtex}\n";
1857 string const BufferParams::loadFonts(string const & rm,
1858 string const & sf, string const & tt,
1859 bool const & sc, bool const & osf,
1860 int const & sfscale, int const & ttscale) const
1862 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1863 several packages have been replaced by others, that might not
1864 be installed on every system. We have to take care for that
1865 (see psnfss.pdf). We try to support all psnfss fonts as well
1866 as the fonts that have become de facto standard in the LaTeX
1867 world (e.g. Latin Modern). We do not support obsolete fonts
1868 (like PSLatex). In general, it should be possible to mix any
1869 rm font with any sf or tt font, respectively. (JSpitzm)
1871 -- separate math fonts.
1874 if (rm == "default" && sf == "default" && tt == "default")
1881 // Computer Modern (must be explicitely selectable -- there might be classes
1882 // that define a different default font!
1884 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1885 // osf for Computer Modern needs eco.sty
1887 os << "\\usepackage{eco}\n";
1889 // Latin Modern Roman
1890 else if (rm == "lmodern")
1891 os << "\\usepackage{lmodern}\n";
1893 else if (rm == "ae") {
1894 // not needed when using OT1 font encoding.
1895 if (lyxrc.fontenc != "default")
1896 os << "\\usepackage{ae,aecompl}\n";
1899 else if (rm == "times") {
1900 // try to load the best available package
1901 if (LaTeXFeatures::isAvailable("mathptmx"))
1902 os << "\\usepackage{mathptmx}\n";
1903 else if (LaTeXFeatures::isAvailable("mathptm"))
1904 os << "\\usepackage{mathptm}\n";
1906 os << "\\usepackage{times}\n";
1909 else if (rm == "palatino") {
1910 // try to load the best available package
1911 if (LaTeXFeatures::isAvailable("mathpazo")) {
1912 os << "\\usepackage";
1918 // "osf" includes "sc"!
1922 os << "{mathpazo}\n";
1924 else if (LaTeXFeatures::isAvailable("mathpple"))
1925 os << "\\usepackage{mathpple}\n";
1927 os << "\\usepackage{palatino}\n";
1930 else if (rm == "utopia") {
1931 // fourier supersedes utopia.sty, but does
1932 // not work with OT1 encoding.
1933 if (LaTeXFeatures::isAvailable("fourier")
1934 && lyxrc.fontenc != "default") {
1935 os << "\\usepackage";
1946 os << "{fourier}\n";
1949 os << "\\usepackage{utopia}\n";
1951 // Bera (complete fontset)
1952 else if (rm == "bera" && sf == "default" && tt == "default")
1953 os << "\\usepackage{bera}\n";
1955 else if (rm != "default")
1956 os << "\\usepackage" << "{" << rm << "}\n";
1959 // Helvetica, Bera Sans
1960 if (sf == "helvet" || sf == "berasans") {
1962 os << "\\usepackage[scaled=" << float(sfscale) / 100
1963 << "]{" << sf << "}\n";
1965 os << "\\usepackage{" << sf << "}\n";
1968 else if (sf == "avant")
1969 os << "\\usepackage{" << sf << "}\n";
1970 // Computer Modern, Latin Modern, CM Bright
1971 else if (sf != "default")
1972 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1974 // monospaced/typewriter
1975 // Courier, LuxiMono
1976 if (tt == "luximono" || tt == "beramono") {
1978 os << "\\usepackage[scaled=" << float(ttscale) / 100
1979 << "]{" << tt << "}\n";
1981 os << "\\usepackage{" << tt << "}\n";
1984 else if (tt == "courier" )
1985 os << "\\usepackage{" << tt << "}\n";
1986 // Computer Modern, Latin Modern, CM Bright
1987 else if (tt != "default")
1988 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1994 Encoding const & BufferParams::encoding() const
1996 if (inputenc == "auto" || inputenc == "default")
1997 return *language->encoding();
1998 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
2001 LYXERR0("Unknown inputenc value `" << inputenc
2002 << "'. Using `auto' instead.");
2003 return *language->encoding();
2007 biblio::CiteEngine BufferParams::citeEngine() const
2009 // FIXME the class should provide the numerical/
2010 // authoryear choice
2011 if (documentClass().provides("natbib")
2012 && cite_engine_ != biblio::ENGINE_NATBIB_NUMERICAL)
2013 return biblio::ENGINE_NATBIB_AUTHORYEAR;
2014 return cite_engine_;
2018 void BufferParams::setCiteEngine(biblio::CiteEngine cite_engine)
2020 cite_engine_ = cite_engine;