2 * \file BufferParams.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Alfredo Braunstein
7 * \author Lars Gullik Bjønnes
8 * \author Jean-Marc Lasgouttes
10 * \author André Pönitz
11 * \author Martin Vermeer
13 * Full author contact details are available in file CREDITS.
18 #include "BufferParams.h"
21 #include "LayoutFile.h"
22 #include "BranchList.h"
23 #include "buffer_funcs.h"
28 #include "LaTeXFeatures.h"
29 #include "ModuleList.h"
33 #include "OutputParams.h"
37 #include "PDFOptions.h"
39 #include "frontends/alert.h"
41 #include "insets/InsetListingsParams.h"
43 #include "support/convert.h"
44 #include "support/debug.h"
45 #include "support/docstream.h"
46 #include "support/FileName.h"
47 #include "support/filetools.h"
48 #include "support/gettext.h"
49 #include "support/Messages.h"
50 #include "support/Translator.h"
51 #include "support/lstrings.h"
57 using namespace lyx::support;
60 static char const * const string_paragraph_separation[] = {
65 static char const * const string_quotes_language[] = {
66 "english", "swedish", "german", "polish", "french", "danish", ""
70 static char const * const string_papersize[] = {
71 "default", "custom", "letterpaper", "executivepaper", "legalpaper",
72 "a3paper", "a4paper", "a5paper", "b3paper", "b4paper", "b5paper", ""
76 static char const * const string_orientation[] = {
77 "portrait", "landscape", ""
81 static char const * const string_footnotekinds[] = {
82 "footnote", "margin", "fig", "tab", "alg", "wide-fig", "wide-tab", ""
86 static char const * const tex_graphics[] = {
87 "default", "dvips", "dvitops", "emtex",
88 "ln", "oztex", "textures", "none", ""
97 // Paragraph separation
98 typedef Translator<string, BufferParams::ParagraphSeparation> ParSepTranslator;
101 ParSepTranslator const init_parseptranslator()
103 ParSepTranslator translator
104 (string_paragraph_separation[0], BufferParams::ParagraphIndentSeparation);
105 translator.addPair(string_paragraph_separation[1], BufferParams::ParagraphSkipSeparation);
110 ParSepTranslator const & parseptranslator()
112 static ParSepTranslator translator = init_parseptranslator();
118 typedef Translator<string, InsetQuotes::QuoteLanguage> QuotesLangTranslator;
121 QuotesLangTranslator const init_quoteslangtranslator()
123 QuotesLangTranslator translator
124 (string_quotes_language[0], InsetQuotes::EnglishQuotes);
125 translator.addPair(string_quotes_language[1], InsetQuotes::SwedishQuotes);
126 translator.addPair(string_quotes_language[2], InsetQuotes::GermanQuotes);
127 translator.addPair(string_quotes_language[3], InsetQuotes::PolishQuotes);
128 translator.addPair(string_quotes_language[4], InsetQuotes::FrenchQuotes);
129 translator.addPair(string_quotes_language[5], InsetQuotes::DanishQuotes);
134 QuotesLangTranslator const & quoteslangtranslator()
136 static QuotesLangTranslator translator = init_quoteslangtranslator();
142 typedef Translator<string, PAPER_SIZE> PaperSizeTranslator;
145 static PaperSizeTranslator initPaperSizeTranslator()
147 PaperSizeTranslator translator(string_papersize[0], PAPER_DEFAULT);
148 translator.addPair(string_papersize[1], PAPER_CUSTOM);
149 translator.addPair(string_papersize[2], PAPER_USLETTER);
150 translator.addPair(string_papersize[3], PAPER_USLEGAL);
151 translator.addPair(string_papersize[4], PAPER_USEXECUTIVE);
152 translator.addPair(string_papersize[5], PAPER_A3);
153 translator.addPair(string_papersize[6], PAPER_A4);
154 translator.addPair(string_papersize[7], PAPER_A5);
155 translator.addPair(string_papersize[8], PAPER_B3);
156 translator.addPair(string_papersize[9], PAPER_B4);
157 translator.addPair(string_papersize[10], PAPER_B5);
162 PaperSizeTranslator const & papersizetranslator()
164 static PaperSizeTranslator translator = initPaperSizeTranslator();
170 typedef Translator<string, PAPER_ORIENTATION> PaperOrientationTranslator;
173 PaperOrientationTranslator const init_paperorientationtranslator()
175 PaperOrientationTranslator translator(string_orientation[0], ORIENTATION_PORTRAIT);
176 translator.addPair(string_orientation[1], ORIENTATION_LANDSCAPE);
181 PaperOrientationTranslator const & paperorientationtranslator()
183 static PaperOrientationTranslator translator = init_paperorientationtranslator();
189 typedef Translator<int, PageSides> SidesTranslator;
192 SidesTranslator const init_sidestranslator()
194 SidesTranslator translator(1, OneSide);
195 translator.addPair(2, TwoSides);
200 SidesTranslator const & sidestranslator()
202 static SidesTranslator translator = init_sidestranslator();
208 typedef Translator<int, BufferParams::Package> PackageTranslator;
211 PackageTranslator const init_packagetranslator()
213 PackageTranslator translator(0, BufferParams::package_off);
214 translator.addPair(1, BufferParams::package_auto);
215 translator.addPair(2, BufferParams::package_on);
220 PackageTranslator const & packagetranslator()
222 static PackageTranslator translator = init_packagetranslator();
228 typedef Translator<string, biblio::CiteEngine> CiteEngineTranslator;
231 CiteEngineTranslator const init_citeenginetranslator()
233 CiteEngineTranslator translator("basic", biblio::ENGINE_BASIC);
234 translator.addPair("natbib_numerical", biblio::ENGINE_NATBIB_NUMERICAL);
235 translator.addPair("natbib_authoryear", biblio::ENGINE_NATBIB_AUTHORYEAR);
236 translator.addPair("jurabib", biblio::ENGINE_JURABIB);
241 CiteEngineTranslator const & citeenginetranslator()
243 static CiteEngineTranslator translator = init_citeenginetranslator();
249 typedef Translator<string, Spacing::Space> SpaceTranslator;
252 SpaceTranslator const init_spacetranslator()
254 SpaceTranslator translator("default", Spacing::Default);
255 translator.addPair("single", Spacing::Single);
256 translator.addPair("onehalf", Spacing::Onehalf);
257 translator.addPair("double", Spacing::Double);
258 translator.addPair("other", Spacing::Other);
263 SpaceTranslator const & spacetranslator()
265 static SpaceTranslator translator = init_spacetranslator();
273 class BufferParams::Impl
278 AuthorList authorlist;
279 BranchList branchlist;
280 vector<string> extraEmbeddedFiles;
281 Bullet temp_bullets[4];
282 Bullet user_defined_bullets[4];
284 /** This is the amount of space used for paragraph_separation "skip",
285 * and for detached paragraphs in "indented" documents.
288 PDFOptions pdfoptions;
289 LayoutFileIndex baseClass_;
293 BufferParams::Impl::Impl()
294 : defskip(VSpace::MEDSKIP), baseClass_(string(""))
296 // set initial author
298 authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
303 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
307 return new BufferParams::Impl(*ptr);
311 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
317 BufferParams::BufferParams()
320 setBaseClass(defaultBaseclass());
322 paragraph_separation = ParagraphIndentSeparation;
323 quotes_language = InsetQuotes::EnglishQuotes;
324 fontsize = "default";
327 papersize = PAPER_DEFAULT;
328 orientation = ORIENTATION_PORTRAIT;
329 use_geometry = false;
330 use_amsmath = package_auto;
331 use_esint = package_auto;
332 cite_engine_ = biblio::ENGINE_BASIC;
333 use_bibtopic = false;
334 trackChanges = false;
335 outputChanges = false;
338 language = default_language;
339 fontsRoman = "default";
340 fontsSans = "default";
341 fontsTypewriter = "default";
342 fontsDefaultFamily = "default";
345 fontsSansScale = 100;
346 fontsTypewriterScale = 100;
348 graphicsDriver = "default";
351 listings_params = string();
352 pagestyle = "default";
354 embedded = lyxrc.use_bundled_format;
355 for (int iter = 0; iter < 4; ++iter) {
356 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
357 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
362 docstring BufferParams::B_(string const & l10n) const
364 LASSERT(language, /**/);
365 return getMessages(language->code()).get(l10n);
369 AuthorList & BufferParams::authors()
371 return pimpl_->authorlist;
375 AuthorList const & BufferParams::authors() const
377 return pimpl_->authorlist;
381 vector<string> & BufferParams::extraEmbeddedFiles()
383 return pimpl_->extraEmbeddedFiles;
387 vector<string> const & BufferParams::extraEmbeddedFiles() const
389 return pimpl_->extraEmbeddedFiles;
393 BranchList & BufferParams::branchlist()
395 return pimpl_->branchlist;
399 BranchList const & BufferParams::branchlist() const
401 return pimpl_->branchlist;
405 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
407 LASSERT(index < 4, /**/);
408 return pimpl_->temp_bullets[index];
412 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
414 LASSERT(index < 4, /**/);
415 return pimpl_->temp_bullets[index];
419 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
421 LASSERT(index < 4, /**/);
422 return pimpl_->user_defined_bullets[index];
426 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
428 LASSERT(index < 4, /**/);
429 return pimpl_->user_defined_bullets[index];
433 Spacing & BufferParams::spacing()
435 return pimpl_->spacing;
439 Spacing const & BufferParams::spacing() const
441 return pimpl_->spacing;
445 PDFOptions & BufferParams::pdfoptions()
447 return pimpl_->pdfoptions;
451 PDFOptions const & BufferParams::pdfoptions() const
453 return pimpl_->pdfoptions;
457 VSpace const & BufferParams::getDefSkip() const
459 return pimpl_->defskip;
463 void BufferParams::setDefSkip(VSpace const & vs)
465 pimpl_->defskip = vs;
469 string BufferParams::readToken(Lexer & lex, string const & token,
470 FileName const & filepath, FileName const & temppath)
472 if (token == "\\textclass") {
474 string const classname = lex.getString();
475 // if there exists a local layout file, ignore the system one
476 // NOTE: in this case, the textclass (.cls file) is assumed to be available.
478 LayoutFileList & bcl = LayoutFileList::get();
479 if (!temppath.empty())
480 tcp = bcl.addLayoutFile(classname, temppath.absFilename(), LayoutFileList::Embedded);
481 if (tcp.empty() && !filepath.empty())
482 tcp = bcl.addLayoutFile(classname, filepath.absFilename(), LayoutFileList::Local);
485 else if (bcl.haveClass(classname)) {
486 setBaseClass(classname);
488 // a warning will be given for unknown class
489 setBaseClass(defaultBaseclass());
492 // FIXME: this warning will be given even if there exists a local .cls
493 // file. Even worse, the .lyx file can not be compiled or exported
494 // because the textclass is marked as unavilable.
495 if (!baseClass()->isTeXClassAvailable()) {
496 docstring const msg =
497 bformat(_("The layout file requested by this document,\n"
499 "is not usable. This is probably because a LaTeX\n"
500 "class or style file required by it is not\n"
501 "available. See the Customization documentation\n"
502 "for more information.\n"), from_utf8(classname));
503 frontend::Alert::warning(_("Document class not available"),
504 msg + _("LyX will not be able to produce output."));
507 } else if (token == "\\begin_preamble") {
509 } else if (token == "\\begin_local_layout") {
510 readLocalLayout(lex);
511 } else if (token == "\\begin_modules") {
513 } else if (token == "\\options") {
515 options = lex.getString();
516 } else if (token == "\\language") {
518 } else if (token == "\\inputencoding") {
520 } else if (token == "\\graphics") {
521 readGraphicsDriver(lex);
522 } else if (token == "\\font_roman") {
524 } else if (token == "\\font_sans") {
526 } else if (token == "\\font_typewriter") {
527 lex >> fontsTypewriter;
528 } else if (token == "\\font_default_family") {
529 lex >> fontsDefaultFamily;
530 } else if (token == "\\font_sc") {
532 } else if (token == "\\font_osf") {
534 } else if (token == "\\font_sf_scale") {
535 lex >> fontsSansScale;
536 } else if (token == "\\font_tt_scale") {
537 lex >> fontsTypewriterScale;
538 } else if (token == "\\paragraph_separation") {
541 paragraph_separation = parseptranslator().find(parsep);
542 } else if (token == "\\defskip") {
544 string defskip = lex.getString();
545 if (defskip == "defskip")
548 pimpl_->defskip = VSpace(defskip);
549 } else if (token == "\\quotes_language") {
552 quotes_language = quoteslangtranslator().find(quotes_lang);
553 } else if (token == "\\papersize") {
556 papersize = papersizetranslator().find(ppsize);
557 } else if (token == "\\use_geometry") {
559 } else if (token == "\\use_amsmath") {
562 use_amsmath = packagetranslator().find(use_ams);
563 } else if (token == "\\use_esint") {
566 use_esint = packagetranslator().find(useesint);
567 } else if (token == "\\cite_engine") {
570 cite_engine_ = citeenginetranslator().find(engine);
571 } else if (token == "\\use_bibtopic") {
573 } else if (token == "\\tracking_changes") {
575 } else if (token == "\\output_changes") {
576 lex >> outputChanges;
577 } else if (token == "\\branch") {
579 docstring branch = lex.getDocString();
580 branchlist().add(branch);
583 string const tok = lex.getString();
584 if (tok == "\\end_branch")
586 Branch * branch_ptr = branchlist().find(branch);
587 if (tok == "\\selected") {
590 branch_ptr->setSelected(lex.getInteger());
592 // not yet operational
593 if (tok == "\\color") {
595 string color = lex.getString();
597 branch_ptr->setColor(color);
598 // Update also the Color table:
600 color = lcolor.getX11Name(Color_background);
602 lcolor.setColor(to_utf8(branch), color);
606 } else if (token == "\\author") {
608 istringstream ss(lex.getString());
611 author_map.push_back(pimpl_->authorlist.record(a));
612 } else if (token == "\\paperorientation") {
615 orientation = paperorientationtranslator().find(orient);
616 } else if (token == "\\paperwidth") {
618 } else if (token == "\\paperheight") {
620 } else if (token == "\\leftmargin") {
622 } else if (token == "\\topmargin") {
624 } else if (token == "\\rightmargin") {
626 } else if (token == "\\bottommargin") {
628 } else if (token == "\\headheight") {
630 } else if (token == "\\headsep") {
632 } else if (token == "\\footskip") {
634 } else if (token == "\\columnsep") {
636 } else if (token == "\\paperfontsize") {
638 } else if (token == "\\papercolumns") {
640 } else if (token == "\\listings_params") {
643 listings_params = InsetListingsParams(par).params();
644 } else if (token == "\\papersides") {
647 sides = sidestranslator().find(psides);
648 } else if (token == "\\paperpagestyle") {
650 } else if (token == "\\bullet") {
652 } else if (token == "\\bulletLaTeX") {
653 readBulletsLaTeX(lex);
654 } else if (token == "\\secnumdepth") {
656 } else if (token == "\\tocdepth") {
658 } else if (token == "\\spacing") {
662 if (nspacing == "other") {
665 spacing().set(spacetranslator().find(nspacing), tmp_val);
666 } else if (token == "\\float_placement") {
667 lex >> float_placement;
669 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
670 string toktmp = pdfoptions().readToken(lex, token);
671 if (!toktmp.empty()) {
672 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
676 } else if (token == "\\extra_embedded_files") {
677 extraEmbeddedFiles().clear();
681 par = split(par, tmp, ',');
682 while (!tmp.empty()) {
683 extraEmbeddedFiles().push_back(tmp);
684 par = split(par, tmp, ',');
687 lyxerr << "BufferParams::readToken(): Unknown token: " <<
696 void BufferParams::writeFile(ostream & os) const
698 // The top of the file is written by the buffer.
699 // Prints out the buffer info into the .lyx file given by file
702 os << "\\textclass " << baseClass()->name() << '\n';
705 if (!preamble.empty()) {
706 // remove '\n' from the end of preamble
707 string const tmppreamble = rtrim(preamble, "\n");
708 os << "\\begin_preamble\n"
710 << "\n\\end_preamble\n";
714 if (!options.empty()) {
715 os << "\\options " << options << '\n';
719 if (!layoutModules_.empty()) {
720 os << "\\begin_modules" << '\n';
721 LayoutModuleList::const_iterator it = layoutModules_.begin();
722 for (; it != layoutModules_.end(); it++)
724 os << "\\end_modules" << '\n';
727 // local layout information
728 if (!local_layout.empty()) {
729 // remove '\n' from the end
730 string const tmplocal = rtrim(local_layout, "\n");
731 os << "\\begin_local_layout\n"
733 << "\n\\end_local_layout\n";
736 // then the text parameters
737 if (language != ignore_language)
738 os << "\\language " << language->lang() << '\n';
739 os << "\\inputencoding " << inputenc
740 << "\n\\font_roman " << fontsRoman
741 << "\n\\font_sans " << fontsSans
742 << "\n\\font_typewriter " << fontsTypewriter
743 << "\n\\font_default_family " << fontsDefaultFamily
744 << "\n\\font_sc " << convert<string>(fontsSC)
745 << "\n\\font_osf " << convert<string>(fontsOSF)
746 << "\n\\font_sf_scale " << fontsSansScale
747 << "\n\\font_tt_scale " << fontsTypewriterScale
748 << "\n\\graphics " << graphicsDriver << '\n';
750 if (!float_placement.empty()) {
751 os << "\\float_placement " << float_placement << '\n';
753 os << "\\paperfontsize " << fontsize << '\n';
755 spacing().writeFile(os);
756 pdfoptions().writeFile(os);
758 os << "\\papersize " << string_papersize[papersize]
759 << "\n\\use_geometry " << convert<string>(use_geometry)
760 << "\n\\use_amsmath " << use_amsmath
761 << "\n\\use_esint " << use_esint
762 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
763 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
764 << "\n\\paperorientation " << string_orientation[orientation]
767 BranchList::const_iterator it = branchlist().begin();
768 BranchList::const_iterator end = branchlist().end();
769 for (; it != end; ++it) {
770 os << "\\branch " << to_utf8(it->getBranch())
771 << "\n\\selected " << it->getSelected()
772 << "\n\\color " << lyx::X11hexname(it->getColor())
777 if (!paperwidth.empty())
778 os << "\\paperwidth "
779 << VSpace(paperwidth).asLyXCommand() << '\n';
780 if (!paperheight.empty())
781 os << "\\paperheight "
782 << VSpace(paperheight).asLyXCommand() << '\n';
783 if (!leftmargin.empty())
784 os << "\\leftmargin "
785 << VSpace(leftmargin).asLyXCommand() << '\n';
786 if (!topmargin.empty())
788 << VSpace(topmargin).asLyXCommand() << '\n';
789 if (!rightmargin.empty())
790 os << "\\rightmargin "
791 << VSpace(rightmargin).asLyXCommand() << '\n';
792 if (!bottommargin.empty())
793 os << "\\bottommargin "
794 << VSpace(bottommargin).asLyXCommand() << '\n';
795 if (!headheight.empty())
796 os << "\\headheight "
797 << VSpace(headheight).asLyXCommand() << '\n';
798 if (!headsep.empty())
800 << VSpace(headsep).asLyXCommand() << '\n';
801 if (!footskip.empty())
803 << VSpace(footskip).asLyXCommand() << '\n';
804 if (!columnsep.empty())
806 << VSpace(columnsep).asLyXCommand() << '\n';
807 os << "\\secnumdepth " << secnumdepth
808 << "\n\\tocdepth " << tocdepth
809 << "\n\\paragraph_separation "
810 << string_paragraph_separation[paragraph_separation]
811 << "\n\\defskip " << getDefSkip().asLyXCommand()
812 << "\n\\quotes_language "
813 << string_quotes_language[quotes_language]
814 << "\n\\papercolumns " << columns
815 << "\n\\papersides " << sides
816 << "\n\\paperpagestyle " << pagestyle << '\n';
817 if (!listings_params.empty())
818 os << "\\listings_params \"" <<
819 InsetListingsParams(listings_params).encodedString() << "\"\n";
820 for (int i = 0; i < 4; ++i) {
821 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
822 if (user_defined_bullet(i).getFont() != -1) {
823 os << "\\bullet " << i << " "
824 << user_defined_bullet(i).getFont() << " "
825 << user_defined_bullet(i).getCharacter() << " "
826 << user_defined_bullet(i).getSize() << "\n";
830 os << "\\bulletLaTeX " << i << " \""
831 << lyx::to_ascii(user_defined_bullet(i).getText())
837 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
838 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
840 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
841 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
842 for (; a_it != a_end; ++a_it) {
843 if (a_it->second.used())
844 os << "\\author " << a_it->second << "\n";
846 os << "\\author " << Author() << "\n";
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 // only add \makeatletter and \makeatother when actually needed
1306 bool makeatletter = false;
1308 // Some macros LyX will need
1309 docstring tmppreamble(from_ascii(features.getMacros()));
1311 if (!tmppreamble.empty()) {
1312 if (!makeatletter) {
1313 lyxpreamble += "\n\\makeatletter\n";
1314 makeatletter = true;
1316 lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1317 "LyX specific LaTeX commands.\n"
1318 + tmppreamble + '\n';
1321 // the text class specific preamble
1322 tmppreamble = features.getTClassPreamble();
1323 if (!tmppreamble.empty()) {
1324 if (!makeatletter) {
1325 lyxpreamble += "\n\\makeatletter\n";
1326 makeatletter = true;
1328 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1329 "Textclass specific LaTeX commands.\n"
1330 + tmppreamble + '\n';
1333 /* the user-defined preamble */
1334 if (!preamble.empty()) {
1335 if (!makeatletter) {
1336 lyxpreamble += "\n\\makeatletter\n";
1337 makeatletter = true;
1340 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1341 "User specified LaTeX commands.\n"
1342 + from_utf8(preamble) + '\n';
1345 // Itemize bullet settings need to be last in case the user
1346 // defines their own bullets that use a package included
1347 // in the user-defined preamble -- ARRae
1348 // Actually it has to be done much later than that
1349 // since some packages like frenchb make modifications
1350 // at \begin{document} time -- JMarc
1351 docstring bullets_def;
1352 for (int i = 0; i < 4; ++i) {
1353 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1354 if (bullets_def.empty())
1355 bullets_def += "\\AtBeginDocument{\n";
1356 bullets_def += " \\def\\labelitemi";
1358 // `i' is one less than the item to modify
1365 bullets_def += "ii";
1371 bullets_def += '{' +
1372 user_defined_bullet(i).getText()
1377 if (!bullets_def.empty()) {
1378 if (!makeatletter) {
1379 lyxpreamble += "\n\\makeatletter\n";
1380 makeatletter = true;
1382 lyxpreamble += bullets_def + "}\n\n";
1386 lyxpreamble += "\\makeatother\n\n";
1389 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1390 for (int j = 0; j != nlines; ++j) {
1399 void BufferParams::useClassDefaults()
1401 DocumentClass const & tclass = documentClass();
1403 sides = tclass.sides();
1404 columns = tclass.columns();
1405 pagestyle = tclass.pagestyle();
1406 options = tclass.options();
1407 // Only if class has a ToC hierarchy
1408 if (tclass.hasTocLevels()) {
1409 secnumdepth = tclass.secnumdepth();
1410 tocdepth = tclass.tocdepth();
1415 bool BufferParams::hasClassDefaults() const
1417 DocumentClass const & tclass = documentClass();
1419 return sides == tclass.sides()
1420 && columns == tclass.columns()
1421 && pagestyle == tclass.pagestyle()
1422 && options == tclass.options()
1423 && secnumdepth == tclass.secnumdepth()
1424 && tocdepth == tclass.tocdepth();
1428 DocumentClass const & BufferParams::documentClass() const
1434 DocumentClass * BufferParams::documentClassPtr() const {
1439 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1440 // evil, but this function is evil
1441 doc_class_ = const_cast<DocumentClass *>(tc);
1445 bool BufferParams::setBaseClass(string const & classname)
1447 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1448 LayoutFileList const & bcl = LayoutFileList::get();
1449 if (!bcl.haveClass(classname)) {
1451 bformat(_("The document class %1$s could not be found."),
1452 from_utf8(classname));
1453 frontend::Alert::error(_("Class not found"), s);
1457 if (bcl[classname].load()) {
1458 pimpl_->baseClass_ = classname;
1463 bformat(_("The document class %1$s could not be loaded."),
1464 from_utf8(classname));
1465 frontend::Alert::error(_("Could not load class"), s);
1470 LayoutFile const * BufferParams::baseClass() const
1472 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
1473 return &(LayoutFileList::get()[pimpl_->baseClass_]);
1479 LayoutFileIndex const & BufferParams::baseClassID() const
1481 return pimpl_->baseClass_;
1485 void BufferParams::makeDocumentClass()
1490 doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass()));
1492 //FIXME It might be worth loading the children's modules here,
1493 //just as we load their bibliographies and such, instead of just
1494 //doing a check in InsetInclude.
1495 LayoutModuleList::const_iterator it = layoutModules_.begin();
1496 for (; it != layoutModules_.end(); it++) {
1497 string const modName = *it;
1498 LyXModule * lm = moduleList[modName];
1500 docstring const msg =
1501 bformat(_("The module %1$s has been requested by\n"
1502 "this document but has not been found in the list of\n"
1503 "available modules. If you recently installed it, you\n"
1504 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1505 frontend::Alert::warning(_("Module not available"),
1506 msg + _("Some layouts may not be available."));
1507 lyxerr << "BufferParams::makeDocumentClass(): Module " <<
1508 modName << " requested but not found in module list." <<
1512 if (!lm->isAvailable()) {
1513 docstring const msg =
1514 bformat(_("The module %1$s requires a package that is\n"
1515 "not available in your LaTeX installation. LaTeX output\n"
1516 "may not be possible.\n"), from_utf8(modName));
1517 frontend::Alert::warning(_("Package not available"), msg);
1519 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1520 if (!doc_class_->read(layout_file, TextClass::MODULE)) {
1521 docstring const msg =
1522 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1523 frontend::Alert::warning(_("Read Error"), msg);
1526 if (!local_layout.empty()) {
1527 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
1528 docstring const msg = _("Error reading internal layout information");
1529 frontend::Alert::warning(_("Read Error"), msg);
1535 vector<string> const & BufferParams::getModules() const
1537 return layoutModules_;
1542 bool BufferParams::addLayoutModule(string const & modName)
1544 LayoutModuleList::const_iterator it = layoutModules_.begin();
1545 LayoutModuleList::const_iterator end = layoutModules_.end();
1546 for (; it != end; it++) {
1550 if (it != layoutModules_.end())
1552 layoutModules_.push_back(modName);
1557 void BufferParams::clearLayoutModules()
1559 layoutModules_.clear();
1563 Font const BufferParams::getFont() const
1565 FontInfo f = documentClass().defaultfont();
1566 if (fontsDefaultFamily == "rmdefault")
1567 f.setFamily(ROMAN_FAMILY);
1568 else if (fontsDefaultFamily == "sfdefault")
1569 f.setFamily(SANS_FAMILY);
1570 else if (fontsDefaultFamily == "ttdefault")
1571 f.setFamily(TYPEWRITER_FAMILY);
1572 return Font(f, language);
1576 void BufferParams::readPreamble(Lexer & lex)
1578 if (lex.getString() != "\\begin_preamble")
1579 lyxerr << "Error (BufferParams::readPreamble):"
1580 "consistency check failed." << endl;
1582 preamble = lex.getLongString("\\end_preamble");
1586 void BufferParams::readLocalLayout(Lexer & lex)
1588 if (lex.getString() != "\\begin_local_layout")
1589 lyxerr << "Error (BufferParams::readLocalLayout):"
1590 "consistency check failed." << endl;
1592 local_layout = lex.getLongString("\\end_local_layout");
1596 void BufferParams::readLanguage(Lexer & lex)
1598 if (!lex.next()) return;
1600 string const tmptok = lex.getString();
1602 // check if tmptok is part of tex_babel in tex-defs.h
1603 language = languages.getLanguage(tmptok);
1605 // Language tmptok was not found
1606 language = default_language;
1607 lyxerr << "Warning: Setting language `"
1608 << tmptok << "' to `" << language->lang()
1614 void BufferParams::readGraphicsDriver(Lexer & lex)
1619 string const tmptok = lex.getString();
1620 // check if tmptok is part of tex_graphics in tex_defs.h
1623 string const test = tex_graphics[n++];
1625 if (test == tmptok) {
1626 graphicsDriver = tmptok;
1631 "Warning: graphics driver `$$Token' not recognized!\n"
1632 " Setting graphics driver to `default'.\n");
1633 graphicsDriver = "default";
1640 void BufferParams::readBullets(Lexer & lex)
1645 int const index = lex.getInteger();
1647 int temp_int = lex.getInteger();
1648 user_defined_bullet(index).setFont(temp_int);
1649 temp_bullet(index).setFont(temp_int);
1651 user_defined_bullet(index).setCharacter(temp_int);
1652 temp_bullet(index).setCharacter(temp_int);
1654 user_defined_bullet(index).setSize(temp_int);
1655 temp_bullet(index).setSize(temp_int);
1659 void BufferParams::readBulletsLaTeX(Lexer & lex)
1661 // The bullet class should be able to read this.
1664 int const index = lex.getInteger();
1666 docstring const temp_str = lex.getDocString();
1668 user_defined_bullet(index).setText(temp_str);
1669 temp_bullet(index).setText(temp_str);
1673 void BufferParams::readModules(Lexer & lex)
1675 if (!lex.eatLine()) {
1676 lyxerr << "Error (BufferParams::readModules):"
1677 "Unexpected end of input." << endl;
1681 string mod = lex.getString();
1682 if (mod == "\\end_modules")
1684 addLayoutModule(mod);
1690 string BufferParams::paperSizeName(PapersizePurpose purpose) const
1692 char real_papersize = papersize;
1693 if (real_papersize == PAPER_DEFAULT)
1694 real_papersize = lyxrc.default_papersize;
1696 switch (real_papersize) {
1698 // could be anything, so don't guess
1700 case PAPER_CUSTOM: {
1701 if (purpose == XDVI && !paperwidth.empty() &&
1702 !paperheight.empty()) {
1703 // heightxwidth<unit>
1704 string first = paperwidth;
1705 string second = paperheight;
1706 if (orientation == ORIENTATION_LANDSCAPE)
1709 return first.erase(first.length() - 2)
1721 // dvips and dvipdfm do not know this
1722 if (purpose == DVIPS || purpose == DVIPDFM)
1726 // dvipdfm does not know this
1727 if (purpose == DVIPDFM)
1731 // dvipdfm does not know this
1732 if (purpose == DVIPDFM)
1735 case PAPER_USEXECUTIVE:
1736 // dvipdfm does not know this
1737 if (purpose == DVIPDFM)
1742 case PAPER_USLETTER:
1744 if (purpose == XDVI)
1751 string const BufferParams::dvips_options() const
1756 && papersize == PAPER_CUSTOM
1757 && !lyxrc.print_paper_dimension_flag.empty()
1758 && !paperwidth.empty()
1759 && !paperheight.empty()) {
1760 // using a custom papersize
1761 result = lyxrc.print_paper_dimension_flag;
1762 result += ' ' + paperwidth;
1763 result += ',' + paperheight;
1765 string const paper_option = paperSizeName(DVIPS);
1766 if (!paper_option.empty() && (paper_option != "letter" ||
1767 orientation != ORIENTATION_LANDSCAPE)) {
1768 // dvips won't accept -t letter -t landscape.
1769 // In all other cases, include the paper size
1771 result = lyxrc.print_paper_flag;
1772 result += ' ' + paper_option;
1775 if (orientation == ORIENTATION_LANDSCAPE &&
1776 papersize != PAPER_CUSTOM)
1777 result += ' ' + lyxrc.print_landscape_flag;
1782 string BufferParams::babelCall(string const & lang_opts) const
1784 string lang_pack = lyxrc.language_package;
1785 if (lang_pack != "\\usepackage{babel}")
1787 // suppress the babel call when there is no babel language defined
1788 // for the document language in the lib/languages file and if no
1789 // other languages are used (lang_opts is then empty)
1790 if (lang_opts.empty())
1792 // when Vietnamese is used, babel must directly be loaded with the
1793 // language options, see
1794 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1795 size_t viet = lang_opts.find("vietnam");
1796 // viet = string::npos when not found
1797 // when Japanese is used, babel must directly be loaded with the
1798 // language options, see
1799 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1800 size_t japan = lang_opts.find("japanese");
1801 // japan = string::npos when not found
1802 if (!lyxrc.language_global_options || viet != string::npos || japan != string::npos)
1803 return "\\usepackage[" + lang_opts + "]{babel}";
1808 void BufferParams::writeEncodingPreamble(odocstream & os,
1809 LaTeXFeatures & features, TexRow & texrow) const
1811 if (inputenc == "auto") {
1812 string const doc_encoding =
1813 language->encoding()->latexName();
1814 Encoding::Package const package =
1815 language->encoding()->package();
1817 // Create a list with all the input encodings used
1819 set<string> encodings =
1820 features.getEncodingSet(doc_encoding);
1822 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1823 // package inputenc must be omitted. Therefore set the encoding to empty.
1824 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1825 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1826 doc_encoding == "SJIS-plain")
1829 if (!encodings.empty() || package == Encoding::inputenc) {
1830 os << "\\usepackage[";
1831 set<string>::const_iterator it = encodings.begin();
1832 set<string>::const_iterator const end = encodings.end();
1834 os << from_ascii(*it);
1837 for (; it != end; ++it)
1838 os << ',' << from_ascii(*it);
1839 if (package == Encoding::inputenc) {
1840 if (!encodings.empty())
1842 os << from_ascii(doc_encoding);
1844 os << "]{inputenc}\n";
1847 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1848 os << "\\usepackage{CJK}\n";
1851 } else if (inputenc != "default") {
1852 switch (encoding().package()) {
1853 case Encoding::none:
1855 case Encoding::inputenc:
1856 os << "\\usepackage[" << from_ascii(inputenc)
1861 os << "\\usepackage{CJK}\n";
1867 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1868 // armscii8 is used for Armenian.
1869 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1870 os << "\\usepackage{armtex}\n";
1876 string const BufferParams::loadFonts(string const & rm,
1877 string const & sf, string const & tt,
1878 bool const & sc, bool const & osf,
1879 int const & sfscale, int const & ttscale) const
1881 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1882 several packages have been replaced by others, that might not
1883 be installed on every system. We have to take care for that
1884 (see psnfss.pdf). We try to support all psnfss fonts as well
1885 as the fonts that have become de facto standard in the LaTeX
1886 world (e.g. Latin Modern). We do not support obsolete fonts
1887 (like PSLatex). In general, it should be possible to mix any
1888 rm font with any sf or tt font, respectively. (JSpitzm)
1890 -- separate math fonts.
1893 if (rm == "default" && sf == "default" && tt == "default")
1900 // Computer Modern (must be explicitely selectable -- there might be classes
1901 // that define a different default font!
1903 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1904 // osf for Computer Modern needs eco.sty
1906 os << "\\usepackage{eco}\n";
1908 // Latin Modern Roman
1909 else if (rm == "lmodern")
1910 os << "\\usepackage{lmodern}\n";
1912 else if (rm == "ae") {
1913 // not needed when using OT1 font encoding.
1914 if (lyxrc.fontenc != "default")
1915 os << "\\usepackage{ae,aecompl}\n";
1918 else if (rm == "times") {
1919 // try to load the best available package
1920 if (LaTeXFeatures::isAvailable("mathptmx"))
1921 os << "\\usepackage{mathptmx}\n";
1922 else if (LaTeXFeatures::isAvailable("mathptm"))
1923 os << "\\usepackage{mathptm}\n";
1925 os << "\\usepackage{times}\n";
1928 else if (rm == "palatino") {
1929 // try to load the best available package
1930 if (LaTeXFeatures::isAvailable("mathpazo")) {
1931 os << "\\usepackage";
1937 // "osf" includes "sc"!
1941 os << "{mathpazo}\n";
1943 else if (LaTeXFeatures::isAvailable("mathpple"))
1944 os << "\\usepackage{mathpple}\n";
1946 os << "\\usepackage{palatino}\n";
1949 else if (rm == "utopia") {
1950 // fourier supersedes utopia.sty, but does
1951 // not work with OT1 encoding.
1952 if (LaTeXFeatures::isAvailable("fourier")
1953 && lyxrc.fontenc != "default") {
1954 os << "\\usepackage";
1965 os << "{fourier}\n";
1968 os << "\\usepackage{utopia}\n";
1970 // Bera (complete fontset)
1971 else if (rm == "bera" && sf == "default" && tt == "default")
1972 os << "\\usepackage{bera}\n";
1974 else if (rm != "default")
1975 os << "\\usepackage" << "{" << rm << "}\n";
1978 // Helvetica, Bera Sans
1979 if (sf == "helvet" || sf == "berasans") {
1981 os << "\\usepackage[scaled=" << float(sfscale) / 100
1982 << "]{" << sf << "}\n";
1984 os << "\\usepackage{" << sf << "}\n";
1987 else if (sf == "avant")
1988 os << "\\usepackage{" << sf << "}\n";
1989 // Computer Modern, Latin Modern, CM Bright
1990 else if (sf != "default")
1991 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1993 // monospaced/typewriter
1994 // Courier, LuxiMono
1995 if (tt == "luximono" || tt == "beramono") {
1997 os << "\\usepackage[scaled=" << float(ttscale) / 100
1998 << "]{" << tt << "}\n";
2000 os << "\\usepackage{" << tt << "}\n";
2003 else if (tt == "courier" )
2004 os << "\\usepackage{" << tt << "}\n";
2005 // Computer Modern, Latin Modern, CM Bright
2006 else if (tt != "default")
2007 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
2013 Encoding const & BufferParams::encoding() const
2015 if (inputenc == "auto" || inputenc == "default")
2016 return *language->encoding();
2017 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
2020 LYXERR0("Unknown inputenc value `" << inputenc
2021 << "'. Using `auto' instead.");
2022 return *language->encoding();
2026 biblio::CiteEngine BufferParams::citeEngine() const
2028 // FIXME the class should provide the numerical/
2029 // authoryear choice
2030 if (documentClass().provides("natbib")
2031 && cite_engine_ != biblio::ENGINE_NATBIB_NUMERICAL)
2032 return biblio::ENGINE_NATBIB_AUTHORYEAR;
2033 return cite_engine_;
2037 void BufferParams::setCiteEngine(biblio::CiteEngine cite_engine)
2039 cite_engine_ = cite_engine;