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 TextClass::ReturnValues success =
2030 doc_class_->read(local_layout, TextClass::MODULE);
2031 if (success != TextClass::OK && success != TextClass::OK_OLDFORMAT) {
2032 docstring const msg = _("Error reading internal layout information");
2033 frontend::Alert::warning(_("Read Error"), msg);
2039 bool BufferParams::moduleCanBeAdded(string const & modName) const
2041 return layout_modules_.moduleCanBeAdded(modName, baseClass());
2045 bool BufferParams::addLayoutModule(string const & modName)
2047 LayoutModuleList::const_iterator it = layout_modules_.begin();
2048 LayoutModuleList::const_iterator end = layout_modules_.end();
2049 for (; it != end; it++)
2052 layout_modules_.push_back(modName);
2057 Font const BufferParams::getFont() const
2059 FontInfo f = documentClass().defaultfont();
2060 if (fonts_default_family == "rmdefault")
2061 f.setFamily(ROMAN_FAMILY);
2062 else if (fonts_default_family == "sfdefault")
2063 f.setFamily(SANS_FAMILY);
2064 else if (fonts_default_family == "ttdefault")
2065 f.setFamily(TYPEWRITER_FAMILY);
2066 return Font(f, language);
2070 void BufferParams::readPreamble(Lexer & lex)
2072 if (lex.getString() != "\\begin_preamble")
2073 lyxerr << "Error (BufferParams::readPreamble):"
2074 "consistency check failed." << endl;
2076 preamble = lex.getLongString("\\end_preamble");
2080 void BufferParams::readLocalLayout(Lexer & lex)
2082 if (lex.getString() != "\\begin_local_layout")
2083 lyxerr << "Error (BufferParams::readLocalLayout):"
2084 "consistency check failed." << endl;
2086 local_layout = lex.getLongString("\\end_local_layout");
2090 void BufferParams::readLanguage(Lexer & lex)
2092 if (!lex.next()) return;
2094 string const tmptok = lex.getString();
2096 // check if tmptok is part of tex_babel in tex-defs.h
2097 language = languages.getLanguage(tmptok);
2099 // Language tmptok was not found
2100 language = default_language;
2101 lyxerr << "Warning: Setting language `"
2102 << tmptok << "' to `" << language->lang()
2108 void BufferParams::readGraphicsDriver(Lexer & lex)
2113 string const tmptok = lex.getString();
2114 // check if tmptok is part of tex_graphics in tex_defs.h
2117 string const test = tex_graphics[n++];
2119 if (test == tmptok) {
2120 graphics_driver = tmptok;
2125 "Warning: graphics driver `$$Token' not recognized!\n"
2126 " Setting graphics driver to `default'.\n");
2127 graphics_driver = "default";
2134 void BufferParams::readBullets(Lexer & lex)
2139 int const index = lex.getInteger();
2141 int temp_int = lex.getInteger();
2142 user_defined_bullet(index).setFont(temp_int);
2143 temp_bullet(index).setFont(temp_int);
2145 user_defined_bullet(index).setCharacter(temp_int);
2146 temp_bullet(index).setCharacter(temp_int);
2148 user_defined_bullet(index).setSize(temp_int);
2149 temp_bullet(index).setSize(temp_int);
2153 void BufferParams::readBulletsLaTeX(Lexer & lex)
2155 // The bullet class should be able to read this.
2158 int const index = lex.getInteger();
2160 docstring const temp_str = lex.getDocString();
2162 user_defined_bullet(index).setText(temp_str);
2163 temp_bullet(index).setText(temp_str);
2167 void BufferParams::readModules(Lexer & lex)
2169 if (!lex.eatLine()) {
2170 lyxerr << "Error (BufferParams::readModules):"
2171 "Unexpected end of input." << endl;
2175 string mod = lex.getString();
2176 if (mod == "\\end_modules")
2178 addLayoutModule(mod);
2184 void BufferParams::readRemovedModules(Lexer & lex)
2186 if (!lex.eatLine()) {
2187 lyxerr << "Error (BufferParams::readRemovedModules):"
2188 "Unexpected end of input." << endl;
2192 string mod = lex.getString();
2193 if (mod == "\\end_removed_modules")
2195 removed_modules_.push_back(mod);
2198 // now we want to remove any removed modules that were previously
2199 // added. normally, that will be because default modules were added in
2200 // setBaseClass(), which gets called when \textclass is read at the
2201 // start of the read.
2202 list<string>::const_iterator rit = removed_modules_.begin();
2203 list<string>::const_iterator const ren = removed_modules_.end();
2204 for (; rit != ren; rit++) {
2205 LayoutModuleList::iterator const mit = layout_modules_.begin();
2206 LayoutModuleList::iterator const men = layout_modules_.end();
2207 LayoutModuleList::iterator found = find(mit, men, *rit);
2210 layout_modules_.erase(found);
2215 void BufferParams::readIncludeonly(Lexer & lex)
2217 if (!lex.eatLine()) {
2218 lyxerr << "Error (BufferParams::readIncludeonly):"
2219 "Unexpected end of input." << endl;
2223 string child = lex.getString();
2224 if (child == "\\end_includeonly")
2226 included_children_.push_back(child);
2232 string BufferParams::paperSizeName(PapersizePurpose purpose) const
2234 char real_papersize = papersize;
2235 if (real_papersize == PAPER_DEFAULT)
2236 real_papersize = lyxrc.default_papersize;
2238 switch (real_papersize) {
2240 // could be anything, so don't guess
2242 case PAPER_CUSTOM: {
2243 if (purpose == XDVI && !paperwidth.empty() &&
2244 !paperheight.empty()) {
2245 // heightxwidth<unit>
2246 string first = paperwidth;
2247 string second = paperheight;
2248 if (orientation == ORIENTATION_LANDSCAPE)
2251 return first.erase(first.length() - 2)
2257 // dvips and dvipdfm do not know this
2258 if (purpose == DVIPS || purpose == DVIPDFM)
2262 if (purpose == DVIPS || purpose == DVIPDFM)
2266 if (purpose == DVIPS || purpose == DVIPDFM)
2276 if (purpose == DVIPS || purpose == DVIPDFM)
2280 if (purpose == DVIPS || purpose == DVIPDFM)
2284 if (purpose == DVIPS || purpose == DVIPDFM)
2288 if (purpose == DVIPS || purpose == DVIPDFM)
2292 if (purpose == DVIPS || purpose == DVIPDFM)
2296 // dvipdfm does not know this
2297 if (purpose == DVIPDFM)
2301 if (purpose == DVIPDFM)
2305 if (purpose == DVIPS || purpose == DVIPDFM)
2309 if (purpose == DVIPS || purpose == DVIPDFM)
2313 if (purpose == DVIPS || purpose == DVIPDFM)
2317 if (purpose == DVIPS || purpose == DVIPDFM)
2321 if (purpose == DVIPS || purpose == DVIPDFM)
2325 if (purpose == DVIPS || purpose == DVIPDFM)
2329 if (purpose == DVIPS || purpose == DVIPDFM)
2333 if (purpose == DVIPS || purpose == DVIPDFM)
2337 if (purpose == DVIPS || purpose == DVIPDFM)
2341 if (purpose == DVIPS || purpose == DVIPDFM)
2345 if (purpose == DVIPS || purpose == DVIPDFM)
2349 if (purpose == DVIPS || purpose == DVIPDFM)
2353 if (purpose == DVIPS || purpose == DVIPDFM)
2357 if (purpose == DVIPS || purpose == DVIPDFM)
2361 if (purpose == DVIPS || purpose == DVIPDFM)
2364 case PAPER_USEXECUTIVE:
2365 // dvipdfm does not know this
2366 if (purpose == DVIPDFM)
2371 case PAPER_USLETTER:
2373 if (purpose == XDVI)
2380 string const BufferParams::dvips_options() const
2385 && papersize == PAPER_CUSTOM
2386 && !lyxrc.print_paper_dimension_flag.empty()
2387 && !paperwidth.empty()
2388 && !paperheight.empty()) {
2389 // using a custom papersize
2390 result = lyxrc.print_paper_dimension_flag;
2391 result += ' ' + paperwidth;
2392 result += ',' + paperheight;
2394 string const paper_option = paperSizeName(DVIPS);
2395 if (!paper_option.empty() && (paper_option != "letter" ||
2396 orientation != ORIENTATION_LANDSCAPE)) {
2397 // dvips won't accept -t letter -t landscape.
2398 // In all other cases, include the paper size
2400 result = lyxrc.print_paper_flag;
2401 result += ' ' + paper_option;
2404 if (orientation == ORIENTATION_LANDSCAPE &&
2405 papersize != PAPER_CUSTOM)
2406 result += ' ' + lyxrc.print_landscape_flag;
2411 string const BufferParams::font_encoding() const
2413 return (fontenc == "global") ? lyxrc.fontenc : fontenc;
2417 string BufferParams::babelCall(string const & lang_opts, bool const langoptions) const
2419 if (lang_package != "auto" && lang_package != "babel"
2420 && lang_package != "default" && lang_package != "none")
2421 return lang_package;
2422 if (lyxrc.language_package_selection == LyXRC::LP_CUSTOM)
2423 return lyxrc.language_custom_package;
2424 // suppress the babel call if there is no BabelName defined
2425 // for the document language in the lib/languages file and if no
2426 // other languages are used (lang_opts is then empty)
2427 if (lang_opts.empty())
2429 // either a specific language (AsBabelOptions setting in
2430 // lib/languages) or the prefs require the languages to
2431 // be submitted to babel itself (not the class).
2433 return "\\usepackage[" + lang_opts + "]{babel}";
2434 return "\\usepackage{babel}";
2438 docstring BufferParams::getGraphicsDriver(string const & package) const
2442 if (package == "geometry") {
2443 if (graphics_driver == "dvips"
2444 || graphics_driver == "dvipdfm"
2445 || graphics_driver == "pdftex"
2446 || graphics_driver == "vtex")
2447 result = from_ascii(graphics_driver);
2448 else if (graphics_driver == "dvipdfmx")
2449 result = from_ascii("dvipdfm");
2456 void BufferParams::writeEncodingPreamble(otexstream & os,
2457 LaTeXFeatures & features) const
2459 // XeTeX does not need this
2460 if (features.runparams().flavor == OutputParams::XETEX)
2462 // LuaTeX neither, but with tex fonts, we need to load
2463 // the luainputenc package.
2464 if (features.runparams().flavor == OutputParams::LUATEX) {
2465 if (!useNonTeXFonts && inputenc != "default"
2466 && ((inputenc == "auto" && language->encoding()->package() == Encoding::inputenc)
2467 || (inputenc != "auto" && encoding().package() == Encoding::inputenc))) {
2468 os << "\\usepackage[utf8]{luainputenc}\n";
2472 if (inputenc == "auto") {
2473 string const doc_encoding =
2474 language->encoding()->latexName();
2475 Encoding::Package const package =
2476 language->encoding()->package();
2478 // Create a list with all the input encodings used
2480 set<string> encodings =
2481 features.getEncodingSet(doc_encoding);
2483 // If the "japanese" package (i.e. pLaTeX) is used,
2484 // inputenc must be omitted.
2485 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
2486 if (package == Encoding::japanese)
2487 features.require("japanese");
2489 if ((!encodings.empty() || package == Encoding::inputenc)
2490 && !features.isRequired("japanese")) {
2491 os << "\\usepackage[";
2492 set<string>::const_iterator it = encodings.begin();
2493 set<string>::const_iterator const end = encodings.end();
2495 os << from_ascii(*it);
2498 for (; it != end; ++it)
2499 os << ',' << from_ascii(*it);
2500 if (package == Encoding::inputenc) {
2501 if (!encodings.empty())
2503 os << from_ascii(doc_encoding);
2505 os << "]{inputenc}\n";
2507 if (package == Encoding::CJK || features.mustProvide("CJK")) {
2508 if (language->encoding()->name() == "utf8-cjk"
2509 && LaTeXFeatures::isAvailable("CJKutf8"))
2510 os << "\\usepackage{CJKutf8}\n";
2512 os << "\\usepackage{CJK}\n";
2514 } else if (inputenc != "default") {
2515 switch (encoding().package()) {
2516 case Encoding::none:
2517 case Encoding::japanese:
2519 case Encoding::inputenc:
2520 // do not load inputenc if japanese is used
2521 if (features.isRequired("japanese"))
2523 os << "\\usepackage[" << from_ascii(inputenc)
2527 if (encoding().name() == "utf8-cjk"
2528 && LaTeXFeatures::isAvailable("CJKutf8"))
2529 os << "\\usepackage{CJKutf8}\n";
2531 os << "\\usepackage{CJK}\n";
2536 // The encoding "armscii8" (for Armenian) is only available when
2537 // the package "armtex" is loaded.
2538 if (language->encoding()->latexName() == "armscii8"
2539 || inputenc == "armscii8")
2540 os << "\\usepackage{armtex}\n";
2544 string const BufferParams::parseFontName(string const & name) const
2546 string mangled = name;
2547 size_t const idx = mangled.find('[');
2548 if (idx == string::npos || idx == 0)
2551 return mangled.substr(0, idx - 1);
2555 string const BufferParams::loadFonts(string const & rm,
2556 string const & sf, string const & tt,
2557 bool const & sc, bool const & osf,
2558 int const & sfscale, int const & ttscale,
2559 bool const & use_systemfonts,
2560 LaTeXFeatures & features) const
2562 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
2563 several packages have been replaced by others, that might not
2564 be installed on every system. We have to take care for that
2565 (see psnfss.pdf). We try to support all psnfss fonts as well
2566 as the fonts that have become de facto standard in the LaTeX
2567 world (e.g. Latin Modern). We do not support obsolete fonts
2568 (like PSLatex). In general, it should be possible to mix any
2569 rm font with any sf or tt font, respectively. (JSpitzm)
2571 -- separate math fonts.
2574 if (rm == "default" && sf == "default" && tt == "default")
2580 /* Fontspec (XeTeX, LuaTeX): we provide GUI support for oldstyle
2581 * numbers (Numbers=OldStyle) and sf/tt scaling. The Ligatures=TeX/
2582 * Mapping=tex-text option assures TeX ligatures (such as "--")
2583 * are resolved. Note that tt does not use these ligatures.
2585 * -- add more GUI options?
2586 * -- add more fonts (fonts for other scripts)
2587 * -- if there's a way to find out if a font really supports
2588 * OldStyle, enable/disable the widget accordingly.
2590 if (use_systemfonts && features.isAvailable("fontspec")) {
2591 // "Mapping=tex-text" and "Ligatures=TeX" are equivalent.
2592 // However, until v.2 (2010/07/11) fontspec only knew
2593 // Mapping=tex-text (for XeTeX only); then "Ligatures=TeX"
2594 // was introduced for both XeTeX and LuaTeX (LuaTeX
2595 // didn't understand "Mapping=tex-text", while XeTeX
2596 // understood both. With most recent versions, both
2597 // variants are understood by both engines. However,
2598 // we want to provide support for at least TeXLive 2009
2599 // (for XeTeX; LuaTeX is only supported as of v.2)
2600 string const texmapping =
2601 (features.runparams().flavor == OutputParams::XETEX) ?
2602 "Mapping=tex-text" : "Ligatures=TeX";
2603 if (rm != "default") {
2604 os << "\\setmainfont[" << texmapping;
2606 os << ",Numbers=OldStyle";
2607 os << "]{" << parseFontName(rm) << "}\n";
2609 if (sf != "default") {
2610 string const sans = parseFontName(sf);
2612 os << "\\setsansfont[Scale="
2613 << float(sfscale) / 100
2614 << "," << texmapping << "]{"
2617 os << "\\setsansfont[" << texmapping << "]{"
2620 if (tt != "default") {
2621 string const mono = parseFontName(tt);
2623 os << "\\setmonofont[Scale="
2624 << float(ttscale) / 100
2628 os << "\\setmonofont{"
2635 // Computer Modern (must be explicitly selectable -- there might be classes
2636 // that define a different default font!
2638 os << "\\renewcommand{\\rmdefault}{cmr}\n";
2639 // osf for Computer Modern needs eco.sty
2641 os << "\\usepackage{eco}\n";
2643 // Latin Modern Roman
2644 else if (rm == "lmodern")
2645 os << "\\usepackage{lmodern}\n";
2647 else if (rm == "ae") {
2648 // not needed when using OT1 font encoding.
2649 if (font_encoding() != "default")
2650 os << "\\usepackage{ae,aecompl}\n";
2653 else if (rm == "times") {
2654 // try to load the best available package
2655 if (LaTeXFeatures::isAvailable("mathptmx"))
2656 os << "\\usepackage{mathptmx}\n";
2657 else if (LaTeXFeatures::isAvailable("mathptm"))
2658 os << "\\usepackage{mathptm}\n";
2660 os << "\\usepackage{times}\n";
2663 else if (rm == "palatino") {
2664 // try to load the best available package
2665 if (LaTeXFeatures::isAvailable("mathpazo")) {
2666 os << "\\usepackage";
2672 // "osf" includes "sc"!
2676 os << "{mathpazo}\n";
2678 else if (LaTeXFeatures::isAvailable("mathpple"))
2679 os << "\\usepackage{mathpple}\n";
2681 os << "\\usepackage{palatino}\n";
2684 else if (rm == "utopia") {
2685 // fourier supersedes utopia.sty, but does
2686 // not work with OT1 encoding.
2687 if (LaTeXFeatures::isAvailable("fourier")
2688 && font_encoding() != "default") {
2689 os << "\\usepackage";
2700 os << "{fourier}\n";
2703 os << "\\usepackage{utopia}\n";
2705 // Bera (complete fontset)
2706 else if (rm == "bera" && sf == "default" && tt == "default")
2707 os << "\\usepackage{bera}\n";
2709 else if (rm != "default")
2710 os << "\\usepackage" << "{" << rm << "}\n";
2713 // Helvetica, Bera Sans
2714 if (sf == "helvet" || sf == "berasans") {
2716 os << "\\usepackage[scaled=" << float(sfscale) / 100
2717 << "]{" << sf << "}\n";
2719 os << "\\usepackage{" << sf << "}\n";
2722 else if (sf == "avant")
2723 os << "\\usepackage{" << sf << "}\n";
2724 // Computer Modern, Latin Modern, CM Bright
2725 else if (sf != "default")
2726 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
2728 // monospaced/typewriter
2729 // Courier, LuxiMono
2730 if (tt == "luximono" || tt == "beramono") {
2732 os << "\\usepackage[scaled=" << float(ttscale) / 100
2733 << "]{" << tt << "}\n";
2735 os << "\\usepackage{" << tt << "}\n";
2738 else if (tt == "courier" )
2739 os << "\\usepackage{" << tt << "}\n";
2740 // Computer Modern, Latin Modern, CM Bright
2741 else if (tt != "default")
2742 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
2748 Encoding const & BufferParams::encoding() const
2750 // FIXME: actually, we should check for the flavor
2751 // or runparams.isFullyUnicode() here:
2752 // This check will not work with XeTeX/LuaTeX and tex fonts.
2753 // Thus we have to reset the encoding in Buffer::makeLaTeXFile.
2755 return *(encodings.fromLaTeXName("utf8-plain"));
2756 if (inputenc == "auto" || inputenc == "default")
2757 return *language->encoding();
2758 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
2761 LYXERR0("Unknown inputenc value `" << inputenc
2762 << "'. Using `auto' instead.");
2763 return *language->encoding();
2767 CiteEngine BufferParams::citeEngine() const
2769 // FIXME the class should provide the numerical/
2770 // authoryear choice
2771 if (documentClass().provides("natbib")
2772 && cite_engine_ != ENGINE_NATBIB_NUMERICAL)
2773 return ENGINE_NATBIB_AUTHORYEAR;
2774 return cite_engine_;
2778 void BufferParams::setCiteEngine(CiteEngine cite_engine)
2780 cite_engine_ = cite_engine;