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"
29 #include "IndicesList.h"
31 #include "LaTeXFeatures.h"
32 #include "ModuleList.h"
36 #include "OutputParams.h"
40 #include "PDFOptions.h"
42 #include "frontends/alert.h"
44 #include "insets/InsetListingsParams.h"
46 #include "support/convert.h"
47 #include "support/debug.h"
48 #include "support/docstream.h"
49 #include "support/FileName.h"
50 #include "support/filetools.h"
51 #include "support/gettext.h"
52 #include "support/Messages.h"
53 #include "support/Translator.h"
54 #include "support/lstrings.h"
60 using namespace lyx::support;
63 static char const * const string_paragraph_separation[] = {
68 static char const * const string_quotes_language[] = {
69 "english", "swedish", "german", "polish", "french", "danish", ""
73 static char const * const string_papersize[] = {
74 "default", "custom", "letterpaper", "legalpaper", "executivepaper",
75 "a0paper", "a1paper", "a2paper", "a3paper", "a4paper", "a5paper",
76 "a6paper", "b0paper", "b1paper", "b2paper","b3paper", "b4paper",
77 "b5paper", "b6paper", "c0paper", "c1paper", "c2paper", "c3paper",
78 "c4paper", "c5paper", "c6paper", "b0j", "b1j", "b2j", "b3j", "b4j", "b5j",
83 static char const * const string_orientation[] = {
84 "portrait", "landscape", ""
88 static char const * const string_footnotekinds[] = {
89 "footnote", "margin", "fig", "tab", "alg", "wide-fig", "wide-tab", ""
93 static char const * const tex_graphics[] = {
94 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
95 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
96 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
97 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
108 // Paragraph separation
109 typedef Translator<string, BufferParams::ParagraphSeparation> ParSepTranslator;
112 ParSepTranslator const init_parseptranslator()
114 ParSepTranslator translator
115 (string_paragraph_separation[0], BufferParams::ParagraphIndentSeparation);
116 translator.addPair(string_paragraph_separation[1], BufferParams::ParagraphSkipSeparation);
121 ParSepTranslator const & parseptranslator()
123 static ParSepTranslator translator = init_parseptranslator();
129 typedef Translator<string, InsetQuotes::QuoteLanguage> QuotesLangTranslator;
132 QuotesLangTranslator const init_quoteslangtranslator()
134 QuotesLangTranslator translator
135 (string_quotes_language[0], InsetQuotes::EnglishQuotes);
136 translator.addPair(string_quotes_language[1], InsetQuotes::SwedishQuotes);
137 translator.addPair(string_quotes_language[2], InsetQuotes::GermanQuotes);
138 translator.addPair(string_quotes_language[3], InsetQuotes::PolishQuotes);
139 translator.addPair(string_quotes_language[4], InsetQuotes::FrenchQuotes);
140 translator.addPair(string_quotes_language[5], InsetQuotes::DanishQuotes);
145 QuotesLangTranslator const & quoteslangtranslator()
147 static QuotesLangTranslator translator = init_quoteslangtranslator();
153 typedef Translator<string, PAPER_SIZE> PaperSizeTranslator;
156 static PaperSizeTranslator initPaperSizeTranslator()
158 PaperSizeTranslator translator(string_papersize[0], PAPER_DEFAULT);
159 translator.addPair(string_papersize[1], PAPER_CUSTOM);
160 translator.addPair(string_papersize[2], PAPER_USLETTER);
161 translator.addPair(string_papersize[3], PAPER_USLEGAL);
162 translator.addPair(string_papersize[4], PAPER_USEXECUTIVE);
163 translator.addPair(string_papersize[5], PAPER_A0);
164 translator.addPair(string_papersize[6], PAPER_A1);
165 translator.addPair(string_papersize[7], PAPER_A2);
166 translator.addPair(string_papersize[8], PAPER_A3);
167 translator.addPair(string_papersize[9], PAPER_A4);
168 translator.addPair(string_papersize[10], PAPER_A5);
169 translator.addPair(string_papersize[11], PAPER_A6);
170 translator.addPair(string_papersize[12], PAPER_B0);
171 translator.addPair(string_papersize[13], PAPER_B1);
172 translator.addPair(string_papersize[14], PAPER_B2);
173 translator.addPair(string_papersize[15], PAPER_B3);
174 translator.addPair(string_papersize[16], PAPER_B4);
175 translator.addPair(string_papersize[17], PAPER_B5);
176 translator.addPair(string_papersize[18], PAPER_B6);
177 translator.addPair(string_papersize[19], PAPER_C0);
178 translator.addPair(string_papersize[20], PAPER_C1);
179 translator.addPair(string_papersize[21], PAPER_C2);
180 translator.addPair(string_papersize[22], PAPER_C3);
181 translator.addPair(string_papersize[23], PAPER_C4);
182 translator.addPair(string_papersize[24], PAPER_C5);
183 translator.addPair(string_papersize[25], PAPER_C6);
184 translator.addPair(string_papersize[26], PAPER_JISB0);
185 translator.addPair(string_papersize[27], PAPER_JISB1);
186 translator.addPair(string_papersize[28], PAPER_JISB2);
187 translator.addPair(string_papersize[29], PAPER_JISB3);
188 translator.addPair(string_papersize[30], PAPER_JISB4);
189 translator.addPair(string_papersize[31], PAPER_JISB5);
190 translator.addPair(string_papersize[32], PAPER_JISB6);
195 PaperSizeTranslator const & papersizetranslator()
197 static PaperSizeTranslator translator = initPaperSizeTranslator();
203 typedef Translator<string, PAPER_ORIENTATION> PaperOrientationTranslator;
206 PaperOrientationTranslator const init_paperorientationtranslator()
208 PaperOrientationTranslator translator(string_orientation[0], ORIENTATION_PORTRAIT);
209 translator.addPair(string_orientation[1], ORIENTATION_LANDSCAPE);
214 PaperOrientationTranslator const & paperorientationtranslator()
216 static PaperOrientationTranslator translator = init_paperorientationtranslator();
222 typedef Translator<int, PageSides> SidesTranslator;
225 SidesTranslator const init_sidestranslator()
227 SidesTranslator translator(1, OneSide);
228 translator.addPair(2, TwoSides);
233 SidesTranslator const & sidestranslator()
235 static SidesTranslator translator = init_sidestranslator();
241 typedef Translator<int, BufferParams::Package> PackageTranslator;
244 PackageTranslator const init_packagetranslator()
246 PackageTranslator translator(0, BufferParams::package_off);
247 translator.addPair(1, BufferParams::package_auto);
248 translator.addPair(2, BufferParams::package_on);
253 PackageTranslator const & packagetranslator()
255 static PackageTranslator translator = init_packagetranslator();
261 typedef Translator<string, CiteEngine> CiteEngineTranslator;
264 CiteEngineTranslator const init_citeenginetranslator()
266 CiteEngineTranslator translator("basic", ENGINE_BASIC);
267 translator.addPair("natbib_numerical", ENGINE_NATBIB_NUMERICAL);
268 translator.addPair("natbib_authoryear", ENGINE_NATBIB_AUTHORYEAR);
269 translator.addPair("jurabib", ENGINE_JURABIB);
274 CiteEngineTranslator const & citeenginetranslator()
276 static CiteEngineTranslator translator = init_citeenginetranslator();
282 typedef Translator<string, Spacing::Space> SpaceTranslator;
285 SpaceTranslator const init_spacetranslator()
287 SpaceTranslator translator("default", Spacing::Default);
288 translator.addPair("single", Spacing::Single);
289 translator.addPair("onehalf", Spacing::Onehalf);
290 translator.addPair("double", Spacing::Double);
291 translator.addPair("other", Spacing::Other);
296 SpaceTranslator const & spacetranslator()
298 static SpaceTranslator translator = init_spacetranslator();
305 class BufferParams::Impl
310 AuthorList authorlist;
311 BranchList branchlist;
312 Bullet temp_bullets[4];
313 Bullet user_defined_bullets[4];
314 IndicesList indiceslist;
316 /** This is the amount of space used for paragraph_separation "skip",
317 * and for detached paragraphs in "indented" documents.
321 PDFOptions pdfoptions;
322 LayoutFileIndex baseClass_;
326 BufferParams::Impl::Impl()
327 : defskip(VSpace::MEDSKIP), baseClass_(string(""))
329 // set initial author
331 authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
336 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
340 return new BufferParams::Impl(*ptr);
344 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
350 BufferParams::BufferParams()
353 setBaseClass(defaultBaseclass());
355 paragraph_separation = ParagraphIndentSeparation;
356 quotes_language = InsetQuotes::EnglishQuotes;
357 fontsize = "default";
360 papersize = PAPER_DEFAULT;
361 orientation = ORIENTATION_PORTRAIT;
362 use_geometry = false;
363 use_amsmath = package_auto;
364 use_esint = package_auto;
365 use_mhchem = package_auto;
366 use_mathdots = package_auto;
367 cite_engine_ = ENGINE_BASIC;
368 use_bibtopic = false;
370 trackChanges = false;
371 outputChanges = false;
372 use_default_options = true;
373 maintain_unincluded_children = false;
376 language = default_language;
378 fonts_roman = "default";
379 fonts_sans = "default";
380 fonts_typewriter = "default";
381 fonts_default_family = "default";
382 useNonTeXFonts = false;
383 fonts_expert_sc = false;
384 fonts_old_figures = false;
385 fonts_sans_scale = 100;
386 fonts_typewriter_scale = 100;
388 lang_package = "default";
389 graphics_driver = "default";
390 default_output_format = "default";
391 bibtex_command = "default";
392 index_command = "default";
395 listings_params = string();
396 pagestyle = "default";
397 suppress_date = false;
398 // no color is the default (white)
399 backgroundcolor = lyx::rgbFromHexName("#ffffff");
400 isbackgroundcolor = false;
401 // no color is the default (black)
402 fontcolor = lyx::rgbFromHexName("#000000");
404 // light gray is the default font color for greyed-out notes
405 notefontcolor = lyx::rgbFromHexName("#cccccc");
406 boxbgcolor = lyx::rgbFromHexName("#ff0000");
407 compressed = lyxrc.save_compressed;
408 for (int iter = 0; iter < 4; ++iter) {
409 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
410 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
413 indiceslist().addDefault(B_("Index"));
414 html_be_strict = false;
415 html_math_output = MathML;
416 html_math_img_scale = 1.0;
417 html_css_as_file = false;
424 docstring BufferParams::B_(string const & l10n) const
426 LASSERT(language, /**/);
427 return getMessages(language->code()).get(l10n);
431 AuthorList & BufferParams::authors()
433 return pimpl_->authorlist;
437 AuthorList const & BufferParams::authors() const
439 return pimpl_->authorlist;
443 BranchList & BufferParams::branchlist()
445 return pimpl_->branchlist;
449 BranchList const & BufferParams::branchlist() const
451 return pimpl_->branchlist;
455 IndicesList & BufferParams::indiceslist()
457 return pimpl_->indiceslist;
461 IndicesList const & BufferParams::indiceslist() const
463 return pimpl_->indiceslist;
467 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
469 LASSERT(index < 4, /**/);
470 return pimpl_->temp_bullets[index];
474 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
476 LASSERT(index < 4, /**/);
477 return pimpl_->temp_bullets[index];
481 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
483 LASSERT(index < 4, /**/);
484 return pimpl_->user_defined_bullets[index];
488 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
490 LASSERT(index < 4, /**/);
491 return pimpl_->user_defined_bullets[index];
495 Spacing & BufferParams::spacing()
497 return pimpl_->spacing;
501 Spacing const & BufferParams::spacing() const
503 return pimpl_->spacing;
507 PDFOptions & BufferParams::pdfoptions()
509 return pimpl_->pdfoptions;
513 PDFOptions const & BufferParams::pdfoptions() const
515 return pimpl_->pdfoptions;
519 HSpace const & BufferParams::getIndentation() const
521 return pimpl_->indentation;
525 void BufferParams::setIndentation(HSpace const & indent)
527 pimpl_->indentation = indent;
531 VSpace const & BufferParams::getDefSkip() const
533 return pimpl_->defskip;
537 void BufferParams::setDefSkip(VSpace const & vs)
539 // DEFSKIP will cause an infinite loop
540 LASSERT(vs.kind() != VSpace::DEFSKIP, return);
541 pimpl_->defskip = vs;
545 string BufferParams::readToken(Lexer & lex, string const & token,
546 FileName const & filepath)
548 if (token == "\\textclass") {
550 string const classname = lex.getString();
551 // if there exists a local layout file, ignore the system one
552 // NOTE: in this case, the textclass (.cls file) is assumed to
555 LayoutFileList & bcl = LayoutFileList::get();
556 if (tcp.empty() && !filepath.empty())
557 tcp = bcl.addLocalLayout(classname, filepath.absFileName());
561 setBaseClass(classname);
562 // We assume that a tex class exists for local or unknown
563 // layouts so this warning, will only be given for system layouts.
564 if (!baseClass()->isTeXClassAvailable()) {
565 docstring const desc =
566 translateIfPossible(from_utf8(baseClass()->description()));
567 docstring const prereqs =
568 from_utf8(baseClass()->prerequisites());
569 docstring const msg =
570 bformat(_("The selected document class\n"
572 "requires external files that are not available.\n"
573 "The document class can still be used, but the\n"
574 "document cannot be compiled until the following\n"
575 "prerequisites are installed:\n"
577 "See section 3.1.2.2 (Class Availability) of the\n"
578 "User's Guide for more information."), desc, prereqs);
579 frontend::Alert::warning(_("Document class not available"),
582 } else if (token == "\\begin_preamble") {
584 } else if (token == "\\begin_local_layout") {
585 readLocalLayout(lex);
586 } else if (token == "\\begin_modules") {
588 } else if (token == "\\begin_removed_modules") {
589 readRemovedModules(lex);
590 } else if (token == "\\begin_includeonly") {
591 readIncludeonly(lex);
592 } else if (token == "\\maintain_unincluded_children") {
593 lex >> maintain_unincluded_children;
594 } else if (token == "\\options") {
596 options = lex.getString();
597 } else if (token == "\\use_default_options") {
598 lex >> use_default_options;
599 } else if (token == "\\master") {
601 master = lex.getString();
602 } else if (token == "\\suppress_date") {
603 lex >> suppress_date;
604 } else if (token == "\\language") {
606 } else if (token == "\\language_package") {
608 lang_package = lex.getString();
609 } else if (token == "\\inputencoding") {
611 } else if (token == "\\graphics") {
612 readGraphicsDriver(lex);
613 } else if (token == "\\default_output_format") {
614 lex >> default_output_format;
615 } else if (token == "\\bibtex_command") {
617 bibtex_command = lex.getString();
618 } else if (token == "\\index_command") {
620 index_command = lex.getString();
621 } else if (token == "\\fontencoding") {
623 fontenc = lex.getString();
624 } else if (token == "\\font_roman") {
626 fonts_roman = lex.getString();
627 } else if (token == "\\font_sans") {
629 fonts_sans = lex.getString();
630 } else if (token == "\\font_typewriter") {
632 fonts_typewriter = lex.getString();
633 } else if (token == "\\font_default_family") {
634 lex >> fonts_default_family;
635 } else if (token == "\\use_non_tex_fonts") {
636 lex >> useNonTeXFonts;
637 } else if (token == "\\font_sc") {
638 lex >> fonts_expert_sc;
639 } else if (token == "\\font_osf") {
640 lex >> fonts_old_figures;
641 } else if (token == "\\font_sf_scale") {
642 lex >> fonts_sans_scale;
643 } else if (token == "\\font_tt_scale") {
644 lex >> fonts_typewriter_scale;
645 } else if (token == "\\font_cjk") {
647 } else if (token == "\\paragraph_separation") {
650 paragraph_separation = parseptranslator().find(parsep);
651 } else if (token == "\\paragraph_indentation") {
653 string indentation = lex.getString();
654 pimpl_->indentation = HSpace(indentation);
655 } else if (token == "\\defskip") {
657 string const defskip = lex.getString();
658 pimpl_->defskip = VSpace(defskip);
659 if (pimpl_->defskip.kind() == VSpace::DEFSKIP)
661 pimpl_->defskip = VSpace(VSpace::MEDSKIP);
662 } else if (token == "\\quotes_language") {
665 quotes_language = quoteslangtranslator().find(quotes_lang);
666 } else if (token == "\\papersize") {
669 papersize = papersizetranslator().find(ppsize);
670 } else if (token == "\\use_geometry") {
672 } else if (token == "\\use_amsmath") {
675 use_amsmath = packagetranslator().find(use_ams);
676 } else if (token == "\\use_esint") {
679 use_esint = packagetranslator().find(useesint);
680 } else if (token == "\\use_mhchem") {
683 use_mhchem = packagetranslator().find(usemhchem);
684 } else if (token == "\\use_mathdots") {
687 use_mathdots = packagetranslator().find(usemathdots);
688 } else if (token == "\\cite_engine") {
691 cite_engine_ = citeenginetranslator().find(engine);
692 } else if (token == "\\use_bibtopic") {
694 } else if (token == "\\use_indices") {
696 } else if (token == "\\tracking_changes") {
698 } else if (token == "\\output_changes") {
699 lex >> outputChanges;
700 } else if (token == "\\branch") {
702 docstring branch = lex.getDocString();
703 branchlist().add(branch);
706 string const tok = lex.getString();
707 if (tok == "\\end_branch")
709 Branch * branch_ptr = branchlist().find(branch);
710 if (tok == "\\selected") {
713 branch_ptr->setSelected(lex.getInteger());
715 if (tok == "\\filename_suffix") {
718 branch_ptr->setFileNameSuffix(lex.getInteger());
720 if (tok == "\\color") {
722 string color = lex.getString();
724 branch_ptr->setColor(color);
725 // Update also the Color table:
727 color = lcolor.getX11Name(Color_background);
729 lcolor.setColor(to_utf8(branch), color);
732 } else if (token == "\\index") {
734 docstring index = lex.getDocString();
736 indiceslist().add(index);
739 string const tok = lex.getString();
740 if (tok == "\\end_index")
742 Index * index_ptr = indiceslist().find(index);
743 if (tok == "\\shortcut") {
745 shortcut = lex.getDocString();
747 index_ptr->setShortcut(shortcut);
749 if (tok == "\\color") {
751 string color = lex.getString();
753 index_ptr->setColor(color);
754 // Update also the Color table:
756 color = lcolor.getX11Name(Color_background);
758 if (!shortcut.empty())
759 lcolor.setColor(to_utf8(shortcut), color);
762 } else if (token == "\\author") {
764 istringstream ss(lex.getString());
767 author_map[a.bufferId()] = pimpl_->authorlist.record(a);
768 } else if (token == "\\paperorientation") {
771 orientation = paperorientationtranslator().find(orient);
772 } else if (token == "\\backgroundcolor") {
774 backgroundcolor = lyx::rgbFromHexName(lex.getString());
775 isbackgroundcolor = true;
776 } else if (token == "\\fontcolor") {
778 fontcolor = lyx::rgbFromHexName(lex.getString());
780 } else if (token == "\\notefontcolor") {
782 string color = lex.getString();
783 notefontcolor = lyx::rgbFromHexName(color);
784 } else if (token == "\\boxbgcolor") {
786 string color = lex.getString();
787 boxbgcolor = lyx::rgbFromHexName(color);
788 } else if (token == "\\paperwidth") {
790 } else if (token == "\\paperheight") {
792 } else if (token == "\\leftmargin") {
794 } else if (token == "\\topmargin") {
796 } else if (token == "\\rightmargin") {
798 } else if (token == "\\bottommargin") {
800 } else if (token == "\\headheight") {
802 } else if (token == "\\headsep") {
804 } else if (token == "\\footskip") {
806 } else if (token == "\\columnsep") {
808 } else if (token == "\\paperfontsize") {
810 } else if (token == "\\papercolumns") {
812 } else if (token == "\\listings_params") {
815 listings_params = InsetListingsParams(par).params();
816 } else if (token == "\\papersides") {
819 sides = sidestranslator().find(psides);
820 } else if (token == "\\paperpagestyle") {
822 } else if (token == "\\bullet") {
824 } else if (token == "\\bulletLaTeX") {
825 readBulletsLaTeX(lex);
826 } else if (token == "\\secnumdepth") {
828 } else if (token == "\\tocdepth") {
830 } else if (token == "\\spacing") {
834 if (nspacing == "other") {
837 spacing().set(spacetranslator().find(nspacing), tmp_val);
838 } else if (token == "\\float_placement") {
839 lex >> float_placement;
841 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
842 string toktmp = pdfoptions().readToken(lex, token);
843 if (!toktmp.empty()) {
844 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
848 } else if (token == "\\html_math_output") {
851 html_math_output = static_cast<MathOutput>(temp);
852 } else if (token == "\\html_be_strict") {
853 lex >> html_be_strict;
854 } else if (token == "\\html_css_as_file") {
855 lex >> html_css_as_file;
856 } else if (token == "\\html_math_img_scale") {
857 lex >> html_math_img_scale;
858 } else if (token == "\\html_latex_start") {
860 html_latex_start = lex.getString();
861 } else if (token == "\\html_latex_end") {
863 html_latex_end = lex.getString();
864 } else if (token == "\\output_sync") {
866 } else if (token == "\\output_sync_macro") {
867 lex >> output_sync_macro;
868 } else if (token == "\\use_refstyle") {
871 lyxerr << "BufferParams::readToken(): Unknown token: " <<
880 void BufferParams::writeFile(ostream & os) const
882 // The top of the file is written by the buffer.
883 // Prints out the buffer info into the .lyx file given by file
886 os << "\\textclass " << baseClass()->name() << '\n';
889 if (!preamble.empty()) {
890 // remove '\n' from the end of preamble
891 string const tmppreamble = rtrim(preamble, "\n");
892 os << "\\begin_preamble\n"
894 << "\n\\end_preamble\n";
898 if (!options.empty()) {
899 os << "\\options " << options << '\n';
902 // use the class options defined in the layout?
903 os << "\\use_default_options "
904 << convert<string>(use_default_options) << "\n";
906 // the master document
907 if (!master.empty()) {
908 os << "\\master " << master << '\n';
912 if (!removed_modules_.empty()) {
913 os << "\\begin_removed_modules" << '\n';
914 list<string>::const_iterator it = removed_modules_.begin();
915 list<string>::const_iterator en = removed_modules_.end();
916 for (; it != en; it++)
918 os << "\\end_removed_modules" << '\n';
922 if (!layout_modules_.empty()) {
923 os << "\\begin_modules" << '\n';
924 LayoutModuleList::const_iterator it = layout_modules_.begin();
925 LayoutModuleList::const_iterator en = layout_modules_.end();
926 for (; it != en; it++)
928 os << "\\end_modules" << '\n';
932 if (!included_children_.empty()) {
933 os << "\\begin_includeonly" << '\n';
934 list<string>::const_iterator it = included_children_.begin();
935 list<string>::const_iterator en = included_children_.end();
936 for (; it != en; it++)
938 os << "\\end_includeonly" << '\n';
940 os << "\\maintain_unincluded_children "
941 << convert<string>(maintain_unincluded_children) << '\n';
943 // local layout information
944 if (!local_layout.empty()) {
945 // remove '\n' from the end
946 string const tmplocal = rtrim(local_layout, "\n");
947 os << "\\begin_local_layout\n"
949 << "\n\\end_local_layout\n";
952 // then the text parameters
953 if (language != ignore_language)
954 os << "\\language " << language->lang() << '\n';
955 os << "\\language_package " << lang_package
956 << "\n\\inputencoding " << inputenc
957 << "\n\\fontencoding " << fontenc
958 << "\n\\font_roman " << fonts_roman
959 << "\n\\font_sans " << fonts_sans
960 << "\n\\font_typewriter " << fonts_typewriter
961 << "\n\\font_default_family " << fonts_default_family
962 << "\n\\use_non_tex_fonts " << convert<string>(useNonTeXFonts)
963 << "\n\\font_sc " << convert<string>(fonts_expert_sc)
964 << "\n\\font_osf " << convert<string>(fonts_old_figures)
965 << "\n\\font_sf_scale " << fonts_sans_scale
966 << "\n\\font_tt_scale " << fonts_typewriter_scale
968 if (!fonts_cjk.empty()) {
969 os << "\\font_cjk " << fonts_cjk << '\n';
971 os << "\n\\graphics " << graphics_driver << '\n';
972 os << "\\default_output_format " << default_output_format << '\n';
973 os << "\\output_sync " << output_sync << '\n';
974 if (!output_sync_macro.empty())
975 os << "\\output_sync_macro \"" << output_sync_macro << "\"\n";
976 os << "\\bibtex_command " << bibtex_command << '\n';
977 os << "\\index_command " << index_command << '\n';
979 if (!float_placement.empty()) {
980 os << "\\float_placement " << float_placement << '\n';
982 os << "\\paperfontsize " << fontsize << '\n';
984 spacing().writeFile(os);
985 pdfoptions().writeFile(os);
987 os << "\\papersize " << string_papersize[papersize]
988 << "\n\\use_geometry " << convert<string>(use_geometry)
989 << "\n\\use_amsmath " << use_amsmath
990 << "\n\\use_esint " << use_esint
991 << "\n\\use_mhchem " << use_mhchem
992 << "\n\\use_mathdots " << use_mathdots
993 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
994 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
995 << "\n\\use_indices " << convert<string>(use_indices)
996 << "\n\\paperorientation " << string_orientation[orientation]
997 << "\n\\suppress_date " << convert<string>(suppress_date)
998 << "\n\\use_refstyle " << use_refstyle
1000 if (isbackgroundcolor == true)
1001 os << "\\backgroundcolor " << lyx::X11hexname(backgroundcolor) << '\n';
1002 if (isfontcolor == true)
1003 os << "\\fontcolor " << lyx::X11hexname(fontcolor) << '\n';
1004 if (notefontcolor != lyx::rgbFromHexName("#cccccc"))
1005 os << "\\notefontcolor " << lyx::X11hexname(notefontcolor) << '\n';
1006 if (boxbgcolor != lyx::rgbFromHexName("#ff0000"))
1007 os << "\\boxbgcolor " << lyx::X11hexname(boxbgcolor) << '\n';
1009 BranchList::const_iterator it = branchlist().begin();
1010 BranchList::const_iterator end = branchlist().end();
1011 for (; it != end; ++it) {
1012 os << "\\branch " << to_utf8(it->branch())
1013 << "\n\\selected " << it->isSelected()
1014 << "\n\\filename_suffix " << it->hasFileNameSuffix()
1015 << "\n\\color " << lyx::X11hexname(it->color())
1020 IndicesList::const_iterator iit = indiceslist().begin();
1021 IndicesList::const_iterator iend = indiceslist().end();
1022 for (; iit != iend; ++iit) {
1023 os << "\\index " << to_utf8(iit->index())
1024 << "\n\\shortcut " << to_utf8(iit->shortcut())
1025 << "\n\\color " << lyx::X11hexname(iit->color())
1030 if (!paperwidth.empty())
1031 os << "\\paperwidth "
1032 << VSpace(paperwidth).asLyXCommand() << '\n';
1033 if (!paperheight.empty())
1034 os << "\\paperheight "
1035 << VSpace(paperheight).asLyXCommand() << '\n';
1036 if (!leftmargin.empty())
1037 os << "\\leftmargin "
1038 << VSpace(leftmargin).asLyXCommand() << '\n';
1039 if (!topmargin.empty())
1040 os << "\\topmargin "
1041 << VSpace(topmargin).asLyXCommand() << '\n';
1042 if (!rightmargin.empty())
1043 os << "\\rightmargin "
1044 << VSpace(rightmargin).asLyXCommand() << '\n';
1045 if (!bottommargin.empty())
1046 os << "\\bottommargin "
1047 << VSpace(bottommargin).asLyXCommand() << '\n';
1048 if (!headheight.empty())
1049 os << "\\headheight "
1050 << VSpace(headheight).asLyXCommand() << '\n';
1051 if (!headsep.empty())
1053 << VSpace(headsep).asLyXCommand() << '\n';
1054 if (!footskip.empty())
1056 << VSpace(footskip).asLyXCommand() << '\n';
1057 if (!columnsep.empty())
1058 os << "\\columnsep "
1059 << VSpace(columnsep).asLyXCommand() << '\n';
1060 os << "\\secnumdepth " << secnumdepth
1061 << "\n\\tocdepth " << tocdepth
1062 << "\n\\paragraph_separation "
1063 << string_paragraph_separation[paragraph_separation];
1064 if (!paragraph_separation)
1065 os << "\n\\paragraph_indentation " << getIndentation().asLyXCommand();
1067 os << "\n\\defskip " << getDefSkip().asLyXCommand();
1068 os << "\n\\quotes_language "
1069 << string_quotes_language[quotes_language]
1070 << "\n\\papercolumns " << columns
1071 << "\n\\papersides " << sides
1072 << "\n\\paperpagestyle " << pagestyle << '\n';
1073 if (!listings_params.empty())
1074 os << "\\listings_params \"" <<
1075 InsetListingsParams(listings_params).encodedString() << "\"\n";
1076 for (int i = 0; i < 4; ++i) {
1077 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1078 if (user_defined_bullet(i).getFont() != -1) {
1079 os << "\\bullet " << i << " "
1080 << user_defined_bullet(i).getFont() << " "
1081 << user_defined_bullet(i).getCharacter() << " "
1082 << user_defined_bullet(i).getSize() << "\n";
1086 os << "\\bulletLaTeX " << i << " \""
1087 << lyx::to_ascii(user_defined_bullet(i).getText())
1093 os << "\\tracking_changes " << convert<string>(trackChanges) << '\n'
1094 << "\\output_changes " << convert<string>(outputChanges) << '\n'
1095 << "\\html_math_output " << html_math_output << '\n'
1096 << "\\html_css_as_file " << html_css_as_file << '\n'
1097 << "\\html_be_strict " << convert<string>(html_be_strict) << '\n';
1099 if (html_math_img_scale != 1.0)
1100 os << "\\html_math_img_scale " << convert<string>(html_math_img_scale) << '\n';
1101 if (!html_latex_start.empty())
1102 os << "\\html_latex_start " << html_latex_start << '\n';
1103 if (!html_latex_end.empty())
1104 os << "\\html_latex_end " << html_latex_end << '\n';
1106 os << pimpl_->authorlist;
1110 void BufferParams::validate(LaTeXFeatures & features) const
1112 features.require(documentClass().requires());
1114 if (outputChanges) {
1115 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
1116 bool xcolorulem = LaTeXFeatures::isAvailable("ulem") &&
1117 LaTeXFeatures::isAvailable("xcolor");
1119 switch (features.runparams().flavor) {
1120 case OutputParams::LATEX:
1122 features.require("ct-dvipost");
1123 features.require("dvipost");
1124 } else if (xcolorulem) {
1125 features.require("ct-xcolor-ulem");
1126 features.require("ulem");
1127 features.require("xcolor");
1129 features.require("ct-none");
1132 case OutputParams::LUATEX:
1133 case OutputParams::PDFLATEX:
1134 case OutputParams::XETEX:
1136 features.require("ct-xcolor-ulem");
1137 features.require("ulem");
1138 features.require("xcolor");
1139 // improves color handling in PDF output
1140 features.require("pdfcolmk");
1142 features.require("ct-none");
1150 // Floats with 'Here definitely' as default setting.
1151 if (float_placement.find('H') != string::npos)
1152 features.require("float");
1154 // AMS Style is at document level
1155 if (use_amsmath == package_on
1156 || documentClass().provides("amsmath"))
1157 features.require("amsmath");
1158 if (use_esint == package_on)
1159 features.require("esint");
1160 if (use_mhchem == package_on)
1161 features.require("mhchem");
1162 if (use_mathdots == package_on)
1163 features.require("mathdots");
1165 // Document-level line spacing
1166 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
1167 features.require("setspace");
1169 // the bullet shapes are buffer level not paragraph level
1170 // so they are tested here
1171 for (int i = 0; i < 4; ++i) {
1172 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
1174 int const font = user_defined_bullet(i).getFont();
1176 int const c = user_defined_bullet(i).getCharacter();
1182 features.require("latexsym");
1184 } else if (font == 1) {
1185 features.require("amssymb");
1186 } else if (font >= 2 && font <= 5) {
1187 features.require("pifont");
1191 if (pdfoptions().use_hyperref) {
1192 features.require("hyperref");
1193 // due to interferences with babel and hyperref, the color package has to
1194 // be loaded after hyperref when hyperref is used with the colorlinks
1195 // option, see http://www.lyx.org/trac/ticket/5291
1196 if (pdfoptions().colorlinks)
1197 features.require("color");
1200 if (features.runparams().flavor == OutputParams::XETEX
1202 features.require("polyglossia");
1204 if (language->lang() == "vietnamese")
1205 features.require("vietnamese");
1206 else if (language->lang() == "japanese")
1207 features.require("japanese");
1211 bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
1212 FileName const & filepath) const
1214 // http://www.tug.org/texmf-dist/doc/latex/base/fixltx2e.pdf
1215 // !! To use the Fix-cm package, load it before \documentclass, and use the command
1216 // \RequirePackage to do so, rather than the normal \usepackage
1217 // Do not to load any other package before the document class, unless you
1218 // have a thorough understanding of the LATEX internals and know exactly what you
1220 if (features.mustProvide("fix-cm"))
1221 os << "\\RequirePackage{fix-cm}\n";
1223 os << "\\documentclass";
1225 DocumentClass const & tclass = documentClass();
1227 ostringstream clsoptions; // the document class options.
1229 if (tokenPos(tclass.opt_fontsize(),
1230 '|', fontsize) >= 0) {
1231 // only write if existing in list (and not default)
1232 clsoptions << fontsize << "pt,";
1235 // all paper sizes except of A4, A5, B5 and the US sizes need the
1237 bool nonstandard_papersize = papersize != PAPER_DEFAULT
1238 && papersize != PAPER_USLETTER
1239 && papersize != PAPER_USLEGAL
1240 && papersize != PAPER_USEXECUTIVE
1241 && papersize != PAPER_A4
1242 && papersize != PAPER_A5
1243 && papersize != PAPER_B5;
1245 if (!use_geometry) {
1246 switch (papersize) {
1248 clsoptions << "a4paper,";
1250 case PAPER_USLETTER:
1251 clsoptions << "letterpaper,";
1254 clsoptions << "a5paper,";
1257 clsoptions << "b5paper,";
1259 case PAPER_USEXECUTIVE:
1260 clsoptions << "executivepaper,";
1263 clsoptions << "legalpaper,";
1297 if (sides != tclass.sides()) {
1300 clsoptions << "oneside,";
1303 clsoptions << "twoside,";
1309 if (columns != tclass.columns()) {
1311 clsoptions << "twocolumn,";
1313 clsoptions << "onecolumn,";
1317 && orientation == ORIENTATION_LANDSCAPE)
1318 clsoptions << "landscape,";
1320 // language should be a parameter to \documentclass
1321 if (language->babel() == "hebrew"
1322 && default_language->babel() != "hebrew")
1323 // This seems necessary
1324 features.useLanguage(default_language);
1326 ostringstream language_options;
1327 bool const use_babel = features.useBabel() && !tclass.provides("babel");
1328 bool const use_polyglossia = features.usePolyglossia();
1329 bool const global = lyxrc.language_global_options;
1330 if (use_babel || (use_polyglossia && global)) {
1331 language_options << features.getLanguages();
1332 if (!language->babel().empty()) {
1333 if (!language_options.str().empty())
1334 language_options << ',';
1335 language_options << language->babel();
1337 if (global && !features.needBabelLangOptions())
1338 clsoptions << language_options.str() << ',';
1341 // the predefined options from the layout
1342 if (use_default_options && !tclass.options().empty())
1343 clsoptions << tclass.options() << ',';
1345 // the user-defined options
1346 if (!options.empty()) {
1347 clsoptions << options << ',';
1350 string strOptions(clsoptions.str());
1351 if (!strOptions.empty()) {
1352 strOptions = rtrim(strOptions, ",");
1354 os << '[' << from_utf8(strOptions) << ']';
1357 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1358 // end of \documentclass defs
1360 // if we use fontspec, we have to load the AMS packages here
1361 string const ams = features.loadAMSPackages();
1362 if (useNonTeXFonts && !ams.empty())
1363 os << from_ascii(ams);
1366 os << "\\usepackage{fontspec}\n";
1368 // font selection must be done before loading fontenc.sty
1369 string const fonts =
1370 loadFonts(fonts_roman, fonts_sans, fonts_typewriter,
1371 fonts_expert_sc, fonts_old_figures,
1372 fonts_sans_scale, fonts_typewriter_scale,
1373 useNonTeXFonts, features);
1375 os << from_ascii(fonts);
1377 if (fonts_default_family != "default")
1378 os << "\\renewcommand{\\familydefault}{\\"
1379 << from_ascii(fonts_default_family) << "}\n";
1381 // set font encoding
1382 // for arabic_arabi and farsi we also need to load the LAE and
1384 // XeTeX and LuaTeX (with OS fonts) work without fontenc
1385 if (font_encoding() != "default" && language->lang() != "japanese"
1386 && !useNonTeXFonts && !tclass.provides("fontenc")) {
1387 size_t fars = language_options.str().find("farsi");
1388 size_t arab = language_options.str().find("arabic");
1389 if (language->lang() == "arabic_arabi"
1390 || language->lang() == "farsi" || fars != string::npos
1391 || arab != string::npos) {
1392 os << "\\usepackage[" << from_ascii(font_encoding())
1393 << ",LFE,LAE]{fontenc}\n";
1395 os << "\\usepackage[" << from_ascii(font_encoding())
1400 // handle inputenc etc.
1401 writeEncodingPreamble(os, features);
1404 if (!features.runparams().includeall && !included_children_.empty()) {
1405 os << "\\includeonly{";
1406 list<string>::const_iterator it = included_children_.begin();
1407 list<string>::const_iterator en = included_children_.end();
1409 for (; it != en; ++it) {
1410 string incfile = *it;
1411 FileName inc = makeAbsPath(incfile, filepath.absFileName());
1412 string mangled = DocFileName(changeExtension(inc.absFileName(), ".tex")).
1414 if (!features.runparams().nice)
1416 // \includeonly doesn't want an extension
1417 incfile = changeExtension(incfile, string());
1418 incfile = support::latex_path(incfile);
1419 if (!incfile.empty()) {
1422 os << from_utf8(incfile);
1429 if (!listings_params.empty() || features.isRequired("listings"))
1430 os << "\\usepackage{listings}\n";
1432 if (!listings_params.empty()) {
1434 // do not test validity because listings_params is
1435 // supposed to be valid
1437 InsetListingsParams(listings_params).separatedParams(true);
1438 // we can't support all packages, but we should load the color package
1439 if (par.find("\\color", 0) != string::npos)
1440 features.require("color");
1441 os << from_utf8(par)
1444 if (!tclass.provides("geometry")
1445 && (use_geometry || nonstandard_papersize)) {
1446 odocstringstream ods;
1447 if (!getGraphicsDriver("geometry").empty())
1448 ods << getGraphicsDriver("geometry");
1449 if (orientation == ORIENTATION_LANDSCAPE)
1450 ods << ",landscape";
1451 switch (papersize) {
1453 if (!paperwidth.empty())
1454 ods << ",paperwidth="
1455 << from_ascii(paperwidth);
1456 if (!paperheight.empty())
1457 ods << ",paperheight="
1458 << from_ascii(paperheight);
1460 case PAPER_USLETTER:
1461 ods << ",letterpaper";
1464 ods << ",legalpaper";
1466 case PAPER_USEXECUTIVE:
1467 ods << ",executivepaper";
1554 // default papersize ie PAPER_DEFAULT
1555 switch (lyxrc.default_papersize) {
1556 case PAPER_DEFAULT: // keep compiler happy
1558 case PAPER_USLETTER:
1559 ods << ",letterpaper";
1562 ods << ",legalpaper";
1564 case PAPER_USEXECUTIVE:
1565 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;
1712 if (!output_sync_macro.empty())
1713 lyxpreamble += from_utf8(output_sync_macro) +"\n";
1714 else if (features.runparams().flavor == OutputParams::LATEX)
1715 lyxpreamble += "\\usepackage[active]{srcltx}\n";
1716 else if (features.runparams().flavor == OutputParams::PDFLATEX)
1717 lyxpreamble += "\\synctex=-1\n";
1720 // due to interferences with babel and hyperref, the color package has to
1721 // be loaded (when it is not already loaded) before babel when hyperref
1722 // is used with the colorlinks option, see
1723 // http://www.lyx.org/trac/ticket/5291
1724 // we decided therefore to load color always before babel, see
1725 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg144349.html
1726 lyxpreamble += from_ascii(features.getColorOptions());
1728 // If we use hyperref, jurabib, japanese, or vietnamese, we have to call babel before them.
1730 && (features.isRequired("jurabib")
1731 || features.isRequired("hyperref")
1732 || features.isRequired("vietnamese")
1733 || features.isRequired("japanese"))) {
1735 lyxpreamble += from_utf8(features.getBabelPresettings());
1736 lyxpreamble += from_utf8(babelCall(language_options.str(),
1737 features.needBabelLangOptions())) + '\n';
1738 lyxpreamble += from_utf8(features.getBabelPostsettings());
1741 // The optional packages;
1742 lyxpreamble += from_ascii(features.getPackages());
1744 // Additional Indices
1745 if (features.isRequired("splitidx")) {
1746 IndicesList::const_iterator iit = indiceslist().begin();
1747 IndicesList::const_iterator iend = indiceslist().end();
1748 for (; iit != iend; ++iit) {
1749 lyxpreamble += "\\newindex[";
1750 lyxpreamble += iit->index();
1751 lyxpreamble += "]{";
1752 lyxpreamble += iit->shortcut();
1753 lyxpreamble += "}\n";
1758 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1761 // * Hyperref manual: "Make sure it comes last of your loaded
1762 // packages, to give it a fighting chance of not being over-written,
1763 // since its job is to redefine many LaTeX commands."
1764 // * Email from Heiko Oberdiek: "It is usually better to load babel
1765 // before hyperref. Then hyperref has a chance to detect babel.
1766 // * Has to be loaded before the "LyX specific LaTeX commands" to
1767 // avoid errors with algorithm floats.
1768 // use hyperref explicitly if it is required
1769 if (features.isRequired("hyperref")) {
1770 // pass what we have to stream here, since we need
1771 // to access the stream itself in PDFOptions.
1774 OutputParams tmp_params = features.runparams();
1775 pdfoptions().writeLaTeX(tmp_params, os,
1776 documentClass().provides("hyperref"));
1777 // set back for the rest
1778 lyxpreamble.clear();
1779 // correctly break URLs with hyperref and dvi output
1780 if (features.runparams().flavor == OutputParams::LATEX
1781 && features.isAvailable("breakurl"))
1782 lyxpreamble += "\\usepackage{breakurl}\n";
1783 } else if (features.isRequired("nameref"))
1784 // hyperref loads this automatically
1785 lyxpreamble += "\\usepackage{nameref}\n";
1787 // Will be surrounded by \makeatletter and \makeatother when not empty
1788 docstring atlyxpreamble;
1790 // Some macros LyX will need
1791 docstring tmppreamble(features.getMacros());
1793 if (!tmppreamble.empty())
1794 atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1795 "LyX specific LaTeX commands.\n"
1796 + tmppreamble + '\n';
1798 // the text class specific preamble
1799 tmppreamble = features.getTClassPreamble();
1800 if (!tmppreamble.empty())
1801 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1802 "Textclass specific LaTeX commands.\n"
1803 + tmppreamble + '\n';
1805 // suppress date if selected
1806 // use \@ifundefined because we cannot be sure that every document class
1807 // has a \date command
1809 atlyxpreamble += "\\@ifundefined{date}{}{\\date{}}\n";
1811 /* the user-defined preamble */
1812 if (!containsOnly(preamble, " \n\t"))
1814 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1815 "User specified LaTeX commands.\n"
1816 + from_utf8(preamble) + '\n';
1818 // subfig loads internally the LaTeX package "caption". As
1819 // caption is a very popular package, users will load it in
1820 // the preamble. Therefore we must load subfig behind the
1821 // user-defined preamble and check if the caption package was
1822 // loaded or not. For the case that caption is loaded before
1823 // subfig, there is the subfig option "caption=false". This
1824 // option also works when a koma-script class is used and
1825 // koma's own caption commands are used instead of caption. We
1826 // use \PassOptionsToPackage here because the user could have
1827 // already loaded subfig in the preamble.
1828 if (features.isRequired("subfig")) {
1829 atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n"
1830 " \\PassOptionsToPackage{caption=false}{subfig}}\n"
1831 "\\usepackage{subfig}\n";
1834 // Itemize bullet settings need to be last in case the user
1835 // defines their own bullets that use a package included
1836 // in the user-defined preamble -- ARRae
1837 // Actually it has to be done much later than that
1838 // since some packages like frenchb make modifications
1839 // at \begin{document} time -- JMarc
1840 docstring bullets_def;
1841 for (int i = 0; i < 4; ++i) {
1842 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1843 if (bullets_def.empty())
1844 bullets_def += "\\AtBeginDocument{\n";
1845 bullets_def += " \\def\\labelitemi";
1847 // `i' is one less than the item to modify
1854 bullets_def += "ii";
1860 bullets_def += '{' +
1861 user_defined_bullet(i).getText()
1866 if (!bullets_def.empty())
1867 atlyxpreamble += bullets_def + "}\n\n";
1869 if (!atlyxpreamble.empty())
1870 lyxpreamble += "\n\\makeatletter\n"
1871 + atlyxpreamble + "\\makeatother\n\n";
1873 // We try to load babel late, in case it interferes with other packages.
1874 // Jurabib and Hyperref have to be called after babel, though.
1875 if (use_babel && !features.isRequired("jurabib")
1876 && !features.isRequired("hyperref")
1877 && !features.isRequired("vietnamese")
1878 && !features.isRequired("japanese")) {
1880 lyxpreamble += from_utf8(features.getBabelPresettings());
1881 lyxpreamble += from_utf8(babelCall(language_options.str(),
1882 features.needBabelLangOptions())) + '\n';
1883 lyxpreamble += from_utf8(features.getBabelPostsettings());
1886 // xunicode needs to be loaded at least after amsmath, amssymb,
1887 // esint and the other packages that provide special glyphs
1888 if (features.runparams().flavor == OutputParams::XETEX)
1889 lyxpreamble += "\\usepackage{xunicode}\n";
1891 // Polyglossia must be loaded last
1892 if (use_polyglossia) {
1894 lyxpreamble += "\\usepackage{polyglossia}\n";
1895 // set the main language
1896 lyxpreamble += "\\setdefaultlanguage";
1897 if (!language->polyglossiaOpts().empty())
1898 lyxpreamble += "[" + from_ascii(language->polyglossiaOpts()) + "]";
1899 lyxpreamble += "{" + from_ascii(language->polyglossia()) + "}\n";
1900 // now setup the other languages
1901 std::map<std::string, std::string> const polylangs =
1902 features.getPolyglossiaLanguages();
1903 for (std::map<std::string, std::string>::const_iterator mit = polylangs.begin();
1904 mit != polylangs.end() ; ++mit) {
1905 lyxpreamble += "\\setotherlanguage";
1906 if (!mit->second.empty())
1907 lyxpreamble += "[" + from_ascii(mit->second) + "]";
1908 lyxpreamble += "{" + from_ascii(mit->first) + "}\n";
1912 docstring const i18npreamble =
1913 features.getTClassI18nPreamble(use_babel, use_polyglossia);
1914 if (!i18npreamble.empty())
1915 lyxpreamble += i18npreamble + '\n';
1923 void BufferParams::useClassDefaults()
1925 DocumentClass const & tclass = documentClass();
1927 sides = tclass.sides();
1928 columns = tclass.columns();
1929 pagestyle = tclass.pagestyle();
1930 use_default_options = true;
1931 // Only if class has a ToC hierarchy
1932 if (tclass.hasTocLevels()) {
1933 secnumdepth = tclass.secnumdepth();
1934 tocdepth = tclass.tocdepth();
1939 bool BufferParams::hasClassDefaults() const
1941 DocumentClass const & tclass = documentClass();
1943 return sides == tclass.sides()
1944 && columns == tclass.columns()
1945 && pagestyle == tclass.pagestyle()
1946 && use_default_options
1947 && secnumdepth == tclass.secnumdepth()
1948 && tocdepth == tclass.tocdepth();
1952 DocumentClass const & BufferParams::documentClass() const
1958 DocumentClass const * BufferParams::documentClassPtr() const
1964 void BufferParams::setDocumentClass(DocumentClass const * const tc)
1966 // evil, but this function is evil
1967 doc_class_ = const_cast<DocumentClass *>(tc);
1971 bool BufferParams::setBaseClass(string const & classname)
1973 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1974 LayoutFileList & bcl = LayoutFileList::get();
1975 if (!bcl.haveClass(classname)) {
1977 bformat(_("The layout file:\n"
1979 "could not be found. A default textclass with default\n"
1980 "layouts will be used. LyX will not be able to produce\n"
1982 from_utf8(classname));
1983 frontend::Alert::error(_("Document class not found"), s);
1984 bcl.addEmptyClass(classname);
1987 bool const success = bcl[classname].load();
1990 bformat(_("Due to some error in it, the layout file:\n"
1992 "could not be loaded. A default textclass with default\n"
1993 "layouts will be used. LyX will not be able to produce\n"
1995 from_utf8(classname));
1996 frontend::Alert::error(_("Could not load class"), s);
1997 bcl.addEmptyClass(classname);
2000 pimpl_->baseClass_ = classname;
2001 layout_modules_.adaptToBaseClass(baseClass(), removed_modules_);
2006 LayoutFile const * BufferParams::baseClass() const
2008 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
2009 return &(LayoutFileList::get()[pimpl_->baseClass_]);
2015 LayoutFileIndex const & BufferParams::baseClassID() const
2017 return pimpl_->baseClass_;
2021 void BufferParams::makeDocumentClass()
2026 doc_class_ = &(DocumentClassBundle::get().makeDocumentClass(*baseClass(), layout_modules_));
2028 if (!local_layout.empty()) {
2029 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
2030 docstring const msg = _("Error reading internal layout information");
2031 frontend::Alert::warning(_("Read Error"), msg);
2037 bool BufferParams::moduleCanBeAdded(string const & modName) const
2039 return layout_modules_.moduleCanBeAdded(modName, baseClass());
2043 bool BufferParams::addLayoutModule(string const & modName)
2045 LayoutModuleList::const_iterator it = layout_modules_.begin();
2046 LayoutModuleList::const_iterator end = layout_modules_.end();
2047 for (; it != end; it++)
2050 layout_modules_.push_back(modName);
2055 Font const BufferParams::getFont() const
2057 FontInfo f = documentClass().defaultfont();
2058 if (fonts_default_family == "rmdefault")
2059 f.setFamily(ROMAN_FAMILY);
2060 else if (fonts_default_family == "sfdefault")
2061 f.setFamily(SANS_FAMILY);
2062 else if (fonts_default_family == "ttdefault")
2063 f.setFamily(TYPEWRITER_FAMILY);
2064 return Font(f, language);
2068 void BufferParams::readPreamble(Lexer & lex)
2070 if (lex.getString() != "\\begin_preamble")
2071 lyxerr << "Error (BufferParams::readPreamble):"
2072 "consistency check failed." << endl;
2074 preamble = lex.getLongString("\\end_preamble");
2078 void BufferParams::readLocalLayout(Lexer & lex)
2080 if (lex.getString() != "\\begin_local_layout")
2081 lyxerr << "Error (BufferParams::readLocalLayout):"
2082 "consistency check failed." << endl;
2084 local_layout = lex.getLongString("\\end_local_layout");
2088 void BufferParams::readLanguage(Lexer & lex)
2090 if (!lex.next()) return;
2092 string const tmptok = lex.getString();
2094 // check if tmptok is part of tex_babel in tex-defs.h
2095 language = languages.getLanguage(tmptok);
2097 // Language tmptok was not found
2098 language = default_language;
2099 lyxerr << "Warning: Setting language `"
2100 << tmptok << "' to `" << language->lang()
2106 void BufferParams::readGraphicsDriver(Lexer & lex)
2111 string const tmptok = lex.getString();
2112 // check if tmptok is part of tex_graphics in tex_defs.h
2115 string const test = tex_graphics[n++];
2117 if (test == tmptok) {
2118 graphics_driver = tmptok;
2123 "Warning: graphics driver `$$Token' not recognized!\n"
2124 " Setting graphics driver to `default'.\n");
2125 graphics_driver = "default";
2132 void BufferParams::readBullets(Lexer & lex)
2137 int const index = lex.getInteger();
2139 int temp_int = lex.getInteger();
2140 user_defined_bullet(index).setFont(temp_int);
2141 temp_bullet(index).setFont(temp_int);
2143 user_defined_bullet(index).setCharacter(temp_int);
2144 temp_bullet(index).setCharacter(temp_int);
2146 user_defined_bullet(index).setSize(temp_int);
2147 temp_bullet(index).setSize(temp_int);
2151 void BufferParams::readBulletsLaTeX(Lexer & lex)
2153 // The bullet class should be able to read this.
2156 int const index = lex.getInteger();
2158 docstring const temp_str = lex.getDocString();
2160 user_defined_bullet(index).setText(temp_str);
2161 temp_bullet(index).setText(temp_str);
2165 void BufferParams::readModules(Lexer & lex)
2167 if (!lex.eatLine()) {
2168 lyxerr << "Error (BufferParams::readModules):"
2169 "Unexpected end of input." << endl;
2173 string mod = lex.getString();
2174 if (mod == "\\end_modules")
2176 addLayoutModule(mod);
2182 void BufferParams::readRemovedModules(Lexer & lex)
2184 if (!lex.eatLine()) {
2185 lyxerr << "Error (BufferParams::readRemovedModules):"
2186 "Unexpected end of input." << endl;
2190 string mod = lex.getString();
2191 if (mod == "\\end_removed_modules")
2193 removed_modules_.push_back(mod);
2196 // now we want to remove any removed modules that were previously
2197 // added. normally, that will be because default modules were added in
2198 // setBaseClass(), which gets called when \textclass is read at the
2199 // start of the read.
2200 list<string>::const_iterator rit = removed_modules_.begin();
2201 list<string>::const_iterator const ren = removed_modules_.end();
2202 for (; rit != ren; rit++) {
2203 LayoutModuleList::iterator const mit = layout_modules_.begin();
2204 LayoutModuleList::iterator const men = layout_modules_.end();
2205 LayoutModuleList::iterator found = find(mit, men, *rit);
2208 layout_modules_.erase(found);
2213 void BufferParams::readIncludeonly(Lexer & lex)
2215 if (!lex.eatLine()) {
2216 lyxerr << "Error (BufferParams::readIncludeonly):"
2217 "Unexpected end of input." << endl;
2221 string child = lex.getString();
2222 if (child == "\\end_includeonly")
2224 included_children_.push_back(child);
2230 string BufferParams::paperSizeName(PapersizePurpose purpose) const
2232 char real_papersize = papersize;
2233 if (real_papersize == PAPER_DEFAULT)
2234 real_papersize = lyxrc.default_papersize;
2236 switch (real_papersize) {
2238 // could be anything, so don't guess
2240 case PAPER_CUSTOM: {
2241 if (purpose == XDVI && !paperwidth.empty() &&
2242 !paperheight.empty()) {
2243 // heightxwidth<unit>
2244 string first = paperwidth;
2245 string second = paperheight;
2246 if (orientation == ORIENTATION_LANDSCAPE)
2249 return first.erase(first.length() - 2)
2255 // dvips and dvipdfm do not know this
2256 if (purpose == DVIPS || purpose == DVIPDFM)
2260 if (purpose == DVIPS || purpose == DVIPDFM)
2264 if (purpose == DVIPS || purpose == DVIPDFM)
2274 if (purpose == DVIPS || purpose == DVIPDFM)
2278 if (purpose == DVIPS || purpose == DVIPDFM)
2282 if (purpose == DVIPS || purpose == DVIPDFM)
2286 if (purpose == DVIPS || purpose == DVIPDFM)
2290 if (purpose == DVIPS || purpose == DVIPDFM)
2294 // dvipdfm does not know this
2295 if (purpose == DVIPDFM)
2299 if (purpose == DVIPDFM)
2303 if (purpose == DVIPS || purpose == DVIPDFM)
2307 if (purpose == DVIPS || purpose == DVIPDFM)
2311 if (purpose == DVIPS || purpose == DVIPDFM)
2315 if (purpose == DVIPS || purpose == DVIPDFM)
2319 if (purpose == DVIPS || purpose == DVIPDFM)
2323 if (purpose == DVIPS || purpose == DVIPDFM)
2327 if (purpose == DVIPS || purpose == DVIPDFM)
2331 if (purpose == DVIPS || purpose == DVIPDFM)
2335 if (purpose == DVIPS || purpose == DVIPDFM)
2339 if (purpose == DVIPS || purpose == DVIPDFM)
2343 if (purpose == DVIPS || purpose == DVIPDFM)
2347 if (purpose == DVIPS || purpose == DVIPDFM)
2351 if (purpose == DVIPS || purpose == DVIPDFM)
2355 if (purpose == DVIPS || purpose == DVIPDFM)
2359 if (purpose == DVIPS || purpose == DVIPDFM)
2362 case PAPER_USEXECUTIVE:
2363 // dvipdfm does not know this
2364 if (purpose == DVIPDFM)
2369 case PAPER_USLETTER:
2371 if (purpose == XDVI)
2378 string const BufferParams::dvips_options() const
2383 && papersize == PAPER_CUSTOM
2384 && !lyxrc.print_paper_dimension_flag.empty()
2385 && !paperwidth.empty()
2386 && !paperheight.empty()) {
2387 // using a custom papersize
2388 result = lyxrc.print_paper_dimension_flag;
2389 result += ' ' + paperwidth;
2390 result += ',' + paperheight;
2392 string const paper_option = paperSizeName(DVIPS);
2393 if (!paper_option.empty() && (paper_option != "letter" ||
2394 orientation != ORIENTATION_LANDSCAPE)) {
2395 // dvips won't accept -t letter -t landscape.
2396 // In all other cases, include the paper size
2398 result = lyxrc.print_paper_flag;
2399 result += ' ' + paper_option;
2402 if (orientation == ORIENTATION_LANDSCAPE &&
2403 papersize != PAPER_CUSTOM)
2404 result += ' ' + lyxrc.print_landscape_flag;
2409 string const BufferParams::font_encoding() const
2411 return (fontenc == "global") ? lyxrc.fontenc : fontenc;
2415 string BufferParams::babelCall(string const & lang_opts, bool const langoptions) const
2417 if (lang_package != "auto" && lang_package != "babel"
2418 && lang_package != "default" && lang_package != "none")
2419 return lang_package;
2420 if (lyxrc.language_package_selection == LyXRC::LP_CUSTOM)
2421 return lyxrc.language_custom_package;
2422 // suppress the babel call if there is no BabelName defined
2423 // for the document language in the lib/languages file and if no
2424 // other languages are used (lang_opts is then empty)
2425 if (lang_opts.empty())
2427 // either a specific language (AsBabelOptions setting in
2428 // lib/languages) or the prefs require the languages to
2429 // be submitted to babel itself (not the class).
2431 return "\\usepackage[" + lang_opts + "]{babel}";
2432 return "\\usepackage{babel}";
2436 docstring BufferParams::getGraphicsDriver(string const & package) const
2440 if (package == "geometry") {
2441 if (graphics_driver == "dvips"
2442 || graphics_driver == "dvipdfm"
2443 || graphics_driver == "pdftex"
2444 || graphics_driver == "vtex")
2445 result = from_ascii(graphics_driver);
2446 else if (graphics_driver == "dvipdfmx")
2447 result = from_ascii("dvipdfm");
2454 void BufferParams::writeEncodingPreamble(otexstream & os,
2455 LaTeXFeatures & features) const
2457 // XeTeX does not need this
2458 if (features.runparams().flavor == OutputParams::XETEX)
2460 // LuaTeX neither, but with tex fonts, we need to load
2461 // the luainputenc package.
2462 if (features.runparams().flavor == OutputParams::LUATEX) {
2463 if (!useNonTeXFonts && inputenc != "default"
2464 && ((inputenc == "auto" && language->encoding()->package() == Encoding::inputenc)
2465 || (inputenc != "auto" && encoding().package() == Encoding::inputenc))) {
2466 os << "\\usepackage[utf8]{luainputenc}\n";
2470 if (inputenc == "auto") {
2471 string const doc_encoding =
2472 language->encoding()->latexName();
2473 Encoding::Package const package =
2474 language->encoding()->package();
2476 // Create a list with all the input encodings used
2478 set<string> encodings =
2479 features.getEncodingSet(doc_encoding);
2481 // If the "japanese" package (i.e. pLaTeX) is used,
2482 // inputenc must be omitted.
2483 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
2484 if (package == Encoding::japanese)
2485 features.require("japanese");
2487 if ((!encodings.empty() || package == Encoding::inputenc)
2488 && !features.isRequired("japanese")) {
2489 os << "\\usepackage[";
2490 set<string>::const_iterator it = encodings.begin();
2491 set<string>::const_iterator const end = encodings.end();
2493 os << from_ascii(*it);
2496 for (; it != end; ++it)
2497 os << ',' << from_ascii(*it);
2498 if (package == Encoding::inputenc) {
2499 if (!encodings.empty())
2501 os << from_ascii(doc_encoding);
2503 os << "]{inputenc}\n";
2505 if (package == Encoding::CJK || features.mustProvide("CJK")) {
2506 if (language->encoding()->name() == "utf8-cjk"
2507 && LaTeXFeatures::isAvailable("CJKutf8"))
2508 os << "\\usepackage{CJKutf8}\n";
2510 os << "\\usepackage{CJK}\n";
2512 } else if (inputenc != "default") {
2513 switch (encoding().package()) {
2514 case Encoding::none:
2515 case Encoding::japanese:
2517 case Encoding::inputenc:
2518 // do not load inputenc if japanese is used
2519 if (features.isRequired("japanese"))
2521 os << "\\usepackage[" << from_ascii(inputenc)
2525 if (encoding().name() == "utf8-cjk"
2526 && LaTeXFeatures::isAvailable("CJKutf8"))
2527 os << "\\usepackage{CJKutf8}\n";
2529 os << "\\usepackage{CJK}\n";
2534 // The encoding "armscii8" (for Armenian) is only available when
2535 // the package "armtex" is loaded.
2536 if (language->encoding()->latexName() == "armscii8"
2537 || inputenc == "armscii8")
2538 os << "\\usepackage{armtex}\n";
2542 string const BufferParams::parseFontName(string const & name) const
2544 string mangled = name;
2545 size_t const idx = mangled.find('[');
2546 if (idx == string::npos || idx == 0)
2549 return mangled.substr(0, idx - 1);
2553 string const BufferParams::loadFonts(string const & rm,
2554 string const & sf, string const & tt,
2555 bool const & sc, bool const & osf,
2556 int const & sfscale, int const & ttscale,
2557 bool const & use_systemfonts,
2558 LaTeXFeatures & features) const
2560 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
2561 several packages have been replaced by others, that might not
2562 be installed on every system. We have to take care for that
2563 (see psnfss.pdf). We try to support all psnfss fonts as well
2564 as the fonts that have become de facto standard in the LaTeX
2565 world (e.g. Latin Modern). We do not support obsolete fonts
2566 (like PSLatex). In general, it should be possible to mix any
2567 rm font with any sf or tt font, respectively. (JSpitzm)
2569 -- separate math fonts.
2572 if (rm == "default" && sf == "default" && tt == "default")
2578 /* Fontspec (XeTeX, LuaTeX): we provide GUI support for oldstyle
2579 * numbers (Numbers=OldStyle) and sf/tt scaling. The Ligatures=TeX/
2580 * Mapping=tex-text option assures TeX ligatures (such as "--")
2581 * are resolved. Note that tt does not use these ligatures.
2583 * -- add more GUI options?
2584 * -- add more fonts (fonts for other scripts)
2585 * -- if there's a way to find out if a font really supports
2586 * OldStyle, enable/disable the widget accordingly.
2588 if (use_systemfonts && features.isAvailable("fontspec")) {
2589 // "Mapping=tex-text" and "Ligatures=TeX" are equivalent.
2590 // However, until v.2 (2010/07/11) fontspec only knew
2591 // Mapping=tex-text (for XeTeX only); then "Ligatures=TeX"
2592 // was introduced for both XeTeX and LuaTeX (LuaTeX
2593 // didn't understand "Mapping=tex-text", while XeTeX
2594 // understood both. With most recent versions, both
2595 // variants are understood by both engines. However,
2596 // we want to provide support for at least TeXLive 2009.
2597 string const texmapping =
2598 (features.runparams().flavor == OutputParams::XETEX) ?
2599 "Mapping=tex-text" : "Ligatures=TeX";
2600 if (rm != "default") {
2601 os << "\\setmainfont[" << texmapping;
2603 os << ",Numbers=OldStyle";
2604 os << "]{" << parseFontName(rm) << "}\n";
2606 if (sf != "default") {
2607 string const sans = parseFontName(sf);
2609 os << "\\setsansfont[Scale="
2610 << float(sfscale) / 100
2611 << "," << texmapping << "]{"
2614 os << "\\setsansfont[" << texmapping << "]{"
2617 if (tt != "default") {
2618 string const mono = parseFontName(tt);
2620 os << "\\setmonofont[Scale="
2621 << float(ttscale) / 100
2625 os << "\\setmonofont{"
2632 // Computer Modern (must be explicitly selectable -- there might be classes
2633 // that define a different default font!
2635 os << "\\renewcommand{\\rmdefault}{cmr}\n";
2636 // osf for Computer Modern needs eco.sty
2638 os << "\\usepackage{eco}\n";
2640 // Latin Modern Roman
2641 else if (rm == "lmodern")
2642 os << "\\usepackage{lmodern}\n";
2644 else if (rm == "ae") {
2645 // not needed when using OT1 font encoding.
2646 if (font_encoding() != "default")
2647 os << "\\usepackage{ae,aecompl}\n";
2650 else if (rm == "times") {
2651 // try to load the best available package
2652 if (LaTeXFeatures::isAvailable("mathptmx"))
2653 os << "\\usepackage{mathptmx}\n";
2654 else if (LaTeXFeatures::isAvailable("mathptm"))
2655 os << "\\usepackage{mathptm}\n";
2657 os << "\\usepackage{times}\n";
2660 else if (rm == "palatino") {
2661 // try to load the best available package
2662 if (LaTeXFeatures::isAvailable("mathpazo")) {
2663 os << "\\usepackage";
2669 // "osf" includes "sc"!
2673 os << "{mathpazo}\n";
2675 else if (LaTeXFeatures::isAvailable("mathpple"))
2676 os << "\\usepackage{mathpple}\n";
2678 os << "\\usepackage{palatino}\n";
2681 else if (rm == "utopia") {
2682 // fourier supersedes utopia.sty, but does
2683 // not work with OT1 encoding.
2684 if (LaTeXFeatures::isAvailable("fourier")
2685 && font_encoding() != "default") {
2686 os << "\\usepackage";
2697 os << "{fourier}\n";
2700 os << "\\usepackage{utopia}\n";
2702 // Bera (complete fontset)
2703 else if (rm == "bera" && sf == "default" && tt == "default")
2704 os << "\\usepackage{bera}\n";
2706 else if (rm != "default")
2707 os << "\\usepackage" << "{" << rm << "}\n";
2710 // Helvetica, Bera Sans
2711 if (sf == "helvet" || sf == "berasans") {
2713 os << "\\usepackage[scaled=" << float(sfscale) / 100
2714 << "]{" << sf << "}\n";
2716 os << "\\usepackage{" << sf << "}\n";
2719 else if (sf == "avant")
2720 os << "\\usepackage{" << sf << "}\n";
2721 // Computer Modern, Latin Modern, CM Bright
2722 else if (sf != "default")
2723 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
2725 // monospaced/typewriter
2726 // Courier, LuxiMono
2727 if (tt == "luximono" || tt == "beramono") {
2729 os << "\\usepackage[scaled=" << float(ttscale) / 100
2730 << "]{" << tt << "}\n";
2732 os << "\\usepackage{" << tt << "}\n";
2735 else if (tt == "courier" )
2736 os << "\\usepackage{" << tt << "}\n";
2737 // Computer Modern, Latin Modern, CM Bright
2738 else if (tt != "default")
2739 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
2745 Encoding const & BufferParams::encoding() const
2747 // FIXME: actually, we should check for the flavor
2748 // or runparams.isFullyUnicode() here:
2749 // This check will not work with XeTeX/LuaTeX and tex fonts.
2750 // Thus we have to reset the encoding in Buffer::makeLaTeXFile.
2752 return *(encodings.fromLaTeXName("utf8-plain"));
2753 if (inputenc == "auto" || inputenc == "default")
2754 return *language->encoding();
2755 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
2758 LYXERR0("Unknown inputenc value `" << inputenc
2759 << "'. Using `auto' instead.");
2760 return *language->encoding();
2764 CiteEngine BufferParams::citeEngine() const
2766 // FIXME the class should provide the numerical/
2767 // authoryear choice
2768 if (documentClass().provides("natbib")
2769 && cite_engine_ != ENGINE_NATBIB_NUMERICAL)
2770 return ENGINE_NATBIB_AUTHORYEAR;
2771 return cite_engine_;
2775 void BufferParams::setCiteEngine(CiteEngine cite_engine)
2777 cite_engine_ = cite_engine;