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 if (lyxrc.language_global_options && !language_options.str().empty()
1039 && viet == string::npos)
1040 clsoptions << language_options.str() << ',';
1043 // the user-defined options
1044 if (!options.empty()) {
1045 clsoptions << options << ',';
1048 string strOptions(clsoptions.str());
1049 if (!strOptions.empty()) {
1050 strOptions = rtrim(strOptions, ",");
1052 os << '[' << from_utf8(strOptions) << ']';
1055 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1057 // end of \documentclass defs
1059 // font selection must be done before loading fontenc.sty
1060 string const fonts =
1061 loadFonts(fontsRoman, fontsSans,
1062 fontsTypewriter, fontsSC, fontsOSF,
1063 fontsSansScale, fontsTypewriterScale);
1064 if (!fonts.empty()) {
1065 os << from_ascii(fonts);
1068 if (fontsDefaultFamily != "default")
1069 os << "\\renewcommand{\\familydefault}{\\"
1070 << from_ascii(fontsDefaultFamily) << "}\n";
1072 // set font encoding
1073 // this one is not per buffer
1074 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1075 if (lyxrc.fontenc != "default") {
1076 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1077 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1078 << ",LFE,LAE]{fontenc}\n";
1081 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1087 // handle inputenc etc.
1088 writeEncodingPreamble(os, features, texrow);
1090 if (!listings_params.empty()) {
1091 os << "\\usepackage{listings}\n";
1094 // do not test validity because listings_params is supposed to be valid
1095 string par = InsetListingsParams(listings_params).separatedParams(true);
1096 os << from_ascii(par);
1097 // count the number of newlines
1098 for (size_t i = 0; i < par.size(); ++i)
1104 if (use_geometry || nonstandard_papersize) {
1105 os << "\\usepackage{geometry}\n";
1107 os << "\\geometry{verbose";
1108 if (orientation == ORIENTATION_LANDSCAPE)
1110 switch (papersize) {
1112 if (!paperwidth.empty())
1113 os << ",paperwidth="
1114 << from_ascii(paperwidth);
1115 if (!paperheight.empty())
1116 os << ",paperheight="
1117 << from_ascii(paperheight);
1119 case PAPER_USLETTER:
1120 os << ",letterpaper";
1123 os << ",legalpaper";
1125 case PAPER_USEXECUTIVE:
1126 os << ",executivepaper";
1147 // default papersize ie PAPER_DEFAULT
1148 switch (lyxrc.default_papersize) {
1149 case PAPER_DEFAULT: // keep compiler happy
1150 case PAPER_USLETTER:
1151 os << ",letterpaper";
1154 os << ",legalpaper";
1156 case PAPER_USEXECUTIVE:
1157 os << ",executivepaper";
1177 if (!topmargin.empty())
1178 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1179 if (!bottommargin.empty())
1180 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1181 if (!leftmargin.empty())
1182 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1183 if (!rightmargin.empty())
1184 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1185 if (!headheight.empty())
1186 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1187 if (!headsep.empty())
1188 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1189 if (!footskip.empty())
1190 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1191 if (!columnsep.empty())
1192 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1197 if (tokenPos(tclass.opt_pagestyle(),
1198 '|', pagestyle) >= 0) {
1199 if (pagestyle == "fancy") {
1200 os << "\\usepackage{fancyhdr}\n";
1203 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1207 // Only if class has a ToC hierarchy
1208 if (tclass.hasTocLevels()) {
1209 if (secnumdepth != tclass.secnumdepth()) {
1210 os << "\\setcounter{secnumdepth}{"
1215 if (tocdepth != tclass.tocdepth()) {
1216 os << "\\setcounter{tocdepth}{"
1223 if (paragraph_separation) {
1224 switch (getDefSkip().kind()) {
1225 case VSpace::SMALLSKIP:
1226 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1228 case VSpace::MEDSKIP:
1229 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1231 case VSpace::BIGSKIP:
1232 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1234 case VSpace::LENGTH:
1235 os << "\\setlength{\\parskip}{"
1236 << from_utf8(getDefSkip().length().asLatexString())
1239 default: // should never happen // Then delete it.
1240 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1245 os << "\\setlength{\\parindent}{0pt}\n";
1249 // If we use jurabib, we have to call babel here.
1250 if (use_babel && features.isRequired("jurabib")) {
1251 os << from_ascii(babelCall(language_options.str()))
1253 << from_ascii(features.getBabelOptions());
1257 // Now insert the LyX specific LaTeX commands...
1259 // The optional packages;
1260 docstring lyxpreamble(from_ascii(features.getPackages()));
1263 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1265 // We try to load babel late, in case it interferes
1266 // with other packages. But some packages also need babel to be loaded
1267 // before, e.g. jurabib has to be called after babel.
1268 // So load babel after the optional packages but before the user-defined
1269 // preamble. This allows the users to redefine babel commands, e.g. to
1270 // translate the word "Index" to the German "Stichwortverzeichnis".
1271 // For more infos why this place was chosen, see
1272 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1273 // If you encounter problems, you can shift babel to its old place behind
1274 // the user-defined preamble. But in this case you must change the Vietnamese
1275 // support from currently "\usepackage[vietnamese]{babel}" to:
1276 // \usepackage{vietnamese}
1277 // \usepackage{babel}
1278 // because vietnamese must be loaded before hyperref
1279 if (use_babel && !features.isRequired("jurabib")) {
1281 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1282 lyxpreamble += from_utf8(features.getBabelOptions());
1285 // When the language "japanese-plain" is used, the package "japanese" must
1286 // be loaded behind babel (it provides babel support for Japanese) but before
1288 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1289 if (language->lang() == "japanese-plain" &&
1290 !documentClass().provides("japanese")) {
1291 //load babel in case it was not loaded due to an empty language list
1292 if (language_options.str().empty())
1293 lyxpreamble += "\\usepackage{babel}\n";
1294 lyxpreamble += "\\usepackage{japanese}\n";
1298 // * Hyperref manual: "Make sure it comes last of your loaded
1299 // packages, to give it a fighting chance of not being over-written,
1300 // since its job is to redefine many LATEX commands."
1301 // * Email from Heiko Oberdiek: "It is usually better to load babel
1302 // before hyperref. Then hyperref has a chance to detect babel.
1303 // * Has to be loaded before the "LyX specific LaTeX commands" to
1304 // avoid errors with algorithm floats.
1305 // use hyperref explicitely when it is required
1306 if (features.isRequired("hyperref")) {
1307 odocstringstream oss;
1308 pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
1309 lyxpreamble += oss.str();
1312 // this might be useful...
1313 lyxpreamble += "\n\\makeatletter\n";
1315 // Some macros LyX will need
1316 docstring tmppreamble(from_ascii(features.getMacros()));
1318 if (!tmppreamble.empty()) {
1319 lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1320 "LyX specific LaTeX commands.\n"
1321 + tmppreamble + '\n';
1324 // the text class specific preamble
1325 tmppreamble = features.getTClassPreamble();
1326 if (!tmppreamble.empty()) {
1327 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1328 "Textclass specific LaTeX commands.\n"
1329 + tmppreamble + '\n';
1332 /* the user-defined preamble */
1333 if (!preamble.empty()) {
1335 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1336 "User specified LaTeX commands.\n"
1337 + from_utf8(preamble) + '\n';
1340 // Itemize bullet settings need to be last in case the user
1341 // defines their own bullets that use a package included
1342 // in the user-defined preamble -- ARRae
1343 // Actually it has to be done much later than that
1344 // since some packages like frenchb make modifications
1345 // at \begin{document} time -- JMarc
1346 docstring bullets_def;
1347 for (int i = 0; i < 4; ++i) {
1348 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1349 if (bullets_def.empty())
1350 bullets_def += "\\AtBeginDocument{\n";
1351 bullets_def += " \\def\\labelitemi";
1353 // `i' is one less than the item to modify
1360 bullets_def += "ii";
1366 bullets_def += '{' +
1367 user_defined_bullet(i).getText()
1372 if (!bullets_def.empty())
1373 lyxpreamble += bullets_def + "}\n\n";
1375 lyxpreamble += "\\makeatother\n\n";
1378 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1379 for (int j = 0; j != nlines; ++j) {
1388 void BufferParams::useClassDefaults()
1390 DocumentClass const & tclass = documentClass();
1392 sides = tclass.sides();
1393 columns = tclass.columns();
1394 pagestyle = tclass.pagestyle();
1395 options = tclass.options();
1396 // Only if class has a ToC hierarchy
1397 if (tclass.hasTocLevels()) {
1398 secnumdepth = tclass.secnumdepth();
1399 tocdepth = tclass.tocdepth();
1404 bool BufferParams::hasClassDefaults() const
1406 DocumentClass const & tclass = documentClass();
1408 return sides == tclass.sides()
1409 && columns == tclass.columns()
1410 && pagestyle == tclass.pagestyle()
1411 && options == tclass.options()
1412 && secnumdepth == tclass.secnumdepth()
1413 && tocdepth == tclass.tocdepth();
1417 DocumentClass const & BufferParams::documentClass() const
1423 DocumentClass * BufferParams::documentClassPtr() const {
1428 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1429 // evil, but this function is evil
1430 doc_class_ = const_cast<DocumentClass *>(tc);
1434 bool BufferParams::setBaseClass(string const & classname)
1436 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1437 LayoutFileList const & bcl = LayoutFileList::get();
1438 if (!bcl.haveClass(classname)) {
1440 bformat(_("The document class %1$s could not be found."),
1441 from_utf8(classname));
1442 frontend::Alert::error(_("Class not found"), s);
1446 if (bcl[classname].load()) {
1447 pimpl_->baseClass_ = classname;
1452 bformat(_("The document class %1$s could not be loaded."),
1453 from_utf8(classname));
1454 frontend::Alert::error(_("Could not load class"), s);
1459 LayoutFile const * BufferParams::baseClass() const
1461 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
1462 return &(LayoutFileList::get()[pimpl_->baseClass_]);
1468 LayoutFileIndex const & BufferParams::baseClassID() const
1470 return pimpl_->baseClass_;
1474 void BufferParams::makeDocumentClass()
1479 doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass()));
1481 //FIXME It might be worth loading the children's modules here,
1482 //just as we load their bibliographies and such, instead of just
1483 //doing a check in InsetInclude.
1484 LayoutModuleList::const_iterator it = layoutModules_.begin();
1485 for (; it != layoutModules_.end(); it++) {
1486 string const modName = *it;
1487 LyXModule * lm = moduleList[modName];
1489 docstring const msg =
1490 bformat(_("The module %1$s has been requested by\n"
1491 "this document but has not been found in the list of\n"
1492 "available modules. If you recently installed it, you\n"
1493 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1494 frontend::Alert::warning(_("Module not available"),
1495 msg + _("Some layouts may not be available."));
1496 lyxerr << "BufferParams::makeDocumentClass(): Module " <<
1497 modName << " requested but not found in module list." <<
1501 if (!lm->isAvailable()) {
1502 docstring const msg =
1503 bformat(_("The module %1$s requires a package that is\n"
1504 "not available in your LaTeX installation. LaTeX output\n"
1505 "may not be possible.\n"), from_utf8(modName));
1506 frontend::Alert::warning(_("Package not available"), msg);
1508 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1509 if (!doc_class_->read(layout_file, TextClass::MODULE)) {
1510 docstring const msg =
1511 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1512 frontend::Alert::warning(_("Read Error"), msg);
1515 if (!local_layout.empty()) {
1516 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
1517 docstring const msg = _("Error reading internal layout information");
1518 frontend::Alert::warning(_("Read Error"), msg);
1524 vector<string> const & BufferParams::getModules() const
1526 return layoutModules_;
1531 bool BufferParams::addLayoutModule(string const & modName)
1533 LayoutModuleList::const_iterator it = layoutModules_.begin();
1534 LayoutModuleList::const_iterator end = layoutModules_.end();
1535 for (; it != end; it++) {
1539 if (it != layoutModules_.end())
1541 layoutModules_.push_back(modName);
1546 void BufferParams::clearLayoutModules()
1548 layoutModules_.clear();
1552 Font const BufferParams::getFont() const
1554 FontInfo f = documentClass().defaultfont();
1555 if (fontsDefaultFamily == "rmdefault")
1556 f.setFamily(ROMAN_FAMILY);
1557 else if (fontsDefaultFamily == "sfdefault")
1558 f.setFamily(SANS_FAMILY);
1559 else if (fontsDefaultFamily == "ttdefault")
1560 f.setFamily(TYPEWRITER_FAMILY);
1561 return Font(f, language);
1565 void BufferParams::readPreamble(Lexer & lex)
1567 if (lex.getString() != "\\begin_preamble")
1568 lyxerr << "Error (BufferParams::readPreamble):"
1569 "consistency check failed." << endl;
1571 preamble = lex.getLongString("\\end_preamble");
1575 void BufferParams::readLocalLayout(Lexer & lex)
1577 if (lex.getString() != "\\begin_local_layout")
1578 lyxerr << "Error (BufferParams::readLocalLayout):"
1579 "consistency check failed." << endl;
1581 local_layout = lex.getLongString("\\end_local_layout");
1585 void BufferParams::readLanguage(Lexer & lex)
1587 if (!lex.next()) return;
1589 string const tmptok = lex.getString();
1591 // check if tmptok is part of tex_babel in tex-defs.h
1592 language = languages.getLanguage(tmptok);
1594 // Language tmptok was not found
1595 language = default_language;
1596 lyxerr << "Warning: Setting language `"
1597 << tmptok << "' to `" << language->lang()
1603 void BufferParams::readGraphicsDriver(Lexer & lex)
1608 string const tmptok = lex.getString();
1609 // check if tmptok is part of tex_graphics in tex_defs.h
1612 string const test = tex_graphics[n++];
1614 if (test == tmptok) {
1615 graphicsDriver = tmptok;
1617 } else if (test == "") {
1619 "Warning: graphics driver `$$Token' not recognized!\n"
1620 " Setting graphics driver to `default'.\n");
1621 graphicsDriver = "default";
1628 void BufferParams::readBullets(Lexer & lex)
1633 int const index = lex.getInteger();
1635 int temp_int = lex.getInteger();
1636 user_defined_bullet(index).setFont(temp_int);
1637 temp_bullet(index).setFont(temp_int);
1639 user_defined_bullet(index).setCharacter(temp_int);
1640 temp_bullet(index).setCharacter(temp_int);
1642 user_defined_bullet(index).setSize(temp_int);
1643 temp_bullet(index).setSize(temp_int);
1647 void BufferParams::readBulletsLaTeX(Lexer & lex)
1649 // The bullet class should be able to read this.
1652 int const index = lex.getInteger();
1654 docstring const temp_str = lex.getDocString();
1656 user_defined_bullet(index).setText(temp_str);
1657 temp_bullet(index).setText(temp_str);
1661 void BufferParams::readModules(Lexer & lex)
1663 if (!lex.eatLine()) {
1664 lyxerr << "Error (BufferParams::readModules):"
1665 "Unexpected end of input." << endl;
1669 string mod = lex.getString();
1670 if (mod == "\\end_modules")
1672 addLayoutModule(mod);
1678 string BufferParams::paperSizeName(PapersizePurpose purpose) const
1680 char real_papersize = papersize;
1681 if (real_papersize == PAPER_DEFAULT)
1682 real_papersize = lyxrc.default_papersize;
1684 switch (real_papersize) {
1686 // could be anything, so don't guess
1688 case PAPER_CUSTOM: {
1689 if (purpose == XDVI && !paperwidth.empty() &&
1690 !paperheight.empty()) {
1691 // heightxwidth<unit>
1692 string first = paperwidth;
1693 string second = paperheight;
1694 if (orientation == ORIENTATION_LANDSCAPE)
1697 return first.erase(first.length() - 2)
1709 // dvips and dvipdfm do not know this
1710 if (purpose == DVIPS || purpose == DVIPDFM)
1714 // dvipdfm does not know this
1715 if (purpose == DVIPDFM)
1719 // dvipdfm does not know this
1720 if (purpose == DVIPDFM)
1723 case PAPER_USEXECUTIVE:
1724 // dvipdfm does not know this
1725 if (purpose == DVIPDFM)
1730 case PAPER_USLETTER:
1732 if (purpose == XDVI)
1739 string const BufferParams::dvips_options() const
1744 && papersize == PAPER_CUSTOM
1745 && !lyxrc.print_paper_dimension_flag.empty()
1746 && !paperwidth.empty()
1747 && !paperheight.empty()) {
1748 // using a custom papersize
1749 result = lyxrc.print_paper_dimension_flag;
1750 result += ' ' + paperwidth;
1751 result += ',' + paperheight;
1753 string const paper_option = paperSizeName(DVIPS);
1754 if (!paper_option.empty() && (paper_option != "letter" ||
1755 orientation != ORIENTATION_LANDSCAPE)) {
1756 // dvips won't accept -t letter -t landscape.
1757 // In all other cases, include the paper size
1759 result = lyxrc.print_paper_flag;
1760 result += ' ' + paper_option;
1763 if (orientation == ORIENTATION_LANDSCAPE &&
1764 papersize != PAPER_CUSTOM)
1765 result += ' ' + lyxrc.print_landscape_flag;
1770 string BufferParams::babelCall(string const & lang_opts) const
1772 string lang_pack = lyxrc.language_package;
1773 if (lang_pack != "\\usepackage{babel}")
1775 // suppress the babel call when there is no babel language defined
1776 // for the document language in the lib/languages file and if no
1777 // other languages are used (lang_opts is then empty)
1778 if (lang_opts.empty())
1780 // when Vietnamese is used, babel must directly be loaded with the
1781 // language options, see
1782 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1783 size_t viet = lang_opts.find("vietnam");
1784 // viet = string::npos when not found
1785 if (!lyxrc.language_global_options || viet != string::npos)
1786 return "\\usepackage[" + lang_opts + "]{babel}";
1791 void BufferParams::writeEncodingPreamble(odocstream & os,
1792 LaTeXFeatures & features, TexRow & texrow) const
1794 if (inputenc == "auto") {
1795 string const doc_encoding =
1796 language->encoding()->latexName();
1797 Encoding::Package const package =
1798 language->encoding()->package();
1800 // Create a list with all the input encodings used
1802 set<string> encodings =
1803 features.getEncodingSet(doc_encoding);
1805 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1806 // package inputenc must be omitted. Therefore set the encoding to empty.
1807 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1808 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1809 doc_encoding == "SJIS-plain")
1812 if (!encodings.empty() || package == Encoding::inputenc) {
1813 os << "\\usepackage[";
1814 set<string>::const_iterator it = encodings.begin();
1815 set<string>::const_iterator const end = encodings.end();
1817 os << from_ascii(*it);
1820 for (; it != end; ++it)
1821 os << ',' << from_ascii(*it);
1822 if (package == Encoding::inputenc) {
1823 if (!encodings.empty())
1825 os << from_ascii(doc_encoding);
1827 os << "]{inputenc}\n";
1830 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1831 os << "\\usepackage{CJK}\n";
1834 } else if (inputenc != "default") {
1835 switch (encoding().package()) {
1836 case Encoding::none:
1838 case Encoding::inputenc:
1839 os << "\\usepackage[" << from_ascii(inputenc)
1844 os << "\\usepackage{CJK}\n";
1850 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1851 // armscii8 is used for Armenian.
1852 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1853 os << "\\usepackage{armtex}\n";
1859 string const BufferParams::loadFonts(string const & rm,
1860 string const & sf, string const & tt,
1861 bool const & sc, bool const & osf,
1862 int const & sfscale, int const & ttscale) const
1864 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1865 several packages have been replaced by others, that might not
1866 be installed on every system. We have to take care for that
1867 (see psnfss.pdf). We try to support all psnfss fonts as well
1868 as the fonts that have become de facto standard in the LaTeX
1869 world (e.g. Latin Modern). We do not support obsolete fonts
1870 (like PSLatex). In general, it should be possible to mix any
1871 rm font with any sf or tt font, respectively. (JSpitzm)
1873 -- separate math fonts.
1876 if (rm == "default" && sf == "default" && tt == "default")
1883 // Computer Modern (must be explicitely selectable -- there might be classes
1884 // that define a different default font!
1886 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1887 // osf for Computer Modern needs eco.sty
1889 os << "\\usepackage{eco}\n";
1891 // Latin Modern Roman
1892 else if (rm == "lmodern")
1893 os << "\\usepackage{lmodern}\n";
1895 else if (rm == "ae") {
1896 // not needed when using OT1 font encoding.
1897 if (lyxrc.fontenc != "default")
1898 os << "\\usepackage{ae,aecompl}\n";
1901 else if (rm == "times") {
1902 // try to load the best available package
1903 if (LaTeXFeatures::isAvailable("mathptmx"))
1904 os << "\\usepackage{mathptmx}\n";
1905 else if (LaTeXFeatures::isAvailable("mathptm"))
1906 os << "\\usepackage{mathptm}\n";
1908 os << "\\usepackage{times}\n";
1911 else if (rm == "palatino") {
1912 // try to load the best available package
1913 if (LaTeXFeatures::isAvailable("mathpazo")) {
1914 os << "\\usepackage";
1920 // "osf" includes "sc"!
1924 os << "{mathpazo}\n";
1926 else if (LaTeXFeatures::isAvailable("mathpple"))
1927 os << "\\usepackage{mathpple}\n";
1929 os << "\\usepackage{palatino}\n";
1932 else if (rm == "utopia") {
1933 // fourier supersedes utopia.sty, but does
1934 // not work with OT1 encoding.
1935 if (LaTeXFeatures::isAvailable("fourier")
1936 && lyxrc.fontenc != "default") {
1937 os << "\\usepackage";
1948 os << "{fourier}\n";
1951 os << "\\usepackage{utopia}\n";
1953 // Bera (complete fontset)
1954 else if (rm == "bera" && sf == "default" && tt == "default")
1955 os << "\\usepackage{bera}\n";
1957 else if (rm != "default")
1958 os << "\\usepackage" << "{" << rm << "}\n";
1961 // Helvetica, Bera Sans
1962 if (sf == "helvet" || sf == "berasans") {
1964 os << "\\usepackage[scaled=" << float(sfscale) / 100
1965 << "]{" << sf << "}\n";
1967 os << "\\usepackage{" << sf << "}\n";
1970 else if (sf == "avant")
1971 os << "\\usepackage{" << sf << "}\n";
1972 // Computer Modern, Latin Modern, CM Bright
1973 else if (sf != "default")
1974 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1976 // monospaced/typewriter
1977 // Courier, LuxiMono
1978 if (tt == "luximono" || tt == "beramono") {
1980 os << "\\usepackage[scaled=" << float(ttscale) / 100
1981 << "]{" << tt << "}\n";
1983 os << "\\usepackage{" << tt << "}\n";
1986 else if (tt == "courier" )
1987 os << "\\usepackage{" << tt << "}\n";
1988 // Computer Modern, Latin Modern, CM Bright
1989 else if (tt != "default")
1990 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1996 Encoding const & BufferParams::encoding() const
1998 if (inputenc == "auto" || inputenc == "default")
1999 return *language->encoding();
2000 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
2003 LYXERR0("Unknown inputenc value `" << inputenc
2004 << "'. Using `auto' instead.");
2005 return *language->encoding();
2009 biblio::CiteEngine BufferParams::citeEngine() const
2011 // FIXME the class should provide the numerical/
2012 // authoryear choice
2013 if (documentClass().provides("natbib")
2014 && cite_engine_ != biblio::ENGINE_NATBIB_NUMERICAL)
2015 return biblio::ENGINE_NATBIB_AUTHORYEAR;
2016 return cite_engine_;
2020 void BufferParams::setCiteEngine(biblio::CiteEngine cite_engine)
2022 cite_engine_ = cite_engine;