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"
27 #include "Converter.h"
30 #include "IndicesList.h"
32 #include "LaTeXFeatures.h"
33 #include "ModuleList.h"
37 #include "OutputParams.h"
41 #include "PDFOptions.h"
43 #include "frontends/alert.h"
45 #include "insets/InsetListingsParams.h"
47 #include "support/convert.h"
48 #include "support/debug.h"
49 #include "support/docstream.h"
50 #include "support/FileName.h"
51 #include "support/filetools.h"
52 #include "support/gettext.h"
53 #include "support/Messages.h"
54 #include "support/Translator.h"
55 #include "support/lstrings.h"
61 using namespace lyx::support;
64 static char const * const string_paragraph_separation[] = {
69 static char const * const string_quotes_language[] = {
70 "english", "swedish", "german", "polish", "french", "danish", ""
74 static char const * const string_papersize[] = {
75 "default", "custom", "letterpaper", "legalpaper", "executivepaper",
76 "a0paper", "a1paper", "a2paper", "a3paper", "a4paper", "a5paper",
77 "a6paper", "b0paper", "b1paper", "b2paper","b3paper", "b4paper",
78 "b5paper", "b6paper", "c0paper", "c1paper", "c2paper", "c3paper",
79 "c4paper", "c5paper", "c6paper", "b0j", "b1j", "b2j", "b3j", "b4j", "b5j",
84 static char const * const string_orientation[] = {
85 "portrait", "landscape", ""
89 static char const * const string_footnotekinds[] = {
90 "footnote", "margin", "fig", "tab", "alg", "wide-fig", "wide-tab", ""
94 static char const * const tex_graphics[] = {
95 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
96 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
97 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
98 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
109 // Paragraph separation
110 typedef Translator<string, BufferParams::ParagraphSeparation> ParSepTranslator;
113 ParSepTranslator const init_parseptranslator()
115 ParSepTranslator translator
116 (string_paragraph_separation[0], BufferParams::ParagraphIndentSeparation);
117 translator.addPair(string_paragraph_separation[1], BufferParams::ParagraphSkipSeparation);
122 ParSepTranslator const & parseptranslator()
124 static ParSepTranslator translator = init_parseptranslator();
130 typedef Translator<string, InsetQuotes::QuoteLanguage> QuotesLangTranslator;
133 QuotesLangTranslator const init_quoteslangtranslator()
135 QuotesLangTranslator translator
136 (string_quotes_language[0], InsetQuotes::EnglishQuotes);
137 translator.addPair(string_quotes_language[1], InsetQuotes::SwedishQuotes);
138 translator.addPair(string_quotes_language[2], InsetQuotes::GermanQuotes);
139 translator.addPair(string_quotes_language[3], InsetQuotes::PolishQuotes);
140 translator.addPair(string_quotes_language[4], InsetQuotes::FrenchQuotes);
141 translator.addPair(string_quotes_language[5], InsetQuotes::DanishQuotes);
146 QuotesLangTranslator const & quoteslangtranslator()
148 static QuotesLangTranslator translator = init_quoteslangtranslator();
154 typedef Translator<string, PAPER_SIZE> PaperSizeTranslator;
157 static PaperSizeTranslator initPaperSizeTranslator()
159 PaperSizeTranslator translator(string_papersize[0], PAPER_DEFAULT);
160 translator.addPair(string_papersize[1], PAPER_CUSTOM);
161 translator.addPair(string_papersize[2], PAPER_USLETTER);
162 translator.addPair(string_papersize[3], PAPER_USLEGAL);
163 translator.addPair(string_papersize[4], PAPER_USEXECUTIVE);
164 translator.addPair(string_papersize[5], PAPER_A0);
165 translator.addPair(string_papersize[6], PAPER_A1);
166 translator.addPair(string_papersize[7], PAPER_A2);
167 translator.addPair(string_papersize[8], PAPER_A3);
168 translator.addPair(string_papersize[9], PAPER_A4);
169 translator.addPair(string_papersize[10], PAPER_A5);
170 translator.addPair(string_papersize[11], PAPER_A6);
171 translator.addPair(string_papersize[12], PAPER_B0);
172 translator.addPair(string_papersize[13], PAPER_B1);
173 translator.addPair(string_papersize[14], PAPER_B2);
174 translator.addPair(string_papersize[15], PAPER_B3);
175 translator.addPair(string_papersize[16], PAPER_B4);
176 translator.addPair(string_papersize[17], PAPER_B5);
177 translator.addPair(string_papersize[18], PAPER_B6);
178 translator.addPair(string_papersize[19], PAPER_C0);
179 translator.addPair(string_papersize[20], PAPER_C1);
180 translator.addPair(string_papersize[21], PAPER_C2);
181 translator.addPair(string_papersize[22], PAPER_C3);
182 translator.addPair(string_papersize[23], PAPER_C4);
183 translator.addPair(string_papersize[24], PAPER_C5);
184 translator.addPair(string_papersize[25], PAPER_C6);
185 translator.addPair(string_papersize[26], PAPER_JISB0);
186 translator.addPair(string_papersize[27], PAPER_JISB1);
187 translator.addPair(string_papersize[28], PAPER_JISB2);
188 translator.addPair(string_papersize[29], PAPER_JISB3);
189 translator.addPair(string_papersize[30], PAPER_JISB4);
190 translator.addPair(string_papersize[31], PAPER_JISB5);
191 translator.addPair(string_papersize[32], PAPER_JISB6);
196 PaperSizeTranslator const & papersizetranslator()
198 static PaperSizeTranslator translator = initPaperSizeTranslator();
204 typedef Translator<string, PAPER_ORIENTATION> PaperOrientationTranslator;
207 PaperOrientationTranslator const init_paperorientationtranslator()
209 PaperOrientationTranslator translator(string_orientation[0], ORIENTATION_PORTRAIT);
210 translator.addPair(string_orientation[1], ORIENTATION_LANDSCAPE);
215 PaperOrientationTranslator const & paperorientationtranslator()
217 static PaperOrientationTranslator translator = init_paperorientationtranslator();
223 typedef Translator<int, PageSides> SidesTranslator;
226 SidesTranslator const init_sidestranslator()
228 SidesTranslator translator(1, OneSide);
229 translator.addPair(2, TwoSides);
234 SidesTranslator const & sidestranslator()
236 static SidesTranslator translator = init_sidestranslator();
242 typedef Translator<int, BufferParams::Package> PackageTranslator;
245 PackageTranslator const init_packagetranslator()
247 PackageTranslator translator(0, BufferParams::package_off);
248 translator.addPair(1, BufferParams::package_auto);
249 translator.addPair(2, BufferParams::package_on);
254 PackageTranslator const & packagetranslator()
256 static PackageTranslator translator = init_packagetranslator();
262 typedef Translator<string, CiteEngine> CiteEngineTranslator;
265 CiteEngineTranslator const init_citeenginetranslator()
267 CiteEngineTranslator translator("basic", ENGINE_BASIC);
268 translator.addPair("natbib", ENGINE_NATBIB);
269 translator.addPair("jurabib", ENGINE_JURABIB);
274 CiteEngineTranslator const & citeenginetranslator()
276 static CiteEngineTranslator translator = init_citeenginetranslator();
281 typedef Translator<string, CiteEngineType> CiteEngineTypeTranslator;
284 CiteEngineTypeTranslator const init_citeenginetypetranslator()
286 CiteEngineTypeTranslator translator("authoryear", ENGINE_TYPE_AUTHORYEAR);
287 translator.addPair("numerical", ENGINE_TYPE_NUMERICAL);
292 CiteEngineTypeTranslator const & citeenginetypetranslator()
294 static CiteEngineTypeTranslator translator = init_citeenginetypetranslator();
300 typedef Translator<string, Spacing::Space> SpaceTranslator;
303 SpaceTranslator const init_spacetranslator()
305 SpaceTranslator translator("default", Spacing::Default);
306 translator.addPair("single", Spacing::Single);
307 translator.addPair("onehalf", Spacing::Onehalf);
308 translator.addPair("double", Spacing::Double);
309 translator.addPair("other", Spacing::Other);
314 SpaceTranslator const & spacetranslator()
316 static SpaceTranslator translator = init_spacetranslator();
323 class BufferParams::Impl
328 AuthorList authorlist;
329 BranchList branchlist;
330 Bullet temp_bullets[4];
331 Bullet user_defined_bullets[4];
332 IndicesList indiceslist;
334 /** This is the amount of space used for paragraph_separation "skip",
335 * and for detached paragraphs in "indented" documents.
339 PDFOptions pdfoptions;
340 LayoutFileIndex baseClass_;
344 BufferParams::Impl::Impl()
345 : defskip(VSpace::MEDSKIP), baseClass_(string(""))
347 // set initial author
349 authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
354 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
358 return new BufferParams::Impl(*ptr);
362 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
368 BufferParams::BufferParams()
371 setBaseClass(defaultBaseclass());
373 paragraph_separation = ParagraphIndentSeparation;
374 quotes_language = InsetQuotes::EnglishQuotes;
375 fontsize = "default";
378 papersize = PAPER_DEFAULT;
379 orientation = ORIENTATION_PORTRAIT;
380 use_geometry = false;
381 cite_engine_ = ENGINE_BASIC;
382 cite_engine_type_ = ENGINE_TYPE_NUMERICAL;
383 biblio_style = "plain";
384 use_bibtopic = false;
386 trackChanges = false;
387 outputChanges = false;
388 use_default_options = true;
389 maintain_unincluded_children = false;
392 language = default_language;
394 fonts_roman = "default";
395 fonts_sans = "default";
396 fonts_typewriter = "default";
397 fonts_default_family = "default";
398 useNonTeXFonts = false;
399 fonts_expert_sc = false;
400 fonts_old_figures = false;
401 fonts_sans_scale = 100;
402 fonts_typewriter_scale = 100;
404 lang_package = "default";
405 graphics_driver = "default";
406 default_output_format = "default";
407 bibtex_command = "default";
408 index_command = "default";
411 listings_params = string();
412 pagestyle = "default";
413 suppress_date = false;
414 justification = true;
415 // no color is the default (white)
416 backgroundcolor = lyx::rgbFromHexName("#ffffff");
417 isbackgroundcolor = false;
418 // no color is the default (black)
419 fontcolor = lyx::rgbFromHexName("#000000");
421 // light gray is the default font color for greyed-out notes
422 notefontcolor = lyx::rgbFromHexName("#cccccc");
423 boxbgcolor = lyx::rgbFromHexName("#ff0000");
424 compressed = lyxrc.save_compressed;
425 for (int iter = 0; iter < 4; ++iter) {
426 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
427 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
430 indiceslist().addDefault(B_("Index"));
431 html_be_strict = false;
432 html_math_output = MathML;
433 html_math_img_scale = 1.0;
434 html_css_as_file = false;
441 docstring BufferParams::B_(string const & l10n) const
443 LASSERT(language, /**/);
444 return getMessages(language->code()).get(l10n);
448 BufferParams::Package BufferParams::use_package(std::string const & p) const
450 PackageMap::const_iterator it = use_packages.find(p);
451 if (it == use_packages.end())
457 void BufferParams::use_package(std::string const & p, BufferParams::Package u)
463 vector<string> const & BufferParams::auto_packages()
465 static vector<string> packages;
466 if (packages.empty()) {
467 // adding a package here implies a file format change!
468 packages.push_back("amsmath");
469 packages.push_back("esint");
470 packages.push_back("mathdots");
471 packages.push_back("mathtools");
472 packages.push_back("mhchem");
473 packages.push_back("undertilde");
479 AuthorList & BufferParams::authors()
481 return pimpl_->authorlist;
485 AuthorList const & BufferParams::authors() const
487 return pimpl_->authorlist;
491 BranchList & BufferParams::branchlist()
493 return pimpl_->branchlist;
497 BranchList const & BufferParams::branchlist() const
499 return pimpl_->branchlist;
503 IndicesList & BufferParams::indiceslist()
505 return pimpl_->indiceslist;
509 IndicesList const & BufferParams::indiceslist() const
511 return pimpl_->indiceslist;
515 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
517 LASSERT(index < 4, /**/);
518 return pimpl_->temp_bullets[index];
522 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
524 LASSERT(index < 4, /**/);
525 return pimpl_->temp_bullets[index];
529 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
531 LASSERT(index < 4, /**/);
532 return pimpl_->user_defined_bullets[index];
536 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
538 LASSERT(index < 4, /**/);
539 return pimpl_->user_defined_bullets[index];
543 Spacing & BufferParams::spacing()
545 return pimpl_->spacing;
549 Spacing const & BufferParams::spacing() const
551 return pimpl_->spacing;
555 PDFOptions & BufferParams::pdfoptions()
557 return pimpl_->pdfoptions;
561 PDFOptions const & BufferParams::pdfoptions() const
563 return pimpl_->pdfoptions;
567 HSpace const & BufferParams::getIndentation() const
569 return pimpl_->indentation;
573 void BufferParams::setIndentation(HSpace const & indent)
575 pimpl_->indentation = indent;
579 VSpace const & BufferParams::getDefSkip() const
581 return pimpl_->defskip;
585 void BufferParams::setDefSkip(VSpace const & vs)
587 // DEFSKIP will cause an infinite loop
588 LASSERT(vs.kind() != VSpace::DEFSKIP, return);
589 pimpl_->defskip = vs;
593 string BufferParams::readToken(Lexer & lex, string const & token,
594 FileName const & filepath)
596 if (token == "\\textclass") {
598 string const classname = lex.getString();
599 // if there exists a local layout file, ignore the system one
600 // NOTE: in this case, the textclass (.cls file) is assumed to
603 LayoutFileList & bcl = LayoutFileList::get();
604 if (tcp.empty() && !filepath.empty())
605 tcp = bcl.addLocalLayout(classname, filepath.absFileName());
609 setBaseClass(classname);
610 // We assume that a tex class exists for local or unknown
611 // layouts so this warning, will only be given for system layouts.
612 if (!baseClass()->isTeXClassAvailable()) {
613 docstring const desc =
614 translateIfPossible(from_utf8(baseClass()->description()));
615 docstring const prereqs =
616 from_utf8(baseClass()->prerequisites());
617 docstring const msg =
618 bformat(_("The selected document class\n"
620 "requires external files that are not available.\n"
621 "The document class can still be used, but the\n"
622 "document cannot be compiled until the following\n"
623 "prerequisites are installed:\n"
625 "See section 3.1.2.2 (Class Availability) of the\n"
626 "User's Guide for more information."), desc, prereqs);
627 frontend::Alert::warning(_("Document class not available"),
630 } else if (token == "\\begin_preamble") {
632 } else if (token == "\\begin_local_layout") {
633 readLocalLayout(lex);
634 } else if (token == "\\begin_modules") {
636 } else if (token == "\\begin_removed_modules") {
637 readRemovedModules(lex);
638 } else if (token == "\\begin_includeonly") {
639 readIncludeonly(lex);
640 } else if (token == "\\maintain_unincluded_children") {
641 lex >> maintain_unincluded_children;
642 } else if (token == "\\options") {
644 options = lex.getString();
645 } else if (token == "\\use_default_options") {
646 lex >> use_default_options;
647 } else if (token == "\\master") {
649 master = lex.getString();
650 } else if (token == "\\suppress_date") {
651 lex >> suppress_date;
652 } else if (token == "\\justification") {
653 lex >> justification;
654 } else if (token == "\\language") {
656 } else if (token == "\\language_package") {
658 lang_package = lex.getString();
659 } else if (token == "\\inputencoding") {
661 } else if (token == "\\graphics") {
662 readGraphicsDriver(lex);
663 } else if (token == "\\default_output_format") {
664 lex >> default_output_format;
665 } else if (token == "\\bibtex_command") {
667 bibtex_command = lex.getString();
668 } else if (token == "\\index_command") {
670 index_command = lex.getString();
671 } else if (token == "\\fontencoding") {
673 fontenc = lex.getString();
674 } else if (token == "\\font_roman") {
676 fonts_roman = lex.getString();
677 } else if (token == "\\font_sans") {
679 fonts_sans = lex.getString();
680 } else if (token == "\\font_typewriter") {
682 fonts_typewriter = lex.getString();
683 } else if (token == "\\font_default_family") {
684 lex >> fonts_default_family;
685 } else if (token == "\\use_non_tex_fonts") {
686 lex >> useNonTeXFonts;
687 } else if (token == "\\font_sc") {
688 lex >> fonts_expert_sc;
689 } else if (token == "\\font_osf") {
690 lex >> fonts_old_figures;
691 } else if (token == "\\font_sf_scale") {
692 lex >> fonts_sans_scale;
693 } else if (token == "\\font_tt_scale") {
694 lex >> fonts_typewriter_scale;
695 } else if (token == "\\font_cjk") {
697 } else if (token == "\\paragraph_separation") {
700 paragraph_separation = parseptranslator().find(parsep);
701 } else if (token == "\\paragraph_indentation") {
703 string indentation = lex.getString();
704 pimpl_->indentation = HSpace(indentation);
705 } else if (token == "\\defskip") {
707 string const defskip = lex.getString();
708 pimpl_->defskip = VSpace(defskip);
709 if (pimpl_->defskip.kind() == VSpace::DEFSKIP)
711 pimpl_->defskip = VSpace(VSpace::MEDSKIP);
712 } else if (token == "\\quotes_language") {
715 quotes_language = quoteslangtranslator().find(quotes_lang);
716 } else if (token == "\\papersize") {
719 papersize = papersizetranslator().find(ppsize);
720 } else if (token == "\\use_geometry") {
722 } else if (token == "\\use_package") {
727 use_package(package, packagetranslator().find(use));
728 } else if (token == "\\cite_engine") {
731 cite_engine_ = citeenginetranslator().find(engine);
732 } else if (token == "\\cite_engine_type") {
735 cite_engine_type_ = citeenginetypetranslator().find(engine_type);
736 } else if (token == "\\biblio_style") {
738 biblio_style = lex.getString();
739 } else if (token == "\\use_bibtopic") {
741 } else if (token == "\\use_indices") {
743 } else if (token == "\\tracking_changes") {
745 } else if (token == "\\output_changes") {
746 lex >> outputChanges;
747 } else if (token == "\\branch") {
749 docstring branch = lex.getDocString();
750 branchlist().add(branch);
753 string const tok = lex.getString();
754 if (tok == "\\end_branch")
756 Branch * branch_ptr = branchlist().find(branch);
757 if (tok == "\\selected") {
760 branch_ptr->setSelected(lex.getInteger());
762 if (tok == "\\filename_suffix") {
765 branch_ptr->setFileNameSuffix(lex.getInteger());
767 if (tok == "\\color") {
769 string color = lex.getString();
771 branch_ptr->setColor(color);
772 // Update also the Color table:
774 color = lcolor.getX11Name(Color_background);
776 lcolor.setColor(to_utf8(branch), color);
779 } else if (token == "\\index") {
781 docstring index = lex.getDocString();
783 indiceslist().add(index);
786 string const tok = lex.getString();
787 if (tok == "\\end_index")
789 Index * index_ptr = indiceslist().find(index);
790 if (tok == "\\shortcut") {
792 shortcut = lex.getDocString();
794 index_ptr->setShortcut(shortcut);
796 if (tok == "\\color") {
798 string color = lex.getString();
800 index_ptr->setColor(color);
801 // Update also the Color table:
803 color = lcolor.getX11Name(Color_background);
805 if (!shortcut.empty())
806 lcolor.setColor(to_utf8(shortcut), color);
809 } else if (token == "\\author") {
811 istringstream ss(lex.getString());
814 author_map[a.bufferId()] = pimpl_->authorlist.record(a);
815 } else if (token == "\\paperorientation") {
818 orientation = paperorientationtranslator().find(orient);
819 } else if (token == "\\backgroundcolor") {
821 backgroundcolor = lyx::rgbFromHexName(lex.getString());
822 isbackgroundcolor = true;
823 } else if (token == "\\fontcolor") {
825 fontcolor = lyx::rgbFromHexName(lex.getString());
827 } else if (token == "\\notefontcolor") {
829 string color = lex.getString();
830 notefontcolor = lyx::rgbFromHexName(color);
831 } else if (token == "\\boxbgcolor") {
833 string color = lex.getString();
834 boxbgcolor = lyx::rgbFromHexName(color);
835 } else if (token == "\\paperwidth") {
837 } else if (token == "\\paperheight") {
839 } else if (token == "\\leftmargin") {
841 } else if (token == "\\topmargin") {
843 } else if (token == "\\rightmargin") {
845 } else if (token == "\\bottommargin") {
847 } else if (token == "\\headheight") {
849 } else if (token == "\\headsep") {
851 } else if (token == "\\footskip") {
853 } else if (token == "\\columnsep") {
855 } else if (token == "\\paperfontsize") {
857 } else if (token == "\\papercolumns") {
859 } else if (token == "\\listings_params") {
862 listings_params = InsetListingsParams(par).params();
863 } else if (token == "\\papersides") {
866 sides = sidestranslator().find(psides);
867 } else if (token == "\\paperpagestyle") {
869 } else if (token == "\\bullet") {
871 } else if (token == "\\bulletLaTeX") {
872 readBulletsLaTeX(lex);
873 } else if (token == "\\secnumdepth") {
875 } else if (token == "\\tocdepth") {
877 } else if (token == "\\spacing") {
881 if (nspacing == "other") {
884 spacing().set(spacetranslator().find(nspacing), tmp_val);
885 } else if (token == "\\float_placement") {
886 lex >> float_placement;
888 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
889 string toktmp = pdfoptions().readToken(lex, token);
890 if (!toktmp.empty()) {
891 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
895 } else if (token == "\\html_math_output") {
898 html_math_output = static_cast<MathOutput>(temp);
899 } else if (token == "\\html_be_strict") {
900 lex >> html_be_strict;
901 } else if (token == "\\html_css_as_file") {
902 lex >> html_css_as_file;
903 } else if (token == "\\html_math_img_scale") {
904 lex >> html_math_img_scale;
905 } else if (token == "\\html_latex_start") {
907 html_latex_start = lex.getString();
908 } else if (token == "\\html_latex_end") {
910 html_latex_end = lex.getString();
911 } else if (token == "\\output_sync") {
913 } else if (token == "\\output_sync_macro") {
914 lex >> output_sync_macro;
915 } else if (token == "\\use_refstyle") {
918 lyxerr << "BufferParams::readToken(): Unknown token: " <<
927 void BufferParams::writeFile(ostream & os) const
929 // The top of the file is written by the buffer.
930 // Prints out the buffer info into the .lyx file given by file
933 os << "\\textclass " << baseClass()->name() << '\n';
936 if (!preamble.empty()) {
937 // remove '\n' from the end of preamble
938 string const tmppreamble = rtrim(preamble, "\n");
939 os << "\\begin_preamble\n"
941 << "\n\\end_preamble\n";
945 if (!options.empty()) {
946 os << "\\options " << options << '\n';
949 // use the class options defined in the layout?
950 os << "\\use_default_options "
951 << convert<string>(use_default_options) << "\n";
953 // the master document
954 if (!master.empty()) {
955 os << "\\master " << master << '\n';
959 if (!removed_modules_.empty()) {
960 os << "\\begin_removed_modules" << '\n';
961 list<string>::const_iterator it = removed_modules_.begin();
962 list<string>::const_iterator en = removed_modules_.end();
963 for (; it != en; it++)
965 os << "\\end_removed_modules" << '\n';
969 if (!layout_modules_.empty()) {
970 os << "\\begin_modules" << '\n';
971 LayoutModuleList::const_iterator it = layout_modules_.begin();
972 LayoutModuleList::const_iterator en = layout_modules_.end();
973 for (; it != en; it++)
975 os << "\\end_modules" << '\n';
979 if (!included_children_.empty()) {
980 os << "\\begin_includeonly" << '\n';
981 list<string>::const_iterator it = included_children_.begin();
982 list<string>::const_iterator en = included_children_.end();
983 for (; it != en; it++)
985 os << "\\end_includeonly" << '\n';
987 os << "\\maintain_unincluded_children "
988 << convert<string>(maintain_unincluded_children) << '\n';
990 // local layout information
991 if (!local_layout.empty()) {
992 // remove '\n' from the end
993 string const tmplocal = rtrim(local_layout, "\n");
994 os << "\\begin_local_layout\n"
996 << "\n\\end_local_layout\n";
999 // then the text parameters
1000 if (language != ignore_language)
1001 os << "\\language " << language->lang() << '\n';
1002 os << "\\language_package " << lang_package
1003 << "\n\\inputencoding " << inputenc
1004 << "\n\\fontencoding " << fontenc
1005 << "\n\\font_roman " << fonts_roman
1006 << "\n\\font_sans " << fonts_sans
1007 << "\n\\font_typewriter " << fonts_typewriter
1008 << "\n\\font_default_family " << fonts_default_family
1009 << "\n\\use_non_tex_fonts " << convert<string>(useNonTeXFonts)
1010 << "\n\\font_sc " << convert<string>(fonts_expert_sc)
1011 << "\n\\font_osf " << convert<string>(fonts_old_figures)
1012 << "\n\\font_sf_scale " << fonts_sans_scale
1013 << "\n\\font_tt_scale " << fonts_typewriter_scale
1015 if (!fonts_cjk.empty()) {
1016 os << "\\font_cjk " << fonts_cjk << '\n';
1018 os << "\n\\graphics " << graphics_driver << '\n';
1019 os << "\\default_output_format " << default_output_format << '\n';
1020 os << "\\output_sync " << output_sync << '\n';
1021 if (!output_sync_macro.empty())
1022 os << "\\output_sync_macro \"" << output_sync_macro << "\"\n";
1023 os << "\\bibtex_command " << bibtex_command << '\n';
1024 os << "\\index_command " << index_command << '\n';
1026 if (!float_placement.empty()) {
1027 os << "\\float_placement " << float_placement << '\n';
1029 os << "\\paperfontsize " << fontsize << '\n';
1031 spacing().writeFile(os);
1032 pdfoptions().writeFile(os);
1034 os << "\\papersize " << string_papersize[papersize]
1035 << "\n\\use_geometry " << convert<string>(use_geometry);
1036 vector<string> const & packages = auto_packages();
1037 for (size_t i = 0; i < packages.size(); ++i)
1038 os << "\n\\use_package " << packages[i] << ' '
1039 << use_package(packages[i]);
1040 os << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
1041 << "\n\\cite_engine_type " << citeenginetypetranslator().find(cite_engine_type_)
1042 << "\n\\biblio_style " << biblio_style
1043 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
1044 << "\n\\use_indices " << convert<string>(use_indices)
1045 << "\n\\paperorientation " << string_orientation[orientation]
1046 << "\n\\suppress_date " << convert<string>(suppress_date)
1047 << "\n\\justification " << convert<string>(justification)
1048 << "\n\\use_refstyle " << use_refstyle
1050 if (isbackgroundcolor == true)
1051 os << "\\backgroundcolor " << lyx::X11hexname(backgroundcolor) << '\n';
1052 if (isfontcolor == true)
1053 os << "\\fontcolor " << lyx::X11hexname(fontcolor) << '\n';
1054 if (notefontcolor != lyx::rgbFromHexName("#cccccc"))
1055 os << "\\notefontcolor " << lyx::X11hexname(notefontcolor) << '\n';
1056 if (boxbgcolor != lyx::rgbFromHexName("#ff0000"))
1057 os << "\\boxbgcolor " << lyx::X11hexname(boxbgcolor) << '\n';
1059 BranchList::const_iterator it = branchlist().begin();
1060 BranchList::const_iterator end = branchlist().end();
1061 for (; it != end; ++it) {
1062 os << "\\branch " << to_utf8(it->branch())
1063 << "\n\\selected " << it->isSelected()
1064 << "\n\\filename_suffix " << it->hasFileNameSuffix()
1065 << "\n\\color " << lyx::X11hexname(it->color())
1070 IndicesList::const_iterator iit = indiceslist().begin();
1071 IndicesList::const_iterator iend = indiceslist().end();
1072 for (; iit != iend; ++iit) {
1073 os << "\\index " << to_utf8(iit->index())
1074 << "\n\\shortcut " << to_utf8(iit->shortcut())
1075 << "\n\\color " << lyx::X11hexname(iit->color())
1080 if (!paperwidth.empty())
1081 os << "\\paperwidth "
1082 << VSpace(paperwidth).asLyXCommand() << '\n';
1083 if (!paperheight.empty())
1084 os << "\\paperheight "
1085 << VSpace(paperheight).asLyXCommand() << '\n';
1086 if (!leftmargin.empty())
1087 os << "\\leftmargin "
1088 << VSpace(leftmargin).asLyXCommand() << '\n';
1089 if (!topmargin.empty())
1090 os << "\\topmargin "
1091 << VSpace(topmargin).asLyXCommand() << '\n';
1092 if (!rightmargin.empty())
1093 os << "\\rightmargin "
1094 << VSpace(rightmargin).asLyXCommand() << '\n';
1095 if (!bottommargin.empty())
1096 os << "\\bottommargin "
1097 << VSpace(bottommargin).asLyXCommand() << '\n';
1098 if (!headheight.empty())
1099 os << "\\headheight "
1100 << VSpace(headheight).asLyXCommand() << '\n';
1101 if (!headsep.empty())
1103 << VSpace(headsep).asLyXCommand() << '\n';
1104 if (!footskip.empty())
1106 << VSpace(footskip).asLyXCommand() << '\n';
1107 if (!columnsep.empty())
1108 os << "\\columnsep "
1109 << VSpace(columnsep).asLyXCommand() << '\n';
1110 os << "\\secnumdepth " << secnumdepth
1111 << "\n\\tocdepth " << tocdepth
1112 << "\n\\paragraph_separation "
1113 << string_paragraph_separation[paragraph_separation];
1114 if (!paragraph_separation)
1115 os << "\n\\paragraph_indentation " << getIndentation().asLyXCommand();
1117 os << "\n\\defskip " << getDefSkip().asLyXCommand();
1118 os << "\n\\quotes_language "
1119 << string_quotes_language[quotes_language]
1120 << "\n\\papercolumns " << columns
1121 << "\n\\papersides " << sides
1122 << "\n\\paperpagestyle " << pagestyle << '\n';
1123 if (!listings_params.empty())
1124 os << "\\listings_params \"" <<
1125 InsetListingsParams(listings_params).encodedString() << "\"\n";
1126 for (int i = 0; i < 4; ++i) {
1127 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1128 if (user_defined_bullet(i).getFont() != -1) {
1129 os << "\\bullet " << i << " "
1130 << user_defined_bullet(i).getFont() << " "
1131 << user_defined_bullet(i).getCharacter() << " "
1132 << user_defined_bullet(i).getSize() << "\n";
1136 os << "\\bulletLaTeX " << i << " \""
1137 << lyx::to_ascii(user_defined_bullet(i).getText())
1143 os << "\\tracking_changes " << convert<string>(trackChanges) << '\n'
1144 << "\\output_changes " << convert<string>(outputChanges) << '\n'
1145 << "\\html_math_output " << html_math_output << '\n'
1146 << "\\html_css_as_file " << html_css_as_file << '\n'
1147 << "\\html_be_strict " << convert<string>(html_be_strict) << '\n';
1149 if (html_math_img_scale != 1.0)
1150 os << "\\html_math_img_scale " << convert<string>(html_math_img_scale) << '\n';
1151 if (!html_latex_start.empty())
1152 os << "\\html_latex_start " << html_latex_start << '\n';
1153 if (!html_latex_end.empty())
1154 os << "\\html_latex_end " << html_latex_end << '\n';
1156 os << pimpl_->authorlist;
1160 void BufferParams::validate(LaTeXFeatures & features) const
1162 features.require(documentClass().requires());
1164 if (outputChanges) {
1165 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
1166 bool xcolorulem = LaTeXFeatures::isAvailable("ulem") &&
1167 LaTeXFeatures::isAvailable("xcolor");
1169 switch (features.runparams().flavor) {
1170 case OutputParams::LATEX:
1171 case OutputParams::DVILUATEX:
1173 features.require("ct-dvipost");
1174 features.require("dvipost");
1175 } else if (xcolorulem) {
1176 features.require("ct-xcolor-ulem");
1177 features.require("ulem");
1178 features.require("xcolor");
1180 features.require("ct-none");
1183 case OutputParams::LUATEX:
1184 case OutputParams::PDFLATEX:
1185 case OutputParams::XETEX:
1187 features.require("ct-xcolor-ulem");
1188 features.require("ulem");
1189 features.require("xcolor");
1190 // improves color handling in PDF output
1191 features.require("pdfcolmk");
1193 features.require("ct-none");
1201 // Floats with 'Here definitely' as default setting.
1202 if (float_placement.find('H') != string::npos)
1203 features.require("float");
1205 for (PackageMap::const_iterator it = use_packages.begin();
1206 it != use_packages.end(); ++it) {
1207 if (it->first == "amsmath") {
1208 // AMS Style is at document level
1209 if (it->second == package_on ||
1210 documentClass().provides("amsmath"))
1211 features.require(it->first);
1212 } else if (it->second == package_on)
1213 features.require(it->first);
1216 // Document-level line spacing
1217 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
1218 features.require("setspace");
1220 // the bullet shapes are buffer level not paragraph level
1221 // so they are tested here
1222 for (int i = 0; i < 4; ++i) {
1223 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
1225 int const font = user_defined_bullet(i).getFont();
1227 int const c = user_defined_bullet(i).getCharacter();
1233 features.require("latexsym");
1235 } else if (font == 1) {
1236 features.require("amssymb");
1237 } else if (font >= 2 && font <= 5) {
1238 features.require("pifont");
1242 if (pdfoptions().use_hyperref) {
1243 features.require("hyperref");
1244 // due to interferences with babel and hyperref, the color package has to
1245 // be loaded after hyperref when hyperref is used with the colorlinks
1246 // option, see http://www.lyx.org/trac/ticket/5291
1247 if (pdfoptions().colorlinks)
1248 features.require("color");
1251 if (features.runparams().flavor == OutputParams::XETEX
1253 features.require("polyglossia");
1255 if (language->lang() == "vietnamese")
1256 features.require("vietnamese");
1257 else if (language->lang() == "japanese")
1258 features.require("japanese");
1262 bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
1263 FileName const & filepath) const
1265 // http://www.tug.org/texmf-dist/doc/latex/base/fixltx2e.pdf
1266 // !! To use the Fix-cm package, load it before \documentclass, and use the command
1267 // \RequirePackage to do so, rather than the normal \usepackage
1268 // Do not try to load any other package before the document class, unless you
1269 // have a thorough understanding of the LATEX internals and know exactly what you
1271 if (features.mustProvide("fix-cm"))
1272 os << "\\RequirePackage{fix-cm}\n";
1274 os << "\\documentclass";
1276 DocumentClass const & tclass = documentClass();
1278 ostringstream clsoptions; // the document class options.
1280 if (tokenPos(tclass.opt_fontsize(),
1281 '|', fontsize) >= 0) {
1282 // only write if existing in list (and not default)
1283 clsoptions << fontsize << "pt,";
1286 // all paper sizes except of A4, A5, B5 and the US sizes need the
1288 bool nonstandard_papersize = papersize != PAPER_DEFAULT
1289 && papersize != PAPER_USLETTER
1290 && papersize != PAPER_USLEGAL
1291 && papersize != PAPER_USEXECUTIVE
1292 && papersize != PAPER_A4
1293 && papersize != PAPER_A5
1294 && papersize != PAPER_B5;
1296 if (!use_geometry) {
1297 switch (papersize) {
1299 clsoptions << "a4paper,";
1301 case PAPER_USLETTER:
1302 clsoptions << "letterpaper,";
1305 clsoptions << "a5paper,";
1308 clsoptions << "b5paper,";
1310 case PAPER_USEXECUTIVE:
1311 clsoptions << "executivepaper,";
1314 clsoptions << "legalpaper,";
1348 if (sides != tclass.sides()) {
1351 clsoptions << "oneside,";
1354 clsoptions << "twoside,";
1360 if (columns != tclass.columns()) {
1362 clsoptions << "twocolumn,";
1364 clsoptions << "onecolumn,";
1368 && orientation == ORIENTATION_LANDSCAPE)
1369 clsoptions << "landscape,";
1371 // language should be a parameter to \documentclass
1372 if (language->babel() == "hebrew"
1373 && default_language->babel() != "hebrew")
1374 // This seems necessary
1375 features.useLanguage(default_language);
1377 ostringstream language_options;
1378 bool const use_babel = features.useBabel() && !tclass.provides("babel");
1379 bool const use_polyglossia = features.usePolyglossia();
1380 bool const global = lyxrc.language_global_options;
1381 if (use_babel || (use_polyglossia && global)) {
1382 language_options << features.getLanguages();
1383 if (!language->babel().empty()) {
1384 if (!language_options.str().empty())
1385 language_options << ',';
1386 language_options << language->babel();
1388 if (global && !features.needBabelLangOptions())
1389 clsoptions << language_options.str() << ',';
1392 // the predefined options from the layout
1393 if (use_default_options && !tclass.options().empty())
1394 clsoptions << tclass.options() << ',';
1396 // the user-defined options
1397 if (!options.empty()) {
1398 clsoptions << options << ',';
1401 string strOptions(clsoptions.str());
1402 if (!strOptions.empty()) {
1403 strOptions = rtrim(strOptions, ",");
1405 os << '[' << from_utf8(strOptions) << ']';
1408 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1409 // end of \documentclass defs
1411 // if we use fontspec, we have to load the AMS packages here
1412 string const ams = features.loadAMSPackages();
1413 if (useNonTeXFonts && !ams.empty())
1414 os << from_ascii(ams);
1417 os << "\\usepackage{fontspec}\n";
1419 // font selection must be done before loading fontenc.sty
1420 string const fonts =
1421 loadFonts(fonts_roman, fonts_sans, fonts_typewriter,
1422 fonts_expert_sc, fonts_old_figures,
1423 fonts_sans_scale, fonts_typewriter_scale,
1424 useNonTeXFonts, features);
1426 os << from_utf8(fonts);
1428 if (fonts_default_family != "default")
1429 os << "\\renewcommand{\\familydefault}{\\"
1430 << from_ascii(fonts_default_family) << "}\n";
1432 // set font encoding
1433 // for arabic_arabi and farsi we also need to load the LAE and
1435 // XeTeX and LuaTeX (with OS fonts) work without fontenc
1436 if (font_encoding() != "default" && language->lang() != "japanese"
1437 && !useNonTeXFonts && !tclass.provides("fontenc")) {
1438 size_t fars = language_options.str().find("farsi");
1439 size_t arab = language_options.str().find("arabic");
1440 if (language->lang() == "arabic_arabi"
1441 || language->lang() == "farsi" || fars != string::npos
1442 || arab != string::npos) {
1443 os << "\\usepackage[" << from_ascii(font_encoding())
1444 << ",LFE,LAE]{fontenc}\n";
1446 os << "\\usepackage[" << from_ascii(font_encoding())
1451 // handle inputenc etc.
1452 writeEncodingPreamble(os, features);
1455 if (!features.runparams().includeall && !included_children_.empty()) {
1456 os << "\\includeonly{";
1457 list<string>::const_iterator it = included_children_.begin();
1458 list<string>::const_iterator en = included_children_.end();
1460 for (; it != en; ++it) {
1461 string incfile = *it;
1462 FileName inc = makeAbsPath(incfile, filepath.absFileName());
1463 string mangled = DocFileName(changeExtension(inc.absFileName(), ".tex")).
1465 if (!features.runparams().nice)
1467 // \includeonly doesn't want an extension
1468 incfile = changeExtension(incfile, string());
1469 incfile = support::latex_path(incfile);
1470 if (!incfile.empty()) {
1473 os << from_utf8(incfile);
1480 if (!listings_params.empty() || features.isRequired("listings"))
1481 os << "\\usepackage{listings}\n";
1483 if (!listings_params.empty()) {
1485 // do not test validity because listings_params is
1486 // supposed to be valid
1488 InsetListingsParams(listings_params).separatedParams(true);
1489 // we can't support all packages, but we should load the color package
1490 if (par.find("\\color", 0) != string::npos)
1491 features.require("color");
1492 os << from_utf8(par)
1495 if (!tclass.provides("geometry")
1496 && (use_geometry || nonstandard_papersize)) {
1497 odocstringstream ods;
1498 if (!getGraphicsDriver("geometry").empty())
1499 ods << getGraphicsDriver("geometry");
1500 if (orientation == ORIENTATION_LANDSCAPE)
1501 ods << ",landscape";
1502 switch (papersize) {
1504 if (!paperwidth.empty())
1505 ods << ",paperwidth="
1506 << from_ascii(paperwidth);
1507 if (!paperheight.empty())
1508 ods << ",paperheight="
1509 << from_ascii(paperheight);
1511 case PAPER_USLETTER:
1512 ods << ",letterpaper";
1515 ods << ",legalpaper";
1517 case PAPER_USEXECUTIVE:
1518 ods << ",executivepaper";
1607 docstring const g_options = trim(ods.str(), ",");
1608 os << "\\usepackage";
1609 if (!g_options.empty())
1610 os << '[' << g_options << ']';
1611 os << "{geometry}\n";
1612 // output this only if use_geometry is true
1614 os << "\\geometry{verbose";
1615 if (!topmargin.empty())
1616 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1617 if (!bottommargin.empty())
1618 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1619 if (!leftmargin.empty())
1620 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1621 if (!rightmargin.empty())
1622 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1623 if (!headheight.empty())
1624 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1625 if (!headsep.empty())
1626 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1627 if (!footskip.empty())
1628 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1629 if (!columnsep.empty())
1630 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1633 } else if (orientation == ORIENTATION_LANDSCAPE
1634 || papersize != PAPER_DEFAULT) {
1635 features.require("papersize");
1638 if (tokenPos(tclass.opt_pagestyle(), '|', pagestyle) >= 0) {
1639 if (pagestyle == "fancy")
1640 os << "\\usepackage{fancyhdr}\n";
1641 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1644 // only output when the background color is not default
1645 if (isbackgroundcolor == true) {
1646 // only require color here, the background color will be defined
1647 // in LaTeXFeatures.cpp to avoid interferences with the LaTeX
1649 features.require("color");
1650 features.require("pagecolor");
1653 // only output when the font color is not default
1654 if (isfontcolor == true) {
1655 // only require color here, the font color will be defined
1656 // in LaTeXFeatures.cpp to avoid interferences with the LaTeX
1658 features.require("color");
1659 features.require("fontcolor");
1662 // Only if class has a ToC hierarchy
1663 if (tclass.hasTocLevels()) {
1664 if (secnumdepth != tclass.secnumdepth()) {
1665 os << "\\setcounter{secnumdepth}{"
1669 if (tocdepth != tclass.tocdepth()) {
1670 os << "\\setcounter{tocdepth}{"
1676 if (paragraph_separation) {
1677 // when skip separation
1678 switch (getDefSkip().kind()) {
1679 case VSpace::SMALLSKIP:
1680 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1682 case VSpace::MEDSKIP:
1683 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1685 case VSpace::BIGSKIP:
1686 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1688 case VSpace::LENGTH:
1689 os << "\\setlength{\\parskip}{"
1690 << from_utf8(getDefSkip().length().asLatexString())
1693 default: // should never happen // Then delete it.
1694 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1697 os << "\\setlength{\\parindent}{0pt}\n";
1699 // when separation by indentation
1700 // only output something when a width is given
1701 if (getIndentation().asLyXCommand() != "default") {
1702 os << "\\setlength{\\parindent}{"
1703 << from_utf8(getIndentation().asLatexCommand())
1708 // Now insert the LyX specific LaTeX commands...
1709 docstring lyxpreamble;
1710 features.resolveAlternatives();
1713 if (!output_sync_macro.empty())
1714 lyxpreamble += from_utf8(output_sync_macro) +"\n";
1715 else if (features.runparams().flavor == OutputParams::LATEX)
1716 lyxpreamble += "\\usepackage[active]{srcltx}\n";
1717 else if (features.runparams().flavor == OutputParams::PDFLATEX)
1718 lyxpreamble += "\\synctex=-1\n";
1721 // due to interferences with babel and hyperref, the color package has to
1722 // be loaded (when it is not already loaded) before babel when hyperref
1723 // is used with the colorlinks option, see
1724 // http://www.lyx.org/trac/ticket/5291
1725 // we decided therefore to load color always before babel, see
1726 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg144349.html
1727 lyxpreamble += from_ascii(features.getColorOptions());
1729 // If we use hyperref, jurabib, japanese, or vietnamese, we have to call babel before them.
1731 && (features.isRequired("jurabib")
1732 || features.isRequired("hyperref")
1733 || features.isRequired("vietnamese")
1734 || features.isRequired("japanese"))) {
1736 lyxpreamble += from_utf8(features.getBabelPresettings());
1737 lyxpreamble += from_utf8(babelCall(language_options.str(),
1738 features.needBabelLangOptions())) + '\n';
1739 lyxpreamble += from_utf8(features.getBabelPostsettings());
1742 // The optional packages;
1743 lyxpreamble += from_ascii(features.getPackages());
1745 // Additional Indices
1746 if (features.isRequired("splitidx")) {
1747 IndicesList::const_iterator iit = indiceslist().begin();
1748 IndicesList::const_iterator iend = indiceslist().end();
1749 for (; iit != iend; ++iit) {
1750 lyxpreamble += "\\newindex[";
1751 lyxpreamble += iit->index();
1752 lyxpreamble += "]{";
1753 lyxpreamble += iit->shortcut();
1754 lyxpreamble += "}\n";
1759 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1762 // * Hyperref manual: "Make sure it comes last of your loaded
1763 // packages, to give it a fighting chance of not being over-written,
1764 // since its job is to redefine many LaTeX commands."
1765 // * Email from Heiko Oberdiek: "It is usually better to load babel
1766 // before hyperref. Then hyperref has a chance to detect babel.
1767 // * Has to be loaded before the "LyX specific LaTeX commands" to
1768 // avoid errors with algorithm floats.
1769 // use hyperref explicitly if it is required
1770 if (features.isRequired("hyperref")) {
1771 // pass what we have to stream here, since we need
1772 // to access the stream itself in PDFOptions.
1775 OutputParams tmp_params = features.runparams();
1776 pdfoptions().writeLaTeX(tmp_params, os,
1777 documentClass().provides("hyperref"));
1778 // set back for the rest
1779 lyxpreamble.clear();
1780 // correctly break URLs with hyperref and dvi output
1781 if (features.runparams().flavor == OutputParams::LATEX
1782 && features.isAvailable("breakurl"))
1783 lyxpreamble += "\\usepackage{breakurl}\n";
1784 } else if (features.isRequired("nameref"))
1785 // hyperref loads this automatically
1786 lyxpreamble += "\\usepackage{nameref}\n";
1788 // Will be surrounded by \makeatletter and \makeatother when not empty
1789 docstring atlyxpreamble;
1791 // Some macros LyX will need
1792 docstring tmppreamble(features.getMacros());
1794 if (!tmppreamble.empty())
1795 atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1796 "LyX specific LaTeX commands.\n"
1797 + tmppreamble + '\n';
1799 // the text class specific preamble
1800 tmppreamble = features.getTClassPreamble();
1801 if (!tmppreamble.empty())
1802 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1803 "Textclass specific LaTeX commands.\n"
1804 + tmppreamble + '\n';
1806 // suppress date if selected
1807 // use \@ifundefined because we cannot be sure that every document class
1808 // has a \date command
1810 atlyxpreamble += "\\@ifundefined{date}{}{\\date{}}\n";
1812 /* the user-defined preamble */
1813 if (!containsOnly(preamble, " \n\t"))
1815 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1816 "User specified LaTeX commands.\n"
1817 + from_utf8(preamble) + '\n';
1819 // subfig loads internally the LaTeX package "caption". As
1820 // caption is a very popular package, users will load it in
1821 // the preamble. Therefore we must load subfig behind the
1822 // user-defined preamble and check if the caption package was
1823 // loaded or not. For the case that caption is loaded before
1824 // subfig, there is the subfig option "caption=false". This
1825 // option also works when a koma-script class is used and
1826 // koma's own caption commands are used instead of caption. We
1827 // use \PassOptionsToPackage here because the user could have
1828 // already loaded subfig in the preamble.
1829 if (features.isRequired("subfig")) {
1830 atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n"
1831 " \\PassOptionsToPackage{caption=false}{subfig}}\n"
1832 "\\usepackage{subfig}\n";
1835 // Itemize bullet settings need to be last in case the user
1836 // defines their own bullets that use a package included
1837 // in the user-defined preamble -- ARRae
1838 // Actually it has to be done much later than that
1839 // since some packages like frenchb make modifications
1840 // at \begin{document} time -- JMarc
1841 docstring bullets_def;
1842 for (int i = 0; i < 4; ++i) {
1843 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1844 if (bullets_def.empty())
1845 bullets_def += "\\AtBeginDocument{\n";
1846 bullets_def += " \\def\\labelitemi";
1848 // `i' is one less than the item to modify
1855 bullets_def += "ii";
1861 bullets_def += '{' +
1862 user_defined_bullet(i).getText()
1867 if (!bullets_def.empty())
1868 atlyxpreamble += bullets_def + "}\n\n";
1870 if (!atlyxpreamble.empty())
1871 lyxpreamble += "\n\\makeatletter\n"
1872 + atlyxpreamble + "\\makeatother\n\n";
1874 // We try to load babel late, in case it interferes with other packages.
1875 // Jurabib and Hyperref have to be called after babel, though.
1876 if (use_babel && !features.isRequired("jurabib")
1877 && !features.isRequired("hyperref")
1878 && !features.isRequired("vietnamese")
1879 && !features.isRequired("japanese")) {
1881 lyxpreamble += from_utf8(features.getBabelPresettings());
1882 lyxpreamble += from_utf8(babelCall(language_options.str(),
1883 features.needBabelLangOptions())) + '\n';
1884 lyxpreamble += from_utf8(features.getBabelPostsettings());
1887 // xunicode needs to be loaded at least after amsmath, amssymb,
1888 // esint and the other packages that provide special glyphs
1889 if (features.runparams().flavor == OutputParams::XETEX)
1890 lyxpreamble += "\\usepackage{xunicode}\n";
1892 // Polyglossia must be loaded last
1893 if (use_polyglossia) {
1895 lyxpreamble += "\\usepackage{polyglossia}\n";
1896 // set the main language
1897 lyxpreamble += "\\setdefaultlanguage";
1898 if (!language->polyglossiaOpts().empty())
1899 lyxpreamble += "[" + from_ascii(language->polyglossiaOpts()) + "]";
1900 lyxpreamble += "{" + from_ascii(language->polyglossia()) + "}\n";
1901 // now setup the other languages
1902 std::map<std::string, std::string> const polylangs =
1903 features.getPolyglossiaLanguages();
1904 for (std::map<std::string, std::string>::const_iterator mit = polylangs.begin();
1905 mit != polylangs.end() ; ++mit) {
1906 lyxpreamble += "\\setotherlanguage";
1907 if (!mit->second.empty())
1908 lyxpreamble += "[" + from_ascii(mit->second) + "]";
1909 lyxpreamble += "{" + from_ascii(mit->first) + "}\n";
1913 docstring const i18npreamble =
1914 features.getTClassI18nPreamble(use_babel, use_polyglossia);
1915 if (!i18npreamble.empty())
1916 lyxpreamble += i18npreamble + '\n';
1924 void BufferParams::useClassDefaults()
1926 DocumentClass const & tclass = documentClass();
1928 sides = tclass.sides();
1929 columns = tclass.columns();
1930 pagestyle = tclass.pagestyle();
1931 use_default_options = true;
1932 // Only if class has a ToC hierarchy
1933 if (tclass.hasTocLevels()) {
1934 secnumdepth = tclass.secnumdepth();
1935 tocdepth = tclass.tocdepth();
1940 bool BufferParams::hasClassDefaults() const
1942 DocumentClass const & tclass = documentClass();
1944 return sides == tclass.sides()
1945 && columns == tclass.columns()
1946 && pagestyle == tclass.pagestyle()
1947 && use_default_options
1948 && secnumdepth == tclass.secnumdepth()
1949 && tocdepth == tclass.tocdepth();
1953 DocumentClass const & BufferParams::documentClass() const
1959 DocumentClass const * BufferParams::documentClassPtr() const
1965 void BufferParams::setDocumentClass(DocumentClass const * const tc)
1967 // evil, but this function is evil
1968 doc_class_ = const_cast<DocumentClass *>(tc);
1972 bool BufferParams::setBaseClass(string const & classname)
1974 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1975 LayoutFileList & bcl = LayoutFileList::get();
1976 if (!bcl.haveClass(classname)) {
1978 bformat(_("The layout file:\n"
1980 "could not be found. A default textclass with default\n"
1981 "layouts will be used. LyX will not be able to produce\n"
1983 from_utf8(classname));
1984 frontend::Alert::error(_("Document class not found"), s);
1985 bcl.addEmptyClass(classname);
1988 bool const success = bcl[classname].load();
1991 bformat(_("Due to some error in it, the layout file:\n"
1993 "could not be loaded. A default textclass with default\n"
1994 "layouts will be used. LyX will not be able to produce\n"
1996 from_utf8(classname));
1997 frontend::Alert::error(_("Could not load class"), s);
1998 bcl.addEmptyClass(classname);
2001 pimpl_->baseClass_ = classname;
2002 layout_modules_.adaptToBaseClass(baseClass(), removed_modules_);
2007 LayoutFile const * BufferParams::baseClass() const
2009 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
2010 return &(LayoutFileList::get()[pimpl_->baseClass_]);
2016 LayoutFileIndex const & BufferParams::baseClassID() const
2018 return pimpl_->baseClass_;
2022 void BufferParams::makeDocumentClass()
2027 doc_class_ = &(DocumentClassBundle::get().makeDocumentClass(*baseClass(), layout_modules_));
2029 if (!local_layout.empty()) {
2030 TextClass::ReturnValues success =
2031 doc_class_->read(local_layout, TextClass::MODULE);
2032 if (success != TextClass::OK && success != TextClass::OK_OLDFORMAT) {
2033 docstring const msg = _("Error reading internal layout information");
2034 frontend::Alert::warning(_("Read Error"), msg);
2040 bool BufferParams::moduleCanBeAdded(string const & modName) const
2042 return layout_modules_.moduleCanBeAdded(modName, baseClass());
2046 bool BufferParams::addLayoutModule(string const & modName)
2048 LayoutModuleList::const_iterator it = layout_modules_.begin();
2049 LayoutModuleList::const_iterator end = layout_modules_.end();
2050 for (; it != end; it++)
2053 layout_modules_.push_back(modName);
2058 string BufferParams::bufferFormat() const
2060 string format = documentClass().outputFormat();
2061 if (format == "latex") {
2064 if (encoding().package() == Encoding::japanese)
2071 bool BufferParams::isExportable(string const & format) const
2073 vector<string> backs = backends();
2074 for (vector<string>::const_iterator it = backs.begin();
2075 it != backs.end(); ++it)
2076 if (theConverters().isReachable(*it, format))
2083 bool formatSorter(Format const * lhs, Format const * rhs) {
2084 return _(lhs->prettyname()) < _(rhs->prettyname());
2089 vector<Format const *> BufferParams::exportableFormats(bool only_viewable) const
2091 vector<string> const backs = backends();
2092 set<string> excludes;
2093 if (useNonTeXFonts) {
2094 excludes.insert("latex");
2095 excludes.insert("pdflatex");
2097 vector<Format const *> result =
2098 theConverters().getReachable(backs[0], only_viewable, true, excludes);
2099 for (vector<string>::const_iterator it = backs.begin() + 1;
2100 it != backs.end(); ++it) {
2101 vector<Format const *> r =
2102 theConverters().getReachable(*it, only_viewable, false, excludes);
2103 result.insert(result.end(), r.begin(), r.end());
2105 sort(result.begin(), result.end(), formatSorter);
2110 bool BufferParams::isExportableFormat(string const & format) const
2112 typedef vector<Format const *> Formats;
2114 formats = exportableFormats(true);
2115 Formats::const_iterator fit = formats.begin();
2116 Formats::const_iterator end = formats.end();
2117 for (; fit != end ; ++fit) {
2118 if ((*fit)->name() == format)
2125 vector<string> BufferParams::backends() const
2128 v.push_back(bufferFormat());
2129 // FIXME: Don't hardcode format names here, but use a flag
2130 if (v.back() == "latex") {
2131 v.push_back("pdflatex");
2132 v.push_back("luatex");
2133 v.push_back("dviluatex");
2134 v.push_back("xetex");
2135 } else if (v.back() == "xetex") {
2136 v.push_back("luatex");
2137 v.push_back("dviluatex");
2139 v.push_back("xhtml");
2140 v.push_back("text");
2146 OutputParams::FLAVOR BufferParams::getOutputFlavor(string const format) const
2148 string const dformat = (format.empty() || format == "default") ?
2149 getDefaultOutputFormat() : format;
2150 DefaultFlavorCache::const_iterator it =
2151 default_flavors_.find(dformat);
2153 if (it != default_flavors_.end())
2156 OutputParams::FLAVOR result = OutputParams::LATEX;
2158 if (dformat == "xhtml")
2159 result = OutputParams::HTML;
2161 // Try to determine flavor of default output format
2162 vector<string> backs = backends();
2163 if (find(backs.begin(), backs.end(), dformat) == backs.end()) {
2164 // Get shortest path to format
2165 Graph::EdgePath path;
2166 for (vector<string>::const_iterator it = backs.begin();
2167 it != backs.end(); ++it) {
2168 Graph::EdgePath p = theConverters().getPath(*it, dformat);
2169 if (!p.empty() && (path.empty() || p.size() < path.size())) {
2174 result = theConverters().getFlavor(path);
2177 // cache this flavor
2178 default_flavors_[dformat] = result;
2183 string BufferParams::getDefaultOutputFormat() const
2185 if (!default_output_format.empty()
2186 && default_output_format != "default")
2187 return default_output_format;
2190 || encoding().package() == Encoding::japanese) {
2191 vector<Format const *> const formats = exportableFormats(true);
2192 if (formats.empty())
2194 // return the first we find
2195 return formats.front()->name();
2197 return lyxrc.default_view_format;
2200 Font const BufferParams::getFont() const
2202 FontInfo f = documentClass().defaultfont();
2203 if (fonts_default_family == "rmdefault")
2204 f.setFamily(ROMAN_FAMILY);
2205 else if (fonts_default_family == "sfdefault")
2206 f.setFamily(SANS_FAMILY);
2207 else if (fonts_default_family == "ttdefault")
2208 f.setFamily(TYPEWRITER_FAMILY);
2209 return Font(f, language);
2213 bool BufferParams::isLatex() const
2215 return documentClass().outputType() == LATEX;
2219 bool BufferParams::isLiterate() const
2221 return documentClass().outputType() == LITERATE;
2225 bool BufferParams::isDocBook() const
2227 return documentClass().outputType() == DOCBOOK;
2231 void BufferParams::readPreamble(Lexer & lex)
2233 if (lex.getString() != "\\begin_preamble")
2234 lyxerr << "Error (BufferParams::readPreamble):"
2235 "consistency check failed." << endl;
2237 preamble = lex.getLongString("\\end_preamble");
2241 void BufferParams::readLocalLayout(Lexer & lex)
2243 if (lex.getString() != "\\begin_local_layout")
2244 lyxerr << "Error (BufferParams::readLocalLayout):"
2245 "consistency check failed." << endl;
2247 local_layout = lex.getLongString("\\end_local_layout");
2251 bool BufferParams::setLanguage(string const & lang)
2253 Language const *new_language = languages.getLanguage(lang);
2254 if (!new_language) {
2255 // Language lang was not found
2258 language = new_language;
2263 void BufferParams::readLanguage(Lexer & lex)
2265 if (!lex.next()) return;
2267 string const tmptok = lex.getString();
2269 // check if tmptok is part of tex_babel in tex-defs.h
2270 if (!setLanguage(tmptok)) {
2271 // Language tmptok was not found
2272 language = default_language;
2273 lyxerr << "Warning: Setting language `"
2274 << tmptok << "' to `" << language->lang()
2280 void BufferParams::readGraphicsDriver(Lexer & lex)
2285 string const tmptok = lex.getString();
2286 // check if tmptok is part of tex_graphics in tex_defs.h
2289 string const test = tex_graphics[n++];
2291 if (test == tmptok) {
2292 graphics_driver = tmptok;
2297 "Warning: graphics driver `$$Token' not recognized!\n"
2298 " Setting graphics driver to `default'.\n");
2299 graphics_driver = "default";
2306 void BufferParams::readBullets(Lexer & lex)
2311 int const index = lex.getInteger();
2313 int temp_int = lex.getInteger();
2314 user_defined_bullet(index).setFont(temp_int);
2315 temp_bullet(index).setFont(temp_int);
2317 user_defined_bullet(index).setCharacter(temp_int);
2318 temp_bullet(index).setCharacter(temp_int);
2320 user_defined_bullet(index).setSize(temp_int);
2321 temp_bullet(index).setSize(temp_int);
2325 void BufferParams::readBulletsLaTeX(Lexer & lex)
2327 // The bullet class should be able to read this.
2330 int const index = lex.getInteger();
2332 docstring const temp_str = lex.getDocString();
2334 user_defined_bullet(index).setText(temp_str);
2335 temp_bullet(index).setText(temp_str);
2339 void BufferParams::readModules(Lexer & lex)
2341 if (!lex.eatLine()) {
2342 lyxerr << "Error (BufferParams::readModules):"
2343 "Unexpected end of input." << endl;
2347 string mod = lex.getString();
2348 if (mod == "\\end_modules")
2350 addLayoutModule(mod);
2356 void BufferParams::readRemovedModules(Lexer & lex)
2358 if (!lex.eatLine()) {
2359 lyxerr << "Error (BufferParams::readRemovedModules):"
2360 "Unexpected end of input." << endl;
2364 string mod = lex.getString();
2365 if (mod == "\\end_removed_modules")
2367 removed_modules_.push_back(mod);
2370 // now we want to remove any removed modules that were previously
2371 // added. normally, that will be because default modules were added in
2372 // setBaseClass(), which gets called when \textclass is read at the
2373 // start of the read.
2374 list<string>::const_iterator rit = removed_modules_.begin();
2375 list<string>::const_iterator const ren = removed_modules_.end();
2376 for (; rit != ren; rit++) {
2377 LayoutModuleList::iterator const mit = layout_modules_.begin();
2378 LayoutModuleList::iterator const men = layout_modules_.end();
2379 LayoutModuleList::iterator found = find(mit, men, *rit);
2382 layout_modules_.erase(found);
2387 void BufferParams::readIncludeonly(Lexer & lex)
2389 if (!lex.eatLine()) {
2390 lyxerr << "Error (BufferParams::readIncludeonly):"
2391 "Unexpected end of input." << endl;
2395 string child = lex.getString();
2396 if (child == "\\end_includeonly")
2398 included_children_.push_back(child);
2404 string BufferParams::paperSizeName(PapersizePurpose purpose) const
2406 switch (papersize) {
2408 // could be anything, so don't guess
2410 case PAPER_CUSTOM: {
2411 if (purpose == XDVI && !paperwidth.empty() &&
2412 !paperheight.empty()) {
2413 // heightxwidth<unit>
2414 string first = paperwidth;
2415 string second = paperheight;
2416 if (orientation == ORIENTATION_LANDSCAPE)
2419 return first.erase(first.length() - 2)
2425 // dvips and dvipdfm do not know this
2426 if (purpose == DVIPS || purpose == DVIPDFM)
2430 if (purpose == DVIPS || purpose == DVIPDFM)
2434 if (purpose == DVIPS || purpose == DVIPDFM)
2444 if (purpose == DVIPS || purpose == DVIPDFM)
2448 if (purpose == DVIPS || purpose == DVIPDFM)
2452 if (purpose == DVIPS || purpose == DVIPDFM)
2456 if (purpose == DVIPS || purpose == DVIPDFM)
2460 if (purpose == DVIPS || purpose == DVIPDFM)
2464 // dvipdfm does not know this
2465 if (purpose == DVIPDFM)
2469 if (purpose == DVIPDFM)
2473 if (purpose == DVIPS || purpose == DVIPDFM)
2477 if (purpose == DVIPS || purpose == DVIPDFM)
2481 if (purpose == DVIPS || purpose == DVIPDFM)
2485 if (purpose == DVIPS || purpose == DVIPDFM)
2489 if (purpose == DVIPS || purpose == DVIPDFM)
2493 if (purpose == DVIPS || purpose == DVIPDFM)
2497 if (purpose == DVIPS || purpose == DVIPDFM)
2501 if (purpose == DVIPS || purpose == DVIPDFM)
2505 if (purpose == DVIPS || purpose == DVIPDFM)
2509 if (purpose == DVIPS || purpose == DVIPDFM)
2513 if (purpose == DVIPS || purpose == DVIPDFM)
2517 if (purpose == DVIPS || purpose == DVIPDFM)
2521 if (purpose == DVIPS || purpose == DVIPDFM)
2525 if (purpose == DVIPS || purpose == DVIPDFM)
2529 if (purpose == DVIPS || purpose == DVIPDFM)
2532 case PAPER_USEXECUTIVE:
2533 // dvipdfm does not know this
2534 if (purpose == DVIPDFM)
2539 case PAPER_USLETTER:
2541 if (purpose == XDVI)
2548 string const BufferParams::dvips_options() const
2552 // If the class loads the geometry package, we do not know which
2553 // paper size is used, since we do not set it (bug 7013).
2554 // Therefore we must not specify any argument here.
2555 // dvips gets the correct paper size via DVI specials in this case
2556 // (if the class uses the geometry package correctly).
2557 if (documentClass().provides("geometry"))
2561 && papersize == PAPER_CUSTOM
2562 && !lyxrc.print_paper_dimension_flag.empty()
2563 && !paperwidth.empty()
2564 && !paperheight.empty()) {
2565 // using a custom papersize
2566 result = lyxrc.print_paper_dimension_flag;
2567 result += ' ' + paperwidth;
2568 result += ',' + paperheight;
2570 string const paper_option = paperSizeName(DVIPS);
2571 if (!paper_option.empty() && (paper_option != "letter" ||
2572 orientation != ORIENTATION_LANDSCAPE)) {
2573 // dvips won't accept -t letter -t landscape.
2574 // In all other cases, include the paper size
2576 result = lyxrc.print_paper_flag;
2577 result += ' ' + paper_option;
2580 if (orientation == ORIENTATION_LANDSCAPE &&
2581 papersize != PAPER_CUSTOM)
2582 result += ' ' + lyxrc.print_landscape_flag;
2587 string const BufferParams::font_encoding() const
2589 return (fontenc == "global") ? lyxrc.fontenc : fontenc;
2593 string BufferParams::babelCall(string const & lang_opts, bool const langoptions) const
2595 if (lang_package != "auto" && lang_package != "babel"
2596 && lang_package != "default" && lang_package != "none")
2597 return lang_package;
2598 if (lyxrc.language_package_selection == LyXRC::LP_CUSTOM)
2599 return lyxrc.language_custom_package;
2600 // suppress the babel call if there is no BabelName defined
2601 // for the document language in the lib/languages file and if no
2602 // other languages are used (lang_opts is then empty)
2603 if (lang_opts.empty())
2605 // either a specific language (AsBabelOptions setting in
2606 // lib/languages) or the prefs require the languages to
2607 // be submitted to babel itself (not the class).
2609 return "\\usepackage[" + lang_opts + "]{babel}";
2610 return "\\usepackage{babel}";
2614 docstring BufferParams::getGraphicsDriver(string const & package) const
2618 if (package == "geometry") {
2619 if (graphics_driver == "dvips"
2620 || graphics_driver == "dvipdfm"
2621 || graphics_driver == "pdftex"
2622 || graphics_driver == "vtex")
2623 result = from_ascii(graphics_driver);
2624 else if (graphics_driver == "dvipdfmx")
2625 result = from_ascii("dvipdfm");
2632 void BufferParams::writeEncodingPreamble(otexstream & os,
2633 LaTeXFeatures & features) const
2635 // XeTeX does not need this
2636 if (features.runparams().flavor == OutputParams::XETEX)
2638 // LuaTeX neither, but with tex fonts, we need to load
2639 // the luainputenc package.
2640 if (features.runparams().flavor == OutputParams::LUATEX
2641 || features.runparams().flavor == OutputParams::DVILUATEX) {
2642 if (!useNonTeXFonts && inputenc != "default"
2643 && ((inputenc == "auto" && language->encoding()->package() == Encoding::inputenc)
2644 || (inputenc != "auto" && encoding().package() == Encoding::inputenc))) {
2645 os << "\\usepackage[utf8]{luainputenc}\n";
2649 if (inputenc == "auto") {
2650 string const doc_encoding =
2651 language->encoding()->latexName();
2652 Encoding::Package const package =
2653 language->encoding()->package();
2655 // Create a list with all the input encodings used
2657 set<string> encodings =
2658 features.getEncodingSet(doc_encoding);
2660 // If the "japanese" package (i.e. pLaTeX) is used,
2661 // inputenc must be omitted.
2662 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
2663 if (package == Encoding::japanese)
2664 features.require("japanese");
2666 if ((!encodings.empty() || package == Encoding::inputenc)
2667 && !features.isRequired("japanese")) {
2668 os << "\\usepackage[";
2669 set<string>::const_iterator it = encodings.begin();
2670 set<string>::const_iterator const end = encodings.end();
2672 os << from_ascii(*it);
2675 for (; it != end; ++it)
2676 os << ',' << from_ascii(*it);
2677 if (package == Encoding::inputenc) {
2678 if (!encodings.empty())
2680 os << from_ascii(doc_encoding);
2682 os << "]{inputenc}\n";
2684 if (package == Encoding::CJK || features.mustProvide("CJK")) {
2685 if (language->encoding()->name() == "utf8-cjk"
2686 && LaTeXFeatures::isAvailable("CJKutf8"))
2687 os << "\\usepackage{CJKutf8}\n";
2689 os << "\\usepackage{CJK}\n";
2691 } else if (inputenc != "default") {
2692 switch (encoding().package()) {
2693 case Encoding::none:
2694 case Encoding::japanese:
2696 case Encoding::inputenc:
2697 // do not load inputenc if japanese is used
2698 if (features.isRequired("japanese"))
2700 os << "\\usepackage[" << from_ascii(inputenc)
2704 if (encoding().name() == "utf8-cjk"
2705 && LaTeXFeatures::isAvailable("CJKutf8"))
2706 os << "\\usepackage{CJKutf8}\n";
2708 os << "\\usepackage{CJK}\n";
2713 // The encoding "armscii8" (for Armenian) is only available when
2714 // the package "armtex" is loaded.
2715 if (language->encoding()->latexName() == "armscii8"
2716 || inputenc == "armscii8")
2717 os << "\\usepackage{armtex}\n";
2721 string const BufferParams::parseFontName(string const & name) const
2723 string mangled = name;
2724 size_t const idx = mangled.find('[');
2725 if (idx == string::npos || idx == 0)
2728 return mangled.substr(0, idx - 1);
2732 string const BufferParams::loadFonts(string const & rm,
2733 string const & sf, string const & tt,
2734 bool const & sc, bool const & osf,
2735 int const & sfscale, int const & ttscale,
2736 bool const & use_systemfonts,
2737 LaTeXFeatures & features) const
2739 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
2740 several packages have been replaced by others, that might not
2741 be installed on every system. We have to take care for that
2742 (see psnfss.pdf). We try to support all psnfss fonts as well
2743 as the fonts that have become de facto standard in the LaTeX
2744 world (e.g. Latin Modern). We do not support obsolete fonts
2745 (like PSLatex). In general, it should be possible to mix any
2746 rm font with any sf or tt font, respectively. (JSpitzm)
2748 -- separate math fonts.
2751 if (rm == "default" && sf == "default" && tt == "default")
2757 /* Fontspec (XeTeX, LuaTeX): we provide GUI support for oldstyle
2758 * numbers (Numbers=OldStyle) and sf/tt scaling. The Ligatures=TeX/
2759 * Mapping=tex-text option assures TeX ligatures (such as "--")
2760 * are resolved. Note that tt does not use these ligatures.
2762 * -- add more GUI options?
2763 * -- add more fonts (fonts for other scripts)
2764 * -- if there's a way to find out if a font really supports
2765 * OldStyle, enable/disable the widget accordingly.
2767 if (use_systemfonts && features.isAvailable("fontspec")) {
2768 // "Mapping=tex-text" and "Ligatures=TeX" are equivalent.
2769 // However, until v.2 (2010/07/11) fontspec only knew
2770 // Mapping=tex-text (for XeTeX only); then "Ligatures=TeX"
2771 // was introduced for both XeTeX and LuaTeX (LuaTeX
2772 // didn't understand "Mapping=tex-text", while XeTeX
2773 // understood both. With most recent versions, both
2774 // variants are understood by both engines. However,
2775 // we want to provide support for at least TeXLive 2009
2776 // (for XeTeX; LuaTeX is only supported as of v.2)
2777 string const texmapping =
2778 (features.runparams().flavor == OutputParams::XETEX) ?
2779 "Mapping=tex-text" : "Ligatures=TeX";
2780 if (rm != "default") {
2781 os << "\\setmainfont[" << texmapping;
2783 os << ",Numbers=OldStyle";
2784 os << "]{" << parseFontName(rm) << "}\n";
2786 if (sf != "default") {
2787 string const sans = parseFontName(sf);
2789 os << "\\setsansfont[Scale="
2790 << float(sfscale) / 100
2791 << "," << texmapping << "]{"
2794 os << "\\setsansfont[" << texmapping << "]{"
2797 if (tt != "default") {
2798 string const mono = parseFontName(tt);
2800 os << "\\setmonofont[Scale="
2801 << float(ttscale) / 100
2805 os << "\\setmonofont{"
2812 // Computer Modern (must be explicitly selectable -- there might be classes
2813 // that define a different default font!
2815 os << "\\renewcommand{\\rmdefault}{cmr}\n";
2816 // osf for Computer Modern needs eco.sty
2818 os << "\\usepackage{eco}\n";
2820 // Latin Modern Roman
2821 else if (rm == "lmodern")
2822 os << "\\usepackage{lmodern}\n";
2824 else if (rm == "ae") {
2825 // not needed when using OT1 font encoding.
2826 if (font_encoding() != "default")
2827 os << "\\usepackage{ae,aecompl}\n";
2830 else if (rm == "times") {
2831 // try to load the best available package
2832 if (LaTeXFeatures::isAvailable("mathptmx"))
2833 os << "\\usepackage{mathptmx}\n";
2834 else if (LaTeXFeatures::isAvailable("mathptm"))
2835 os << "\\usepackage{mathptm}\n";
2837 os << "\\usepackage{times}\n";
2840 else if (rm == "palatino") {
2841 // try to load the best available package
2842 if (LaTeXFeatures::isAvailable("mathpazo")) {
2843 os << "\\usepackage";
2849 // "osf" includes "sc"!
2853 os << "{mathpazo}\n";
2855 else if (LaTeXFeatures::isAvailable("mathpple"))
2856 os << "\\usepackage{mathpple}\n";
2858 os << "\\usepackage{palatino}\n";
2861 else if (rm == "utopia") {
2862 // fourier supersedes utopia.sty, but does
2863 // not work with OT1 encoding.
2864 if (LaTeXFeatures::isAvailable("fourier")
2865 && font_encoding() != "default") {
2866 os << "\\usepackage";
2877 os << "{fourier}\n";
2880 os << "\\usepackage{utopia}\n";
2882 // Bera (complete fontset)
2883 else if (rm == "bera" && sf == "default" && tt == "default")
2884 os << "\\usepackage{bera}\n";
2886 else if (rm != "default")
2887 os << "\\usepackage" << "{" << rm << "}\n";
2890 // Helvetica, Bera Sans
2891 if (sf == "helvet" || sf == "berasans") {
2893 os << "\\usepackage[scaled=" << float(sfscale) / 100
2894 << "]{" << sf << "}\n";
2896 os << "\\usepackage{" << sf << "}\n";
2899 else if (sf == "avant")
2900 os << "\\usepackage{" << sf << "}\n";
2901 // Computer Modern, Latin Modern, CM Bright
2902 else if (sf != "default")
2903 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
2905 // monospaced/typewriter
2906 // Courier, LuxiMono
2907 if (tt == "luximono" || tt == "beramono") {
2909 os << "\\usepackage[scaled=" << float(ttscale) / 100
2910 << "]{" << tt << "}\n";
2912 os << "\\usepackage{" << tt << "}\n";
2915 else if (tt == "courier" )
2916 os << "\\usepackage{" << tt << "}\n";
2917 // Computer Modern, Latin Modern, CM Bright
2918 else if (tt != "default")
2919 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
2925 Encoding const & BufferParams::encoding() const
2927 // FIXME: actually, we should check for the flavor
2928 // or runparams.isFullyUnicode() here:
2929 // This check will not work with XeTeX/LuaTeX and tex fonts.
2930 // Thus we have to reset the encoding in Buffer::makeLaTeXFile.
2932 return *(encodings.fromLaTeXName("utf8-plain"));
2933 if (inputenc == "auto" || inputenc == "default")
2934 return *language->encoding();
2935 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
2938 LYXERR0("Unknown inputenc value `" << inputenc
2939 << "'. Using `auto' instead.");
2940 return *language->encoding();
2944 CiteEngine BufferParams::citeEngine() const
2946 // FIXME the class should provide the numerical/
2947 // authoryear choice
2948 if (documentClass().provides("natbib"))
2949 return ENGINE_NATBIB;
2950 return cite_engine_;
2954 void BufferParams::setCiteEngine(CiteEngine cite_engine)
2956 cite_engine_ = cite_engine;