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", "legalpaper", "executivepaper",
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, CiteEngine> CiteEngineTranslator;
231 CiteEngineTranslator const init_citeenginetranslator()
233 CiteEngineTranslator translator("basic", ENGINE_BASIC);
234 translator.addPair("natbib_numerical", ENGINE_NATBIB_NUMERICAL);
235 translator.addPair("natbib_authoryear", ENGINE_NATBIB_AUTHORYEAR);
236 translator.addPair("jurabib", 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 Bullet temp_bullets[4];
281 Bullet user_defined_bullets[4];
283 /** This is the amount of space used for paragraph_separation "skip",
284 * and for detached paragraphs in "indented" documents.
287 PDFOptions pdfoptions;
288 LayoutFileIndex baseClass_;
292 BufferParams::Impl::Impl()
293 : defskip(VSpace::MEDSKIP), baseClass_(string(""))
295 // set initial author
297 authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
302 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
306 return new BufferParams::Impl(*ptr);
310 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
316 BufferParams::BufferParams()
319 setBaseClass(defaultBaseclass());
321 paragraph_separation = ParagraphIndentSeparation;
322 quotes_language = InsetQuotes::EnglishQuotes;
323 fontsize = "default";
326 papersize = PAPER_DEFAULT;
327 orientation = ORIENTATION_PORTRAIT;
328 use_geometry = false;
329 use_amsmath = package_auto;
330 use_esint = package_auto;
331 cite_engine_ = ENGINE_BASIC;
332 use_bibtopic = false;
333 trackChanges = false;
334 outputChanges = false;
337 language = default_language;
338 fontsRoman = "default";
339 fontsSans = "default";
340 fontsTypewriter = "default";
341 fontsDefaultFamily = "default";
344 fontsSansScale = 100;
345 fontsTypewriterScale = 100;
347 graphicsDriver = "default";
350 listings_params = string();
351 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 docstring BufferParams::B_(string const & l10n) const
362 LASSERT(language, /**/);
363 return getMessages(language->code()).get(l10n);
367 AuthorList & BufferParams::authors()
369 return pimpl_->authorlist;
373 AuthorList const & BufferParams::authors() const
375 return pimpl_->authorlist;
379 BranchList & BufferParams::branchlist()
381 return pimpl_->branchlist;
385 BranchList const & BufferParams::branchlist() const
387 return pimpl_->branchlist;
391 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
393 LASSERT(index < 4, /**/);
394 return pimpl_->temp_bullets[index];
398 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
400 LASSERT(index < 4, /**/);
401 return pimpl_->temp_bullets[index];
405 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
407 LASSERT(index < 4, /**/);
408 return pimpl_->user_defined_bullets[index];
412 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
414 LASSERT(index < 4, /**/);
415 return pimpl_->user_defined_bullets[index];
419 Spacing & BufferParams::spacing()
421 return pimpl_->spacing;
425 Spacing const & BufferParams::spacing() const
427 return pimpl_->spacing;
431 PDFOptions & BufferParams::pdfoptions()
433 return pimpl_->pdfoptions;
437 PDFOptions const & BufferParams::pdfoptions() const
439 return pimpl_->pdfoptions;
443 VSpace const & BufferParams::getDefSkip() const
445 return pimpl_->defskip;
449 void BufferParams::setDefSkip(VSpace const & vs)
451 pimpl_->defskip = vs;
455 string BufferParams::readToken(Lexer & lex, string const & token,
456 FileName const & filepath)
458 if (token == "\\textclass") {
460 string const classname = lex.getString();
461 // if there exists a local layout file, ignore the system one
462 // NOTE: in this case, the textclass (.cls file) is assumed to be available.
464 LayoutFileList & bcl = LayoutFileList::get();
465 if (tcp.empty() && !filepath.empty())
466 tcp = bcl.addLocalLayout(classname, filepath.absFilename());
470 setBaseClass(classname);
471 // We assume that a tex class exists for local or unknown layouts so this warning
472 // will only be given for system layouts.
473 if (!baseClass()->isTeXClassAvailable()) {
474 docstring const msg =
475 bformat(_("The layout file requested by this document,\n"
477 "is not usable. This is probably because a LaTeX\n"
478 "class or style file required by it is not\n"
479 "available. See the Customization documentation\n"
480 "for more information.\n"), from_utf8(classname));
481 frontend::Alert::warning(_("Document class not available"),
482 msg + _("LyX will not be able to produce output."));
484 } else if (token == "\\begin_preamble") {
486 } else if (token == "\\begin_local_layout") {
487 readLocalLayout(lex);
488 } else if (token == "\\begin_modules") {
490 } else if (token == "\\options") {
492 options = lex.getString();
493 } else if (token == "\\master") {
495 master = lex.getString();
496 } else if (token == "\\language") {
498 } else if (token == "\\inputencoding") {
500 } else if (token == "\\graphics") {
501 readGraphicsDriver(lex);
502 } else if (token == "\\font_roman") {
504 } else if (token == "\\font_sans") {
506 } else if (token == "\\font_typewriter") {
507 lex >> fontsTypewriter;
508 } else if (token == "\\font_default_family") {
509 lex >> fontsDefaultFamily;
510 } else if (token == "\\font_sc") {
512 } else if (token == "\\font_osf") {
514 } else if (token == "\\font_sf_scale") {
515 lex >> fontsSansScale;
516 } else if (token == "\\font_tt_scale") {
517 lex >> fontsTypewriterScale;
518 } else if (token == "\\font_cjk") {
520 } else if (token == "\\paragraph_separation") {
523 paragraph_separation = parseptranslator().find(parsep);
524 } else if (token == "\\defskip") {
526 string defskip = lex.getString();
527 if (defskip == "defskip")
530 pimpl_->defskip = VSpace(defskip);
531 } else if (token == "\\quotes_language") {
534 quotes_language = quoteslangtranslator().find(quotes_lang);
535 } else if (token == "\\papersize") {
538 papersize = papersizetranslator().find(ppsize);
539 } else if (token == "\\use_geometry") {
541 } else if (token == "\\use_amsmath") {
544 use_amsmath = packagetranslator().find(use_ams);
545 } else if (token == "\\use_esint") {
548 use_esint = packagetranslator().find(useesint);
549 } else if (token == "\\cite_engine") {
552 cite_engine_ = citeenginetranslator().find(engine);
553 } else if (token == "\\use_bibtopic") {
555 } else if (token == "\\tracking_changes") {
557 } else if (token == "\\output_changes") {
558 lex >> outputChanges;
559 } else if (token == "\\branch") {
561 docstring branch = lex.getDocString();
562 branchlist().add(branch);
565 string const tok = lex.getString();
566 if (tok == "\\end_branch")
568 Branch * branch_ptr = branchlist().find(branch);
569 if (tok == "\\selected") {
572 branch_ptr->setSelected(lex.getInteger());
574 // not yet operational
575 if (tok == "\\color") {
577 string color = lex.getString();
579 branch_ptr->setColor(color);
580 // Update also the Color table:
582 color = lcolor.getX11Name(Color_background);
584 lcolor.setColor(to_utf8(branch), color);
588 } else if (token == "\\author") {
590 istringstream ss(lex.getString());
593 author_map.push_back(pimpl_->authorlist.record(a));
594 } else if (token == "\\paperorientation") {
597 orientation = paperorientationtranslator().find(orient);
598 } else if (token == "\\paperwidth") {
600 } else if (token == "\\paperheight") {
602 } else if (token == "\\leftmargin") {
604 } else if (token == "\\topmargin") {
606 } else if (token == "\\rightmargin") {
608 } else if (token == "\\bottommargin") {
610 } else if (token == "\\headheight") {
612 } else if (token == "\\headsep") {
614 } else if (token == "\\footskip") {
616 } else if (token == "\\columnsep") {
618 } else if (token == "\\paperfontsize") {
620 } else if (token == "\\papercolumns") {
622 } else if (token == "\\listings_params") {
625 listings_params = InsetListingsParams(par).params();
626 } else if (token == "\\papersides") {
629 sides = sidestranslator().find(psides);
630 } else if (token == "\\paperpagestyle") {
632 } else if (token == "\\bullet") {
634 } else if (token == "\\bulletLaTeX") {
635 readBulletsLaTeX(lex);
636 } else if (token == "\\secnumdepth") {
638 } else if (token == "\\tocdepth") {
640 } else if (token == "\\spacing") {
644 if (nspacing == "other") {
647 spacing().set(spacetranslator().find(nspacing), tmp_val);
648 } else if (token == "\\float_placement") {
649 lex >> float_placement;
651 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
652 string toktmp = pdfoptions().readToken(lex, token);
653 if (!toktmp.empty()) {
654 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
659 lyxerr << "BufferParams::readToken(): Unknown token: " <<
668 void BufferParams::writeFile(ostream & os) const
670 // The top of the file is written by the buffer.
671 // Prints out the buffer info into the .lyx file given by file
674 os << "\\textclass " << baseClass()->name() << '\n';
677 if (!preamble.empty()) {
678 // remove '\n' from the end of preamble
679 string const tmppreamble = rtrim(preamble, "\n");
680 os << "\\begin_preamble\n"
682 << "\n\\end_preamble\n";
686 if (!options.empty()) {
687 os << "\\options " << options << '\n';
690 // the master document
691 if (!master.empty()) {
692 os << "\\master " << master << '\n';
696 if (!layoutModules_.empty()) {
697 os << "\\begin_modules" << '\n';
698 LayoutModuleList::const_iterator it = layoutModules_.begin();
699 for (; it != layoutModules_.end(); it++)
701 os << "\\end_modules" << '\n';
704 // local layout information
705 if (!local_layout.empty()) {
706 // remove '\n' from the end
707 string const tmplocal = rtrim(local_layout, "\n");
708 os << "\\begin_local_layout\n"
710 << "\n\\end_local_layout\n";
713 // then the text parameters
714 if (language != ignore_language)
715 os << "\\language " << language->lang() << '\n';
716 os << "\\inputencoding " << inputenc
717 << "\n\\font_roman " << fontsRoman
718 << "\n\\font_sans " << fontsSans
719 << "\n\\font_typewriter " << fontsTypewriter
720 << "\n\\font_default_family " << fontsDefaultFamily
721 << "\n\\font_sc " << convert<string>(fontsSC)
722 << "\n\\font_osf " << convert<string>(fontsOSF)
723 << "\n\\font_sf_scale " << fontsSansScale
724 << "\n\\font_tt_scale " << fontsTypewriterScale
726 if (!fontsCJK.empty()) {
727 os << "\\font_cjk " << fontsCJK << '\n';
729 os << "\n\\graphics " << graphicsDriver << '\n';
731 if (!float_placement.empty()) {
732 os << "\\float_placement " << float_placement << '\n';
734 os << "\\paperfontsize " << fontsize << '\n';
736 spacing().writeFile(os);
737 pdfoptions().writeFile(os);
739 os << "\\papersize " << string_papersize[papersize]
740 << "\n\\use_geometry " << convert<string>(use_geometry)
741 << "\n\\use_amsmath " << use_amsmath
742 << "\n\\use_esint " << use_esint
743 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
744 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
745 << "\n\\paperorientation " << string_orientation[orientation]
748 BranchList::const_iterator it = branchlist().begin();
749 BranchList::const_iterator end = branchlist().end();
750 for (; it != end; ++it) {
751 os << "\\branch " << to_utf8(it->getBranch())
752 << "\n\\selected " << it->getSelected()
753 << "\n\\color " << lyx::X11hexname(it->getColor())
758 if (!paperwidth.empty())
759 os << "\\paperwidth "
760 << VSpace(paperwidth).asLyXCommand() << '\n';
761 if (!paperheight.empty())
762 os << "\\paperheight "
763 << VSpace(paperheight).asLyXCommand() << '\n';
764 if (!leftmargin.empty())
765 os << "\\leftmargin "
766 << VSpace(leftmargin).asLyXCommand() << '\n';
767 if (!topmargin.empty())
769 << VSpace(topmargin).asLyXCommand() << '\n';
770 if (!rightmargin.empty())
771 os << "\\rightmargin "
772 << VSpace(rightmargin).asLyXCommand() << '\n';
773 if (!bottommargin.empty())
774 os << "\\bottommargin "
775 << VSpace(bottommargin).asLyXCommand() << '\n';
776 if (!headheight.empty())
777 os << "\\headheight "
778 << VSpace(headheight).asLyXCommand() << '\n';
779 if (!headsep.empty())
781 << VSpace(headsep).asLyXCommand() << '\n';
782 if (!footskip.empty())
784 << VSpace(footskip).asLyXCommand() << '\n';
785 if (!columnsep.empty())
787 << VSpace(columnsep).asLyXCommand() << '\n';
788 os << "\\secnumdepth " << secnumdepth
789 << "\n\\tocdepth " << tocdepth
790 << "\n\\paragraph_separation "
791 << string_paragraph_separation[paragraph_separation]
792 << "\n\\defskip " << getDefSkip().asLyXCommand()
793 << "\n\\quotes_language "
794 << string_quotes_language[quotes_language]
795 << "\n\\papercolumns " << columns
796 << "\n\\papersides " << sides
797 << "\n\\paperpagestyle " << pagestyle << '\n';
798 if (!listings_params.empty())
799 os << "\\listings_params \"" <<
800 InsetListingsParams(listings_params).encodedString() << "\"\n";
801 for (int i = 0; i < 4; ++i) {
802 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
803 if (user_defined_bullet(i).getFont() != -1) {
804 os << "\\bullet " << i << " "
805 << user_defined_bullet(i).getFont() << " "
806 << user_defined_bullet(i).getCharacter() << " "
807 << user_defined_bullet(i).getSize() << "\n";
811 os << "\\bulletLaTeX " << i << " \""
812 << lyx::to_ascii(user_defined_bullet(i).getText())
818 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
819 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
821 AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
822 AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
823 for (; a_it != a_end; ++a_it) {
824 if (a_it->second.used())
825 os << "\\author " << a_it->second << "\n";
827 os << "\\author " << Author() << "\n";
832 void BufferParams::validate(LaTeXFeatures & features) const
834 features.require(documentClass().requires());
837 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
838 bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
839 LaTeXFeatures::isAvailable("xcolor");
841 switch (features.runparams().flavor) {
842 case OutputParams::LATEX:
844 features.require("ct-dvipost");
845 features.require("dvipost");
846 } else if (xcolorsoul) {
847 features.require("ct-xcolor-soul");
848 features.require("soul");
849 features.require("xcolor");
851 features.require("ct-none");
854 case OutputParams::PDFLATEX:
856 features.require("ct-xcolor-soul");
857 features.require("soul");
858 features.require("xcolor");
859 // improves color handling in PDF output
860 features.require("pdfcolmk");
862 features.require("ct-none");
870 // Floats with 'Here definitely' as default setting.
871 if (float_placement.find('H') != string::npos)
872 features.require("float");
874 // AMS Style is at document level
875 if (use_amsmath == package_on
876 || documentClass().provides("amsmath"))
877 features.require("amsmath");
878 if (use_esint == package_on)
879 features.require("esint");
881 // Document-level line spacing
882 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
883 features.require("setspace");
885 // the bullet shapes are buffer level not paragraph level
886 // so they are tested here
887 for (int i = 0; i < 4; ++i) {
888 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
890 int const font = user_defined_bullet(i).getFont();
892 int const c = user_defined_bullet(i).getCharacter();
898 features.require("latexsym");
900 } else if (font == 1) {
901 features.require("amssymb");
902 } else if (font >= 2 && font <= 5) {
903 features.require("pifont");
907 if (pdfoptions().use_hyperref)
908 features.require("hyperref");
910 if (language->lang() == "vietnamese")
911 features.require("vietnamese");
912 else if (language->lang() == "japanese")
913 features.require("japanese");
917 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
918 TexRow & texrow) const
920 os << "\\documentclass";
922 DocumentClass const & tclass = documentClass();
924 ostringstream clsoptions; // the document class options.
926 if (tokenPos(tclass.opt_fontsize(),
927 '|', fontsize) >= 0) {
928 // only write if existing in list (and not default)
929 clsoptions << fontsize << "pt,";
932 // custom, A3, B3 and B4 paper sizes need geometry
933 bool nonstandard_papersize = papersize == PAPER_B3
934 || papersize == PAPER_B4
935 || papersize == PAPER_A3
936 || papersize == PAPER_CUSTOM;
941 clsoptions << "a4paper,";
944 clsoptions << "letterpaper,";
947 clsoptions << "a5paper,";
950 clsoptions << "b5paper,";
952 case PAPER_USEXECUTIVE:
953 clsoptions << "executivepaper,";
956 clsoptions << "legalpaper,";
968 if (sides != tclass.sides()) {
971 clsoptions << "oneside,";
974 clsoptions << "twoside,";
980 if (columns != tclass.columns()) {
982 clsoptions << "twocolumn,";
984 clsoptions << "onecolumn,";
988 && orientation == ORIENTATION_LANDSCAPE)
989 clsoptions << "landscape,";
991 // language should be a parameter to \documentclass
992 if (language->babel() == "hebrew"
993 && default_language->babel() != "hebrew")
994 // This seems necessary
995 features.useLanguage(default_language);
997 ostringstream language_options;
998 bool const use_babel = features.useBabel();
1000 language_options << features.getLanguages();
1001 if (!language->babel().empty()) {
1002 if (!language_options.str().empty())
1003 language_options << ',';
1004 language_options << language->babel();
1006 // if Vietnamese is used, babel must directly be loaded with the
1007 // language options, not in the class options, see
1008 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1009 size_t viet = language_options.str().find("vietnam");
1010 // viet = string::npos when not found
1011 // if Japanese is used, babel must directly be loaded with the
1012 // language options, not in the class options, see
1013 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1014 size_t japan = language_options.str().find("japanese");
1015 // japan = string::npos when not found
1016 if (lyxrc.language_global_options && !language_options.str().empty()
1017 && viet == string::npos && japan == string::npos)
1018 clsoptions << language_options.str() << ',';
1021 // the user-defined options
1022 if (!options.empty()) {
1023 clsoptions << options << ',';
1026 string strOptions(clsoptions.str());
1027 if (!strOptions.empty()) {
1028 strOptions = rtrim(strOptions, ",");
1030 os << '[' << from_utf8(strOptions) << ']';
1033 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1035 // end of \documentclass defs
1037 // font selection must be done before loading fontenc.sty
1038 string const fonts =
1039 loadFonts(fontsRoman, fontsSans,
1040 fontsTypewriter, fontsSC, fontsOSF,
1041 fontsSansScale, fontsTypewriterScale);
1042 if (!fonts.empty()) {
1043 os << from_ascii(fonts);
1046 if (fontsDefaultFamily != "default")
1047 os << "\\renewcommand{\\familydefault}{\\"
1048 << from_ascii(fontsDefaultFamily) << "}\n";
1050 // set font encoding
1051 // this one is not per buffer
1052 // for arabic_arabi and farsi we also need to load the LAE and LFE encoding
1053 if (lyxrc.fontenc != "default") {
1054 if (language->lang() == "arabic_arabi" || language->lang() == "farsi") {
1055 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1056 << ",LFE,LAE]{fontenc}\n";
1059 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1065 // handle inputenc etc.
1066 writeEncodingPreamble(os, features, texrow);
1068 if (!listings_params.empty()) {
1069 os << "\\usepackage{listings}\n";
1072 // do not test validity because listings_params is supposed to be valid
1073 string par = InsetListingsParams(listings_params).separatedParams(true);
1074 os << from_ascii(par);
1075 // count the number of newlines
1076 for (size_t i = 0; i < par.size(); ++i)
1082 if (use_geometry || nonstandard_papersize) {
1083 os << "\\usepackage{geometry}\n";
1085 os << "\\geometry{verbose";
1086 if (orientation == ORIENTATION_LANDSCAPE)
1088 switch (papersize) {
1090 if (!paperwidth.empty())
1091 os << ",paperwidth="
1092 << from_ascii(paperwidth);
1093 if (!paperheight.empty())
1094 os << ",paperheight="
1095 << from_ascii(paperheight);
1097 case PAPER_USLETTER:
1098 os << ",letterpaper";
1101 os << ",legalpaper";
1103 case PAPER_USEXECUTIVE:
1104 os << ",executivepaper";
1125 // default papersize ie PAPER_DEFAULT
1126 switch (lyxrc.default_papersize) {
1127 case PAPER_DEFAULT: // keep compiler happy
1128 case PAPER_USLETTER:
1129 os << ",letterpaper";
1132 os << ",legalpaper";
1134 case PAPER_USEXECUTIVE:
1135 os << ",executivepaper";
1155 if (!topmargin.empty())
1156 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1157 if (!bottommargin.empty())
1158 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1159 if (!leftmargin.empty())
1160 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1161 if (!rightmargin.empty())
1162 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1163 if (!headheight.empty())
1164 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1165 if (!headsep.empty())
1166 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1167 if (!footskip.empty())
1168 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1169 if (!columnsep.empty())
1170 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1173 } else if (orientation == ORIENTATION_LANDSCAPE) {
1174 features.require("papersize");
1177 if (tokenPos(tclass.opt_pagestyle(),
1178 '|', pagestyle) >= 0) {
1179 if (pagestyle == "fancy") {
1180 os << "\\usepackage{fancyhdr}\n";
1183 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1187 // Only if class has a ToC hierarchy
1188 if (tclass.hasTocLevels()) {
1189 if (secnumdepth != tclass.secnumdepth()) {
1190 os << "\\setcounter{secnumdepth}{"
1195 if (tocdepth != tclass.tocdepth()) {
1196 os << "\\setcounter{tocdepth}{"
1203 if (paragraph_separation) {
1204 switch (getDefSkip().kind()) {
1205 case VSpace::SMALLSKIP:
1206 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1208 case VSpace::MEDSKIP:
1209 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1211 case VSpace::BIGSKIP:
1212 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1214 case VSpace::LENGTH:
1215 os << "\\setlength{\\parskip}{"
1216 << from_utf8(getDefSkip().length().asLatexString())
1219 default: // should never happen // Then delete it.
1220 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1225 os << "\\setlength{\\parindent}{0pt}\n";
1229 // If we use hyperref, jurabib, japanese, or vietnamese, we have to call babel here.
1231 && (features.isRequired("jurabib")
1232 || features.isRequired("hyperref")
1233 || features.isRequired("vietnamese")
1234 || features.isRequired("japanese") ) ) {
1236 os << from_utf8(babelCall(language_options.str()))
1238 << from_utf8(features.getBabelOptions());
1242 // Now insert the LyX specific LaTeX commands...
1244 // The optional packages;
1245 docstring lyxpreamble(from_ascii(features.getPackages()));
1248 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1251 // * Hyperref manual: "Make sure it comes last of your loaded
1252 // packages, to give it a fighting chance of not being over-written,
1253 // since its job is to redefine many LATEX commands."
1254 // * Email from Heiko Oberdiek: "It is usually better to load babel
1255 // before hyperref. Then hyperref has a chance to detect babel.
1256 // * Has to be loaded before the "LyX specific LaTeX commands" to
1257 // avoid errors with algorithm floats.
1258 // use hyperref explicitely when it is required
1259 if (features.isRequired("hyperref")) {
1260 odocstringstream oss;
1261 pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
1262 lyxpreamble += oss.str();
1265 // Will be surrounded by \makeatletter and \makeatother when needed
1266 docstring atlyxpreamble;
1268 // Some macros LyX will need
1269 docstring tmppreamble(from_ascii(features.getMacros()));
1271 if (!tmppreamble.empty())
1272 atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1273 "LyX specific LaTeX commands.\n"
1274 + tmppreamble + '\n';
1276 // the text class specific preamble
1277 tmppreamble = features.getTClassPreamble();
1278 if (!tmppreamble.empty())
1279 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1280 "Textclass specific LaTeX commands.\n"
1281 + tmppreamble + '\n';
1283 /* the user-defined preamble */
1284 if (!preamble.empty())
1286 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1287 "User specified LaTeX commands.\n"
1288 + from_utf8(preamble) + '\n';
1290 // subfig loads internally the LaTeX package "caption". As
1291 // caption is a very popular package, users will load it in
1292 // the preamble. Therefore we must load subfig behind the
1293 // user-defined preamble and check if the caption package was
1294 // loaded or not. For the case that caption is loaded before
1295 // subfig, there is the subfig option "caption=false". This
1296 // option also works when a koma-script class is used and
1297 // koma's own caption commands are used instead of caption. We
1298 // use \PassOptionsToPackage here because the user could have
1299 // already loaded subfig in the preamble.
1300 if (features.isRequired("subfig")) {
1301 atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n"
1302 " \\PassOptionsToPackage{caption=false}{subfig}}\n"
1303 "\\usepackage{subfig}\n";
1306 // Itemize bullet settings need to be last in case the user
1307 // defines their own bullets that use a package included
1308 // in the user-defined preamble -- ARRae
1309 // Actually it has to be done much later than that
1310 // since some packages like frenchb make modifications
1311 // at \begin{document} time -- JMarc
1312 docstring bullets_def;
1313 for (int i = 0; i < 4; ++i) {
1314 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1315 if (bullets_def.empty())
1316 bullets_def += "\\AtBeginDocument{\n";
1317 bullets_def += " \\def\\labelitemi";
1319 // `i' is one less than the item to modify
1326 bullets_def += "ii";
1332 bullets_def += '{' +
1333 user_defined_bullet(i).getText()
1338 if (!bullets_def.empty())
1339 atlyxpreamble += bullets_def + "}\n\n";
1341 if (atlyxpreamble.find(from_ascii("@")) != docstring::npos)
1342 lyxpreamble += "\n\\makeatletter\n"
1343 + atlyxpreamble + "\\makeatother\n\n";
1345 lyxpreamble += '\n' + atlyxpreamble;
1347 // We try to load babel late, in case it interferes
1348 // with other packages.
1349 // Jurabib and Hyperref have to be called after babel, though.
1350 if (use_babel && !features.isRequired("jurabib")
1351 && !features.isRequired("hyperref")
1352 && !features.isRequired("vietnamese")
1353 && !features.isRequired("japanese")) {
1355 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1356 lyxpreamble += from_utf8(features.getBabelOptions()) + '\n';
1360 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1361 for (int j = 0; j != nlines; ++j) {
1370 void BufferParams::useClassDefaults()
1372 DocumentClass const & tclass = documentClass();
1374 sides = tclass.sides();
1375 columns = tclass.columns();
1376 pagestyle = tclass.pagestyle();
1377 options = tclass.options();
1378 // Only if class has a ToC hierarchy
1379 if (tclass.hasTocLevels()) {
1380 secnumdepth = tclass.secnumdepth();
1381 tocdepth = tclass.tocdepth();
1386 bool BufferParams::hasClassDefaults() const
1388 DocumentClass const & tclass = documentClass();
1390 return sides == tclass.sides()
1391 && columns == tclass.columns()
1392 && pagestyle == tclass.pagestyle()
1393 && options == tclass.options()
1394 && secnumdepth == tclass.secnumdepth()
1395 && tocdepth == tclass.tocdepth();
1399 DocumentClass const & BufferParams::documentClass() const
1405 DocumentClass const * BufferParams::documentClassPtr() const {
1410 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1411 // evil, but this function is evil
1412 doc_class_ = const_cast<DocumentClass *>(tc);
1416 bool BufferParams::setBaseClass(string const & classname)
1418 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1419 LayoutFileList & bcl = LayoutFileList::get();
1420 if (!bcl.haveClass(classname)) {
1422 bformat(_("The document class %1$s could not be found. "
1423 "A default textclass with default layouts will be used. "
1424 "LyX might not be able to produce output unless a correct "
1425 "textclass is selected from the document settings dialog."),
1426 from_utf8(classname));
1427 frontend::Alert::error(_("Document class not found"), s);
1428 bcl.addEmptyClass(classname);
1431 if (bcl[classname].load()) {
1432 pimpl_->baseClass_ = classname;
1437 bformat(_("The document class %1$s could not be loaded."),
1438 from_utf8(classname));
1439 frontend::Alert::error(_("Could not load class"), s);
1444 LayoutFile const * BufferParams::baseClass() const
1446 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
1447 return &(LayoutFileList::get()[pimpl_->baseClass_]);
1453 LayoutFileIndex const & BufferParams::baseClassID() const
1455 return pimpl_->baseClass_;
1459 void BufferParams::makeDocumentClass()
1464 doc_class_ = &(DocumentClassBundle::get().newClass(*baseClass()));
1466 // add any required modules not already in use
1467 set<string> const & mods = baseClass()->defaultModules();
1468 set<string>::const_iterator mit = mods.begin();
1469 set<string>::const_iterator men = mods.end();
1470 for (; mit != men; mit++) {
1471 string const & modName = *mit;
1472 LayoutModuleList::const_iterator const fit =
1473 find(layoutModules_.begin(), layoutModules_.end(), modName);
1474 if (fit == layoutModules_.end()) {
1475 // We need to make sure there's no module chosen that excludes this one
1476 LayoutModuleList::const_iterator lit = layoutModules_.begin();
1477 LayoutModuleList::const_iterator len = layoutModules_.end();
1478 bool foundit = false;
1479 // so iterate over the selected modules...
1480 for (; lit != len; lit++) {
1481 LyXModule * lm = moduleList[*lit];
1484 vector<string> const & exc = lm->getExcludedModules();
1485 // ...and see if one of them excludes us.
1486 if (find(exc.begin(), exc.end(), modName) != exc.end()) {
1488 LYXERR(Debug::TCLASS, "Default module `" << modName <<
1489 "' not added because excluded by loaded module `" <<
1495 LYXERR(Debug::TCLASS, "Default module `" << modName << "' added.");
1496 layoutModules_.push_back(modName);
1501 // FIXME It might be worth loading the children's modules here,
1502 // just as we load their bibliographies and such, instead of just
1503 // doing a check in InsetInclude.
1504 LayoutModuleList::const_iterator it = layoutModules_.begin();
1505 for (; it != layoutModules_.end(); it++) {
1506 string const modName = *it;
1507 LyXModule * lm = moduleList[modName];
1509 docstring const msg =
1510 bformat(_("The module %1$s has been requested by\n"
1511 "this document but has not been found in the list of\n"
1512 "available modules. If you recently installed it, you\n"
1513 "probably need to reconfigure LyX.\n"), from_utf8(modName));
1514 frontend::Alert::warning(_("Module not available"),
1515 msg + _("Some layouts may not be available."));
1516 LYXERR0("BufferParams::makeDocumentClass(): Module " <<
1517 modName << " requested but not found in module list.");
1520 if (!lm->isAvailable()) {
1521 docstring const msg =
1522 bformat(_("The module %1$s requires a package that is\n"
1523 "not available in your LaTeX installation. LaTeX output\n"
1524 "may not be possible.\n"), from_utf8(modName));
1525 frontend::Alert::warning(_("Package not available"), msg);
1527 FileName layout_file = libFileSearch("layouts", lm->getFilename());
1528 if (!doc_class_->read(layout_file, TextClass::MODULE)) {
1529 docstring const msg =
1530 bformat(_("Error reading module %1$s\n"), from_utf8(modName));
1531 frontend::Alert::warning(_("Read Error"), msg);
1534 if (!local_layout.empty()) {
1535 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
1536 docstring const msg = _("Error reading internal layout information");
1537 frontend::Alert::warning(_("Read Error"), msg);
1543 vector<string> const & BufferParams::getModules() const
1545 return layoutModules_;
1550 bool BufferParams::addLayoutModule(string const & modName)
1552 LayoutModuleList::const_iterator it = layoutModules_.begin();
1553 LayoutModuleList::const_iterator end = layoutModules_.end();
1554 for (; it != end; it++)
1557 layoutModules_.push_back(modName);
1562 void BufferParams::clearLayoutModules()
1564 layoutModules_.clear();
1568 Font const BufferParams::getFont() const
1570 FontInfo f = documentClass().defaultfont();
1571 if (fontsDefaultFamily == "rmdefault")
1572 f.setFamily(ROMAN_FAMILY);
1573 else if (fontsDefaultFamily == "sfdefault")
1574 f.setFamily(SANS_FAMILY);
1575 else if (fontsDefaultFamily == "ttdefault")
1576 f.setFamily(TYPEWRITER_FAMILY);
1577 return Font(f, language);
1581 void BufferParams::readPreamble(Lexer & lex)
1583 if (lex.getString() != "\\begin_preamble")
1584 lyxerr << "Error (BufferParams::readPreamble):"
1585 "consistency check failed." << endl;
1587 preamble = lex.getLongString("\\end_preamble");
1591 void BufferParams::readLocalLayout(Lexer & lex)
1593 if (lex.getString() != "\\begin_local_layout")
1594 lyxerr << "Error (BufferParams::readLocalLayout):"
1595 "consistency check failed." << endl;
1597 local_layout = lex.getLongString("\\end_local_layout");
1601 void BufferParams::readLanguage(Lexer & lex)
1603 if (!lex.next()) return;
1605 string const tmptok = lex.getString();
1607 // check if tmptok is part of tex_babel in tex-defs.h
1608 language = languages.getLanguage(tmptok);
1610 // Language tmptok was not found
1611 language = default_language;
1612 lyxerr << "Warning: Setting language `"
1613 << tmptok << "' to `" << language->lang()
1619 void BufferParams::readGraphicsDriver(Lexer & lex)
1624 string const tmptok = lex.getString();
1625 // check if tmptok is part of tex_graphics in tex_defs.h
1628 string const test = tex_graphics[n++];
1630 if (test == tmptok) {
1631 graphicsDriver = tmptok;
1636 "Warning: graphics driver `$$Token' not recognized!\n"
1637 " Setting graphics driver to `default'.\n");
1638 graphicsDriver = "default";
1645 void BufferParams::readBullets(Lexer & lex)
1650 int const index = lex.getInteger();
1652 int temp_int = lex.getInteger();
1653 user_defined_bullet(index).setFont(temp_int);
1654 temp_bullet(index).setFont(temp_int);
1656 user_defined_bullet(index).setCharacter(temp_int);
1657 temp_bullet(index).setCharacter(temp_int);
1659 user_defined_bullet(index).setSize(temp_int);
1660 temp_bullet(index).setSize(temp_int);
1664 void BufferParams::readBulletsLaTeX(Lexer & lex)
1666 // The bullet class should be able to read this.
1669 int const index = lex.getInteger();
1671 docstring const temp_str = lex.getDocString();
1673 user_defined_bullet(index).setText(temp_str);
1674 temp_bullet(index).setText(temp_str);
1678 void BufferParams::readModules(Lexer & lex)
1680 if (!lex.eatLine()) {
1681 lyxerr << "Error (BufferParams::readModules):"
1682 "Unexpected end of input." << endl;
1686 string mod = lex.getString();
1687 if (mod == "\\end_modules")
1689 addLayoutModule(mod);
1695 string BufferParams::paperSizeName(PapersizePurpose purpose) const
1697 char real_papersize = papersize;
1698 if (real_papersize == PAPER_DEFAULT)
1699 real_papersize = lyxrc.default_papersize;
1701 switch (real_papersize) {
1703 // could be anything, so don't guess
1705 case PAPER_CUSTOM: {
1706 if (purpose == XDVI && !paperwidth.empty() &&
1707 !paperheight.empty()) {
1708 // heightxwidth<unit>
1709 string first = paperwidth;
1710 string second = paperheight;
1711 if (orientation == ORIENTATION_LANDSCAPE)
1714 return first.erase(first.length() - 2)
1726 // dvips and dvipdfm do not know this
1727 if (purpose == DVIPS || purpose == DVIPDFM)
1731 // dvipdfm does not know this
1732 if (purpose == DVIPDFM)
1736 // dvipdfm does not know this
1737 if (purpose == DVIPDFM)
1740 case PAPER_USEXECUTIVE:
1741 // dvipdfm does not know this
1742 if (purpose == DVIPDFM)
1747 case PAPER_USLETTER:
1749 if (purpose == XDVI)
1756 string const BufferParams::dvips_options() const
1761 && papersize == PAPER_CUSTOM
1762 && !lyxrc.print_paper_dimension_flag.empty()
1763 && !paperwidth.empty()
1764 && !paperheight.empty()) {
1765 // using a custom papersize
1766 result = lyxrc.print_paper_dimension_flag;
1767 result += ' ' + paperwidth;
1768 result += ',' + paperheight;
1770 string const paper_option = paperSizeName(DVIPS);
1771 if (!paper_option.empty() && (paper_option != "letter" ||
1772 orientation != ORIENTATION_LANDSCAPE)) {
1773 // dvips won't accept -t letter -t landscape.
1774 // In all other cases, include the paper size
1776 result = lyxrc.print_paper_flag;
1777 result += ' ' + paper_option;
1780 if (orientation == ORIENTATION_LANDSCAPE &&
1781 papersize != PAPER_CUSTOM)
1782 result += ' ' + lyxrc.print_landscape_flag;
1787 string BufferParams::babelCall(string const & lang_opts) const
1789 string lang_pack = lyxrc.language_package;
1790 if (lang_pack != "\\usepackage{babel}")
1792 // suppress the babel call when there is no babel language defined
1793 // for the document language in the lib/languages file and if no
1794 // other languages are used (lang_opts is then empty)
1795 if (lang_opts.empty())
1797 // If Vietnamese is used, babel must directly be loaded with the
1798 // language options, see
1799 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1800 size_t viet = lang_opts.find("vietnam");
1801 // viet = string::npos when not found
1802 // If Japanese is used, babel must directly be loaded with the
1803 // language options, see
1804 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1805 size_t japan = lang_opts.find("japanese");
1806 // japan = string::npos when not found
1807 if (!lyxrc.language_global_options || viet != string::npos || japan != string::npos)
1808 return "\\usepackage[" + lang_opts + "]{babel}";
1813 void BufferParams::writeEncodingPreamble(odocstream & os,
1814 LaTeXFeatures & features, TexRow & texrow) const
1816 if (inputenc == "auto") {
1817 string const doc_encoding =
1818 language->encoding()->latexName();
1819 Encoding::Package const package =
1820 language->encoding()->package();
1822 // Create a list with all the input encodings used
1824 set<string> encodings =
1825 features.getEncodingSet(doc_encoding);
1827 // If the encodings EUC-JP-plain, JIS-plain, or SJIS-plain are used, the
1828 // package inputenc must be omitted. Therefore set the encoding to empty.
1829 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
1830 if (doc_encoding == "EUC-JP-plain" || doc_encoding == "JIS-plain" ||
1831 doc_encoding == "SJIS-plain")
1834 if (!encodings.empty() || package == Encoding::inputenc) {
1835 os << "\\usepackage[";
1836 set<string>::const_iterator it = encodings.begin();
1837 set<string>::const_iterator const end = encodings.end();
1839 os << from_ascii(*it);
1842 for (; it != end; ++it)
1843 os << ',' << from_ascii(*it);
1844 if (package == Encoding::inputenc) {
1845 if (!encodings.empty())
1847 os << from_ascii(doc_encoding);
1849 os << "]{inputenc}\n";
1852 if (package == Encoding::CJK || features.mustProvide("CJK")) {
1853 os << "\\usepackage{CJK}\n";
1856 } else if (inputenc != "default") {
1857 switch (encoding().package()) {
1858 case Encoding::none:
1860 case Encoding::inputenc:
1861 os << "\\usepackage[" << from_ascii(inputenc)
1866 os << "\\usepackage{CJK}\n";
1872 // The encoding "armscii8" is only available when the package "armtex" is loaded.
1873 // armscii8 is used for Armenian.
1874 if (language->encoding()->latexName() == "armscii8" || inputenc == "armscii8") {
1875 os << "\\usepackage{armtex}\n";
1881 string const BufferParams::loadFonts(string const & rm,
1882 string const & sf, string const & tt,
1883 bool const & sc, bool const & osf,
1884 int const & sfscale, int const & ttscale) const
1886 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
1887 several packages have been replaced by others, that might not
1888 be installed on every system. We have to take care for that
1889 (see psnfss.pdf). We try to support all psnfss fonts as well
1890 as the fonts that have become de facto standard in the LaTeX
1891 world (e.g. Latin Modern). We do not support obsolete fonts
1892 (like PSLatex). In general, it should be possible to mix any
1893 rm font with any sf or tt font, respectively. (JSpitzm)
1895 -- separate math fonts.
1898 if (rm == "default" && sf == "default" && tt == "default")
1905 // Computer Modern (must be explicitely selectable -- there might be classes
1906 // that define a different default font!
1908 os << "\\renewcommand{\\rmdefault}{cmr}\n";
1909 // osf for Computer Modern needs eco.sty
1911 os << "\\usepackage{eco}\n";
1913 // Latin Modern Roman
1914 else if (rm == "lmodern")
1915 os << "\\usepackage{lmodern}\n";
1917 else if (rm == "ae") {
1918 // not needed when using OT1 font encoding.
1919 if (lyxrc.fontenc != "default")
1920 os << "\\usepackage{ae,aecompl}\n";
1923 else if (rm == "times") {
1924 // try to load the best available package
1925 if (LaTeXFeatures::isAvailable("mathptmx"))
1926 os << "\\usepackage{mathptmx}\n";
1927 else if (LaTeXFeatures::isAvailable("mathptm"))
1928 os << "\\usepackage{mathptm}\n";
1930 os << "\\usepackage{times}\n";
1933 else if (rm == "palatino") {
1934 // try to load the best available package
1935 if (LaTeXFeatures::isAvailable("mathpazo")) {
1936 os << "\\usepackage";
1942 // "osf" includes "sc"!
1946 os << "{mathpazo}\n";
1948 else if (LaTeXFeatures::isAvailable("mathpple"))
1949 os << "\\usepackage{mathpple}\n";
1951 os << "\\usepackage{palatino}\n";
1954 else if (rm == "utopia") {
1955 // fourier supersedes utopia.sty, but does
1956 // not work with OT1 encoding.
1957 if (LaTeXFeatures::isAvailable("fourier")
1958 && lyxrc.fontenc != "default") {
1959 os << "\\usepackage";
1970 os << "{fourier}\n";
1973 os << "\\usepackage{utopia}\n";
1975 // Bera (complete fontset)
1976 else if (rm == "bera" && sf == "default" && tt == "default")
1977 os << "\\usepackage{bera}\n";
1979 else if (rm != "default")
1980 os << "\\usepackage" << "{" << rm << "}\n";
1983 // Helvetica, Bera Sans
1984 if (sf == "helvet" || sf == "berasans") {
1986 os << "\\usepackage[scaled=" << float(sfscale) / 100
1987 << "]{" << sf << "}\n";
1989 os << "\\usepackage{" << sf << "}\n";
1992 else if (sf == "avant")
1993 os << "\\usepackage{" << sf << "}\n";
1994 // Computer Modern, Latin Modern, CM Bright
1995 else if (sf != "default")
1996 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
1998 // monospaced/typewriter
1999 // Courier, LuxiMono
2000 if (tt == "luximono" || tt == "beramono") {
2002 os << "\\usepackage[scaled=" << float(ttscale) / 100
2003 << "]{" << tt << "}\n";
2005 os << "\\usepackage{" << tt << "}\n";
2008 else if (tt == "courier" )
2009 os << "\\usepackage{" << tt << "}\n";
2010 // Computer Modern, Latin Modern, CM Bright
2011 else if (tt != "default")
2012 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
2018 Encoding const & BufferParams::encoding() const
2020 if (inputenc == "auto" || inputenc == "default")
2021 return *language->encoding();
2022 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
2025 LYXERR0("Unknown inputenc value `" << inputenc
2026 << "'. Using `auto' instead.");
2027 return *language->encoding();
2031 CiteEngine BufferParams::citeEngine() const
2033 // FIXME the class should provide the numerical/
2034 // authoryear choice
2035 if (documentClass().provides("natbib")
2036 && cite_engine_ != ENGINE_NATBIB_NUMERICAL)
2037 return ENGINE_NATBIB_AUTHORYEAR;
2038 return cite_engine_;
2042 void BufferParams::setCiteEngine(CiteEngine cite_engine)
2044 cite_engine_ = cite_engine;