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::PARSEP> ParSepTranslator;
101 ParSepTranslator const init_parseptranslator()
103 ParSepTranslator translator(string_paragraph_separation[0], BufferParams::PARSEP_INDENT);
104 translator.addPair(string_paragraph_separation[1], BufferParams::PARSEP_SKIP);
109 ParSepTranslator const & parseptranslator()
111 static ParSepTranslator translator = init_parseptranslator();
117 typedef Translator<string, InsetQuotes::quote_language> QuotesLangTranslator;
120 QuotesLangTranslator const init_quoteslangtranslator()
122 QuotesLangTranslator translator(string_quotes_language[0], InsetQuotes::EnglishQ);
123 translator.addPair(string_quotes_language[1], InsetQuotes::SwedishQ);
124 translator.addPair(string_quotes_language[2], InsetQuotes::GermanQ);
125 translator.addPair(string_quotes_language[3], InsetQuotes::PolishQ);
126 translator.addPair(string_quotes_language[4], InsetQuotes::FrenchQ);
127 translator.addPair(string_quotes_language[5], InsetQuotes::DanishQ);
132 QuotesLangTranslator const & quoteslangtranslator()
134 static QuotesLangTranslator translator = init_quoteslangtranslator();
140 typedef Translator<string, PAPER_SIZE> PaperSizeTranslator;
143 PaperSizeTranslator const init_papersizetranslator()
145 PaperSizeTranslator translator(string_papersize[0], PAPER_DEFAULT);
146 translator.addPair(string_papersize[1], PAPER_CUSTOM);
147 translator.addPair(string_papersize[2], PAPER_USLETTER);
148 translator.addPair(string_papersize[3], PAPER_USLEGAL);
149 translator.addPair(string_papersize[4], PAPER_USEXECUTIVE);
150 translator.addPair(string_papersize[5], PAPER_A3);
151 translator.addPair(string_papersize[6], PAPER_A4);
152 translator.addPair(string_papersize[7], PAPER_A5);
153 translator.addPair(string_papersize[8], PAPER_B3);
154 translator.addPair(string_papersize[9], PAPER_B4);
155 translator.addPair(string_papersize[10], PAPER_B5);
160 PaperSizeTranslator const & papersizetranslator()
162 static PaperSizeTranslator translator = init_papersizetranslator();
168 typedef Translator<string, PAPER_ORIENTATION> PaperOrientationTranslator;
171 PaperOrientationTranslator const init_paperorientationtranslator()
173 PaperOrientationTranslator translator(string_orientation[0], ORIENTATION_PORTRAIT);
174 translator.addPair(string_orientation[1], ORIENTATION_LANDSCAPE);
179 PaperOrientationTranslator const & paperorientationtranslator()
181 static PaperOrientationTranslator translator = init_paperorientationtranslator();
187 typedef Translator<int, PageSides> SidesTranslator;
190 SidesTranslator const init_sidestranslator()
192 SidesTranslator translator(1, OneSide);
193 translator.addPair(2, TwoSides);
198 SidesTranslator const & sidestranslator()
200 static SidesTranslator translator = init_sidestranslator();
206 typedef Translator<int, BufferParams::Package> PackageTranslator;
209 PackageTranslator const init_packagetranslator()
211 PackageTranslator translator(0, BufferParams::package_off);
212 translator.addPair(1, BufferParams::package_auto);
213 translator.addPair(2, BufferParams::package_on);
218 PackageTranslator const & packagetranslator()
220 static PackageTranslator translator = init_packagetranslator();
226 typedef Translator<string, biblio::CiteEngine> CiteEngineTranslator;
229 CiteEngineTranslator const init_citeenginetranslator()
231 CiteEngineTranslator translator("basic", biblio::ENGINE_BASIC);
232 translator.addPair("natbib_numerical", biblio::ENGINE_NATBIB_NUMERICAL);
233 translator.addPair("natbib_authoryear", biblio::ENGINE_NATBIB_AUTHORYEAR);
234 translator.addPair("jurabib", biblio::ENGINE_JURABIB);
239 CiteEngineTranslator const & citeenginetranslator()
241 static CiteEngineTranslator translator = init_citeenginetranslator();
247 typedef Translator<string, Spacing::Space> SpaceTranslator;
250 SpaceTranslator const init_spacetranslator()
252 SpaceTranslator translator("default", Spacing::Default);
253 translator.addPair("single", Spacing::Single);
254 translator.addPair("onehalf", Spacing::Onehalf);
255 translator.addPair("double", Spacing::Double);
256 translator.addPair("other", Spacing::Other);
261 SpaceTranslator const & spacetranslator()
263 static SpaceTranslator translator = init_spacetranslator();
271 class BufferParams::Impl
276 AuthorList authorlist;
277 BranchList branchlist;
278 vector<string> extraEmbeddedFiles;
279 Bullet temp_bullets[4];
280 Bullet user_defined_bullets[4];
282 /** This is the amount of space used for paragraph_separation "skip",
283 * and for detached paragraphs in "indented" documents.
286 PDFOptions pdfoptions;
287 LayoutFileIndex baseClass_;
291 BufferParams::Impl::Impl()
292 : defskip(VSpace::MEDSKIP), baseClass_(string(""))
294 // set initial author
296 authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
301 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
305 return new BufferParams::Impl(*ptr);
309 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
315 BufferParams::BufferParams()
318 setBaseClass(defaultBaseclass());
320 paragraph_separation = PARSEP_INDENT;
321 quotes_language = InsetQuotes::EnglishQ;
322 fontsize = "default";
325 papersize = PAPER_DEFAULT;
326 orientation = ORIENTATION_PORTRAIT;
327 use_geometry = false;
328 use_amsmath = package_auto;
329 use_esint = package_auto;
330 cite_engine_ = biblio::ENGINE_BASIC;
331 use_bibtopic = false;
332 trackChanges = false;
333 outputChanges = false;
336 language = default_language;
337 fontsRoman = "default";
338 fontsSans = "default";
339 fontsTypewriter = "default";
340 fontsDefaultFamily = "default";
343 fontsSansScale = 100;
344 fontsTypewriterScale = 100;
346 graphicsDriver = "default";
349 listings_params = string();
350 pagestyle = "default";
353 for (int iter = 0; iter < 4; ++iter) {
354 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
355 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
360 BufferParams::~BufferParams()
364 docstring const BufferParams::B_(string const & l10n) const
366 BOOST_ASSERT(language);
367 return getMessages(language->code()).get(l10n);
371 AuthorList & BufferParams::authors()
373 return pimpl_->authorlist;
377 AuthorList const & BufferParams::authors() const
379 return pimpl_->authorlist;
383 vector<string> & BufferParams::extraEmbeddedFiles()
385 return pimpl_->extraEmbeddedFiles;
389 vector<string> const & BufferParams::extraEmbeddedFiles() const
391 return pimpl_->extraEmbeddedFiles;
395 BranchList & BufferParams::branchlist()
397 return pimpl_->branchlist;
401 BranchList const & BufferParams::branchlist() const
403 return pimpl_->branchlist;
407 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
409 BOOST_ASSERT(index < 4);
410 return pimpl_->temp_bullets[index];
414 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
416 BOOST_ASSERT(index < 4);
417 return pimpl_->temp_bullets[index];
421 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
423 BOOST_ASSERT(index < 4);
424 return pimpl_->user_defined_bullets[index];
428 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
430 BOOST_ASSERT(index < 4);
431 return pimpl_->user_defined_bullets[index];
435 Spacing & BufferParams::spacing()
437 return pimpl_->spacing;
441 Spacing const & BufferParams::spacing() const
443 return pimpl_->spacing;
447 PDFOptions & BufferParams::pdfoptions()
449 return pimpl_->pdfoptions;
453 PDFOptions const & BufferParams::pdfoptions() const
455 return pimpl_->pdfoptions;
459 VSpace const & BufferParams::getDefSkip() const
461 return pimpl_->defskip;
465 void BufferParams::setDefSkip(VSpace const & vs)
467 pimpl_->defskip = vs;
471 string const BufferParams::readToken(Lexer & lex, string const & token,
472 FileName const & filepath, FileName const & temppath)
474 if (token == "\\textclass") {
476 string const classname = lex.getString();
477 // if there exists a local layout file, ignore the system one
478 // NOTE: in this case, the textclass (.cls file) is assumed to be available.
480 LayoutFileList & bcl = LayoutFileList::get();
481 if (!temppath.empty())
482 tcp = bcl.addLayoutFile(classname, temppath.absFilename(), LayoutFileList::Embedded);
483 if (tcp.empty() && !filepath.empty())
484 tcp = bcl.addLayoutFile(classname, filepath.absFilename(), LayoutFileList::Local);
487 else if (bcl.haveClass(classname)) {
488 setBaseClass(classname);
490 // a warning will be given for unknown class
491 setBaseClass(defaultBaseclass());
494 // FIXME: this warning will be given even if there exists a local .cls
495 // file. Even worse, the .lyx file can not be compiled or exported
496 // because the textclass is marked as unavilable.
497 if (!baseClass()->isTeXClassAvailable()) {
498 docstring const msg =
499 bformat(_("The layout file requested by this document,\n"
501 "is not usable. This is probably because a LaTeX\n"
502 "class or style file required by it is not\n"
503 "available. See the Customization documentation\n"
504 "for more information.\n"), from_utf8(classname));
505 frontend::Alert::warning(_("Document class not available"),
506 msg + _("LyX will not be able to produce output."));
509 } else if (token == "\\begin_preamble") {
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 // then the text parameters
728 if (language != ignore_language)
729 os << "\\language " << language->lang() << '\n';
730 os << "\\inputencoding " << inputenc
731 << "\n\\font_roman " << fontsRoman
732 << "\n\\font_sans " << fontsSans
733 << "\n\\font_typewriter " << fontsTypewriter
734 << "\n\\font_default_family " << fontsDefaultFamily
735 << "\n\\font_sc " << convert<string>(fontsSC)
736 << "\n\\font_osf " << convert<string>(fontsOSF)
737 << "\n\\font_sf_scale " << fontsSansScale
738 << "\n\\font_tt_scale " << fontsTypewriterScale
739 << "\n\\graphics " << graphicsDriver << '\n';
741 if (!float_placement.empty()) {
742 os << "\\float_placement " << float_placement << '\n';
744 os << "\\paperfontsize " << fontsize << '\n';
746 spacing().writeFile(os);
747 pdfoptions().writeFile(os);
749 os << "\\papersize " << string_papersize[papersize]
750 << "\n\\use_geometry " << convert<string>(use_geometry)
751 << "\n\\use_amsmath " << use_amsmath
752 << "\n\\use_esint " << use_esint
753 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
754 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
755 << "\n\\paperorientation " << string_orientation[orientation]
758 BranchList::const_iterator it = branchlist().begin();
759 BranchList::const_iterator end = branchlist().end();
760 for (; it != end; ++it) {
761 os << "\\branch " << to_utf8(it->getBranch())
762 << "\n\\selected " << it->getSelected()
763 << "\n\\color " << lyx::X11hexname(it->getColor())
768 if (!paperwidth.empty())
769 os << "\\paperwidth "
770 << VSpace(paperwidth).asLyXCommand() << '\n';
771 if (!paperheight.empty())
772 os << "\\paperheight "
773 << VSpace(paperheight).asLyXCommand() << '\n';
774 if (!leftmargin.empty())
775 os << "\\leftmargin "
776 << VSpace(leftmargin).asLyXCommand() << '\n';
777 if (!topmargin.empty())
779 << VSpace(topmargin).asLyXCommand() << '\n';
780 if (!rightmargin.empty())
781 os << "\\rightmargin "
782 << VSpace(rightmargin).asLyXCommand() << '\n';
783 if (!bottommargin.empty())
784 os << "\\bottommargin "
785 << VSpace(bottommargin).asLyXCommand() << '\n';
786 if (!headheight.empty())
787 os << "\\headheight "
788 << VSpace(headheight).asLyXCommand() << '\n';
789 if (!headsep.empty())
791 << VSpace(headsep).asLyXCommand() << '\n';
792 if (!footskip.empty())
794 << VSpace(footskip).asLyXCommand() << '\n';
795 if (!columnsep.empty())
797 << VSpace(columnsep).asLyXCommand() << '\n';
798 os << "\\secnumdepth " << secnumdepth
799 << "\n\\tocdepth " << tocdepth
800 << "\n\\paragraph_separation "
801 << string_paragraph_separation[paragraph_separation]
802 << "\n\\defskip " << getDefSkip().asLyXCommand()
803 << "\n\\quotes_language "
804 << string_quotes_language[quotes_language]
805 << "\n\\papercolumns " << columns
806 << "\n\\papersides " << sides
807 << "\n\\paperpagestyle " << pagestyle << '\n';
808 if (!listings_params.empty())
809 os << "\\listings_params \"" <<
810 InsetListingsParams(listings_params).encodedString() << "\"\n";
811 for (int i = 0; i < 4; ++i) {
812 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
813 if (user_defined_bullet(i).getFont() != -1) {
814 os << "\\bullet " << i << " "
815 << user_defined_bullet(i).getFont() << " "
816 << user_defined_bullet(i).getCharacter() << " "
817 << user_defined_bullet(i).getSize() << "\n";
821 os << "\\bulletLaTeX " << i << " \""
822 << lyx::to_ascii(user_defined_bullet(i).getText())
828 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
829 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
831 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
832 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
833 for (; a_it != a_end; ++a_it) {
834 if (a_it->second.used())
835 os << "\\author " << a_it->second << "\n";
837 os << "\\author " << Author() << "\n";
840 vector<string>::const_iterator e_it = extraEmbeddedFiles().begin();
841 vector<string>::const_iterator e_end = extraEmbeddedFiles().end();
842 os << "\\extra_embedded_files \"";
844 for (; e_it != e_end; ++e_it) {
855 void BufferParams::validate(LaTeXFeatures & features) const
857 features.require(documentClass().requires());
860 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
861 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
862 LaTeXFeatures::isAvailable("xcolor");
864 switch (features.runparams().flavor) {
865 case OutputParams::LATEX:
867 features.require("ct-dvipost");
868 features.require("dvipost");
869 } else if (xcolorsoul) {
870 features.require("ct-xcolor-soul");
871 features.require("soul");
872 features.require("xcolor");
874 features.require("ct-none");
877 case OutputParams::PDFLATEX:
879 features.require("ct-xcolor-soul");
880 features.require("soul");
881 features.require("xcolor");
882 // improves color handling in PDF output
883 features.require("pdfcolmk");
885 features.require("ct-none");
893 // Floats with 'Here definitely' as default setting.
894 if (float_placement.find('H') != string::npos)
895 features.require("float");
897 // AMS Style is at document level
898 if (use_amsmath == package_on
899 || documentClass().provides("amsmath"))
900 features.require("amsmath");
901 if (use_esint == package_on)
902 features.require("esint");
904 // Document-level line spacing
905 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
906 features.require("setspace");
908 // the bullet shapes are buffer level not paragraph level
909 // so they are tested here
910 for (int i = 0; i < 4; ++i) {
911 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
913 int const font = user_defined_bullet(i).getFont();
915 int const c = user_defined_bullet(i).getCharacter();
921 features.require("latexsym");
923 } else if (font == 1) {
924 features.require("amssymb");
925 } else if (font >= 2 && font <= 5) {
926 features.require("pifont");
930 if (pdfoptions().use_hyperref)
931 features.require("hyperref");
935 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
936 TexRow & texrow) const
938 os << "\\documentclass";
940 DocumentClass const & tclass = documentClass();
942 ostringstream clsoptions; // the document class options.
944 if (tokenPos(tclass.opt_fontsize(),
945 '|', fontsize) >= 0) {
946 // only write if existing in list (and not default)
947 clsoptions << fontsize << "pt,";
950 // custom, A3, B3 and B4 paper sizes need geometry
951 bool nonstandard_papersize = papersize == PAPER_B3
952 || papersize == PAPER_B4
953 || papersize == PAPER_A3
954 || papersize == PAPER_CUSTOM;
959 clsoptions << "a4paper,";
962 clsoptions << "letterpaper,";
965 clsoptions << "a5paper,";
968 clsoptions << "b5paper,";
970 case PAPER_USEXECUTIVE:
971 clsoptions << "executivepaper,";
974 clsoptions << "legalpaper,";
986 if (sides != tclass.sides()) {
989 clsoptions << "oneside,";
992 clsoptions << "twoside,";
998 if (columns != tclass.columns()) {
1000 clsoptions << "twocolumn,";
1002 clsoptions << "onecolumn,";
1006 && orientation == ORIENTATION_LANDSCAPE)
1007 clsoptions << "landscape,";
1009 // language should be a parameter to \documentclass
1010 if (language->babel() == "hebrew"
1011 && default_language->babel() != "hebrew")
1012 // This seems necessary
1013 features.useLanguage(default_language);
1015 ostringstream language_options;
1016 bool const use_babel = features.useBabel();
1018 language_options << features.getLanguages();
1019 if (!language->babel().empty()) {
1020 if (!language_options.str().empty())
1021 language_options << ',';
1022 language_options << language->babel();
1024 // when Vietnamese is used, babel must directly be loaded with the
1025 // language options, not in the class options, see
1026 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1027 size_t viet = language_options.str().find("vietnam");
1028 // viet = string::npos when not found
1029 if (lyxrc.language_global_options && !language_options.str().empty()
1030 && viet == string::npos)
1031 clsoptions << language_options.str() << ',';
1034 // the user-defined options
1035 if (!options.empty()) {
1036 clsoptions << options << ',';
1039 string strOptions(clsoptions.str());
1040 if (!strOptions.empty()) {
1041 strOptions = rtrim(strOptions, ",");
1043 os << '[' << from_utf8(strOptions) << ']';
1046 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1048 // end of \documentclass defs
1050 // font selection must be done before loading fontenc.sty
1051 string const fonts =
1052 loadFonts(fontsRoman, fontsSans,
1053 fontsTypewriter, fontsSC, fontsOSF,
1054 fontsSansScale, fontsTypewriterScale);
1055 if (!fonts.empty()) {
1056 os << from_ascii(fonts);
1059 if (fontsDefaultFamily != "default")
1060 os << "\\renewcommand{\\familydefault}{\\"
1061 << from_ascii(fontsDefaultFamily) << "}\n";
1063 // set font encoding
1064 // this one is not per buffer
1065 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1066 if (lyxrc.fontenc != "default") {
1067 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1068 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1069 << ",LFE,LAE]{fontenc}\n";
1072 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1078 // handle inputenc etc.
1079 writeEncodingPreamble(os, features, texrow);
1081 if (!listings_params.empty()) {
1082 os << "\\usepackage{listings}\n";
1085 // do not test validity because listings_params is supposed to be valid
1086 string par = InsetListingsParams(listings_params).separatedParams(true);
1087 os << from_ascii(par);
1088 // count the number of newlines
1089 for (size_t i = 0; i < par.size(); ++i)
1095 if (use_geometry || nonstandard_papersize) {
1096 os << "\\usepackage{geometry}\n";
1098 os << "\\geometry{verbose";
1099 if (orientation == ORIENTATION_LANDSCAPE)
1101 switch (papersize) {
1103 if (!paperwidth.empty())
1104 os << ",paperwidth="
1105 << from_ascii(paperwidth);
1106 if (!paperheight.empty())
1107 os << ",paperheight="
1108 << from_ascii(paperheight);
1110 case PAPER_USLETTER:
1111 os << ",letterpaper";
1114 os << ",legalpaper";
1116 case PAPER_USEXECUTIVE:
1117 os << ",executivepaper";
1138 // default papersize ie PAPER_DEFAULT
1139 switch (lyxrc.default_papersize) {
1140 case PAPER_DEFAULT: // keep compiler happy
1141 case PAPER_USLETTER:
1142 os << ",letterpaper";
1145 os << ",legalpaper";
1147 case PAPER_USEXECUTIVE:
1148 os << ",executivepaper";
1168 if (!topmargin.empty())
1169 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1170 if (!bottommargin.empty())
1171 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1172 if (!leftmargin.empty())
1173 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1174 if (!rightmargin.empty())
1175 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1176 if (!headheight.empty())
1177 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1178 if (!headsep.empty())
1179 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1180 if (!footskip.empty())
1181 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1182 if (!columnsep.empty())
1183 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1188 if (tokenPos(tclass.opt_pagestyle(),
1189 '|', pagestyle) >= 0) {
1190 if (pagestyle == "fancy") {
1191 os << "\\usepackage{fancyhdr}\n";
1194 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1198 // Only if class has a ToC hierarchy
1199 if (tclass.hasTocLevels()) {
1200 if (secnumdepth != tclass.secnumdepth()) {
1201 os << "\\setcounter{secnumdepth}{"
1206 if (tocdepth != tclass.tocdepth()) {
1207 os << "\\setcounter{tocdepth}{"
1214 if (paragraph_separation) {
1215 switch (getDefSkip().kind()) {
1216 case VSpace::SMALLSKIP:
1217 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1219 case VSpace::MEDSKIP:
1220 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1222 case VSpace::BIGSKIP:
1223 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1225 case VSpace::LENGTH:
1226 os << "\\setlength{\\parskip}{"
1227 << from_utf8(getDefSkip().length().asLatexString())
1230 default: // should never happen // Then delete it.
1231 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1236 os << "\\setlength{\\parindent}{0pt}\n";
1240 // If we use jurabib, we have to call babel here.
1241 if (use_babel && features.isRequired("jurabib")) {
1242 os << from_ascii(babelCall(language_options.str()))
1244 << from_ascii(features.getBabelOptions());
1248 // Now insert the LyX specific LaTeX commands...
1250 // The optional packages;
1251 docstring lyxpreamble(from_ascii(features.getPackages()));
1254 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1256 // We try to load babel late, in case it interferes
1257 // with other packages. But some packages also need babel to be loaded
1258 // before, e.g. jurabib has to be called after babel.
1259 // So load babel after the optional packages but before the user-defined
1260 // preamble. This allows the users to redefine babel commands, e.g. to
1261 // translate the word "Index" to the German "Stichwortverzeichnis".
1262 // For more infos why this place was chosen, see
1263 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128425.html
1264 // If you encounter problems, you can shift babel to its old place behind
1265 // the user-defined preamble. But in this case you must change the Vietnamese
1266 // support from currently "\usepackage[vietnamese]{babel}" to:
1267 // \usepackage{vietnamese}
1268 // \usepackage{babel}
1269 // because vietnamese must be loaded before hyperref
1270 if (use_babel && !features.isRequired("jurabib")) {
1272 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1273 lyxpreamble += from_utf8(features.getBabelOptions());
1276 // When the language "japanese-plain" is used, the package "japanese" must
1277 // be loaded behind babel (it provides babel support for Japanese) but before
1279 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1280 if (language->lang() == "japanese-plain" &&
1281 !documentClass().provides("japanese")) {
1282 //load babel in case it was not loaded due to an empty language list
1283 if (language_options.str().empty())
1284 lyxpreamble += "\\usepackage{babel}\n";
1285 lyxpreamble += "\\usepackage{japanese}\n";
1289 // * Hyperref manual: "Make sure it comes last of your loaded
1290 // packages, to give it a fighting chance of not being over-written,
1291 // since its job is to redefine many LATEX commands."
1292 // * Email from Heiko Oberdiek: "It is usually better to load babel
1293 // before hyperref. Then hyperref has a chance to detect babel.
1294 // * Has to be loaded before the "LyX specific LaTeX commands" to
1295 // avoid errors with algorithm floats.
1296 // use hyperref explicitely when it is required
1297 if (features.isRequired("hyperref")) {
1298 odocstringstream oss;
1299 pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
1300 lyxpreamble += oss.str();
1303 // this might be useful...
1304 lyxpreamble += "\n\\makeatletter\n";
1306 // Some macros LyX will need
1307 docstring tmppreamble(from_ascii(features.getMacros()));
1309 if (!tmppreamble.empty()) {
1310 lyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1311 "LyX specific LaTeX commands.\n"
1312 + tmppreamble + '\n';
1315 // the text class specific preamble
1316 tmppreamble = features.getTClassPreamble();
1317 if (!tmppreamble.empty()) {
1318 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1319 "Textclass specific LaTeX commands.\n"
1320 + tmppreamble + '\n';
1323 /* the user-defined preamble */
1324 if (!preamble.empty()) {
1326 lyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1327 "User specified LaTeX commands.\n"
1328 + from_utf8(preamble) + '\n';
1331 // Itemize bullet settings need to be last in case the user
1332 // defines their own bullets that use a package included
1333 // in the user-defined preamble -- ARRae
1334 // Actually it has to be done much later than that
1335 // since some packages like frenchb make modifications
1336 // at \begin{document} time -- JMarc
1337 docstring bullets_def;
1338 for (int i = 0; i < 4; ++i) {
1339 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1340 if (bullets_def.empty())
1341 bullets_def += "\\AtBeginDocument{\n";
1342 bullets_def += " \\def\\labelitemi";
1344 // `i' is one less than the item to modify
1351 bullets_def += "ii";
1357 bullets_def += '{' +
1358 user_defined_bullet(i).getText()
1363 if (!bullets_def.empty())
1364 lyxpreamble += bullets_def + "}\n\n";
1366 lyxpreamble += "\\makeatother\n\n";
1369 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1370 for (int j = 0; j != nlines; ++j) {
1379 void BufferParams::useClassDefaults()
1381 DocumentClass const & tclass = documentClass();
1383 sides = tclass.sides();
1384 columns = tclass.columns();
1385 pagestyle = tclass.pagestyle();
1386 options = tclass.options();
1387 // Only if class has a ToC hierarchy
1388 if (tclass.hasTocLevels()) {
1389 secnumdepth = tclass.secnumdepth();
1390 tocdepth = tclass.tocdepth();
1395 bool BufferParams::hasClassDefaults() const
1397 DocumentClass const & tclass = documentClass();
1399 return sides == tclass.sides()
1400 && columns == tclass.columns()
1401 && pagestyle == tclass.pagestyle()
1402 && options == tclass.options()
1403 && secnumdepth == tclass.secnumdepth()
1404 && tocdepth == tclass.tocdepth();
1408 DocumentClass const & BufferParams::documentClass() const
1414 DocumentClass * BufferParams::documentClassPtr() const {
1419 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1420 // evil, but this function is evil
1421 doc_class_ = const_cast<DocumentClass *>(tc);
1425 bool BufferParams::setBaseClass(string const & classname)
1427 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1428 LayoutFileList const & bcl = LayoutFileList::get();
1429 if (!bcl.haveClass(classname)) {
1431 bformat(_("The document class %1$s could not be found."),
1432 from_utf8(classname));
1433 frontend::Alert::error(_("Class not found"), s);
1437 if (bcl[classname].load()) {
1438 pimpl_->baseClass_ = classname;
1443 bformat(_("The document class %1$s could not be loaded."),
1444 from_utf8(classname));
1445 frontend::Alert::error(_("Could not load class"), s);
1450 LayoutFile const * BufferParams::baseClass() const
1452 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
1453 return &(LayoutFileList::get()[pimpl_->baseClass_]);
1459 LayoutFileIndex const & BufferParams::baseClassID() const
1461 return pimpl_->baseClass_;
1465 void BufferParams::makeDocumentClass()
1470 doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass()));
1472 //FIXME It might be worth loading the children's modules here,
1473 //just as we load their bibliographies and such, instead of just
1474 //doing a check in InsetInclude.
1475 LayoutModuleList::const_iterator it = layoutModules_.begin();
1476 for (; it != layoutModules_.end(); it++) {
1477 string const modName = *it;
1478 LyXModule * lm = moduleList[modName];
1480 docstring const msg =
1481 bformat(_("The module %1$s has been requested by\n"
1482 "this document but has not been found in the list of\n"
1483 "available modules. If you recently installed it, you\n"
1484 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1485 frontend::Alert::warning(_("Module not available"),
1486 msg + _("Some layouts may not be available."));
1487 lyxerr << "BufferParams::makeDocumentClass(): Module " <<
1488 modName << " requested but not found in module list." <<
1492 if (!lm->isAvailable()) {
1493 docstring const msg =
1494 bformat(_("The module %1$s requires a package that is\n"
1495 "not available in your LaTeX installation. LaTeX output\n"
1496 "may not be possible.\n"), from_utf8(modName));
1497 frontend::Alert::warning(_("Package not available"), msg);
1499 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1500 if (!doc_class_->read(layout_file, TextClass::MODULE)) {
1501 docstring const msg =
1502 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1503 frontend::Alert::warning(_("Read Error"), msg);
1509 vector<string> const & BufferParams::getModules() const
1511 return layoutModules_;
1516 bool BufferParams::addLayoutModule(string const & modName)
1518 LayoutModuleList::const_iterator it = layoutModules_.begin();
1519 LayoutModuleList::const_iterator end = layoutModules_.end();
1520 for (; it != end; it++) {
1524 if (it != layoutModules_.end())
1526 layoutModules_.push_back(modName);
1531 void BufferParams::clearLayoutModules()
1533 layoutModules_.clear();
1537 Font const BufferParams::getFont() const
1539 FontInfo f = documentClass().defaultfont();
1540 if (fontsDefaultFamily == "rmdefault")
1541 f.setFamily(ROMAN_FAMILY);
1542 else if (fontsDefaultFamily == "sfdefault")
1543 f.setFamily(SANS_FAMILY);
1544 else if (fontsDefaultFamily == "ttdefault")
1545 f.setFamily(TYPEWRITER_FAMILY);
1546 return Font(f, language);
1550 void BufferParams::readPreamble(Lexer & lex)
1552 if (lex.getString() != "\\begin_preamble")
1553 lyxerr << "Error (BufferParams::readPreamble):"
1554 "consistency check failed." << endl;
1556 preamble = lex.getLongString("\\end_preamble");
1560 void BufferParams::readLanguage(Lexer & lex)
1562 if (!lex.next()) return;
1564 string const tmptok = lex.getString();
1566 // check if tmptok is part of tex_babel in tex-defs.h
1567 language = languages.getLanguage(tmptok);
1569 // Language tmptok was not found
1570 language = default_language;
1571 lyxerr << "Warning: Setting language `"
1572 << tmptok << "' to `" << language->lang()
1578 void BufferParams::readGraphicsDriver(Lexer & lex)
1583 string const tmptok = lex.getString();
1584 // check if tmptok is part of tex_graphics in tex_defs.h
1587 string const test = tex_graphics[n++];
1589 if (test == tmptok) {
1590 graphicsDriver = tmptok;
1592 } else if (test == "") {
1594 "Warning: graphics driver `$$Token' not recognized!\n"
1595 " Setting graphics driver to `default'.\n");
1596 graphicsDriver = "default";
1603 void BufferParams::readBullets(Lexer & lex)
1608 int const index = lex.getInteger();
1610 int temp_int = lex.getInteger();
1611 user_defined_bullet(index).setFont(temp_int);
1612 temp_bullet(index).setFont(temp_int);
1614 user_defined_bullet(index).setCharacter(temp_int);
1615 temp_bullet(index).setCharacter(temp_int);
1617 user_defined_bullet(index).setSize(temp_int);
1618 temp_bullet(index).setSize(temp_int);
1622 void BufferParams::readBulletsLaTeX(Lexer & lex)
1624 // The bullet class should be able to read this.
1627 int const index = lex.getInteger();
1629 docstring const temp_str = lex.getDocString();
1631 user_defined_bullet(index).setText(temp_str);
1632 temp_bullet(index).setText(temp_str);
1636 void BufferParams::readModules(Lexer & lex)
1638 if (!lex.eatLine()) {
1639 lyxerr << "Error (BufferParams::readModules):"
1640 "Unexpected end of input." << endl;
1644 string mod = lex.getString();
1645 if (mod == "\\end_modules")
1647 addLayoutModule(mod);
1653 string const BufferParams::paperSizeName(Papersize_Purpose const & purpose) const
1655 char real_papersize = papersize;
1656 if (real_papersize == PAPER_DEFAULT)
1657 real_papersize = lyxrc.default_papersize;
1659 switch (real_papersize) {
1661 // could be anything, so don't guess
1663 case PAPER_CUSTOM: {
1664 if (purpose == XDVI && !paperwidth.empty() &&
1665 !paperheight.empty()) {
1666 // heightxwidth<unit>
1667 string first = paperwidth;
1668 string second = paperheight;
1669 if (orientation == ORIENTATION_LANDSCAPE)
1672 return first.erase(first.length() - 2)
1684 // dvips and dvipdfm do not know this
1685 if (purpose == DVIPS || purpose == DVIPDFM)
1689 // dvipdfm does not know this
1690 if (purpose == DVIPDFM)
1694 // dvipdfm does not know this
1695 if (purpose == DVIPDFM)
1698 case PAPER_USEXECUTIVE:
1699 // dvipdfm does not know this
1700 if (purpose == DVIPDFM)
1705 case PAPER_USLETTER:
1707 if (purpose == XDVI)
1714 string const BufferParams::dvips_options() const
1719 && papersize == PAPER_CUSTOM
1720 && !lyxrc.print_paper_dimension_flag.empty()
1721 && !paperwidth.empty()
1722 && !paperheight.empty()) {
1723 // using a custom papersize
1724 result = lyxrc.print_paper_dimension_flag;
1725 result += ' ' + paperwidth;
1726 result += ',' + paperheight;
1728 string const paper_option = paperSizeName(DVIPS);
1729 if (!paper_option.empty() && (paper_option != "letter" ||
1730 orientation != ORIENTATION_LANDSCAPE)) {
1731 // dvips won't accept -t letter -t landscape.
1732 // In all other cases, include the paper size
1734 result = lyxrc.print_paper_flag;
1735 result += ' ' + paper_option;
1738 if (orientation == ORIENTATION_LANDSCAPE &&
1739 papersize != PAPER_CUSTOM)
1740 result += ' ' + lyxrc.print_landscape_flag;
1745 string const BufferParams::babelCall(string const & lang_opts) const
1747 string lang_pack = lyxrc.language_package;
1748 if (lang_pack != "\\usepackage{babel}")
1750 // suppress the babel call when there is no babel language defined
1751 // for the document language in the lib/languages file and if no
1752 // other languages are used (lang_opts is then empty)
1753 if (lang_opts.empty())
1755 // when Vietnamese is used, babel must directly be loaded with the
1756 // language options, see
1757 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1758 size_t viet = lang_opts.find("vietnam");
1759 // viet = string::npos when not found
1760 if (!lyxrc.language_global_options || viet != string::npos)
1761 return "\\usepackage[" + lang_opts + "]{babel}";
1766 void BufferParams::writeEncodingPreamble(odocstream & os,
1767 LaTeXFeatures & features, TexRow & texrow) const
1769 if (inputenc == "auto") {
1770 string const doc_encoding =
1771 language->encoding()->latexName();
1772 Encoding::Package const package =
1773 language->encoding()->package();
1775 // Create a list with all the input encodings used
1777 set<string> encodings =
1778 features.getEncodingSet(doc_encoding);
1780 // When the encodings EUC-JP-plain, JIS-plain, or SJIS-plainare used, the
1781 // package inputenc must be omitted. Therefore set the encoding to empty.
1782 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1783 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1784 doc_encoding == "SJIS-plain")
1787 if (!encodings.empty() || package == Encoding::inputenc) {
1788 os << "\\usepackage[";
1789 set<string>::const_iterator it = encodings.begin();
1790 set<string>::const_iterator const end = encodings.end();
1792 os << from_ascii(*it);
1795 for (; it != end; ++it)
1796 os << ',' << from_ascii(*it);
1797 if (package == Encoding::inputenc) {
1798 if (!encodings.empty())
1800 os << from_ascii(doc_encoding);
1802 os << "]{inputenc}\n";
1805 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1806 os << "\\usepackage{CJK}\n";
1809 } else if (inputenc != "default") {
1810 switch (encoding().package()) {
1811 case Encoding::none:
1813 case Encoding::inputenc:
1814 os << "\\usepackage[" << from_ascii(inputenc)
1819 os << "\\usepackage{CJK}\n";
1825 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1826 // armscii8 is used for Armenian.
1827 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1828 os << "\\usepackage{armtex}\n";
1834 string const BufferParams::loadFonts(string const & rm,
1835 string const & sf, string const & tt,
1836 bool const & sc, bool const & osf,
1837 int const & sfscale, int const & ttscale) const
1839 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1840 several packages have been replaced by others, that might not
1841 be installed on every system. We have to take care for that
1842 (see psnfss.pdf). We try to support all psnfss fonts as well
1843 as the fonts that have become de facto standard in the LaTeX
1844 world (e.g. Latin Modern). We do not support obsolete fonts
1845 (like PSLatex). In general, it should be possible to mix any
1846 rm font with any sf or tt font, respectively. (JSpitzm)
1848 -- separate math fonts.
1851 if (rm == "default" && sf == "default" && tt == "default")
1858 // Computer Modern (must be explicitely selectable -- there might be classes
1859 // that define a different default font!
1861 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1862 // osf for Computer Modern needs eco.sty
1864 os << "\\usepackage{eco}\n";
1866 // Latin Modern Roman
1867 else if (rm == "lmodern")
1868 os << "\\usepackage{lmodern}\n";
1870 else if (rm == "ae") {
1871 // not needed when using OT1 font encoding.
1872 if (lyxrc.fontenc != "default")
1873 os << "\\usepackage{ae,aecompl}\n";
1876 else if (rm == "times") {
1877 // try to load the best available package
1878 if (LaTeXFeatures::isAvailable("mathptmx"))
1879 os << "\\usepackage{mathptmx}\n";
1880 else if (LaTeXFeatures::isAvailable("mathptm"))
1881 os << "\\usepackage{mathptm}\n";
1883 os << "\\usepackage{times}\n";
1886 else if (rm == "palatino") {
1887 // try to load the best available package
1888 if (LaTeXFeatures::isAvailable("mathpazo")) {
1889 os << "\\usepackage";
1895 // "osf" includes "sc"!
1899 os << "{mathpazo}\n";
1901 else if (LaTeXFeatures::isAvailable("mathpple"))
1902 os << "\\usepackage{mathpple}\n";
1904 os << "\\usepackage{palatino}\n";
1907 else if (rm == "utopia") {
1908 // fourier supersedes utopia.sty, but does
1909 // not work with OT1 encoding.
1910 if (LaTeXFeatures::isAvailable("fourier")
1911 && lyxrc.fontenc != "default") {
1912 os << "\\usepackage";
1923 os << "{fourier}\n";
1926 os << "\\usepackage{utopia}\n";
1928 // Bera (complete fontset)
1929 else if (rm == "bera" && sf == "default" && tt == "default")
1930 os << "\\usepackage{bera}\n";
1932 else if (rm != "default")
1933 os << "\\usepackage" << "{" << rm << "}\n";
1936 // Helvetica, Bera Sans
1937 if (sf == "helvet" || sf == "berasans") {
1939 os << "\\usepackage[scaled=" << float(sfscale) / 100
1940 << "]{" << sf << "}\n";
1942 os << "\\usepackage{" << sf << "}\n";
1945 else if (sf == "avant")
1946 os << "\\usepackage{" << sf << "}\n";
1947 // Computer Modern, Latin Modern, CM Bright
1948 else if (sf != "default")
1949 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1951 // monospaced/typewriter
1952 // Courier, LuxiMono
1953 if (tt == "luximono" || tt == "beramono") {
1955 os << "\\usepackage[scaled=" << float(ttscale) / 100
1956 << "]{" << tt << "}\n";
1958 os << "\\usepackage{" << tt << "}\n";
1961 else if (tt == "courier" )
1962 os << "\\usepackage{" << tt << "}\n";
1963 // Computer Modern, Latin Modern, CM Bright
1964 else if (tt != "default")
1965 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
1971 Encoding const & BufferParams::encoding() const
1973 if (inputenc == "auto" || inputenc == "default")
1974 return *(language->encoding());
1975 Encoding const * const enc =
1976 encodings.getFromLaTeXName(inputenc);
1979 lyxerr << "Unknown inputenc value `" << inputenc
1980 << "'. Using `auto' instead." << endl;
1981 return *(language->encoding());
1985 biblio::CiteEngine BufferParams::getEngine() const
1987 // FIXME the class should provide the numerical/
1988 // authoryear choice
1989 if (documentClass().provides("natbib")
1990 && cite_engine_ != biblio::ENGINE_NATBIB_NUMERICAL)
1991 return biblio::ENGINE_NATBIB_AUTHORYEAR;
1992 return cite_engine_;
1996 void BufferParams::setCiteEngine(biblio::CiteEngine const cite_engine)
1998 cite_engine_ = cite_engine;