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;
423 docstring BufferParams::B_(string const & l10n) const
425 LASSERT(language, /**/);
426 return getMessages(language->code()).get(l10n);
430 AuthorList & BufferParams::authors()
432 return pimpl_->authorlist;
436 AuthorList const & BufferParams::authors() const
438 return pimpl_->authorlist;
442 BranchList & BufferParams::branchlist()
444 return pimpl_->branchlist;
448 BranchList const & BufferParams::branchlist() const
450 return pimpl_->branchlist;
454 IndicesList & BufferParams::indiceslist()
456 return pimpl_->indiceslist;
460 IndicesList const & BufferParams::indiceslist() const
462 return pimpl_->indiceslist;
466 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
468 LASSERT(index < 4, /**/);
469 return pimpl_->temp_bullets[index];
473 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
475 LASSERT(index < 4, /**/);
476 return pimpl_->temp_bullets[index];
480 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
482 LASSERT(index < 4, /**/);
483 return pimpl_->user_defined_bullets[index];
487 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
489 LASSERT(index < 4, /**/);
490 return pimpl_->user_defined_bullets[index];
494 Spacing & BufferParams::spacing()
496 return pimpl_->spacing;
500 Spacing const & BufferParams::spacing() const
502 return pimpl_->spacing;
506 PDFOptions & BufferParams::pdfoptions()
508 return pimpl_->pdfoptions;
512 PDFOptions const & BufferParams::pdfoptions() const
514 return pimpl_->pdfoptions;
518 HSpace const & BufferParams::getIndentation() const
520 return pimpl_->indentation;
524 void BufferParams::setIndentation(HSpace const & indent)
526 pimpl_->indentation = indent;
530 VSpace const & BufferParams::getDefSkip() const
532 return pimpl_->defskip;
536 void BufferParams::setDefSkip(VSpace const & vs)
538 // DEFSKIP will cause an infinite loop
539 LASSERT(vs.kind() != VSpace::DEFSKIP, return);
540 pimpl_->defskip = vs;
544 string BufferParams::readToken(Lexer & lex, string const & token,
545 FileName const & filepath)
547 if (token == "\\textclass") {
549 string const classname = lex.getString();
550 // if there exists a local layout file, ignore the system one
551 // NOTE: in this case, the textclass (.cls file) is assumed to
554 LayoutFileList & bcl = LayoutFileList::get();
555 if (tcp.empty() && !filepath.empty())
556 tcp = bcl.addLocalLayout(classname, filepath.absFileName());
560 setBaseClass(classname);
561 // We assume that a tex class exists for local or unknown
562 // layouts so this warning, will only be given for system layouts.
563 if (!baseClass()->isTeXClassAvailable()) {
564 docstring const desc =
565 translateIfPossible(from_utf8(baseClass()->description()));
566 docstring const prereqs =
567 from_utf8(baseClass()->prerequisites());
568 docstring const msg =
569 bformat(_("The selected document class\n"
571 "requires external files that are not available.\n"
572 "The document class can still be used, but the\n"
573 "document cannot be compiled until the following\n"
574 "prerequisites are installed:\n"
576 "See section 3.1.2.2 (Class Availability) of the\n"
577 "User's Guide for more information."), desc, prereqs);
578 frontend::Alert::warning(_("Document class not available"),
581 } else if (token == "\\begin_preamble") {
583 } else if (token == "\\begin_local_layout") {
584 readLocalLayout(lex);
585 } else if (token == "\\begin_modules") {
587 } else if (token == "\\begin_removed_modules") {
588 readRemovedModules(lex);
589 } else if (token == "\\begin_includeonly") {
590 readIncludeonly(lex);
591 } else if (token == "\\maintain_unincluded_children") {
592 lex >> maintain_unincluded_children;
593 } else if (token == "\\options") {
595 options = lex.getString();
596 } else if (token == "\\use_default_options") {
597 lex >> use_default_options;
598 } else if (token == "\\master") {
600 master = lex.getString();
601 } else if (token == "\\suppress_date") {
602 lex >> suppress_date;
603 } else if (token == "\\language") {
605 } else if (token == "\\language_package") {
607 lang_package = lex.getString();
608 } else if (token == "\\inputencoding") {
610 } else if (token == "\\graphics") {
611 readGraphicsDriver(lex);
612 } else if (token == "\\default_output_format") {
613 lex >> default_output_format;
614 } else if (token == "\\bibtex_command") {
616 bibtex_command = lex.getString();
617 } else if (token == "\\index_command") {
619 index_command = lex.getString();
620 } else if (token == "\\fontencoding") {
622 fontenc = lex.getString();
623 } else if (token == "\\font_roman") {
625 fonts_roman = lex.getString();
626 } else if (token == "\\font_sans") {
628 fonts_sans = lex.getString();
629 } else if (token == "\\font_typewriter") {
631 fonts_typewriter = lex.getString();
632 } else if (token == "\\font_default_family") {
633 lex >> fonts_default_family;
634 } else if (token == "\\use_non_tex_fonts") {
635 lex >> useNonTeXFonts;
636 } else if (token == "\\font_sc") {
637 lex >> fonts_expert_sc;
638 } else if (token == "\\font_osf") {
639 lex >> fonts_old_figures;
640 } else if (token == "\\font_sf_scale") {
641 lex >> fonts_sans_scale;
642 } else if (token == "\\font_tt_scale") {
643 lex >> fonts_typewriter_scale;
644 } else if (token == "\\font_cjk") {
646 } else if (token == "\\paragraph_separation") {
649 paragraph_separation = parseptranslator().find(parsep);
650 } else if (token == "\\paragraph_indentation") {
652 string indentation = lex.getString();
653 pimpl_->indentation = HSpace(indentation);
654 } else if (token == "\\defskip") {
656 string const defskip = lex.getString();
657 pimpl_->defskip = VSpace(defskip);
658 if (pimpl_->defskip.kind() == VSpace::DEFSKIP)
660 pimpl_->defskip = VSpace(VSpace::MEDSKIP);
661 } else if (token == "\\quotes_language") {
664 quotes_language = quoteslangtranslator().find(quotes_lang);
665 } else if (token == "\\papersize") {
668 papersize = papersizetranslator().find(ppsize);
669 } else if (token == "\\use_geometry") {
671 } else if (token == "\\use_amsmath") {
674 use_amsmath = packagetranslator().find(use_ams);
675 } else if (token == "\\use_esint") {
678 use_esint = packagetranslator().find(useesint);
679 } else if (token == "\\use_mhchem") {
682 use_mhchem = packagetranslator().find(usemhchem);
683 } else if (token == "\\use_mathdots") {
686 use_mathdots = packagetranslator().find(usemathdots);
687 } else if (token == "\\cite_engine") {
690 cite_engine_ = citeenginetranslator().find(engine);
691 } else if (token == "\\use_bibtopic") {
693 } else if (token == "\\use_indices") {
695 } else if (token == "\\tracking_changes") {
697 } else if (token == "\\output_changes") {
698 lex >> outputChanges;
699 } else if (token == "\\branch") {
701 docstring branch = lex.getDocString();
702 branchlist().add(branch);
705 string const tok = lex.getString();
706 if (tok == "\\end_branch")
708 Branch * branch_ptr = branchlist().find(branch);
709 if (tok == "\\selected") {
712 branch_ptr->setSelected(lex.getInteger());
714 if (tok == "\\filename_suffix") {
717 branch_ptr->setFileNameSuffix(lex.getInteger());
719 if (tok == "\\color") {
721 string color = lex.getString();
723 branch_ptr->setColor(color);
724 // Update also the Color table:
726 color = lcolor.getX11Name(Color_background);
728 lcolor.setColor(to_utf8(branch), color);
731 } else if (token == "\\index") {
733 docstring index = lex.getDocString();
735 indiceslist().add(index);
738 string const tok = lex.getString();
739 if (tok == "\\end_index")
741 Index * index_ptr = indiceslist().find(index);
742 if (tok == "\\shortcut") {
744 shortcut = lex.getDocString();
746 index_ptr->setShortcut(shortcut);
748 if (tok == "\\color") {
750 string color = lex.getString();
752 index_ptr->setColor(color);
753 // Update also the Color table:
755 color = lcolor.getX11Name(Color_background);
757 if (!shortcut.empty())
758 lcolor.setColor(to_utf8(shortcut), color);
761 } else if (token == "\\author") {
763 istringstream ss(lex.getString());
766 author_map[a.bufferId()] = pimpl_->authorlist.record(a);
767 } else if (token == "\\paperorientation") {
770 orientation = paperorientationtranslator().find(orient);
771 } else if (token == "\\backgroundcolor") {
773 backgroundcolor = lyx::rgbFromHexName(lex.getString());
774 isbackgroundcolor = true;
775 } else if (token == "\\fontcolor") {
777 fontcolor = lyx::rgbFromHexName(lex.getString());
779 } else if (token == "\\notefontcolor") {
781 string color = lex.getString();
782 notefontcolor = lyx::rgbFromHexName(color);
783 } else if (token == "\\boxbgcolor") {
785 string color = lex.getString();
786 boxbgcolor = lyx::rgbFromHexName(color);
787 } else if (token == "\\paperwidth") {
789 } else if (token == "\\paperheight") {
791 } else if (token == "\\leftmargin") {
793 } else if (token == "\\topmargin") {
795 } else if (token == "\\rightmargin") {
797 } else if (token == "\\bottommargin") {
799 } else if (token == "\\headheight") {
801 } else if (token == "\\headsep") {
803 } else if (token == "\\footskip") {
805 } else if (token == "\\columnsep") {
807 } else if (token == "\\paperfontsize") {
809 } else if (token == "\\papercolumns") {
811 } else if (token == "\\listings_params") {
814 listings_params = InsetListingsParams(par).params();
815 } else if (token == "\\papersides") {
818 sides = sidestranslator().find(psides);
819 } else if (token == "\\paperpagestyle") {
821 } else if (token == "\\bullet") {
823 } else if (token == "\\bulletLaTeX") {
824 readBulletsLaTeX(lex);
825 } else if (token == "\\secnumdepth") {
827 } else if (token == "\\tocdepth") {
829 } else if (token == "\\spacing") {
833 if (nspacing == "other") {
836 spacing().set(spacetranslator().find(nspacing), tmp_val);
837 } else if (token == "\\float_placement") {
838 lex >> float_placement;
840 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
841 string toktmp = pdfoptions().readToken(lex, token);
842 if (!toktmp.empty()) {
843 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
847 } else if (token == "\\html_math_output") {
850 html_math_output = static_cast<MathOutput>(temp);
851 } else if (token == "\\html_be_strict") {
852 lex >> html_be_strict;
853 } else if (token == "\\html_math_img_scale") {
854 lex >> html_math_img_scale;
855 } else if (token == "\\html_latex_start") {
857 html_latex_start = lex.getString();
858 } else if (token == "\\html_latex_end") {
860 html_latex_end = lex.getString();
861 } else if (token == "\\output_sync") {
863 } else if (token == "\\output_sync_macro") {
864 lex >> output_sync_macro;
865 } else if (token == "\\use_refstyle") {
868 lyxerr << "BufferParams::readToken(): Unknown token: " <<
877 void BufferParams::writeFile(ostream & os) const
879 // The top of the file is written by the buffer.
880 // Prints out the buffer info into the .lyx file given by file
883 os << "\\textclass " << baseClass()->name() << '\n';
886 if (!preamble.empty()) {
887 // remove '\n' from the end of preamble
888 string const tmppreamble = rtrim(preamble, "\n");
889 os << "\\begin_preamble\n"
891 << "\n\\end_preamble\n";
895 if (!options.empty()) {
896 os << "\\options " << options << '\n';
899 // use the class options defined in the layout?
900 os << "\\use_default_options "
901 << convert<string>(use_default_options) << "\n";
903 // the master document
904 if (!master.empty()) {
905 os << "\\master " << master << '\n';
909 if (!removed_modules_.empty()) {
910 os << "\\begin_removed_modules" << '\n';
911 list<string>::const_iterator it = removed_modules_.begin();
912 list<string>::const_iterator en = removed_modules_.end();
913 for (; it != en; it++)
915 os << "\\end_removed_modules" << '\n';
919 if (!layout_modules_.empty()) {
920 os << "\\begin_modules" << '\n';
921 LayoutModuleList::const_iterator it = layout_modules_.begin();
922 LayoutModuleList::const_iterator en = layout_modules_.end();
923 for (; it != en; it++)
925 os << "\\end_modules" << '\n';
929 if (!included_children_.empty()) {
930 os << "\\begin_includeonly" << '\n';
931 list<string>::const_iterator it = included_children_.begin();
932 list<string>::const_iterator en = included_children_.end();
933 for (; it != en; it++)
935 os << "\\end_includeonly" << '\n';
937 os << "\\maintain_unincluded_children "
938 << convert<string>(maintain_unincluded_children) << '\n';
940 // local layout information
941 if (!local_layout.empty()) {
942 // remove '\n' from the end
943 string const tmplocal = rtrim(local_layout, "\n");
944 os << "\\begin_local_layout\n"
946 << "\n\\end_local_layout\n";
949 // then the text parameters
950 if (language != ignore_language)
951 os << "\\language " << language->lang() << '\n';
952 os << "\\language_package " << lang_package
953 << "\n\\inputencoding " << inputenc
954 << "\n\\fontencoding " << fontenc
955 << "\n\\font_roman " << fonts_roman
956 << "\n\\font_sans " << fonts_sans
957 << "\n\\font_typewriter " << fonts_typewriter
958 << "\n\\font_default_family " << fonts_default_family
959 << "\n\\use_non_tex_fonts " << convert<string>(useNonTeXFonts)
960 << "\n\\font_sc " << convert<string>(fonts_expert_sc)
961 << "\n\\font_osf " << convert<string>(fonts_old_figures)
962 << "\n\\font_sf_scale " << fonts_sans_scale
963 << "\n\\font_tt_scale " << fonts_typewriter_scale
965 if (!fonts_cjk.empty()) {
966 os << "\\font_cjk " << fonts_cjk << '\n';
968 os << "\n\\graphics " << graphics_driver << '\n';
969 os << "\\default_output_format " << default_output_format << '\n';
970 os << "\\output_sync " << output_sync << '\n';
971 if (!output_sync_macro.empty())
972 os << "\\output_sync_macro \"" << output_sync_macro << "\"\n";
973 os << "\\bibtex_command " << bibtex_command << '\n';
974 os << "\\index_command " << index_command << '\n';
976 if (!float_placement.empty()) {
977 os << "\\float_placement " << float_placement << '\n';
979 os << "\\paperfontsize " << fontsize << '\n';
981 spacing().writeFile(os);
982 pdfoptions().writeFile(os);
984 os << "\\papersize " << string_papersize[papersize]
985 << "\n\\use_geometry " << convert<string>(use_geometry)
986 << "\n\\use_amsmath " << use_amsmath
987 << "\n\\use_esint " << use_esint
988 << "\n\\use_mhchem " << use_mhchem
989 << "\n\\use_mathdots " << use_mathdots
990 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
991 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
992 << "\n\\use_indices " << convert<string>(use_indices)
993 << "\n\\paperorientation " << string_orientation[orientation]
994 << "\n\\suppress_date " << convert<string>(suppress_date)
995 << "\n\\use_refstyle " << use_refstyle
997 if (isbackgroundcolor == true)
998 os << "\\backgroundcolor " << lyx::X11hexname(backgroundcolor) << '\n';
999 if (isfontcolor == true)
1000 os << "\\fontcolor " << lyx::X11hexname(fontcolor) << '\n';
1001 if (notefontcolor != lyx::rgbFromHexName("#cccccc"))
1002 os << "\\notefontcolor " << lyx::X11hexname(notefontcolor) << '\n';
1003 if (boxbgcolor != lyx::rgbFromHexName("#ff0000"))
1004 os << "\\boxbgcolor " << lyx::X11hexname(boxbgcolor) << '\n';
1006 BranchList::const_iterator it = branchlist().begin();
1007 BranchList::const_iterator end = branchlist().end();
1008 for (; it != end; ++it) {
1009 os << "\\branch " << to_utf8(it->branch())
1010 << "\n\\selected " << it->isSelected()
1011 << "\n\\filename_suffix " << it->hasFileNameSuffix()
1012 << "\n\\color " << lyx::X11hexname(it->color())
1017 IndicesList::const_iterator iit = indiceslist().begin();
1018 IndicesList::const_iterator iend = indiceslist().end();
1019 for (; iit != iend; ++iit) {
1020 os << "\\index " << to_utf8(iit->index())
1021 << "\n\\shortcut " << to_utf8(iit->shortcut())
1022 << "\n\\color " << lyx::X11hexname(iit->color())
1027 if (!paperwidth.empty())
1028 os << "\\paperwidth "
1029 << VSpace(paperwidth).asLyXCommand() << '\n';
1030 if (!paperheight.empty())
1031 os << "\\paperheight "
1032 << VSpace(paperheight).asLyXCommand() << '\n';
1033 if (!leftmargin.empty())
1034 os << "\\leftmargin "
1035 << VSpace(leftmargin).asLyXCommand() << '\n';
1036 if (!topmargin.empty())
1037 os << "\\topmargin "
1038 << VSpace(topmargin).asLyXCommand() << '\n';
1039 if (!rightmargin.empty())
1040 os << "\\rightmargin "
1041 << VSpace(rightmargin).asLyXCommand() << '\n';
1042 if (!bottommargin.empty())
1043 os << "\\bottommargin "
1044 << VSpace(bottommargin).asLyXCommand() << '\n';
1045 if (!headheight.empty())
1046 os << "\\headheight "
1047 << VSpace(headheight).asLyXCommand() << '\n';
1048 if (!headsep.empty())
1050 << VSpace(headsep).asLyXCommand() << '\n';
1051 if (!footskip.empty())
1053 << VSpace(footskip).asLyXCommand() << '\n';
1054 if (!columnsep.empty())
1055 os << "\\columnsep "
1056 << VSpace(columnsep).asLyXCommand() << '\n';
1057 os << "\\secnumdepth " << secnumdepth
1058 << "\n\\tocdepth " << tocdepth
1059 << "\n\\paragraph_separation "
1060 << string_paragraph_separation[paragraph_separation];
1061 if (!paragraph_separation)
1062 os << "\n\\paragraph_indentation " << getIndentation().asLyXCommand();
1064 os << "\n\\defskip " << getDefSkip().asLyXCommand();
1065 os << "\n\\quotes_language "
1066 << string_quotes_language[quotes_language]
1067 << "\n\\papercolumns " << columns
1068 << "\n\\papersides " << sides
1069 << "\n\\paperpagestyle " << pagestyle << '\n';
1070 if (!listings_params.empty())
1071 os << "\\listings_params \"" <<
1072 InsetListingsParams(listings_params).encodedString() << "\"\n";
1073 for (int i = 0; i < 4; ++i) {
1074 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1075 if (user_defined_bullet(i).getFont() != -1) {
1076 os << "\\bullet " << i << " "
1077 << user_defined_bullet(i).getFont() << " "
1078 << user_defined_bullet(i).getCharacter() << " "
1079 << user_defined_bullet(i).getSize() << "\n";
1083 os << "\\bulletLaTeX " << i << " \""
1084 << lyx::to_ascii(user_defined_bullet(i).getText())
1090 os << "\\tracking_changes " << convert<string>(trackChanges) << '\n'
1091 << "\\output_changes " << convert<string>(outputChanges) << '\n'
1092 << "\\html_math_output " << html_math_output << '\n'
1093 << "\\html_be_strict " << convert<string>(html_be_strict) << '\n';
1095 if (html_math_img_scale != 1.0)
1096 os << "\\html_math_img_scale " << convert<string>(html_math_img_scale) << '\n';
1097 if (!html_latex_start.empty())
1098 os << "\\html_latex_start " << html_latex_start << '\n';
1099 if (!html_latex_end.empty())
1100 os << "\\html_latex_end " << html_latex_end << '\n';
1102 os << pimpl_->authorlist;
1106 void BufferParams::validate(LaTeXFeatures & features) const
1108 features.require(documentClass().requires());
1110 if (outputChanges) {
1111 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
1112 bool xcolorulem = LaTeXFeatures::isAvailable("ulem") &&
1113 LaTeXFeatures::isAvailable("xcolor");
1115 switch (features.runparams().flavor) {
1116 case OutputParams::LATEX:
1118 features.require("ct-dvipost");
1119 features.require("dvipost");
1120 } else if (xcolorulem) {
1121 features.require("ct-xcolor-ulem");
1122 features.require("ulem");
1123 features.require("xcolor");
1125 features.require("ct-none");
1128 case OutputParams::LUATEX:
1129 case OutputParams::PDFLATEX:
1130 case OutputParams::XETEX:
1132 features.require("ct-xcolor-ulem");
1133 features.require("ulem");
1134 features.require("xcolor");
1135 // improves color handling in PDF output
1136 features.require("pdfcolmk");
1138 features.require("ct-none");
1146 // Floats with 'Here definitely' as default setting.
1147 if (float_placement.find('H') != string::npos)
1148 features.require("float");
1150 // AMS Style is at document level
1151 if (use_amsmath == package_on
1152 || documentClass().provides("amsmath"))
1153 features.require("amsmath");
1154 if (use_esint == package_on)
1155 features.require("esint");
1156 if (use_mhchem == package_on)
1157 features.require("mhchem");
1158 if (use_mathdots == package_on)
1159 features.require("mathdots");
1161 // Document-level line spacing
1162 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
1163 features.require("setspace");
1165 // the bullet shapes are buffer level not paragraph level
1166 // so they are tested here
1167 for (int i = 0; i < 4; ++i) {
1168 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
1170 int const font = user_defined_bullet(i).getFont();
1172 int const c = user_defined_bullet(i).getCharacter();
1178 features.require("latexsym");
1180 } else if (font == 1) {
1181 features.require("amssymb");
1182 } else if (font >= 2 && font <= 5) {
1183 features.require("pifont");
1187 if (pdfoptions().use_hyperref) {
1188 features.require("hyperref");
1189 // due to interferences with babel and hyperref, the color package has to
1190 // be loaded after hyperref when hyperref is used with the colorlinks
1191 // option, see http://www.lyx.org/trac/ticket/5291
1192 if (pdfoptions().colorlinks)
1193 features.require("color");
1196 if (features.runparams().flavor == OutputParams::XETEX
1198 features.require("polyglossia");
1200 if (language->lang() == "vietnamese")
1201 features.require("vietnamese");
1202 else if (language->lang() == "japanese")
1203 features.require("japanese");
1207 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
1208 TexRow & texrow, FileName const & filepath) const
1210 // http://www.tug.org/texmf-dist/doc/latex/base/fixltx2e.pdf
1211 // !! To use the Fix-cm package, load it before \documentclass, and use the command
1212 // \RequirePackage to do so, rather than the normal \usepackage
1213 // Do not to load any other package before the document class, unless you
1214 // have a thorough understanding of the LATEX internals and know exactly what you
1216 if (features.mustProvide("fix-cm")) {
1217 os << "\\RequirePackage{fix-cm}\n";
1221 os << "\\documentclass";
1223 DocumentClass const & tclass = documentClass();
1225 ostringstream clsoptions; // the document class options.
1227 if (tokenPos(tclass.opt_fontsize(),
1228 '|', fontsize) >= 0) {
1229 // only write if existing in list (and not default)
1230 clsoptions << fontsize << "pt,";
1233 // all paper sizes except of A4, A5, B5 and the US sizes need the
1235 bool nonstandard_papersize = papersize != PAPER_DEFAULT
1236 && papersize != PAPER_USLETTER
1237 && papersize != PAPER_USLEGAL
1238 && papersize != PAPER_USEXECUTIVE
1239 && papersize != PAPER_A4
1240 && papersize != PAPER_A5
1241 && papersize != PAPER_B5;
1243 if (!use_geometry) {
1244 switch (papersize) {
1246 clsoptions << "a4paper,";
1248 case PAPER_USLETTER:
1249 clsoptions << "letterpaper,";
1252 clsoptions << "a5paper,";
1255 clsoptions << "b5paper,";
1257 case PAPER_USEXECUTIVE:
1258 clsoptions << "executivepaper,";
1261 clsoptions << "legalpaper,";
1295 if (sides != tclass.sides()) {
1298 clsoptions << "oneside,";
1301 clsoptions << "twoside,";
1307 if (columns != tclass.columns()) {
1309 clsoptions << "twocolumn,";
1311 clsoptions << "onecolumn,";
1315 && orientation == ORIENTATION_LANDSCAPE)
1316 clsoptions << "landscape,";
1318 // language should be a parameter to \documentclass
1319 if (language->babel() == "hebrew"
1320 && default_language->babel() != "hebrew")
1321 // This seems necessary
1322 features.useLanguage(default_language);
1324 ostringstream language_options;
1325 bool const use_babel = features.useBabel() && !tclass.provides("babel");
1326 bool const use_polyglossia = features.usePolyglossia();
1327 bool const global = lyxrc.language_global_options;
1328 if (use_babel || (use_polyglossia && global)) {
1329 language_options << features.getLanguages();
1330 if (!language->babel().empty()) {
1331 if (!language_options.str().empty())
1332 language_options << ',';
1333 language_options << language->babel();
1335 if (global && !features.needBabelLangOptions())
1336 clsoptions << language_options.str() << ',';
1339 // the predefined options from the layout
1340 if (use_default_options && !tclass.options().empty())
1341 clsoptions << tclass.options() << ',';
1343 // the user-defined options
1344 if (!options.empty()) {
1345 clsoptions << options << ',';
1348 string strOptions(clsoptions.str());
1349 if (!strOptions.empty()) {
1350 strOptions = rtrim(strOptions, ",");
1352 os << '[' << from_utf8(strOptions) << ']';
1355 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1357 // 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);
1364 nlines = int(count(ams.begin(), ams.end(), '\n'));
1365 texrow.newlines(nlines);
1368 if (useNonTeXFonts) {
1369 os << "\\usepackage{fontspec}\n";
1373 // font selection must be done before loading fontenc.sty
1374 string const fonts =
1375 loadFonts(fonts_roman, fonts_sans, fonts_typewriter,
1376 fonts_expert_sc, fonts_old_figures,
1377 fonts_sans_scale, fonts_typewriter_scale,
1378 useNonTeXFonts, features);
1379 if (!fonts.empty()) {
1380 os << from_ascii(fonts);
1382 int(count(fonts.begin(), fonts.end(), '\n'));
1383 texrow.newlines(nlines);
1385 if (fonts_default_family != "default")
1386 os << "\\renewcommand{\\familydefault}{\\"
1387 << from_ascii(fonts_default_family) << "}\n";
1389 // set font encoding
1390 // for arabic_arabi and farsi we also need to load the LAE and
1392 // XeTeX and LuaTeX (with OS fonts) work without fontenc
1393 if (font_encoding() != "default" && language->lang() != "japanese"
1394 && !useNonTeXFonts && !tclass.provides("fontenc")) {
1395 size_t fars = language_options.str().find("farsi");
1396 size_t arab = language_options.str().find("arabic");
1397 if (language->lang() == "arabic_arabi"
1398 || language->lang() == "farsi" || fars != string::npos
1399 || arab != string::npos) {
1400 os << "\\usepackage[" << from_ascii(font_encoding())
1401 << ",LFE,LAE]{fontenc}\n";
1404 os << "\\usepackage[" << from_ascii(font_encoding())
1410 // handle inputenc etc.
1411 writeEncodingPreamble(os, features, texrow);
1414 if (!features.runparams().includeall && !included_children_.empty()) {
1415 os << "\\includeonly{";
1416 list<string>::const_iterator it = included_children_.begin();
1417 list<string>::const_iterator en = included_children_.end();
1419 for (; it != en; ++it) {
1420 string incfile = *it;
1421 FileName inc = makeAbsPath(incfile, filepath.absFileName());
1422 string mangled = DocFileName(changeExtension(inc.absFileName(), ".tex")).
1424 if (!features.runparams().nice)
1426 // \includeonly doesn't want an extension
1427 incfile = changeExtension(incfile, string());
1428 incfile = support::latex_path(incfile);
1429 if (!incfile.empty()) {
1432 os << from_utf8(incfile);
1439 if (!listings_params.empty() || features.isRequired("listings")) {
1440 os << "\\usepackage{listings}\n";
1443 if (!listings_params.empty()) {
1445 // do not test validity because listings_params is
1446 // supposed to be valid
1448 InsetListingsParams(listings_params).separatedParams(true);
1449 // we can't support all packages, but we should load the color package
1450 if (par.find("\\color", 0) != string::npos)
1451 features.require("color");
1452 os << from_utf8(par);
1453 // count the number of newlines
1454 for (size_t i = 0; i < par.size(); ++i)
1460 if (!tclass.provides("geometry")
1461 && (use_geometry || nonstandard_papersize)) {
1462 odocstringstream ods;
1463 if (!getGraphicsDriver("geometry").empty())
1464 ods << getGraphicsDriver("geometry");
1465 if (orientation == ORIENTATION_LANDSCAPE)
1466 ods << ",landscape";
1467 switch (papersize) {
1469 if (!paperwidth.empty())
1470 ods << ",paperwidth="
1471 << from_ascii(paperwidth);
1472 if (!paperheight.empty())
1473 ods << ",paperheight="
1474 << from_ascii(paperheight);
1476 case PAPER_USLETTER:
1477 ods << ",letterpaper";
1480 ods << ",legalpaper";
1482 case PAPER_USEXECUTIVE:
1483 ods << ",executivepaper";
1570 // default papersize ie PAPER_DEFAULT
1571 switch (lyxrc.default_papersize) {
1572 case PAPER_DEFAULT: // keep compiler happy
1574 case PAPER_USLETTER:
1575 ods << ",letterpaper";
1578 ods << ",legalpaper";
1580 case PAPER_USEXECUTIVE:
1581 ods << ",executivepaper";
1623 docstring const g_options = trim(ods.str(), ",");
1624 os << "\\usepackage";
1625 if (!g_options.empty())
1626 os << '[' << g_options << ']';
1627 os << "{geometry}\n";
1629 // output this only if use_geometry is true
1631 os << "\\geometry{verbose";
1632 if (!topmargin.empty())
1633 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1634 if (!bottommargin.empty())
1635 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1636 if (!leftmargin.empty())
1637 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1638 if (!rightmargin.empty())
1639 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1640 if (!headheight.empty())
1641 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1642 if (!headsep.empty())
1643 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1644 if (!footskip.empty())
1645 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1646 if (!columnsep.empty())
1647 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1651 } else if (orientation == ORIENTATION_LANDSCAPE
1652 || papersize != PAPER_DEFAULT) {
1653 features.require("papersize");
1656 if (tokenPos(tclass.opt_pagestyle(),
1657 '|', pagestyle) >= 0) {
1658 if (pagestyle == "fancy") {
1659 os << "\\usepackage{fancyhdr}\n";
1662 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1666 // only output when the background color is not default
1667 if (isbackgroundcolor == true) {
1668 // only require color here, the background color will be defined
1669 // in LaTeXFeatures.cpp to avoid interferences with the LaTeX
1671 features.require("color");
1672 features.require("pagecolor");
1675 // only output when the font color is not default
1676 if (isfontcolor == true) {
1677 // only require color here, the font color will be defined
1678 // in LaTeXFeatures.cpp to avoid interferences with the LaTeX
1680 features.require("color");
1681 features.require("fontcolor");
1684 // Only if class has a ToC hierarchy
1685 if (tclass.hasTocLevels()) {
1686 if (secnumdepth != tclass.secnumdepth()) {
1687 os << "\\setcounter{secnumdepth}{"
1692 if (tocdepth != tclass.tocdepth()) {
1693 os << "\\setcounter{tocdepth}{"
1700 if (paragraph_separation) {
1701 // when skip separation
1702 switch (getDefSkip().kind()) {
1703 case VSpace::SMALLSKIP:
1704 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1706 case VSpace::MEDSKIP:
1707 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1709 case VSpace::BIGSKIP:
1710 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1712 case VSpace::LENGTH:
1713 os << "\\setlength{\\parskip}{"
1714 << from_utf8(getDefSkip().length().asLatexString())
1717 default: // should never happen // Then delete it.
1718 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1722 os << "\\setlength{\\parindent}{0pt}\n";
1725 // when separation by indentation
1726 // only output something when a width is given
1727 if (getIndentation().asLyXCommand() != "default") {
1728 os << "\\setlength{\\parindent}{"
1729 << from_utf8(getIndentation().asLatexCommand())
1735 // Now insert the LyX specific LaTeX commands...
1736 docstring lyxpreamble;
1739 if (!output_sync_macro.empty())
1740 lyxpreamble += from_utf8(output_sync_macro) +"\n";
1741 else if (features.runparams().flavor == OutputParams::LATEX)
1742 lyxpreamble += "\\usepackage[active]{srcltx}\n";
1743 else if (features.runparams().flavor == OutputParams::PDFLATEX)
1744 lyxpreamble += "\\synctex=-1\n";
1747 // due to interferences with babel and hyperref, the color package has to
1748 // be loaded (when it is not already loaded) before babel when hyperref
1749 // is used with the colorlinks option, see
1750 // http://www.lyx.org/trac/ticket/5291
1751 // we decided therefore to load color always before babel, see
1752 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg144349.html
1753 lyxpreamble += from_ascii(features.getColorOptions());
1755 // If we use hyperref, jurabib, japanese, or vietnamese, we have to call babel before them.
1757 && (features.isRequired("jurabib")
1758 || features.isRequired("hyperref")
1759 || features.isRequired("vietnamese")
1760 || features.isRequired("japanese"))) {
1762 lyxpreamble += from_utf8(features.getBabelPresettings());
1763 lyxpreamble += from_utf8(babelCall(language_options.str(),
1764 features.needBabelLangOptions())) + '\n';
1765 lyxpreamble += from_utf8(features.getBabelPostsettings());
1768 // The optional packages;
1769 lyxpreamble += from_ascii(features.getPackages());
1771 // Additional Indices
1772 if (features.isRequired("splitidx")) {
1773 IndicesList::const_iterator iit = indiceslist().begin();
1774 IndicesList::const_iterator iend = indiceslist().end();
1775 for (; iit != iend; ++iit) {
1776 lyxpreamble += "\\newindex[";
1777 lyxpreamble += iit->index();
1778 lyxpreamble += "]{";
1779 lyxpreamble += iit->shortcut();
1780 lyxpreamble += "}\n";
1785 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1788 // * Hyperref manual: "Make sure it comes last of your loaded
1789 // packages, to give it a fighting chance of not being over-written,
1790 // since its job is to redefine many LaTeX commands."
1791 // * Email from Heiko Oberdiek: "It is usually better to load babel
1792 // before hyperref. Then hyperref has a chance to detect babel.
1793 // * Has to be loaded before the "LyX specific LaTeX commands" to
1794 // avoid errors with algorithm floats.
1795 // use hyperref explicitly if it is required
1796 if (features.isRequired("hyperref")) {
1797 // pass what we have to stream here, since we need
1798 // to access the stream itself in PDFOptions.
1802 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1804 OutputParams tmp_params = features.runparams();
1805 lines += pdfoptions().writeLaTeX(tmp_params, os,
1806 documentClass().provides("hyperref"));
1807 texrow.newlines(lines);
1808 // set back for the rest
1809 lyxpreamble.clear();
1810 // correctly break URLs with hyperref and dvi output
1811 if (features.runparams().flavor == OutputParams::LATEX
1812 && features.isAvailable("breakurl"))
1813 lyxpreamble += "\\usepackage{breakurl}\n";
1814 } else if (features.isRequired("nameref"))
1815 // hyperref loads this automatically
1816 lyxpreamble += "\\usepackage{nameref}\n";
1818 // Will be surrounded by \makeatletter and \makeatother when not empty
1819 docstring atlyxpreamble;
1821 // Some macros LyX will need
1822 docstring tmppreamble(features.getMacros());
1824 if (!tmppreamble.empty())
1825 atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1826 "LyX specific LaTeX commands.\n"
1827 + tmppreamble + '\n';
1829 // the text class specific preamble
1830 tmppreamble = features.getTClassPreamble();
1831 if (!tmppreamble.empty())
1832 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1833 "Textclass specific LaTeX commands.\n"
1834 + tmppreamble + '\n';
1836 // suppress date if selected
1837 // use \@ifundefined because we cannot be sure that every document class
1838 // has a \date command
1840 atlyxpreamble += "\\@ifundefined{date}{}{\\date{}}\n";
1842 /* the user-defined preamble */
1843 if (!containsOnly(preamble, " \n\t"))
1845 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1846 "User specified LaTeX commands.\n"
1847 + from_utf8(preamble) + '\n';
1849 // subfig loads internally the LaTeX package "caption". As
1850 // caption is a very popular package, users will load it in
1851 // the preamble. Therefore we must load subfig behind the
1852 // user-defined preamble and check if the caption package was
1853 // loaded or not. For the case that caption is loaded before
1854 // subfig, there is the subfig option "caption=false". This
1855 // option also works when a koma-script class is used and
1856 // koma's own caption commands are used instead of caption. We
1857 // use \PassOptionsToPackage here because the user could have
1858 // already loaded subfig in the preamble.
1859 if (features.isRequired("subfig")) {
1860 atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n"
1861 " \\PassOptionsToPackage{caption=false}{subfig}}\n"
1862 "\\usepackage{subfig}\n";
1865 // Itemize bullet settings need to be last in case the user
1866 // defines their own bullets that use a package included
1867 // in the user-defined preamble -- ARRae
1868 // Actually it has to be done much later than that
1869 // since some packages like frenchb make modifications
1870 // at \begin{document} time -- JMarc
1871 docstring bullets_def;
1872 for (int i = 0; i < 4; ++i) {
1873 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1874 if (bullets_def.empty())
1875 bullets_def += "\\AtBeginDocument{\n";
1876 bullets_def += " \\def\\labelitemi";
1878 // `i' is one less than the item to modify
1885 bullets_def += "ii";
1891 bullets_def += '{' +
1892 user_defined_bullet(i).getText()
1897 if (!bullets_def.empty())
1898 atlyxpreamble += bullets_def + "}\n\n";
1900 if (!atlyxpreamble.empty())
1901 lyxpreamble += "\n\\makeatletter\n"
1902 + atlyxpreamble + "\\makeatother\n\n";
1904 // We try to load babel late, in case it interferes with other packages.
1905 // Jurabib and Hyperref have to be called after babel, though.
1906 if (use_babel && !features.isRequired("jurabib")
1907 && !features.isRequired("hyperref")
1908 && !features.isRequired("vietnamese")
1909 && !features.isRequired("japanese")) {
1911 lyxpreamble += from_utf8(features.getBabelPresettings());
1912 lyxpreamble += from_utf8(babelCall(language_options.str(),
1913 features.needBabelLangOptions())) + '\n';
1914 lyxpreamble += from_utf8(features.getBabelPostsettings());
1917 // xunicode needs to be loaded at least after amsmath, amssymb,
1918 // esint and the other packages that provide special glyphs
1919 if (features.runparams().flavor == OutputParams::XETEX)
1920 lyxpreamble += "\\usepackage{xunicode}\n";
1922 // Polyglossia must be loaded last
1923 if (use_polyglossia) {
1925 lyxpreamble += "\\usepackage{polyglossia}\n";
1926 // set the main language
1927 lyxpreamble += "\\setdefaultlanguage";
1928 if (!language->polyglossiaOpts().empty())
1929 lyxpreamble += "[" + from_ascii(language->polyglossiaOpts()) + "]";
1930 lyxpreamble += "{" + from_ascii(language->polyglossia()) + "}\n";
1931 // now setup the other languages
1932 std::map<std::string, std::string> const polylangs =
1933 features.getPolyglossiaLanguages();
1934 for (std::map<std::string, std::string>::const_iterator mit = polylangs.begin();
1935 mit != polylangs.end() ; ++mit) {
1936 lyxpreamble += "\\setotherlanguage";
1937 if (!mit->second.empty())
1938 lyxpreamble += "[" + from_ascii(mit->second) + "]";
1939 lyxpreamble += "{" + from_ascii(mit->first) + "}\n";
1943 docstring const i18npreamble =
1944 features.getTClassI18nPreamble(use_babel, use_polyglossia);
1945 if (!i18npreamble.empty())
1946 lyxpreamble += i18npreamble + '\n';
1948 nlines = int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1949 texrow.newlines(nlines);
1957 void BufferParams::useClassDefaults()
1959 DocumentClass const & tclass = documentClass();
1961 sides = tclass.sides();
1962 columns = tclass.columns();
1963 pagestyle = tclass.pagestyle();
1964 use_default_options = true;
1965 // Only if class has a ToC hierarchy
1966 if (tclass.hasTocLevels()) {
1967 secnumdepth = tclass.secnumdepth();
1968 tocdepth = tclass.tocdepth();
1973 bool BufferParams::hasClassDefaults() const
1975 DocumentClass const & tclass = documentClass();
1977 return sides == tclass.sides()
1978 && columns == tclass.columns()
1979 && pagestyle == tclass.pagestyle()
1980 && use_default_options
1981 && secnumdepth == tclass.secnumdepth()
1982 && tocdepth == tclass.tocdepth();
1986 DocumentClass const & BufferParams::documentClass() const
1992 DocumentClass const * BufferParams::documentClassPtr() const
1998 void BufferParams::setDocumentClass(DocumentClass const * const tc)
2000 // evil, but this function is evil
2001 doc_class_ = const_cast<DocumentClass *>(tc);
2005 bool BufferParams::setBaseClass(string const & classname)
2007 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
2008 LayoutFileList & bcl = LayoutFileList::get();
2009 if (!bcl.haveClass(classname)) {
2011 bformat(_("The layout file:\n"
2013 "could not be found. A default textclass with default\n"
2014 "layouts will be used. LyX will not be able to produce\n"
2016 from_utf8(classname));
2017 frontend::Alert::error(_("Document class not found"), s);
2018 bcl.addEmptyClass(classname);
2021 bool const success = bcl[classname].load();
2024 bformat(_("Due to some error in it, the layout file:\n"
2026 "could not be loaded. A default textclass with default\n"
2027 "layouts will be used. LyX will not be able to produce\n"
2029 from_utf8(classname));
2030 frontend::Alert::error(_("Could not load class"), s);
2031 bcl.addEmptyClass(classname);
2034 pimpl_->baseClass_ = classname;
2035 layout_modules_.adaptToBaseClass(baseClass(), removed_modules_);
2040 LayoutFile const * BufferParams::baseClass() const
2042 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
2043 return &(LayoutFileList::get()[pimpl_->baseClass_]);
2049 LayoutFileIndex const & BufferParams::baseClassID() const
2051 return pimpl_->baseClass_;
2055 void BufferParams::makeDocumentClass()
2060 doc_class_ = &(DocumentClassBundle::get().makeDocumentClass(*baseClass(), layout_modules_));
2062 if (!local_layout.empty()) {
2063 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
2064 docstring const msg = _("Error reading internal layout information");
2065 frontend::Alert::warning(_("Read Error"), msg);
2071 bool BufferParams::moduleCanBeAdded(string const & modName) const
2073 return layout_modules_.moduleCanBeAdded(modName, baseClass());
2077 bool BufferParams::addLayoutModule(string const & modName)
2079 LayoutModuleList::const_iterator it = layout_modules_.begin();
2080 LayoutModuleList::const_iterator end = layout_modules_.end();
2081 for (; it != end; it++)
2084 layout_modules_.push_back(modName);
2089 Font const BufferParams::getFont() const
2091 FontInfo f = documentClass().defaultfont();
2092 if (fonts_default_family == "rmdefault")
2093 f.setFamily(ROMAN_FAMILY);
2094 else if (fonts_default_family == "sfdefault")
2095 f.setFamily(SANS_FAMILY);
2096 else if (fonts_default_family == "ttdefault")
2097 f.setFamily(TYPEWRITER_FAMILY);
2098 return Font(f, language);
2102 void BufferParams::readPreamble(Lexer & lex)
2104 if (lex.getString() != "\\begin_preamble")
2105 lyxerr << "Error (BufferParams::readPreamble):"
2106 "consistency check failed." << endl;
2108 preamble = lex.getLongString("\\end_preamble");
2112 void BufferParams::readLocalLayout(Lexer & lex)
2114 if (lex.getString() != "\\begin_local_layout")
2115 lyxerr << "Error (BufferParams::readLocalLayout):"
2116 "consistency check failed." << endl;
2118 local_layout = lex.getLongString("\\end_local_layout");
2122 void BufferParams::readLanguage(Lexer & lex)
2124 if (!lex.next()) return;
2126 string const tmptok = lex.getString();
2128 // check if tmptok is part of tex_babel in tex-defs.h
2129 language = languages.getLanguage(tmptok);
2131 // Language tmptok was not found
2132 language = default_language;
2133 lyxerr << "Warning: Setting language `"
2134 << tmptok << "' to `" << language->lang()
2140 void BufferParams::readGraphicsDriver(Lexer & lex)
2145 string const tmptok = lex.getString();
2146 // check if tmptok is part of tex_graphics in tex_defs.h
2149 string const test = tex_graphics[n++];
2151 if (test == tmptok) {
2152 graphics_driver = tmptok;
2157 "Warning: graphics driver `$$Token' not recognized!\n"
2158 " Setting graphics driver to `default'.\n");
2159 graphics_driver = "default";
2166 void BufferParams::readBullets(Lexer & lex)
2171 int const index = lex.getInteger();
2173 int temp_int = lex.getInteger();
2174 user_defined_bullet(index).setFont(temp_int);
2175 temp_bullet(index).setFont(temp_int);
2177 user_defined_bullet(index).setCharacter(temp_int);
2178 temp_bullet(index).setCharacter(temp_int);
2180 user_defined_bullet(index).setSize(temp_int);
2181 temp_bullet(index).setSize(temp_int);
2185 void BufferParams::readBulletsLaTeX(Lexer & lex)
2187 // The bullet class should be able to read this.
2190 int const index = lex.getInteger();
2192 docstring const temp_str = lex.getDocString();
2194 user_defined_bullet(index).setText(temp_str);
2195 temp_bullet(index).setText(temp_str);
2199 void BufferParams::readModules(Lexer & lex)
2201 if (!lex.eatLine()) {
2202 lyxerr << "Error (BufferParams::readModules):"
2203 "Unexpected end of input." << endl;
2207 string mod = lex.getString();
2208 if (mod == "\\end_modules")
2210 addLayoutModule(mod);
2216 void BufferParams::readRemovedModules(Lexer & lex)
2218 if (!lex.eatLine()) {
2219 lyxerr << "Error (BufferParams::readRemovedModules):"
2220 "Unexpected end of input." << endl;
2224 string mod = lex.getString();
2225 if (mod == "\\end_removed_modules")
2227 removed_modules_.push_back(mod);
2230 // now we want to remove any removed modules that were previously
2231 // added. normally, that will be because default modules were added in
2232 // setBaseClass(), which gets called when \textclass is read at the
2233 // start of the read.
2234 list<string>::const_iterator rit = removed_modules_.begin();
2235 list<string>::const_iterator const ren = removed_modules_.end();
2236 for (; rit != ren; rit++) {
2237 LayoutModuleList::iterator const mit = layout_modules_.begin();
2238 LayoutModuleList::iterator const men = layout_modules_.end();
2239 LayoutModuleList::iterator found = find(mit, men, *rit);
2242 layout_modules_.erase(found);
2247 void BufferParams::readIncludeonly(Lexer & lex)
2249 if (!lex.eatLine()) {
2250 lyxerr << "Error (BufferParams::readIncludeonly):"
2251 "Unexpected end of input." << endl;
2255 string child = lex.getString();
2256 if (child == "\\end_includeonly")
2258 included_children_.push_back(child);
2264 string BufferParams::paperSizeName(PapersizePurpose purpose) const
2266 char real_papersize = papersize;
2267 if (real_papersize == PAPER_DEFAULT)
2268 real_papersize = lyxrc.default_papersize;
2270 switch (real_papersize) {
2272 // could be anything, so don't guess
2274 case PAPER_CUSTOM: {
2275 if (purpose == XDVI && !paperwidth.empty() &&
2276 !paperheight.empty()) {
2277 // heightxwidth<unit>
2278 string first = paperwidth;
2279 string second = paperheight;
2280 if (orientation == ORIENTATION_LANDSCAPE)
2283 return first.erase(first.length() - 2)
2289 // dvips and dvipdfm do not know this
2290 if (purpose == DVIPS || purpose == DVIPDFM)
2294 if (purpose == DVIPS || purpose == DVIPDFM)
2298 if (purpose == DVIPS || purpose == DVIPDFM)
2308 if (purpose == DVIPS || purpose == DVIPDFM)
2312 if (purpose == DVIPS || purpose == DVIPDFM)
2316 if (purpose == DVIPS || purpose == DVIPDFM)
2320 if (purpose == DVIPS || purpose == DVIPDFM)
2324 if (purpose == DVIPS || purpose == DVIPDFM)
2328 // dvipdfm does not know this
2329 if (purpose == DVIPDFM)
2333 if (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)
2365 if (purpose == DVIPS || purpose == DVIPDFM)
2369 if (purpose == DVIPS || purpose == DVIPDFM)
2373 if (purpose == DVIPS || purpose == DVIPDFM)
2377 if (purpose == DVIPS || purpose == DVIPDFM)
2381 if (purpose == DVIPS || purpose == DVIPDFM)
2385 if (purpose == DVIPS || purpose == DVIPDFM)
2389 if (purpose == DVIPS || purpose == DVIPDFM)
2393 if (purpose == DVIPS || purpose == DVIPDFM)
2396 case PAPER_USEXECUTIVE:
2397 // dvipdfm does not know this
2398 if (purpose == DVIPDFM)
2403 case PAPER_USLETTER:
2405 if (purpose == XDVI)
2412 string const BufferParams::dvips_options() const
2417 && papersize == PAPER_CUSTOM
2418 && !lyxrc.print_paper_dimension_flag.empty()
2419 && !paperwidth.empty()
2420 && !paperheight.empty()) {
2421 // using a custom papersize
2422 result = lyxrc.print_paper_dimension_flag;
2423 result += ' ' + paperwidth;
2424 result += ',' + paperheight;
2426 string const paper_option = paperSizeName(DVIPS);
2427 if (!paper_option.empty() && (paper_option != "letter" ||
2428 orientation != ORIENTATION_LANDSCAPE)) {
2429 // dvips won't accept -t letter -t landscape.
2430 // In all other cases, include the paper size
2432 result = lyxrc.print_paper_flag;
2433 result += ' ' + paper_option;
2436 if (orientation == ORIENTATION_LANDSCAPE &&
2437 papersize != PAPER_CUSTOM)
2438 result += ' ' + lyxrc.print_landscape_flag;
2443 string const BufferParams::font_encoding() const
2445 return (fontenc == "global") ? lyxrc.fontenc : fontenc;
2449 string BufferParams::babelCall(string const & lang_opts, bool const langoptions) const
2451 if (lang_package != "auto" && lang_package != "babel"
2452 && lang_package != "default" && lang_package != "none")
2453 return lang_package;
2454 if (lyxrc.language_package_selection == LyXRC::LP_CUSTOM)
2455 return lyxrc.language_custom_package;
2456 // suppress the babel call if there is no BabelName defined
2457 // for the document language in the lib/languages file and if no
2458 // other languages are used (lang_opts is then empty)
2459 if (lang_opts.empty())
2461 // either a specific language (AsBabelOptions setting in
2462 // lib/languages) or the prefs require the languages to
2463 // be submitted to babel itself (not the class).
2465 return "\\usepackage[" + lang_opts + "]{babel}";
2466 return "\\usepackage{babel}";
2470 docstring BufferParams::getGraphicsDriver(string const & package) const
2474 if (package == "geometry") {
2475 if (graphics_driver == "dvips"
2476 || graphics_driver == "dvipdfm"
2477 || graphics_driver == "pdftex"
2478 || graphics_driver == "vtex")
2479 result = from_ascii(graphics_driver);
2480 else if (graphics_driver == "dvipdfmx")
2481 result = from_ascii("dvipdfm");
2488 void BufferParams::writeEncodingPreamble(odocstream & os,
2489 LaTeXFeatures & features, TexRow & texrow) const
2491 // XeTeX does not need this
2492 if (features.runparams().flavor == OutputParams::XETEX)
2494 // LuaTeX neither, but with tex fonts, we need to load
2495 // the luainputenc package.
2496 if (features.runparams().flavor == OutputParams::LUATEX) {
2497 if (!useNonTeXFonts) {
2498 os << "\\usepackage[utf8]{luainputenc}\n";
2503 if (inputenc == "auto") {
2504 string const doc_encoding =
2505 language->encoding()->latexName();
2506 Encoding::Package const package =
2507 language->encoding()->package();
2509 // Create a list with all the input encodings used
2511 set<string> encodings =
2512 features.getEncodingSet(doc_encoding);
2514 // If the "japanese" package (i.e. pLaTeX) is used,
2515 // inputenc must be omitted.
2516 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
2517 if (package == Encoding::japanese)
2518 features.require("japanese");
2520 if ((!encodings.empty() || package == Encoding::inputenc)
2521 && !features.isRequired("japanese")) {
2522 os << "\\usepackage[";
2523 set<string>::const_iterator it = encodings.begin();
2524 set<string>::const_iterator const end = encodings.end();
2526 os << from_ascii(*it);
2529 for (; it != end; ++it)
2530 os << ',' << from_ascii(*it);
2531 if (package == Encoding::inputenc) {
2532 if (!encodings.empty())
2534 os << from_ascii(doc_encoding);
2536 os << "]{inputenc}\n";
2539 if (package == Encoding::CJK || features.mustProvide("CJK")) {
2540 if (language->encoding()->name() == "utf8-cjk"
2541 && LaTeXFeatures::isAvailable("CJKutf8"))
2542 os << "\\usepackage{CJKutf8}\n";
2544 os << "\\usepackage{CJK}\n";
2547 } else if (inputenc != "default") {
2548 switch (encoding().package()) {
2549 case Encoding::none:
2550 case Encoding::japanese:
2552 case Encoding::inputenc:
2553 // do not load inputenc if japanese is used
2554 if (features.isRequired("japanese"))
2556 os << "\\usepackage[" << from_ascii(inputenc)
2561 if (encoding().name() == "utf8-cjk"
2562 && LaTeXFeatures::isAvailable("CJKutf8"))
2563 os << "\\usepackage{CJKutf8}\n";
2565 os << "\\usepackage{CJK}\n";
2571 // The encoding "armscii8" (for Armenian) is only available when
2572 // the package "armtex" is loaded.
2573 if (language->encoding()->latexName() == "armscii8"
2574 || inputenc == "armscii8") {
2575 os << "\\usepackage{armtex}\n";
2581 string const BufferParams::parseFontName(string const & name) const
2583 string mangled = name;
2584 size_t const idx = mangled.find('[');
2585 if (idx == string::npos || idx == 0)
2588 return mangled.substr(0, idx - 1);
2592 string const BufferParams::loadFonts(string const & rm,
2593 string const & sf, string const & tt,
2594 bool const & sc, bool const & osf,
2595 int const & sfscale, int const & ttscale,
2596 bool const & use_systemfonts,
2597 LaTeXFeatures & features) const
2599 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
2600 several packages have been replaced by others, that might not
2601 be installed on every system. We have to take care for that
2602 (see psnfss.pdf). We try to support all psnfss fonts as well
2603 as the fonts that have become de facto standard in the LaTeX
2604 world (e.g. Latin Modern). We do not support obsolete fonts
2605 (like PSLatex). In general, it should be possible to mix any
2606 rm font with any sf or tt font, respectively. (JSpitzm)
2608 -- separate math fonts.
2611 if (rm == "default" && sf == "default" && tt == "default")
2617 /* Fontspec (XeTeX, LuaTeX): we provide GUI support for oldstyle
2618 * numbers (Numbers=OldStyle) and sf/tt scaling. The Ligatures=TeX/
2619 * Mapping=tex-text option assures TeX ligatures (such as "--")
2620 * are resolved. Note that tt does not use these ligatures.
2622 * -- add more GUI options?
2623 * -- add more fonts (fonts for other scripts)
2624 * -- if there's a way to find out if a font really supports
2625 * OldStyle, enable/disable the widget accordingly.
2627 if (use_systemfonts) {
2628 // "Mapping=tex-text" and "Ligatures=TeX" are equivalent.
2629 // However, until v.2 (2010/07/11) fontspec only knew
2630 // Mapping=tex-text (for XeTeX only); then "Ligatures=TeX"
2631 // was introduced for both XeTeX and LuaTeX (LuaTeX
2632 // didn't understand "Mapping=tex-text", while XeTeX
2633 // understood both. With most recent versions, both
2634 // variants are understood by both engines. However,
2635 // we want to provide support for at least TeXLive 2009.
2636 string const texmapping =
2637 (features.runparams().flavor == OutputParams::XETEX) ?
2638 "Mapping=tex-text" : "Ligatures=TeX";
2639 if (rm != "default") {
2640 os << "\\setmainfont[" << texmapping;
2642 os << ",Numbers=OldStyle";
2643 os << "]{" << parseFontName(rm) << "}\n";
2645 if (sf != "default") {
2646 string const sans = parseFontName(sf);
2648 os << "\\setsansfont[Scale="
2649 << float(sfscale) / 100
2650 << "," << texmapping << "]{"
2653 os << "\\setsansfont[" << texmapping << "]{"
2656 if (tt != "default") {
2657 string const mono = parseFontName(tt);
2659 os << "\\setmonofont[Scale="
2660 << float(ttscale) / 100
2664 os << "\\setmonofont{"
2671 // Computer Modern (must be explicitly selectable -- there might be classes
2672 // that define a different default font!
2674 os << "\\renewcommand{\\rmdefault}{cmr}\n";
2675 // osf for Computer Modern needs eco.sty
2677 os << "\\usepackage{eco}\n";
2679 // Latin Modern Roman
2680 else if (rm == "lmodern")
2681 os << "\\usepackage{lmodern}\n";
2683 else if (rm == "ae") {
2684 // not needed when using OT1 font encoding.
2685 if (font_encoding() != "default")
2686 os << "\\usepackage{ae,aecompl}\n";
2689 else if (rm == "times") {
2690 // try to load the best available package
2691 if (LaTeXFeatures::isAvailable("mathptmx"))
2692 os << "\\usepackage{mathptmx}\n";
2693 else if (LaTeXFeatures::isAvailable("mathptm"))
2694 os << "\\usepackage{mathptm}\n";
2696 os << "\\usepackage{times}\n";
2699 else if (rm == "palatino") {
2700 // try to load the best available package
2701 if (LaTeXFeatures::isAvailable("mathpazo")) {
2702 os << "\\usepackage";
2708 // "osf" includes "sc"!
2712 os << "{mathpazo}\n";
2714 else if (LaTeXFeatures::isAvailable("mathpple"))
2715 os << "\\usepackage{mathpple}\n";
2717 os << "\\usepackage{palatino}\n";
2720 else if (rm == "utopia") {
2721 // fourier supersedes utopia.sty, but does
2722 // not work with OT1 encoding.
2723 if (LaTeXFeatures::isAvailable("fourier")
2724 && font_encoding() != "default") {
2725 os << "\\usepackage";
2736 os << "{fourier}\n";
2739 os << "\\usepackage{utopia}\n";
2741 // Bera (complete fontset)
2742 else if (rm == "bera" && sf == "default" && tt == "default")
2743 os << "\\usepackage{bera}\n";
2745 else if (rm != "default")
2746 os << "\\usepackage" << "{" << rm << "}\n";
2749 // Helvetica, Bera Sans
2750 if (sf == "helvet" || sf == "berasans") {
2752 os << "\\usepackage[scaled=" << float(sfscale) / 100
2753 << "]{" << sf << "}\n";
2755 os << "\\usepackage{" << sf << "}\n";
2758 else if (sf == "avant")
2759 os << "\\usepackage{" << sf << "}\n";
2760 // Computer Modern, Latin Modern, CM Bright
2761 else if (sf != "default")
2762 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
2764 // monospaced/typewriter
2765 // Courier, LuxiMono
2766 if (tt == "luximono" || tt == "beramono") {
2768 os << "\\usepackage[scaled=" << float(ttscale) / 100
2769 << "]{" << tt << "}\n";
2771 os << "\\usepackage{" << tt << "}\n";
2774 else if (tt == "courier" )
2775 os << "\\usepackage{" << tt << "}\n";
2776 // Computer Modern, Latin Modern, CM Bright
2777 else if (tt != "default")
2778 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
2784 Encoding const & BufferParams::encoding() const
2786 // FIXME: actually, we should check for the flavor
2787 // or runparams.isFullyUnicode() here:
2788 // This check will not work with XeTeX/LuaTeX and tex fonts.
2789 // Thus we have to reset the encoding in Buffer::makeLaTeXFile.
2791 return *(encodings.fromLaTeXName("utf8-plain"));
2792 if (inputenc == "auto" || inputenc == "default")
2793 return *language->encoding();
2794 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
2797 LYXERR0("Unknown inputenc value `" << inputenc
2798 << "'. Using `auto' instead.");
2799 return *language->encoding();
2803 CiteEngine BufferParams::citeEngine() const
2805 // FIXME the class should provide the numerical/
2806 // authoryear choice
2807 if (documentClass().provides("natbib")
2808 && cite_engine_ != ENGINE_NATBIB_NUMERICAL)
2809 return ENGINE_NATBIB_AUTHORYEAR;
2810 return cite_engine_;
2814 void BufferParams::setCiteEngine(CiteEngine cite_engine)
2816 cite_engine_ = cite_engine;