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 graphics_driver = "default";
389 default_output_format = "default";
390 bibtex_command = "default";
391 index_command = "default";
394 listings_params = string();
395 pagestyle = "default";
396 suppress_date = false;
397 // no color is the default (white)
398 backgroundcolor = lyx::rgbFromHexName("#ffffff");
399 isbackgroundcolor = false;
400 // no color is the default (black)
401 fontcolor = lyx::rgbFromHexName("#000000");
403 // light gray is the default font color for greyed-out notes
404 notefontcolor = lyx::rgbFromHexName("#cccccc");
405 boxbgcolor = lyx::rgbFromHexName("#ff0000");
406 compressed = lyxrc.save_compressed;
407 for (int iter = 0; iter < 4; ++iter) {
408 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
409 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
412 indiceslist().addDefault(B_("Index"));
413 html_be_strict = false;
414 html_math_output = MathML;
415 html_math_img_scale = 1.0;
422 docstring BufferParams::B_(string const & l10n) const
424 LASSERT(language, /**/);
425 return getMessages(language->code()).get(l10n);
429 AuthorList & BufferParams::authors()
431 return pimpl_->authorlist;
435 AuthorList const & BufferParams::authors() const
437 return pimpl_->authorlist;
441 BranchList & BufferParams::branchlist()
443 return pimpl_->branchlist;
447 BranchList const & BufferParams::branchlist() const
449 return pimpl_->branchlist;
453 IndicesList & BufferParams::indiceslist()
455 return pimpl_->indiceslist;
459 IndicesList const & BufferParams::indiceslist() const
461 return pimpl_->indiceslist;
465 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
467 LASSERT(index < 4, /**/);
468 return pimpl_->temp_bullets[index];
472 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
474 LASSERT(index < 4, /**/);
475 return pimpl_->temp_bullets[index];
479 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
481 LASSERT(index < 4, /**/);
482 return pimpl_->user_defined_bullets[index];
486 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
488 LASSERT(index < 4, /**/);
489 return pimpl_->user_defined_bullets[index];
493 Spacing & BufferParams::spacing()
495 return pimpl_->spacing;
499 Spacing const & BufferParams::spacing() const
501 return pimpl_->spacing;
505 PDFOptions & BufferParams::pdfoptions()
507 return pimpl_->pdfoptions;
511 PDFOptions const & BufferParams::pdfoptions() const
513 return pimpl_->pdfoptions;
517 HSpace const & BufferParams::getIndentation() const
519 return pimpl_->indentation;
523 void BufferParams::setIndentation(HSpace const & indent)
525 pimpl_->indentation = indent;
529 VSpace const & BufferParams::getDefSkip() const
531 return pimpl_->defskip;
535 void BufferParams::setDefSkip(VSpace const & vs)
537 // DEFSKIP will cause an infinite loop
538 LASSERT(vs.kind() != VSpace::DEFSKIP, return);
539 pimpl_->defskip = vs;
543 string BufferParams::readToken(Lexer & lex, string const & token,
544 FileName const & filepath)
546 if (token == "\\textclass") {
548 string const classname = lex.getString();
549 // if there exists a local layout file, ignore the system one
550 // NOTE: in this case, the textclass (.cls file) is assumed to
553 LayoutFileList & bcl = LayoutFileList::get();
554 if (tcp.empty() && !filepath.empty())
555 tcp = bcl.addLocalLayout(classname, filepath.absFileName());
559 setBaseClass(classname);
560 // We assume that a tex class exists for local or unknown
561 // layouts so this warning, will only be given for system layouts.
562 if (!baseClass()->isTeXClassAvailable()) {
563 docstring const desc =
564 translateIfPossible(from_utf8(baseClass()->description()));
565 docstring const prereqs =
566 from_utf8(baseClass()->prerequisites());
567 docstring const msg =
568 bformat(_("The selected document class\n"
570 "requires external files that are not available.\n"
571 "The document class can still be used, but the\n"
572 "document cannot be compiled until the following\n"
573 "prerequisites are installed:\n"
575 "See section 3.1.2.2 (Class Availability) of the\n"
576 "User's Guide for more information."), desc, prereqs);
577 frontend::Alert::warning(_("Document class not available"),
580 } else if (token == "\\begin_preamble") {
582 } else if (token == "\\begin_local_layout") {
583 readLocalLayout(lex);
584 } else if (token == "\\begin_modules") {
586 } else if (token == "\\begin_removed_modules") {
587 readRemovedModules(lex);
588 } else if (token == "\\begin_includeonly") {
589 readIncludeonly(lex);
590 } else if (token == "\\maintain_unincluded_children") {
591 lex >> maintain_unincluded_children;
592 } else if (token == "\\options") {
594 options = lex.getString();
595 } else if (token == "\\use_default_options") {
596 lex >> use_default_options;
597 } else if (token == "\\master") {
599 master = lex.getString();
600 } else if (token == "\\suppress_date") {
601 lex >> suppress_date;
602 } else if (token == "\\language") {
604 } else if (token == "\\inputencoding") {
606 } else if (token == "\\graphics") {
607 readGraphicsDriver(lex);
608 } else if (token == "\\default_output_format") {
609 lex >> default_output_format;
610 } else if (token == "\\bibtex_command") {
612 bibtex_command = lex.getString();
613 } else if (token == "\\index_command") {
615 index_command = lex.getString();
616 } else if (token == "\\fontencoding") {
618 fontenc = lex.getString();
619 } else if (token == "\\font_roman") {
621 fonts_roman = lex.getString();
622 } else if (token == "\\font_sans") {
624 fonts_sans = lex.getString();
625 } else if (token == "\\font_typewriter") {
627 fonts_typewriter = lex.getString();
628 } else if (token == "\\font_default_family") {
629 lex >> fonts_default_family;
630 } else if (token == "\\use_non_tex_fonts") {
631 lex >> useNonTeXFonts;
632 } else if (token == "\\font_sc") {
633 lex >> fonts_expert_sc;
634 } else if (token == "\\font_osf") {
635 lex >> fonts_old_figures;
636 } else if (token == "\\font_sf_scale") {
637 lex >> fonts_sans_scale;
638 } else if (token == "\\font_tt_scale") {
639 lex >> fonts_typewriter_scale;
640 } else if (token == "\\font_cjk") {
642 } else if (token == "\\paragraph_separation") {
645 paragraph_separation = parseptranslator().find(parsep);
646 } else if (token == "\\paragraph_indentation") {
648 string indentation = lex.getString();
649 pimpl_->indentation = HSpace(indentation);
650 } else if (token == "\\defskip") {
652 string const defskip = lex.getString();
653 pimpl_->defskip = VSpace(defskip);
654 if (pimpl_->defskip.kind() == VSpace::DEFSKIP)
656 pimpl_->defskip = VSpace(VSpace::MEDSKIP);
657 } else if (token == "\\quotes_language") {
660 quotes_language = quoteslangtranslator().find(quotes_lang);
661 } else if (token == "\\papersize") {
664 papersize = papersizetranslator().find(ppsize);
665 } else if (token == "\\use_geometry") {
667 } else if (token == "\\use_amsmath") {
670 use_amsmath = packagetranslator().find(use_ams);
671 } else if (token == "\\use_esint") {
674 use_esint = packagetranslator().find(useesint);
675 } else if (token == "\\use_mhchem") {
678 use_mhchem = packagetranslator().find(usemhchem);
679 } else if (token == "\\use_mathdots") {
682 use_mathdots = packagetranslator().find(usemathdots);
683 } else if (token == "\\cite_engine") {
686 cite_engine_ = citeenginetranslator().find(engine);
687 } else if (token == "\\use_bibtopic") {
689 } else if (token == "\\use_indices") {
691 } else if (token == "\\tracking_changes") {
693 } else if (token == "\\output_changes") {
694 lex >> outputChanges;
695 } else if (token == "\\branch") {
697 docstring branch = lex.getDocString();
698 branchlist().add(branch);
701 string const tok = lex.getString();
702 if (tok == "\\end_branch")
704 Branch * branch_ptr = branchlist().find(branch);
705 if (tok == "\\selected") {
708 branch_ptr->setSelected(lex.getInteger());
710 if (tok == "\\filename_suffix") {
713 branch_ptr->setFileNameSuffix(lex.getInteger());
715 if (tok == "\\color") {
717 string color = lex.getString();
719 branch_ptr->setColor(color);
720 // Update also the Color table:
722 color = lcolor.getX11Name(Color_background);
724 lcolor.setColor(to_utf8(branch), color);
727 } else if (token == "\\index") {
729 docstring index = lex.getDocString();
731 indiceslist().add(index);
734 string const tok = lex.getString();
735 if (tok == "\\end_index")
737 Index * index_ptr = indiceslist().find(index);
738 if (tok == "\\shortcut") {
740 shortcut = lex.getDocString();
742 index_ptr->setShortcut(shortcut);
744 if (tok == "\\color") {
746 string color = lex.getString();
748 index_ptr->setColor(color);
749 // Update also the Color table:
751 color = lcolor.getX11Name(Color_background);
753 if (!shortcut.empty())
754 lcolor.setColor(to_utf8(shortcut), color);
757 } else if (token == "\\author") {
759 istringstream ss(lex.getString());
762 author_map[a.bufferId()] = pimpl_->authorlist.record(a);
763 } else if (token == "\\paperorientation") {
766 orientation = paperorientationtranslator().find(orient);
767 } else if (token == "\\backgroundcolor") {
769 backgroundcolor = lyx::rgbFromHexName(lex.getString());
770 isbackgroundcolor = true;
771 } else if (token == "\\fontcolor") {
773 fontcolor = lyx::rgbFromHexName(lex.getString());
775 } else if (token == "\\notefontcolor") {
777 string color = lex.getString();
778 notefontcolor = lyx::rgbFromHexName(color);
779 } else if (token == "\\boxbgcolor") {
781 string color = lex.getString();
782 boxbgcolor = lyx::rgbFromHexName(color);
783 } else if (token == "\\paperwidth") {
785 } else if (token == "\\paperheight") {
787 } else if (token == "\\leftmargin") {
789 } else if (token == "\\topmargin") {
791 } else if (token == "\\rightmargin") {
793 } else if (token == "\\bottommargin") {
795 } else if (token == "\\headheight") {
797 } else if (token == "\\headsep") {
799 } else if (token == "\\footskip") {
801 } else if (token == "\\columnsep") {
803 } else if (token == "\\paperfontsize") {
805 } else if (token == "\\papercolumns") {
807 } else if (token == "\\listings_params") {
810 listings_params = InsetListingsParams(par).params();
811 } else if (token == "\\papersides") {
814 sides = sidestranslator().find(psides);
815 } else if (token == "\\paperpagestyle") {
817 } else if (token == "\\bullet") {
819 } else if (token == "\\bulletLaTeX") {
820 readBulletsLaTeX(lex);
821 } else if (token == "\\secnumdepth") {
823 } else if (token == "\\tocdepth") {
825 } else if (token == "\\spacing") {
829 if (nspacing == "other") {
832 spacing().set(spacetranslator().find(nspacing), tmp_val);
833 } else if (token == "\\float_placement") {
834 lex >> float_placement;
836 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
837 string toktmp = pdfoptions().readToken(lex, token);
838 if (!toktmp.empty()) {
839 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
843 } else if (token == "\\html_math_output") {
846 html_math_output = static_cast<MathOutput>(temp);
847 } else if (token == "\\html_be_strict") {
848 lex >> html_be_strict;
849 } else if (token == "\\html_math_img_scale") {
850 lex >> html_math_img_scale;
851 } else if (token == "\\html_latex_start") {
853 html_latex_start = lex.getString();
854 } else if (token == "\\html_latex_end") {
856 html_latex_end = lex.getString();
857 } else if (token == "\\output_sync") {
859 } else if (token == "\\output_sync_macro") {
860 lex >> output_sync_macro;
861 } else if (token == "\\use_refstyle") {
864 lyxerr << "BufferParams::readToken(): Unknown token: " <<
873 void BufferParams::writeFile(ostream & os) const
875 // The top of the file is written by the buffer.
876 // Prints out the buffer info into the .lyx file given by file
879 os << "\\textclass " << baseClass()->name() << '\n';
882 if (!preamble.empty()) {
883 // remove '\n' from the end of preamble
884 string const tmppreamble = rtrim(preamble, "\n");
885 os << "\\begin_preamble\n"
887 << "\n\\end_preamble\n";
891 if (!options.empty()) {
892 os << "\\options " << options << '\n';
895 // use the class options defined in the layout?
896 os << "\\use_default_options "
897 << convert<string>(use_default_options) << "\n";
899 // the master document
900 if (!master.empty()) {
901 os << "\\master " << master << '\n';
905 if (!removed_modules_.empty()) {
906 os << "\\begin_removed_modules" << '\n';
907 list<string>::const_iterator it = removed_modules_.begin();
908 list<string>::const_iterator en = removed_modules_.end();
909 for (; it != en; it++)
911 os << "\\end_removed_modules" << '\n';
915 if (!layout_modules_.empty()) {
916 os << "\\begin_modules" << '\n';
917 LayoutModuleList::const_iterator it = layout_modules_.begin();
918 LayoutModuleList::const_iterator en = layout_modules_.end();
919 for (; it != en; it++)
921 os << "\\end_modules" << '\n';
925 if (!included_children_.empty()) {
926 os << "\\begin_includeonly" << '\n';
927 list<string>::const_iterator it = included_children_.begin();
928 list<string>::const_iterator en = included_children_.end();
929 for (; it != en; it++)
931 os << "\\end_includeonly" << '\n';
933 os << "\\maintain_unincluded_children "
934 << convert<string>(maintain_unincluded_children) << '\n';
936 // local layout information
937 if (!local_layout.empty()) {
938 // remove '\n' from the end
939 string const tmplocal = rtrim(local_layout, "\n");
940 os << "\\begin_local_layout\n"
942 << "\n\\end_local_layout\n";
945 // then the text parameters
946 if (language != ignore_language)
947 os << "\\language " << language->lang() << '\n';
948 os << "\\inputencoding " << inputenc
949 << "\n\\fontencoding " << fontenc
950 << "\n\\font_roman " << fonts_roman
951 << "\n\\font_sans " << fonts_sans
952 << "\n\\font_typewriter " << fonts_typewriter
953 << "\n\\font_default_family " << fonts_default_family
954 << "\n\\use_non_tex_fonts " << convert<string>(useNonTeXFonts)
955 << "\n\\font_sc " << convert<string>(fonts_expert_sc)
956 << "\n\\font_osf " << convert<string>(fonts_old_figures)
957 << "\n\\font_sf_scale " << fonts_sans_scale
958 << "\n\\font_tt_scale " << fonts_typewriter_scale
960 if (!fonts_cjk.empty()) {
961 os << "\\font_cjk " << fonts_cjk << '\n';
963 os << "\n\\graphics " << graphics_driver << '\n';
964 os << "\\default_output_format " << default_output_format << '\n';
965 os << "\\output_sync " << output_sync << '\n';
966 if (!output_sync_macro.empty())
967 os << "\\output_sync_macro \"" << output_sync_macro << "\"\n";
968 os << "\\bibtex_command " << bibtex_command << '\n';
969 os << "\\index_command " << index_command << '\n';
971 if (!float_placement.empty()) {
972 os << "\\float_placement " << float_placement << '\n';
974 os << "\\paperfontsize " << fontsize << '\n';
976 spacing().writeFile(os);
977 pdfoptions().writeFile(os);
979 os << "\\papersize " << string_papersize[papersize]
980 << "\n\\use_geometry " << convert<string>(use_geometry)
981 << "\n\\use_amsmath " << use_amsmath
982 << "\n\\use_esint " << use_esint
983 << "\n\\use_mhchem " << use_mhchem
984 << "\n\\use_mathdots " << use_mathdots
985 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
986 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
987 << "\n\\use_indices " << convert<string>(use_indices)
988 << "\n\\paperorientation " << string_orientation[orientation]
989 << "\n\\suppress_date " << convert<string>(suppress_date)
990 << "\n\\use_refstyle " << use_refstyle
992 if (isbackgroundcolor == true)
993 os << "\\backgroundcolor " << lyx::X11hexname(backgroundcolor) << '\n';
994 if (isfontcolor == true)
995 os << "\\fontcolor " << lyx::X11hexname(fontcolor) << '\n';
996 if (notefontcolor != lyx::rgbFromHexName("#cccccc"))
997 os << "\\notefontcolor " << lyx::X11hexname(notefontcolor) << '\n';
998 if (boxbgcolor != lyx::rgbFromHexName("#ff0000"))
999 os << "\\boxbgcolor " << lyx::X11hexname(boxbgcolor) << '\n';
1001 BranchList::const_iterator it = branchlist().begin();
1002 BranchList::const_iterator end = branchlist().end();
1003 for (; it != end; ++it) {
1004 os << "\\branch " << to_utf8(it->branch())
1005 << "\n\\selected " << it->isSelected()
1006 << "\n\\filename_suffix " << it->hasFileNameSuffix()
1007 << "\n\\color " << lyx::X11hexname(it->color())
1012 IndicesList::const_iterator iit = indiceslist().begin();
1013 IndicesList::const_iterator iend = indiceslist().end();
1014 for (; iit != iend; ++iit) {
1015 os << "\\index " << to_utf8(iit->index())
1016 << "\n\\shortcut " << to_utf8(iit->shortcut())
1017 << "\n\\color " << lyx::X11hexname(iit->color())
1022 if (!paperwidth.empty())
1023 os << "\\paperwidth "
1024 << VSpace(paperwidth).asLyXCommand() << '\n';
1025 if (!paperheight.empty())
1026 os << "\\paperheight "
1027 << VSpace(paperheight).asLyXCommand() << '\n';
1028 if (!leftmargin.empty())
1029 os << "\\leftmargin "
1030 << VSpace(leftmargin).asLyXCommand() << '\n';
1031 if (!topmargin.empty())
1032 os << "\\topmargin "
1033 << VSpace(topmargin).asLyXCommand() << '\n';
1034 if (!rightmargin.empty())
1035 os << "\\rightmargin "
1036 << VSpace(rightmargin).asLyXCommand() << '\n';
1037 if (!bottommargin.empty())
1038 os << "\\bottommargin "
1039 << VSpace(bottommargin).asLyXCommand() << '\n';
1040 if (!headheight.empty())
1041 os << "\\headheight "
1042 << VSpace(headheight).asLyXCommand() << '\n';
1043 if (!headsep.empty())
1045 << VSpace(headsep).asLyXCommand() << '\n';
1046 if (!footskip.empty())
1048 << VSpace(footskip).asLyXCommand() << '\n';
1049 if (!columnsep.empty())
1050 os << "\\columnsep "
1051 << VSpace(columnsep).asLyXCommand() << '\n';
1052 os << "\\secnumdepth " << secnumdepth
1053 << "\n\\tocdepth " << tocdepth
1054 << "\n\\paragraph_separation "
1055 << string_paragraph_separation[paragraph_separation];
1056 if (!paragraph_separation)
1057 os << "\n\\paragraph_indentation " << getIndentation().asLyXCommand();
1059 os << "\n\\defskip " << getDefSkip().asLyXCommand();
1060 os << "\n\\quotes_language "
1061 << string_quotes_language[quotes_language]
1062 << "\n\\papercolumns " << columns
1063 << "\n\\papersides " << sides
1064 << "\n\\paperpagestyle " << pagestyle << '\n';
1065 if (!listings_params.empty())
1066 os << "\\listings_params \"" <<
1067 InsetListingsParams(listings_params).encodedString() << "\"\n";
1068 for (int i = 0; i < 4; ++i) {
1069 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1070 if (user_defined_bullet(i).getFont() != -1) {
1071 os << "\\bullet " << i << " "
1072 << user_defined_bullet(i).getFont() << " "
1073 << user_defined_bullet(i).getCharacter() << " "
1074 << user_defined_bullet(i).getSize() << "\n";
1078 os << "\\bulletLaTeX " << i << " \""
1079 << lyx::to_ascii(user_defined_bullet(i).getText())
1085 os << "\\tracking_changes " << convert<string>(trackChanges) << '\n'
1086 << "\\output_changes " << convert<string>(outputChanges) << '\n'
1087 << "\\html_math_output " << html_math_output << '\n'
1088 << "\\html_be_strict " << convert<string>(html_be_strict) << '\n';
1090 if (html_math_img_scale != 1.0)
1091 os << "\\html_math_img_scale " << convert<string>(html_math_img_scale) << '\n';
1092 if (!html_latex_start.empty())
1093 os << "\\html_latex_start " << html_latex_start << '\n';
1094 if (!html_latex_end.empty())
1095 os << "\\html_latex_end " << html_latex_end << '\n';
1097 os << pimpl_->authorlist;
1101 void BufferParams::validate(LaTeXFeatures & features) const
1103 features.require(documentClass().requires());
1105 if (outputChanges) {
1106 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
1107 bool xcolorulem = LaTeXFeatures::isAvailable("ulem") &&
1108 LaTeXFeatures::isAvailable("xcolor");
1110 switch (features.runparams().flavor) {
1111 case OutputParams::LATEX:
1113 features.require("ct-dvipost");
1114 features.require("dvipost");
1115 } else if (xcolorulem) {
1116 features.require("ct-xcolor-ulem");
1117 features.require("ulem");
1118 features.require("xcolor");
1120 features.require("ct-none");
1123 case OutputParams::LUATEX:
1124 case OutputParams::PDFLATEX:
1125 case OutputParams::XETEX:
1127 features.require("ct-xcolor-ulem");
1128 features.require("ulem");
1129 features.require("xcolor");
1130 // improves color handling in PDF output
1131 features.require("pdfcolmk");
1133 features.require("ct-none");
1141 // Floats with 'Here definitely' as default setting.
1142 if (float_placement.find('H') != string::npos)
1143 features.require("float");
1145 // AMS Style is at document level
1146 if (use_amsmath == package_on
1147 || documentClass().provides("amsmath"))
1148 features.require("amsmath");
1149 if (use_esint == package_on)
1150 features.require("esint");
1151 if (use_mhchem == package_on)
1152 features.require("mhchem");
1153 if (use_mathdots == package_on)
1154 features.require("mathdots");
1156 // Document-level line spacing
1157 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
1158 features.require("setspace");
1160 // the bullet shapes are buffer level not paragraph level
1161 // so they are tested here
1162 for (int i = 0; i < 4; ++i) {
1163 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
1165 int const font = user_defined_bullet(i).getFont();
1167 int const c = user_defined_bullet(i).getCharacter();
1173 features.require("latexsym");
1175 } else if (font == 1) {
1176 features.require("amssymb");
1177 } else if (font >= 2 && font <= 5) {
1178 features.require("pifont");
1182 if (pdfoptions().use_hyperref) {
1183 features.require("hyperref");
1184 // due to interferences with babel and hyperref, the color package has to
1185 // be loaded after hyperref when hyperref is used with the colorlinks
1186 // option, see http://www.lyx.org/trac/ticket/5291
1187 if (pdfoptions().colorlinks)
1188 features.require("color");
1191 if (features.runparams().flavor == OutputParams::XETEX
1193 features.require("polyglossia");
1195 if (language->lang() == "vietnamese")
1196 features.require("vietnamese");
1197 else if (language->lang() == "japanese")
1198 features.require("japanese");
1202 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
1203 TexRow & texrow, FileName const & filepath) const
1205 // http://www.tug.org/texmf-dist/doc/latex/base/fixltx2e.pdf
1206 // !! To use the Fix-cm package, load it before \documentclass, and use the command
1207 // \RequirePackage to do so, rather than the normal \usepackage
1208 // Do not to load any other package before the document class, unless you
1209 // have a thorough understanding of the LATEX internals and know exactly what you
1211 if (features.mustProvide("fix-cm")) {
1212 os << "\\RequirePackage{fix-cm}\n";
1216 os << "\\documentclass";
1218 DocumentClass const & tclass = documentClass();
1220 ostringstream clsoptions; // the document class options.
1222 if (tokenPos(tclass.opt_fontsize(),
1223 '|', fontsize) >= 0) {
1224 // only write if existing in list (and not default)
1225 clsoptions << fontsize << "pt,";
1228 // all paper sizes except of A4, A5, B5 and the US sizes need the
1230 bool nonstandard_papersize = papersize != PAPER_DEFAULT
1231 && papersize != PAPER_USLETTER
1232 && papersize != PAPER_USLEGAL
1233 && papersize != PAPER_USEXECUTIVE
1234 && papersize != PAPER_A4
1235 && papersize != PAPER_A5
1236 && papersize != PAPER_B5;
1238 if (!use_geometry) {
1239 switch (papersize) {
1241 clsoptions << "a4paper,";
1243 case PAPER_USLETTER:
1244 clsoptions << "letterpaper,";
1247 clsoptions << "a5paper,";
1250 clsoptions << "b5paper,";
1252 case PAPER_USEXECUTIVE:
1253 clsoptions << "executivepaper,";
1256 clsoptions << "legalpaper,";
1290 if (sides != tclass.sides()) {
1293 clsoptions << "oneside,";
1296 clsoptions << "twoside,";
1302 if (columns != tclass.columns()) {
1304 clsoptions << "twocolumn,";
1306 clsoptions << "onecolumn,";
1310 && orientation == ORIENTATION_LANDSCAPE)
1311 clsoptions << "landscape,";
1313 // language should be a parameter to \documentclass
1314 if (language->babel() == "hebrew"
1315 && default_language->babel() != "hebrew")
1316 // This seems necessary
1317 features.useLanguage(default_language);
1319 ostringstream language_options;
1320 bool const use_babel = features.useBabel() && !tclass.provides("babel");
1321 bool const use_polyglossia = features.usePolyglossia();
1322 bool const global = lyxrc.language_global_options;
1323 if (use_babel || (use_polyglossia && global)) {
1324 language_options << features.getLanguages();
1325 if (!language->babel().empty()) {
1326 if (!language_options.str().empty())
1327 language_options << ',';
1328 language_options << language->babel();
1330 if (global && !features.needBabelLangOptions())
1331 clsoptions << language_options.str() << ',';
1334 // the predefined options from the layout
1335 if (use_default_options && !tclass.options().empty())
1336 clsoptions << tclass.options() << ',';
1338 // the user-defined options
1339 if (!options.empty()) {
1340 clsoptions << options << ',';
1343 string strOptions(clsoptions.str());
1344 if (!strOptions.empty()) {
1345 strOptions = rtrim(strOptions, ",");
1347 os << '[' << from_utf8(strOptions) << ']';
1350 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1352 // end of \documentclass defs
1355 // if we use fontspec, we have to load the AMS packages here
1356 string const ams = features.loadAMSPackages();
1357 if (useNonTeXFonts && !ams.empty()) {
1358 os << from_ascii(ams);
1359 nlines = int(count(ams.begin(), ams.end(), '\n'));
1360 texrow.newlines(nlines);
1363 if (useNonTeXFonts) {
1364 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);
1374 if (!fonts.empty()) {
1375 os << from_ascii(fonts);
1377 int(count(fonts.begin(), fonts.end(), '\n'));
1378 texrow.newlines(nlines);
1380 if (fonts_default_family != "default")
1381 os << "\\renewcommand{\\familydefault}{\\"
1382 << from_ascii(fonts_default_family) << "}\n";
1384 // set font encoding
1385 // for arabic_arabi and farsi we also need to load the LAE and
1387 // XeTeX and LuaTeX (with OS fonts) work without fontenc
1388 if (font_encoding() != "default" && language->lang() != "japanese"
1389 && !useNonTeXFonts && !tclass.provides("fontenc")) {
1390 size_t fars = language_options.str().find("farsi");
1391 size_t arab = language_options.str().find("arabic");
1392 if (language->lang() == "arabic_arabi"
1393 || language->lang() == "farsi" || fars != string::npos
1394 || arab != string::npos) {
1395 os << "\\usepackage[" << from_ascii(font_encoding())
1396 << ",LFE,LAE]{fontenc}\n";
1399 os << "\\usepackage[" << from_ascii(font_encoding())
1405 // handle inputenc etc.
1406 writeEncodingPreamble(os, features, texrow);
1409 if (!features.runparams().includeall && !included_children_.empty()) {
1410 os << "\\includeonly{";
1411 list<string>::const_iterator it = included_children_.begin();
1412 list<string>::const_iterator en = included_children_.end();
1414 for (; it != en; ++it) {
1415 string incfile = *it;
1416 FileName inc = makeAbsPath(incfile, filepath.absFileName());
1417 string mangled = DocFileName(changeExtension(inc.absFileName(), ".tex")).
1419 if (!features.runparams().nice)
1421 // \includeonly doesn't want an extension
1422 incfile = changeExtension(incfile, string());
1423 incfile = support::latex_path(incfile);
1424 if (!incfile.empty()) {
1427 os << from_utf8(incfile);
1434 if (!listings_params.empty() || features.isRequired("listings")) {
1435 os << "\\usepackage{listings}\n";
1438 if (!listings_params.empty()) {
1440 // do not test validity because listings_params is
1441 // supposed to be valid
1443 InsetListingsParams(listings_params).separatedParams(true);
1444 // we can't support all packages, but we should load the color package
1445 if (par.find("\\color", 0) != string::npos)
1446 features.require("color");
1447 os << from_utf8(par);
1448 // count the number of newlines
1449 for (size_t i = 0; i < par.size(); ++i)
1455 if (!tclass.provides("geometry")
1456 && (use_geometry || nonstandard_papersize)) {
1457 odocstringstream ods;
1458 if (!getGraphicsDriver("geometry").empty())
1459 ods << getGraphicsDriver("geometry");
1460 if (orientation == ORIENTATION_LANDSCAPE)
1461 ods << ",landscape";
1462 switch (papersize) {
1464 if (!paperwidth.empty())
1465 ods << ",paperwidth="
1466 << from_ascii(paperwidth);
1467 if (!paperheight.empty())
1468 ods << ",paperheight="
1469 << from_ascii(paperheight);
1471 case PAPER_USLETTER:
1472 ods << ",letterpaper";
1475 ods << ",legalpaper";
1477 case PAPER_USEXECUTIVE:
1478 ods << ",executivepaper";
1565 // default papersize ie PAPER_DEFAULT
1566 switch (lyxrc.default_papersize) {
1567 case PAPER_DEFAULT: // keep compiler happy
1568 case PAPER_USLETTER:
1569 ods << ",letterpaper";
1572 ods << ",legalpaper";
1574 case PAPER_USEXECUTIVE:
1575 ods << ",executivepaper";
1617 docstring const g_options = trim(ods.str(), ",");
1618 os << "\\usepackage";
1619 if (!g_options.empty())
1620 os << '[' << g_options << ']';
1621 os << "{geometry}\n";
1623 // output this only if use_geometry is true
1625 os << "\\geometry{verbose";
1626 if (!topmargin.empty())
1627 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1628 if (!bottommargin.empty())
1629 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1630 if (!leftmargin.empty())
1631 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1632 if (!rightmargin.empty())
1633 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1634 if (!headheight.empty())
1635 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1636 if (!headsep.empty())
1637 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1638 if (!footskip.empty())
1639 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1640 if (!columnsep.empty())
1641 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1645 } else if (orientation == ORIENTATION_LANDSCAPE
1646 || papersize != PAPER_DEFAULT) {
1647 features.require("papersize");
1650 if (tokenPos(tclass.opt_pagestyle(),
1651 '|', pagestyle) >= 0) {
1652 if (pagestyle == "fancy") {
1653 os << "\\usepackage{fancyhdr}\n";
1656 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1660 // only output when the background color is not default
1661 if (isbackgroundcolor == true) {
1662 // only require color here, the background color will be defined
1663 // in LaTeXFeatures.cpp to avoid interferences with the LaTeX
1665 features.require("color");
1666 features.require("pagecolor");
1669 // only output when the font color is not default
1670 if (isfontcolor == true) {
1671 // only require color here, the font color will be defined
1672 // in LaTeXFeatures.cpp to avoid interferences with the LaTeX
1674 features.require("color");
1675 features.require("fontcolor");
1678 // Only if class has a ToC hierarchy
1679 if (tclass.hasTocLevels()) {
1680 if (secnumdepth != tclass.secnumdepth()) {
1681 os << "\\setcounter{secnumdepth}{"
1686 if (tocdepth != tclass.tocdepth()) {
1687 os << "\\setcounter{tocdepth}{"
1694 if (paragraph_separation) {
1695 // when skip separation
1696 switch (getDefSkip().kind()) {
1697 case VSpace::SMALLSKIP:
1698 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1700 case VSpace::MEDSKIP:
1701 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1703 case VSpace::BIGSKIP:
1704 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1706 case VSpace::LENGTH:
1707 os << "\\setlength{\\parskip}{"
1708 << from_utf8(getDefSkip().length().asLatexString())
1711 default: // should never happen // Then delete it.
1712 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1716 os << "\\setlength{\\parindent}{0pt}\n";
1719 // when separation by indentation
1720 // only output something when a width is given
1721 if (getIndentation().asLyXCommand() != "default") {
1722 os << "\\setlength{\\parindent}{"
1723 << from_utf8(getIndentation().asLatexCommand())
1729 // Now insert the LyX specific LaTeX commands...
1730 docstring lyxpreamble;
1733 if (!output_sync_macro.empty())
1734 lyxpreamble += from_utf8(output_sync_macro) +"\n";
1735 else if (features.runparams().flavor == OutputParams::LATEX)
1736 lyxpreamble += "\\usepackage[active]{srcltx}\n";
1737 else if (features.runparams().flavor == OutputParams::PDFLATEX)
1738 lyxpreamble += "\\synctex=-1\n";
1741 // due to interferences with babel and hyperref, the color package has to
1742 // be loaded (when it is not already loaded) before babel when hyperref
1743 // is used with the colorlinks option, see
1744 // http://www.lyx.org/trac/ticket/5291
1745 // we decided therefore to load color always before babel, see
1746 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg144349.html
1747 lyxpreamble += from_ascii(features.getColorOptions());
1749 // If we use hyperref, jurabib, japanese, or vietnamese, we have to call babel before them.
1751 && (features.isRequired("jurabib")
1752 || features.isRequired("hyperref")
1753 || features.isRequired("vietnamese")
1754 || features.isRequired("japanese"))) {
1756 lyxpreamble += from_utf8(features.getBabelPresettings());
1757 lyxpreamble += from_utf8(babelCall(language_options.str(),
1758 features.needBabelLangOptions())) + '\n';
1759 lyxpreamble += from_utf8(features.getBabelPostsettings());
1762 // The optional packages;
1763 lyxpreamble += from_ascii(features.getPackages());
1765 // Additional Indices
1766 if (features.isRequired("splitidx")) {
1767 IndicesList::const_iterator iit = indiceslist().begin();
1768 IndicesList::const_iterator iend = indiceslist().end();
1769 for (; iit != iend; ++iit) {
1770 lyxpreamble += "\\newindex[";
1771 lyxpreamble += iit->index();
1772 lyxpreamble += "]{";
1773 lyxpreamble += iit->shortcut();
1774 lyxpreamble += "}\n";
1779 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1782 // * Hyperref manual: "Make sure it comes last of your loaded
1783 // packages, to give it a fighting chance of not being over-written,
1784 // since its job is to redefine many LaTeX commands."
1785 // * Email from Heiko Oberdiek: "It is usually better to load babel
1786 // before hyperref. Then hyperref has a chance to detect babel.
1787 // * Has to be loaded before the "LyX specific LaTeX commands" to
1788 // avoid errors with algorithm floats.
1789 // use hyperref explicitly if it is required
1790 if (features.isRequired("hyperref")) {
1791 // pass what we have to stream here, since we need
1792 // to access the stream itself in PDFOptions.
1796 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1798 OutputParams tmp_params = features.runparams();
1799 lines += pdfoptions().writeLaTeX(tmp_params, os,
1800 documentClass().provides("hyperref"));
1801 texrow.newlines(lines);
1802 // set back for the rest
1803 lyxpreamble.clear();
1804 // correctly break URLs with hyperref and dvi output
1805 if (features.runparams().flavor == OutputParams::LATEX
1806 && features.isAvailable("breakurl"))
1807 lyxpreamble += "\\usepackage{breakurl}\n";
1808 } else if (features.isRequired("nameref"))
1809 // hyperref loads this automatically
1810 lyxpreamble += "\\usepackage{nameref}\n";
1812 // Will be surrounded by \makeatletter and \makeatother when not empty
1813 docstring atlyxpreamble;
1815 // Some macros LyX will need
1816 docstring tmppreamble(features.getMacros());
1818 if (!tmppreamble.empty())
1819 atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1820 "LyX specific LaTeX commands.\n"
1821 + tmppreamble + '\n';
1823 // the text class specific preamble
1824 tmppreamble = features.getTClassPreamble();
1825 if (!tmppreamble.empty())
1826 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1827 "Textclass specific LaTeX commands.\n"
1828 + tmppreamble + '\n';
1830 // suppress date if selected
1831 // use \@ifundefined because we cannot be sure that every document class
1832 // has a \date command
1834 atlyxpreamble += "\\@ifundefined{date}{}{\\date{}}\n";
1836 /* the user-defined preamble */
1837 if (!containsOnly(preamble, " \n\t"))
1839 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1840 "User specified LaTeX commands.\n"
1841 + from_utf8(preamble) + '\n';
1843 // subfig loads internally the LaTeX package "caption". As
1844 // caption is a very popular package, users will load it in
1845 // the preamble. Therefore we must load subfig behind the
1846 // user-defined preamble and check if the caption package was
1847 // loaded or not. For the case that caption is loaded before
1848 // subfig, there is the subfig option "caption=false". This
1849 // option also works when a koma-script class is used and
1850 // koma's own caption commands are used instead of caption. We
1851 // use \PassOptionsToPackage here because the user could have
1852 // already loaded subfig in the preamble.
1853 if (features.isRequired("subfig")) {
1854 atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n"
1855 " \\PassOptionsToPackage{caption=false}{subfig}}\n"
1856 "\\usepackage{subfig}\n";
1859 // Itemize bullet settings need to be last in case the user
1860 // defines their own bullets that use a package included
1861 // in the user-defined preamble -- ARRae
1862 // Actually it has to be done much later than that
1863 // since some packages like frenchb make modifications
1864 // at \begin{document} time -- JMarc
1865 docstring bullets_def;
1866 for (int i = 0; i < 4; ++i) {
1867 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1868 if (bullets_def.empty())
1869 bullets_def += "\\AtBeginDocument{\n";
1870 bullets_def += " \\def\\labelitemi";
1872 // `i' is one less than the item to modify
1879 bullets_def += "ii";
1885 bullets_def += '{' +
1886 user_defined_bullet(i).getText()
1891 if (!bullets_def.empty())
1892 atlyxpreamble += bullets_def + "}\n\n";
1894 if (!atlyxpreamble.empty())
1895 lyxpreamble += "\n\\makeatletter\n"
1896 + atlyxpreamble + "\\makeatother\n\n";
1898 // We try to load babel late, in case it interferes with other packages.
1899 // Jurabib and Hyperref have to be called after babel, though.
1900 if (use_babel && !features.isRequired("jurabib")
1901 && !features.isRequired("hyperref")
1902 && !features.isRequired("vietnamese")
1903 && !features.isRequired("japanese")) {
1905 lyxpreamble += from_utf8(features.getBabelPresettings());
1906 lyxpreamble += from_utf8(babelCall(language_options.str(),
1907 features.needBabelLangOptions())) + '\n';
1908 lyxpreamble += from_utf8(features.getBabelPostsettings());
1911 // xunicode needs to be loaded at least after amsmath, amssymb,
1912 // esint and the other packages that provide special glyphs
1913 if (features.runparams().flavor == OutputParams::XETEX)
1914 lyxpreamble += "\\usepackage{xunicode}\n";
1916 // Polyglossia must be loaded last
1917 if (use_polyglossia) {
1919 lyxpreamble += "\\usepackage{polyglossia}\n";
1920 // set the main language
1921 lyxpreamble += "\\setdefaultlanguage";
1922 if (!language->polyglossiaOpts().empty())
1923 lyxpreamble += "[" + from_ascii(language->polyglossiaOpts()) + "]";
1924 lyxpreamble += "{" + from_ascii(language->polyglossia()) + "}\n";
1925 // now setup the other languages
1926 std::map<std::string, std::string> const polylangs =
1927 features.getPolyglossiaLanguages();
1928 for (std::map<std::string, std::string>::const_iterator mit = polylangs.begin();
1929 mit != polylangs.end() ; ++mit) {
1930 lyxpreamble += "\\setotherlanguage";
1931 if (!mit->second.empty())
1932 lyxpreamble += "[" + from_ascii(mit->second) + "]";
1933 lyxpreamble += "{" + from_ascii(mit->first) + "}\n";
1937 docstring const i18npreamble =
1938 features.getTClassI18nPreamble(use_babel, use_polyglossia);
1939 if (!i18npreamble.empty())
1940 lyxpreamble += i18npreamble + '\n';
1942 nlines = int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1943 texrow.newlines(nlines);
1951 void BufferParams::useClassDefaults()
1953 DocumentClass const & tclass = documentClass();
1955 sides = tclass.sides();
1956 columns = tclass.columns();
1957 pagestyle = tclass.pagestyle();
1958 use_default_options = true;
1959 // Only if class has a ToC hierarchy
1960 if (tclass.hasTocLevels()) {
1961 secnumdepth = tclass.secnumdepth();
1962 tocdepth = tclass.tocdepth();
1967 bool BufferParams::hasClassDefaults() const
1969 DocumentClass const & tclass = documentClass();
1971 return sides == tclass.sides()
1972 && columns == tclass.columns()
1973 && pagestyle == tclass.pagestyle()
1974 && use_default_options
1975 && secnumdepth == tclass.secnumdepth()
1976 && tocdepth == tclass.tocdepth();
1980 DocumentClass const & BufferParams::documentClass() const
1986 DocumentClass const * BufferParams::documentClassPtr() const
1992 void BufferParams::setDocumentClass(DocumentClass const * const tc)
1994 // evil, but this function is evil
1995 doc_class_ = const_cast<DocumentClass *>(tc);
1999 bool BufferParams::setBaseClass(string const & classname)
2001 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
2002 LayoutFileList & bcl = LayoutFileList::get();
2003 if (!bcl.haveClass(classname)) {
2005 bformat(_("The layout file:\n"
2007 "could not be found. A default textclass with default\n"
2008 "layouts will be used. LyX will not be able to produce\n"
2010 from_utf8(classname));
2011 frontend::Alert::error(_("Document class not found"), s);
2012 bcl.addEmptyClass(classname);
2015 bool const success = bcl[classname].load();
2018 bformat(_("Due to some error in it, the layout file:\n"
2020 "could not be loaded. A default textclass with default\n"
2021 "layouts will be used. LyX will not be able to produce\n"
2023 from_utf8(classname));
2024 frontend::Alert::error(_("Could not load class"), s);
2025 bcl.addEmptyClass(classname);
2028 pimpl_->baseClass_ = classname;
2029 layout_modules_.adaptToBaseClass(baseClass(), removed_modules_);
2034 LayoutFile const * BufferParams::baseClass() const
2036 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
2037 return &(LayoutFileList::get()[pimpl_->baseClass_]);
2043 LayoutFileIndex const & BufferParams::baseClassID() const
2045 return pimpl_->baseClass_;
2049 void BufferParams::makeDocumentClass()
2054 doc_class_ = &(DocumentClassBundle::get().makeDocumentClass(*baseClass(), layout_modules_));
2056 if (!local_layout.empty()) {
2057 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
2058 docstring const msg = _("Error reading internal layout information");
2059 frontend::Alert::warning(_("Read Error"), msg);
2065 bool BufferParams::moduleCanBeAdded(string const & modName) const
2067 return layout_modules_.moduleCanBeAdded(modName, baseClass());
2071 bool BufferParams::addLayoutModule(string const & modName)
2073 LayoutModuleList::const_iterator it = layout_modules_.begin();
2074 LayoutModuleList::const_iterator end = layout_modules_.end();
2075 for (; it != end; it++)
2078 layout_modules_.push_back(modName);
2083 Font const BufferParams::getFont() const
2085 FontInfo f = documentClass().defaultfont();
2086 if (fonts_default_family == "rmdefault")
2087 f.setFamily(ROMAN_FAMILY);
2088 else if (fonts_default_family == "sfdefault")
2089 f.setFamily(SANS_FAMILY);
2090 else if (fonts_default_family == "ttdefault")
2091 f.setFamily(TYPEWRITER_FAMILY);
2092 return Font(f, language);
2096 void BufferParams::readPreamble(Lexer & lex)
2098 if (lex.getString() != "\\begin_preamble")
2099 lyxerr << "Error (BufferParams::readPreamble):"
2100 "consistency check failed." << endl;
2102 preamble = lex.getLongString("\\end_preamble");
2106 void BufferParams::readLocalLayout(Lexer & lex)
2108 if (lex.getString() != "\\begin_local_layout")
2109 lyxerr << "Error (BufferParams::readLocalLayout):"
2110 "consistency check failed." << endl;
2112 local_layout = lex.getLongString("\\end_local_layout");
2116 void BufferParams::readLanguage(Lexer & lex)
2118 if (!lex.next()) return;
2120 string const tmptok = lex.getString();
2122 // check if tmptok is part of tex_babel in tex-defs.h
2123 language = languages.getLanguage(tmptok);
2125 // Language tmptok was not found
2126 language = default_language;
2127 lyxerr << "Warning: Setting language `"
2128 << tmptok << "' to `" << language->lang()
2134 void BufferParams::readGraphicsDriver(Lexer & lex)
2139 string const tmptok = lex.getString();
2140 // check if tmptok is part of tex_graphics in tex_defs.h
2143 string const test = tex_graphics[n++];
2145 if (test == tmptok) {
2146 graphics_driver = tmptok;
2151 "Warning: graphics driver `$$Token' not recognized!\n"
2152 " Setting graphics driver to `default'.\n");
2153 graphics_driver = "default";
2160 void BufferParams::readBullets(Lexer & lex)
2165 int const index = lex.getInteger();
2167 int temp_int = lex.getInteger();
2168 user_defined_bullet(index).setFont(temp_int);
2169 temp_bullet(index).setFont(temp_int);
2171 user_defined_bullet(index).setCharacter(temp_int);
2172 temp_bullet(index).setCharacter(temp_int);
2174 user_defined_bullet(index).setSize(temp_int);
2175 temp_bullet(index).setSize(temp_int);
2179 void BufferParams::readBulletsLaTeX(Lexer & lex)
2181 // The bullet class should be able to read this.
2184 int const index = lex.getInteger();
2186 docstring const temp_str = lex.getDocString();
2188 user_defined_bullet(index).setText(temp_str);
2189 temp_bullet(index).setText(temp_str);
2193 void BufferParams::readModules(Lexer & lex)
2195 if (!lex.eatLine()) {
2196 lyxerr << "Error (BufferParams::readModules):"
2197 "Unexpected end of input." << endl;
2201 string mod = lex.getString();
2202 if (mod == "\\end_modules")
2204 addLayoutModule(mod);
2210 void BufferParams::readRemovedModules(Lexer & lex)
2212 if (!lex.eatLine()) {
2213 lyxerr << "Error (BufferParams::readRemovedModules):"
2214 "Unexpected end of input." << endl;
2218 string mod = lex.getString();
2219 if (mod == "\\end_removed_modules")
2221 removed_modules_.push_back(mod);
2224 // now we want to remove any removed modules that were previously
2225 // added. normally, that will be because default modules were added in
2226 // setBaseClass(), which gets called when \textclass is read at the
2227 // start of the read.
2228 list<string>::const_iterator rit = removed_modules_.begin();
2229 list<string>::const_iterator const ren = removed_modules_.end();
2230 for (; rit != ren; rit++) {
2231 LayoutModuleList::iterator const mit = layout_modules_.begin();
2232 LayoutModuleList::iterator const men = layout_modules_.end();
2233 LayoutModuleList::iterator found = find(mit, men, *rit);
2236 layout_modules_.erase(found);
2241 void BufferParams::readIncludeonly(Lexer & lex)
2243 if (!lex.eatLine()) {
2244 lyxerr << "Error (BufferParams::readIncludeonly):"
2245 "Unexpected end of input." << endl;
2249 string child = lex.getString();
2250 if (child == "\\end_includeonly")
2252 included_children_.push_back(child);
2258 string BufferParams::paperSizeName(PapersizePurpose purpose) const
2260 char real_papersize = papersize;
2261 if (real_papersize == PAPER_DEFAULT)
2262 real_papersize = lyxrc.default_papersize;
2264 switch (real_papersize) {
2266 // could be anything, so don't guess
2268 case PAPER_CUSTOM: {
2269 if (purpose == XDVI && !paperwidth.empty() &&
2270 !paperheight.empty()) {
2271 // heightxwidth<unit>
2272 string first = paperwidth;
2273 string second = paperheight;
2274 if (orientation == ORIENTATION_LANDSCAPE)
2277 return first.erase(first.length() - 2)
2283 // dvips and dvipdfm do not know this
2284 if (purpose == DVIPS || purpose == DVIPDFM)
2288 if (purpose == DVIPS || purpose == DVIPDFM)
2292 if (purpose == DVIPS || purpose == DVIPDFM)
2302 if (purpose == DVIPS || purpose == DVIPDFM)
2306 if (purpose == DVIPS || purpose == DVIPDFM)
2310 if (purpose == DVIPS || purpose == DVIPDFM)
2314 if (purpose == DVIPS || purpose == DVIPDFM)
2318 if (purpose == DVIPS || purpose == DVIPDFM)
2322 // dvipdfm does not know this
2323 if (purpose == DVIPDFM)
2327 if (purpose == DVIPDFM)
2331 if (purpose == DVIPS || purpose == DVIPDFM)
2335 if (purpose == DVIPS || purpose == DVIPDFM)
2339 if (purpose == DVIPS || purpose == DVIPDFM)
2343 if (purpose == DVIPS || purpose == DVIPDFM)
2347 if (purpose == DVIPS || purpose == DVIPDFM)
2351 if (purpose == DVIPS || purpose == DVIPDFM)
2355 if (purpose == DVIPS || purpose == DVIPDFM)
2359 if (purpose == DVIPS || purpose == DVIPDFM)
2363 if (purpose == DVIPS || purpose == DVIPDFM)
2367 if (purpose == DVIPS || purpose == DVIPDFM)
2371 if (purpose == DVIPS || purpose == DVIPDFM)
2375 if (purpose == DVIPS || purpose == DVIPDFM)
2379 if (purpose == DVIPS || purpose == DVIPDFM)
2383 if (purpose == DVIPS || purpose == DVIPDFM)
2387 if (purpose == DVIPS || purpose == DVIPDFM)
2390 case PAPER_USEXECUTIVE:
2391 // dvipdfm does not know this
2392 if (purpose == DVIPDFM)
2397 case PAPER_USLETTER:
2399 if (purpose == XDVI)
2406 string const BufferParams::dvips_options() const
2411 && papersize == PAPER_CUSTOM
2412 && !lyxrc.print_paper_dimension_flag.empty()
2413 && !paperwidth.empty()
2414 && !paperheight.empty()) {
2415 // using a custom papersize
2416 result = lyxrc.print_paper_dimension_flag;
2417 result += ' ' + paperwidth;
2418 result += ',' + paperheight;
2420 string const paper_option = paperSizeName(DVIPS);
2421 if (!paper_option.empty() && (paper_option != "letter" ||
2422 orientation != ORIENTATION_LANDSCAPE)) {
2423 // dvips won't accept -t letter -t landscape.
2424 // In all other cases, include the paper size
2426 result = lyxrc.print_paper_flag;
2427 result += ' ' + paper_option;
2430 if (orientation == ORIENTATION_LANDSCAPE &&
2431 papersize != PAPER_CUSTOM)
2432 result += ' ' + lyxrc.print_landscape_flag;
2437 string const BufferParams::font_encoding() const
2439 return (fontenc == "global") ? lyxrc.fontenc : fontenc;
2443 string BufferParams::babelCall(string const & lang_opts, bool const langoptions) const
2445 if (lyxrc.language_package_selection == LyXRC::LP_CUSTOM)
2446 return lyxrc.language_custom_package;
2447 // suppress the babel call if there is no BabelName defined
2448 // for the document language in the lib/languages file and if no
2449 // other languages are used (lang_opts is then empty)
2450 if (lang_opts.empty())
2452 // either a specific language (AsBabelOptions setting in
2453 // lib/languages) or the prefs require the languages to
2454 // be submitted to babel itself (not the class).
2456 return "\\usepackage[" + lang_opts + "]{babel}";
2457 return "\\usepackage{babel}";
2461 docstring BufferParams::getGraphicsDriver(string const & package) const
2465 if (package == "geometry") {
2466 if (graphics_driver == "dvips"
2467 || graphics_driver == "dvipdfm"
2468 || graphics_driver == "pdftex"
2469 || graphics_driver == "vtex")
2470 result = from_ascii(graphics_driver);
2471 else if (graphics_driver == "dvipdfmx")
2472 result = from_ascii("dvipdfm");
2479 void BufferParams::writeEncodingPreamble(odocstream & os,
2480 LaTeXFeatures & features, TexRow & texrow) const
2482 // XeTeX does not need this
2483 if (features.runparams().flavor == OutputParams::XETEX)
2485 // LuaTeX neither, but with tex fonts, we need to load
2486 // the luainputenc package.
2487 if (features.runparams().flavor == OutputParams::LUATEX) {
2488 if (!useNonTeXFonts) {
2489 os << "\\usepackage[utf8]{luainputenc}\n";
2494 if (inputenc == "auto") {
2495 string const doc_encoding =
2496 language->encoding()->latexName();
2497 Encoding::Package const package =
2498 language->encoding()->package();
2500 // Create a list with all the input encodings used
2502 set<string> encodings =
2503 features.getEncodingSet(doc_encoding);
2505 // If the "japanese" package (i.e. pLaTeX) is used,
2506 // inputenc must be omitted.
2507 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
2508 if (package == Encoding::japanese)
2509 features.require("japanese");
2511 if ((!encodings.empty() || package == Encoding::inputenc)
2512 && !features.isRequired("japanese")) {
2513 os << "\\usepackage[";
2514 set<string>::const_iterator it = encodings.begin();
2515 set<string>::const_iterator const end = encodings.end();
2517 os << from_ascii(*it);
2520 for (; it != end; ++it)
2521 os << ',' << from_ascii(*it);
2522 if (package == Encoding::inputenc) {
2523 if (!encodings.empty())
2525 os << from_ascii(doc_encoding);
2527 os << "]{inputenc}\n";
2530 if (package == Encoding::CJK || features.mustProvide("CJK")) {
2531 if (language->encoding()->name() == "utf8-cjk"
2532 && LaTeXFeatures::isAvailable("CJKutf8"))
2533 os << "\\usepackage{CJKutf8}\n";
2535 os << "\\usepackage{CJK}\n";
2538 } else if (inputenc != "default") {
2539 switch (encoding().package()) {
2540 case Encoding::none:
2541 case Encoding::japanese:
2543 case Encoding::inputenc:
2544 // do not load inputenc if japanese is used
2545 if (features.isRequired("japanese"))
2547 os << "\\usepackage[" << from_ascii(inputenc)
2552 if (encoding().name() == "utf8-cjk"
2553 && LaTeXFeatures::isAvailable("CJKutf8"))
2554 os << "\\usepackage{CJKutf8}\n";
2556 os << "\\usepackage{CJK}\n";
2562 // The encoding "armscii8" (for Armenian) is only available when
2563 // the package "armtex" is loaded.
2564 if (language->encoding()->latexName() == "armscii8"
2565 || inputenc == "armscii8") {
2566 os << "\\usepackage{armtex}\n";
2572 string const BufferParams::parseFontName(string const & name) const
2574 string mangled = name;
2575 size_t const idx = mangled.find('[');
2576 if (idx == string::npos || idx == 0)
2579 return mangled.substr(0, idx - 1);
2583 string const BufferParams::loadFonts(string const & rm,
2584 string const & sf, string const & tt,
2585 bool const & sc, bool const & osf,
2586 int const & sfscale, int const & ttscale,
2587 bool const & use_systemfonts,
2588 LaTeXFeatures & features) const
2590 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
2591 several packages have been replaced by others, that might not
2592 be installed on every system. We have to take care for that
2593 (see psnfss.pdf). We try to support all psnfss fonts as well
2594 as the fonts that have become de facto standard in the LaTeX
2595 world (e.g. Latin Modern). We do not support obsolete fonts
2596 (like PSLatex). In general, it should be possible to mix any
2597 rm font with any sf or tt font, respectively. (JSpitzm)
2599 -- separate math fonts.
2602 if (rm == "default" && sf == "default" && tt == "default")
2608 /* Fontspec (XeTeX, LuaTeX): we provide GUI support for oldstyle
2609 * numbers (Numbers=OldStyle) and sf/tt scaling. The Ligatures=TeX/
2610 * Mapping=tex-text option assures TeX ligatures (such as "--")
2611 * are resolved. Note that tt does not use these ligatures.
2613 * -- add more GUI options?
2614 * -- add more fonts (fonts for other scripts)
2615 * -- if there's a way to find out if a font really supports
2616 * OldStyle, enable/disable the widget accordingly.
2618 if (use_systemfonts) {
2619 // "Mapping=tex-text" and "Ligatures=TeX" are equivalent.
2620 // However, until v.2 (2010/07/11) fontspec only knew
2621 // Mapping=tex-text (for XeTeX only); then "Ligatures=TeX"
2622 // was introduced for both XeTeX and LuaTeX (LuaTeX
2623 // didn't understand "Mapping=tex-text", while XeTeX
2624 // understood both. With most recent versions, both
2625 // variants are understood by both engines. However,
2626 // we want to provide support for at least TeXLive 2009.
2627 string const texmapping =
2628 (features.runparams().flavor == OutputParams::XETEX) ?
2629 "Mapping=tex-text" : "Ligatures=TeX";
2630 if (rm != "default") {
2631 os << "\\setmainfont[" << texmapping;
2633 os << ",Numbers=OldStyle";
2634 os << "]{" << parseFontName(rm) << "}\n";
2636 if (sf != "default") {
2637 string const sans = parseFontName(sf);
2639 os << "\\setsansfont[Scale="
2640 << float(sfscale) / 100
2641 << "," << texmapping << "]{"
2644 os << "\\setsansfont[" << texmapping << "]{"
2647 if (tt != "default") {
2648 string const mono = parseFontName(tt);
2650 os << "\\setmonofont[Scale="
2651 << float(ttscale) / 100
2655 os << "\\setmonofont{"
2662 // Computer Modern (must be explicitly selectable -- there might be classes
2663 // that define a different default font!
2665 os << "\\renewcommand{\\rmdefault}{cmr}\n";
2666 // osf for Computer Modern needs eco.sty
2668 os << "\\usepackage{eco}\n";
2670 // Latin Modern Roman
2671 else if (rm == "lmodern")
2672 os << "\\usepackage{lmodern}\n";
2674 else if (rm == "ae") {
2675 // not needed when using OT1 font encoding.
2676 if (font_encoding() != "default")
2677 os << "\\usepackage{ae,aecompl}\n";
2680 else if (rm == "times") {
2681 // try to load the best available package
2682 if (LaTeXFeatures::isAvailable("mathptmx"))
2683 os << "\\usepackage{mathptmx}\n";
2684 else if (LaTeXFeatures::isAvailable("mathptm"))
2685 os << "\\usepackage{mathptm}\n";
2687 os << "\\usepackage{times}\n";
2690 else if (rm == "palatino") {
2691 // try to load the best available package
2692 if (LaTeXFeatures::isAvailable("mathpazo")) {
2693 os << "\\usepackage";
2699 // "osf" includes "sc"!
2703 os << "{mathpazo}\n";
2705 else if (LaTeXFeatures::isAvailable("mathpple"))
2706 os << "\\usepackage{mathpple}\n";
2708 os << "\\usepackage{palatino}\n";
2711 else if (rm == "utopia") {
2712 // fourier supersedes utopia.sty, but does
2713 // not work with OT1 encoding.
2714 if (LaTeXFeatures::isAvailable("fourier")
2715 && font_encoding() != "default") {
2716 os << "\\usepackage";
2727 os << "{fourier}\n";
2730 os << "\\usepackage{utopia}\n";
2732 // Bera (complete fontset)
2733 else if (rm == "bera" && sf == "default" && tt == "default")
2734 os << "\\usepackage{bera}\n";
2736 else if (rm != "default")
2737 os << "\\usepackage" << "{" << rm << "}\n";
2740 // Helvetica, Bera Sans
2741 if (sf == "helvet" || sf == "berasans") {
2743 os << "\\usepackage[scaled=" << float(sfscale) / 100
2744 << "]{" << sf << "}\n";
2746 os << "\\usepackage{" << sf << "}\n";
2749 else if (sf == "avant")
2750 os << "\\usepackage{" << sf << "}\n";
2751 // Computer Modern, Latin Modern, CM Bright
2752 else if (sf != "default")
2753 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
2755 // monospaced/typewriter
2756 // Courier, LuxiMono
2757 if (tt == "luximono" || tt == "beramono") {
2759 os << "\\usepackage[scaled=" << float(ttscale) / 100
2760 << "]{" << tt << "}\n";
2762 os << "\\usepackage{" << tt << "}\n";
2765 else if (tt == "courier" )
2766 os << "\\usepackage{" << tt << "}\n";
2767 // Computer Modern, Latin Modern, CM Bright
2768 else if (tt != "default")
2769 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
2775 Encoding const & BufferParams::encoding() const
2777 // FIXME: actually, we should check for the flavor
2778 // or runparams.isFullyUnicode() here:
2779 // This check will not work with XeTeX/LuaTeX and tex fonts.
2780 // Thus we have to reset the encoding in Buffer::makeLaTeXFile.
2782 return *(encodings.fromLaTeXName("utf8-plain"));
2783 if (inputenc == "auto" || inputenc == "default")
2784 return *language->encoding();
2785 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
2788 LYXERR0("Unknown inputenc value `" << inputenc
2789 << "'. Using `auto' instead.");
2790 return *language->encoding();
2794 CiteEngine BufferParams::citeEngine() const
2796 // FIXME the class should provide the numerical/
2797 // authoryear choice
2798 if (documentClass().provides("natbib")
2799 && cite_engine_ != ENGINE_NATBIB_NUMERICAL)
2800 return ENGINE_NATBIB_AUTHORYEAR;
2801 return cite_engine_;
2805 void BufferParams::setCiteEngine(CiteEngine cite_engine)
2807 cite_engine_ = cite_engine;