Another minor change, but this should almost get us to the point that we
[lyx.git] / src / BufferParams.cpp
blobf369c8d6d9cbdf03d67c3cf520ec2c45edc3a5ce
1 /**
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
9 * \author John Levon
10 * \author André Pönitz
11 * \author Martin Vermeer
13 * Full author contact details are available in file CREDITS.
16 #include <config.h>
18 #include "BufferParams.h"
20 #include "Author.h"
21 #include "LayoutFile.h"
22 #include "BranchList.h"
23 #include "buffer_funcs.h"
24 #include "Bullet.h"
25 #include "Color.h"
26 #include "ColorSet.h"
27 #include "Encoding.h"
28 #include "HSpace.h"
29 #include "IndicesList.h"
30 #include "Language.h"
31 #include "LaTeXFeatures.h"
32 #include "ModuleList.h"
33 #include "Font.h"
34 #include "Lexer.h"
35 #include "LyXRC.h"
36 #include "OutputParams.h"
37 #include "Spacing.h"
38 #include "TexRow.h"
39 #include "VSpace.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"
56 #include <algorithm>
57 #include <sstream>
59 using namespace std;
60 using namespace lyx::support;
63 static char const * const string_paragraph_separation[] = {
64 "indent", "skip", ""
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 "a3paper", "a4paper", "a5paper", "b3paper", "b4paper", "b5paper", ""
79 static char const * const string_orientation[] = {
80 "portrait", "landscape", ""
84 static char const * const string_footnotekinds[] = {
85 "footnote", "margin", "fig", "tab", "alg", "wide-fig", "wide-tab", ""
89 static char const * const tex_graphics[] = {
90 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
91 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
92 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
93 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
94 "xetex", "none", ""
99 namespace lyx {
101 // Local translators
102 namespace {
104 // Paragraph separation
105 typedef Translator<string, BufferParams::ParagraphSeparation> ParSepTranslator;
108 ParSepTranslator const init_parseptranslator()
110 ParSepTranslator translator
111 (string_paragraph_separation[0], BufferParams::ParagraphIndentSeparation);
112 translator.addPair(string_paragraph_separation[1], BufferParams::ParagraphSkipSeparation);
113 return translator;
117 ParSepTranslator const & parseptranslator()
119 static ParSepTranslator translator = init_parseptranslator();
120 return translator;
124 // Quotes language
125 typedef Translator<string, InsetQuotes::QuoteLanguage> QuotesLangTranslator;
128 QuotesLangTranslator const init_quoteslangtranslator()
130 QuotesLangTranslator translator
131 (string_quotes_language[0], InsetQuotes::EnglishQuotes);
132 translator.addPair(string_quotes_language[1], InsetQuotes::SwedishQuotes);
133 translator.addPair(string_quotes_language[2], InsetQuotes::GermanQuotes);
134 translator.addPair(string_quotes_language[3], InsetQuotes::PolishQuotes);
135 translator.addPair(string_quotes_language[4], InsetQuotes::FrenchQuotes);
136 translator.addPair(string_quotes_language[5], InsetQuotes::DanishQuotes);
137 return translator;
141 QuotesLangTranslator const & quoteslangtranslator()
143 static QuotesLangTranslator translator = init_quoteslangtranslator();
144 return translator;
148 // Paper size
149 typedef Translator<string, PAPER_SIZE> PaperSizeTranslator;
152 static PaperSizeTranslator initPaperSizeTranslator()
154 PaperSizeTranslator translator(string_papersize[0], PAPER_DEFAULT);
155 translator.addPair(string_papersize[1], PAPER_CUSTOM);
156 translator.addPair(string_papersize[2], PAPER_USLETTER);
157 translator.addPair(string_papersize[3], PAPER_USLEGAL);
158 translator.addPair(string_papersize[4], PAPER_USEXECUTIVE);
159 translator.addPair(string_papersize[5], PAPER_A3);
160 translator.addPair(string_papersize[6], PAPER_A4);
161 translator.addPair(string_papersize[7], PAPER_A5);
162 translator.addPair(string_papersize[8], PAPER_B3);
163 translator.addPair(string_papersize[9], PAPER_B4);
164 translator.addPair(string_papersize[10], PAPER_B5);
165 return translator;
169 PaperSizeTranslator const & papersizetranslator()
171 static PaperSizeTranslator translator = initPaperSizeTranslator();
172 return translator;
176 // Paper orientation
177 typedef Translator<string, PAPER_ORIENTATION> PaperOrientationTranslator;
180 PaperOrientationTranslator const init_paperorientationtranslator()
182 PaperOrientationTranslator translator(string_orientation[0], ORIENTATION_PORTRAIT);
183 translator.addPair(string_orientation[1], ORIENTATION_LANDSCAPE);
184 return translator;
188 PaperOrientationTranslator const & paperorientationtranslator()
190 static PaperOrientationTranslator translator = init_paperorientationtranslator();
191 return translator;
195 // Page sides
196 typedef Translator<int, PageSides> SidesTranslator;
199 SidesTranslator const init_sidestranslator()
201 SidesTranslator translator(1, OneSide);
202 translator.addPair(2, TwoSides);
203 return translator;
207 SidesTranslator const & sidestranslator()
209 static SidesTranslator translator = init_sidestranslator();
210 return translator;
214 // LaTeX packages
215 typedef Translator<int, BufferParams::Package> PackageTranslator;
218 PackageTranslator const init_packagetranslator()
220 PackageTranslator translator(0, BufferParams::package_off);
221 translator.addPair(1, BufferParams::package_auto);
222 translator.addPair(2, BufferParams::package_on);
223 return translator;
227 PackageTranslator const & packagetranslator()
229 static PackageTranslator translator = init_packagetranslator();
230 return translator;
234 // Cite engine
235 typedef Translator<string, CiteEngine> CiteEngineTranslator;
238 CiteEngineTranslator const init_citeenginetranslator()
240 CiteEngineTranslator translator("basic", ENGINE_BASIC);
241 translator.addPair("natbib_numerical", ENGINE_NATBIB_NUMERICAL);
242 translator.addPair("natbib_authoryear", ENGINE_NATBIB_AUTHORYEAR);
243 translator.addPair("jurabib", ENGINE_JURABIB);
244 return translator;
248 CiteEngineTranslator const & citeenginetranslator()
250 static CiteEngineTranslator translator = init_citeenginetranslator();
251 return translator;
255 // Spacing
256 typedef Translator<string, Spacing::Space> SpaceTranslator;
259 SpaceTranslator const init_spacetranslator()
261 SpaceTranslator translator("default", Spacing::Default);
262 translator.addPair("single", Spacing::Single);
263 translator.addPair("onehalf", Spacing::Onehalf);
264 translator.addPair("double", Spacing::Double);
265 translator.addPair("other", Spacing::Other);
266 return translator;
270 SpaceTranslator const & spacetranslator()
272 static SpaceTranslator translator = init_spacetranslator();
273 return translator;
276 } // anon namespace
279 class BufferParams::Impl
281 public:
282 Impl();
284 AuthorList authorlist;
285 BranchList branchlist;
286 Bullet temp_bullets[4];
287 Bullet user_defined_bullets[4];
288 IndicesList indiceslist;
289 Spacing spacing;
290 /** This is the amount of space used for paragraph_separation "skip",
291 * and for detached paragraphs in "indented" documents.
293 HSpace indentation;
294 VSpace defskip;
295 PDFOptions pdfoptions;
296 LayoutFileIndex baseClass_;
300 BufferParams::Impl::Impl()
301 : defskip(VSpace::MEDSKIP), baseClass_(string(""))
303 // set initial author
304 // FIXME UNICODE
305 authorlist.record(Author(from_utf8(lyxrc.user_name), from_utf8(lyxrc.user_email)));
309 BufferParams::Impl *
310 BufferParams::MemoryTraits::clone(BufferParams::Impl const * ptr)
312 LASSERT(ptr, /**/);
314 return new BufferParams::Impl(*ptr);
318 void BufferParams::MemoryTraits::destroy(BufferParams::Impl * ptr)
320 delete ptr;
324 BufferParams::BufferParams()
325 : pimpl_(new Impl)
327 setBaseClass(defaultBaseclass());
328 makeDocumentClass();
329 paragraph_separation = ParagraphIndentSeparation;
330 quotes_language = InsetQuotes::EnglishQuotes;
331 fontsize = "default";
333 /* PaperLayout */
334 papersize = PAPER_DEFAULT;
335 orientation = ORIENTATION_PORTRAIT;
336 use_geometry = false;
337 use_amsmath = package_auto;
338 use_esint = package_auto;
339 cite_engine_ = ENGINE_BASIC;
340 use_bibtopic = false;
341 use_indices = false;
342 trackChanges = false;
343 outputChanges = false;
344 use_default_options = true;
345 secnumdepth = 3;
346 tocdepth = 3;
347 language = default_language;
348 fontsRoman = "default";
349 fontsSans = "default";
350 fontsTypewriter = "default";
351 fontsDefaultFamily = "default";
352 useXetex = false;
353 fontsSC = false;
354 fontsOSF = false;
355 fontsSansScale = 100;
356 fontsTypewriterScale = 100;
357 inputenc = "auto";
358 graphicsDriver = "default";
359 defaultOutputFormat = "default";
360 bibtex_command = "default";
361 index_command = "default";
362 sides = OneSide;
363 columns = 1;
364 listings_params = string();
365 pagestyle = "default";
366 suppress_date = false;
367 // white is equal to no background color
368 backgroundcolor = lyx::rgbFromHexName("#ffffff");
369 compressed = false;
370 for (int iter = 0; iter < 4; ++iter) {
371 user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
372 temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];
374 // default index
375 indiceslist().addDefault(B_("Index"));
379 docstring BufferParams::B_(string const & l10n) const
381 LASSERT(language, /**/);
382 return getMessages(language->code()).get(l10n);
386 AuthorList & BufferParams::authors()
388 return pimpl_->authorlist;
392 AuthorList const & BufferParams::authors() const
394 return pimpl_->authorlist;
398 BranchList & BufferParams::branchlist()
400 return pimpl_->branchlist;
404 BranchList const & BufferParams::branchlist() const
406 return pimpl_->branchlist;
410 IndicesList & BufferParams::indiceslist()
412 return pimpl_->indiceslist;
416 IndicesList const & BufferParams::indiceslist() const
418 return pimpl_->indiceslist;
422 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
424 LASSERT(index < 4, /**/);
425 return pimpl_->temp_bullets[index];
429 Bullet const & BufferParams::temp_bullet(lyx::size_type const index) const
431 LASSERT(index < 4, /**/);
432 return pimpl_->temp_bullets[index];
436 Bullet & BufferParams::user_defined_bullet(lyx::size_type const index)
438 LASSERT(index < 4, /**/);
439 return pimpl_->user_defined_bullets[index];
443 Bullet const & BufferParams::user_defined_bullet(lyx::size_type const index) const
445 LASSERT(index < 4, /**/);
446 return pimpl_->user_defined_bullets[index];
450 Spacing & BufferParams::spacing()
452 return pimpl_->spacing;
456 Spacing const & BufferParams::spacing() const
458 return pimpl_->spacing;
462 PDFOptions & BufferParams::pdfoptions()
464 return pimpl_->pdfoptions;
468 PDFOptions const & BufferParams::pdfoptions() const
470 return pimpl_->pdfoptions;
474 HSpace const & BufferParams::getIndentation() const
476 return pimpl_->indentation;
480 void BufferParams::setIndentation(HSpace const & indent)
482 pimpl_->indentation = indent;
486 VSpace const & BufferParams::getDefSkip() const
488 return pimpl_->defskip;
492 void BufferParams::setDefSkip(VSpace const & vs)
494 pimpl_->defskip = vs;
498 string BufferParams::readToken(Lexer & lex, string const & token,
499 FileName const & filepath)
501 if (token == "\\textclass") {
502 lex.next();
503 string const classname = lex.getString();
504 // if there exists a local layout file, ignore the system one
505 // NOTE: in this case, the textclass (.cls file) is assumed to be available.
506 string tcp;
507 LayoutFileList & bcl = LayoutFileList::get();
508 if (tcp.empty() && !filepath.empty())
509 tcp = bcl.addLocalLayout(classname, filepath.absFilename());
510 if (!tcp.empty())
511 setBaseClass(tcp);
512 else
513 setBaseClass(classname);
514 // We assume that a tex class exists for local or unknown layouts so this warning
515 // will only be given for system layouts.
516 if (!baseClass()->isTeXClassAvailable()) {
517 docstring const msg =
518 bformat(_("The layout file requested by this document,\n"
519 "%1$s.layout,\n"
520 "is not usable. This is probably because a LaTeX\n"
521 "class or style file required by it is not\n"
522 "available. See the Customization documentation\n"
523 "for more information.\n"), from_utf8(classname));
524 frontend::Alert::warning(_("Document class not available"),
525 msg + _("LyX will not be able to produce output."));
527 } else if (token == "\\begin_preamble") {
528 readPreamble(lex);
529 } else if (token == "\\begin_local_layout") {
530 readLocalLayout(lex);
531 } else if (token == "\\begin_modules") {
532 readModules(lex);
533 } else if (token == "\\begin_removed_modules") {
534 readRemovedModules(lex);
535 } else if (token == "\\options") {
536 lex.eatLine();
537 options = lex.getString();
538 } else if (token == "\\use_default_options") {
539 lex >> use_default_options;
540 } else if (token == "\\master") {
541 lex.eatLine();
542 master = lex.getString();
543 } else if (token == "\\suppress_date") {
544 lex >> suppress_date;
545 } else if (token == "\\language") {
546 readLanguage(lex);
547 } else if (token == "\\inputencoding") {
548 lex >> inputenc;
549 } else if (token == "\\graphics") {
550 readGraphicsDriver(lex);
551 } else if (token == "\\default_output_format") {
552 lex >> defaultOutputFormat;
553 } else if (token == "\\bibtex_command") {
554 lex.eatLine();
555 bibtex_command = lex.getString();
556 } else if (token == "\\index_command") {
557 lex.eatLine();
558 index_command = lex.getString();
559 } else if (token == "\\font_roman") {
560 lex.eatLine();
561 fontsRoman = lex.getString();
562 } else if (token == "\\font_sans") {
563 lex.eatLine();
564 fontsSans = lex.getString();
565 } else if (token == "\\font_typewriter") {
566 lex.eatLine();
567 fontsTypewriter = lex.getString();
568 } else if (token == "\\font_default_family") {
569 lex >> fontsDefaultFamily;
570 } else if (token == "\\use_xetex") {
571 lex >> useXetex;
572 } else if (token == "\\font_sc") {
573 lex >> fontsSC;
574 } else if (token == "\\font_osf") {
575 lex >> fontsOSF;
576 } else if (token == "\\font_sf_scale") {
577 lex >> fontsSansScale;
578 } else if (token == "\\font_tt_scale") {
579 lex >> fontsTypewriterScale;
580 } else if (token == "\\font_cjk") {
581 lex >> fontsCJK;
582 } else if (token == "\\paragraph_separation") {
583 string parsep;
584 lex >> parsep;
585 paragraph_separation = parseptranslator().find(parsep);
586 } else if (token == "\\paragraph_indentation") {
587 lex.next();
588 string indentation = lex.getString();
589 pimpl_->indentation = HSpace(indentation);
590 } else if (token == "\\defskip") {
591 lex.next();
592 string defskip = lex.getString();
593 if (defskip == "defskip")
594 // this is invalid
595 defskip = "medskip";
596 pimpl_->defskip = VSpace(defskip);
597 } else if (token == "\\quotes_language") {
598 string quotes_lang;
599 lex >> quotes_lang;
600 quotes_language = quoteslangtranslator().find(quotes_lang);
601 } else if (token == "\\papersize") {
602 string ppsize;
603 lex >> ppsize;
604 papersize = papersizetranslator().find(ppsize);
605 } else if (token == "\\use_geometry") {
606 lex >> use_geometry;
607 } else if (token == "\\use_amsmath") {
608 int use_ams;
609 lex >> use_ams;
610 use_amsmath = packagetranslator().find(use_ams);
611 } else if (token == "\\use_esint") {
612 int useesint;
613 lex >> useesint;
614 use_esint = packagetranslator().find(useesint);
615 } else if (token == "\\cite_engine") {
616 string engine;
617 lex >> engine;
618 cite_engine_ = citeenginetranslator().find(engine);
619 } else if (token == "\\use_bibtopic") {
620 lex >> use_bibtopic;
621 } else if (token == "\\use_indices") {
622 lex >> use_indices;
623 } else if (token == "\\tracking_changes") {
624 lex >> trackChanges;
625 } else if (token == "\\output_changes") {
626 lex >> outputChanges;
627 } else if (token == "\\branch") {
628 lex.eatLine();
629 docstring branch = lex.getDocString();
630 branchlist().add(branch);
631 while (true) {
632 lex.next();
633 string const tok = lex.getString();
634 if (tok == "\\end_branch")
635 break;
636 Branch * branch_ptr = branchlist().find(branch);
637 if (tok == "\\selected") {
638 lex.next();
639 if (branch_ptr)
640 branch_ptr->setSelected(lex.getInteger());
642 if (tok == "\\filename_suffix") {
643 lex.next();
644 if (branch_ptr)
645 branch_ptr->setFilenameSuffix(lex.getInteger());
647 if (tok == "\\color") {
648 lex.eatLine();
649 string color = lex.getString();
650 if (branch_ptr)
651 branch_ptr->setColor(color);
652 // Update also the Color table:
653 if (color == "none")
654 color = lcolor.getX11Name(Color_background);
655 // FIXME UNICODE
656 lcolor.setColor(to_utf8(branch), color);
659 } else if (token == "\\index") {
660 lex.eatLine();
661 docstring index = lex.getDocString();
662 docstring shortcut;
663 indiceslist().add(index);
664 while (true) {
665 lex.next();
666 string const tok = lex.getString();
667 if (tok == "\\end_index")
668 break;
669 Index * index_ptr = indiceslist().find(index);
670 if (tok == "\\shortcut") {
671 lex.next();
672 shortcut = lex.getDocString();
673 if (index_ptr)
674 index_ptr->setShortcut(shortcut);
676 if (tok == "\\color") {
677 lex.eatLine();
678 string color = lex.getString();
679 if (index_ptr)
680 index_ptr->setColor(color);
681 // Update also the Color table:
682 if (color == "none")
683 color = lcolor.getX11Name(Color_background);
684 // FIXME UNICODE
685 if (!shortcut.empty())
686 lcolor.setColor(to_utf8(shortcut), color);
689 } else if (token == "\\author") {
690 lex.eatLine();
691 istringstream ss(lex.getString());
692 Author a;
693 ss >> a;
694 author_map[a.buffer_id()] = pimpl_->authorlist.record(a);
695 } else if (token == "\\paperorientation") {
696 string orient;
697 lex >> orient;
698 orientation = paperorientationtranslator().find(orient);
699 } else if (token == "\\backgroundcolor") {
700 lex.eatLine();
701 backgroundcolor = lyx::rgbFromHexName(lex.getString());
702 } else if (token == "\\paperwidth") {
703 lex >> paperwidth;
704 } else if (token == "\\paperheight") {
705 lex >> paperheight;
706 } else if (token == "\\leftmargin") {
707 lex >> leftmargin;
708 } else if (token == "\\topmargin") {
709 lex >> topmargin;
710 } else if (token == "\\rightmargin") {
711 lex >> rightmargin;
712 } else if (token == "\\bottommargin") {
713 lex >> bottommargin;
714 } else if (token == "\\headheight") {
715 lex >> headheight;
716 } else if (token == "\\headsep") {
717 lex >> headsep;
718 } else if (token == "\\footskip") {
719 lex >> footskip;
720 } else if (token == "\\columnsep") {
721 lex >> columnsep;
722 } else if (token == "\\paperfontsize") {
723 lex >> fontsize;
724 } else if (token == "\\papercolumns") {
725 lex >> columns;
726 } else if (token == "\\listings_params") {
727 string par;
728 lex >> par;
729 listings_params = InsetListingsParams(par).params();
730 } else if (token == "\\papersides") {
731 int psides;
732 lex >> psides;
733 sides = sidestranslator().find(psides);
734 } else if (token == "\\paperpagestyle") {
735 lex >> pagestyle;
736 } else if (token == "\\bullet") {
737 readBullets(lex);
738 } else if (token == "\\bulletLaTeX") {
739 readBulletsLaTeX(lex);
740 } else if (token == "\\secnumdepth") {
741 lex >> secnumdepth;
742 } else if (token == "\\tocdepth") {
743 lex >> tocdepth;
744 } else if (token == "\\spacing") {
745 string nspacing;
746 lex >> nspacing;
747 string tmp_val;
748 if (nspacing == "other") {
749 lex >> tmp_val;
751 spacing().set(spacetranslator().find(nspacing), tmp_val);
752 } else if (token == "\\float_placement") {
753 lex >> float_placement;
755 } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") {
756 string toktmp = pdfoptions().readToken(lex, token);
757 if (!toktmp.empty()) {
758 lyxerr << "PDFOptions::readToken(): Unknown token: " <<
759 toktmp << endl;
760 return toktmp;
762 } else {
763 lyxerr << "BufferParams::readToken(): Unknown token: " <<
764 token << endl;
765 return token;
768 return string();
772 void BufferParams::writeFile(ostream & os) const
774 // The top of the file is written by the buffer.
775 // Prints out the buffer info into the .lyx file given by file
777 // the textclass
778 os << "\\textclass " << baseClass()->name() << '\n';
780 // then the preamble
781 if (!preamble.empty()) {
782 // remove '\n' from the end of preamble
783 string const tmppreamble = rtrim(preamble, "\n");
784 os << "\\begin_preamble\n"
785 << tmppreamble
786 << "\n\\end_preamble\n";
789 // the options
790 if (!options.empty()) {
791 os << "\\options " << options << '\n';
794 // use the class options defined in the layout?
795 os << "\\use_default_options "
796 << convert<string>(use_default_options) << "\n";
798 // the master document
799 if (!master.empty()) {
800 os << "\\master " << master << '\n';
803 // removed modules
804 if (!removedModules_.empty()) {
805 os << "\\begin_removed_modules" << '\n';
806 list<string>::const_iterator it = removedModules_.begin();
807 list<string>::const_iterator en = removedModules_.end();
808 for (; it != en; it++)
809 os << *it << '\n';
810 os << "\\end_removed_modules" << '\n';
813 // the modules
814 if (!layoutModules_.empty()) {
815 os << "\\begin_modules" << '\n';
816 LayoutModuleList::const_iterator it = layoutModules_.begin();
817 LayoutModuleList::const_iterator en = layoutModules_.end();
818 for (; it != en; it++)
819 os << *it << '\n';
820 os << "\\end_modules" << '\n';
823 // local layout information
824 if (!local_layout.empty()) {
825 // remove '\n' from the end
826 string const tmplocal = rtrim(local_layout, "\n");
827 os << "\\begin_local_layout\n"
828 << tmplocal
829 << "\n\\end_local_layout\n";
832 // then the text parameters
833 if (language != ignore_language)
834 os << "\\language " << language->lang() << '\n';
835 os << "\\inputencoding " << inputenc
836 << "\n\\font_roman " << fontsRoman
837 << "\n\\font_sans " << fontsSans
838 << "\n\\font_typewriter " << fontsTypewriter
839 << "\n\\font_default_family " << fontsDefaultFamily
840 << "\n\\use_xetex " << convert<string>(useXetex)
841 << "\n\\font_sc " << convert<string>(fontsSC)
842 << "\n\\font_osf " << convert<string>(fontsOSF)
843 << "\n\\font_sf_scale " << fontsSansScale
844 << "\n\\font_tt_scale " << fontsTypewriterScale
845 << '\n';
846 if (!fontsCJK.empty()) {
847 os << "\\font_cjk " << fontsCJK << '\n';
849 os << "\n\\graphics " << graphicsDriver << '\n';
850 os << "\\default_output_format " << defaultOutputFormat << '\n';
851 os << "\\bibtex_command " << bibtex_command << '\n';
852 os << "\\index_command " << index_command << '\n';
854 if (!float_placement.empty()) {
855 os << "\\float_placement " << float_placement << '\n';
857 os << "\\paperfontsize " << fontsize << '\n';
859 spacing().writeFile(os);
860 pdfoptions().writeFile(os);
862 os << "\\papersize " << string_papersize[papersize]
863 << "\n\\use_geometry " << convert<string>(use_geometry)
864 << "\n\\use_amsmath " << use_amsmath
865 << "\n\\use_esint " << use_esint
866 << "\n\\cite_engine " << citeenginetranslator().find(cite_engine_)
867 << "\n\\use_bibtopic " << convert<string>(use_bibtopic)
868 << "\n\\use_indices " << convert<string>(use_indices)
869 << "\n\\paperorientation " << string_orientation[orientation]
870 << "\n\\suppress_date " << convert<string>(suppress_date)
871 << '\n';
872 if (backgroundcolor != lyx::rgbFromHexName("#ffffff"))
873 os << "\\backgroundcolor " << lyx::X11hexname(backgroundcolor) << '\n';
875 BranchList::const_iterator it = branchlist().begin();
876 BranchList::const_iterator end = branchlist().end();
877 for (; it != end; ++it) {
878 os << "\\branch " << to_utf8(it->branch())
879 << "\n\\selected " << it->isSelected()
880 << "\n\\filename_suffix " << it->hasFilenameSuffix()
881 << "\n\\color " << lyx::X11hexname(it->color())
882 << "\n\\end_branch"
883 << "\n";
886 IndicesList::const_iterator iit = indiceslist().begin();
887 IndicesList::const_iterator iend = indiceslist().end();
888 for (; iit != iend; ++iit) {
889 os << "\\index " << to_utf8(iit->index())
890 << "\n\\shortcut " << to_utf8(iit->shortcut())
891 << "\n\\color " << lyx::X11hexname(iit->color())
892 << "\n\\end_index"
893 << "\n";
896 if (!paperwidth.empty())
897 os << "\\paperwidth "
898 << VSpace(paperwidth).asLyXCommand() << '\n';
899 if (!paperheight.empty())
900 os << "\\paperheight "
901 << VSpace(paperheight).asLyXCommand() << '\n';
902 if (!leftmargin.empty())
903 os << "\\leftmargin "
904 << VSpace(leftmargin).asLyXCommand() << '\n';
905 if (!topmargin.empty())
906 os << "\\topmargin "
907 << VSpace(topmargin).asLyXCommand() << '\n';
908 if (!rightmargin.empty())
909 os << "\\rightmargin "
910 << VSpace(rightmargin).asLyXCommand() << '\n';
911 if (!bottommargin.empty())
912 os << "\\bottommargin "
913 << VSpace(bottommargin).asLyXCommand() << '\n';
914 if (!headheight.empty())
915 os << "\\headheight "
916 << VSpace(headheight).asLyXCommand() << '\n';
917 if (!headsep.empty())
918 os << "\\headsep "
919 << VSpace(headsep).asLyXCommand() << '\n';
920 if (!footskip.empty())
921 os << "\\footskip "
922 << VSpace(footskip).asLyXCommand() << '\n';
923 if (!columnsep.empty())
924 os << "\\columnsep "
925 << VSpace(columnsep).asLyXCommand() << '\n';
926 os << "\\secnumdepth " << secnumdepth
927 << "\n\\tocdepth " << tocdepth
928 << "\n\\paragraph_separation "
929 << string_paragraph_separation[paragraph_separation];
930 if (!paragraph_separation)
931 os << "\n\\paragraph_indentation " << getIndentation().asLyXCommand();
932 else
933 os << "\n\\defskip " << getDefSkip().asLyXCommand();
934 os << "\n\\quotes_language "
935 << string_quotes_language[quotes_language]
936 << "\n\\papercolumns " << columns
937 << "\n\\papersides " << sides
938 << "\n\\paperpagestyle " << pagestyle << '\n';
939 if (!listings_params.empty())
940 os << "\\listings_params \"" <<
941 InsetListingsParams(listings_params).encodedString() << "\"\n";
942 for (int i = 0; i < 4; ++i) {
943 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
944 if (user_defined_bullet(i).getFont() != -1) {
945 os << "\\bullet " << i << " "
946 << user_defined_bullet(i).getFont() << " "
947 << user_defined_bullet(i).getCharacter() << " "
948 << user_defined_bullet(i).getSize() << "\n";
950 else {
951 // FIXME UNICODE
952 os << "\\bulletLaTeX " << i << " \""
953 << lyx::to_ascii(user_defined_bullet(i).getText())
954 << "\"\n";
959 os << "\\tracking_changes " << convert<string>(trackChanges) << "\n";
960 os << "\\output_changes " << convert<string>(outputChanges) << "\n";
962 os << pimpl_->authorlist;
966 void BufferParams::validate(LaTeXFeatures & features) const
968 features.require(documentClass().requires());
970 if (outputChanges) {
971 bool dvipost = LaTeXFeatures::isAvailable("dvipost");
972 bool xcolorulem = LaTeXFeatures::isAvailable("ulem") &&
973 LaTeXFeatures::isAvailable("xcolor");
975 switch (features.runparams().flavor) {
976 case OutputParams::LATEX:
977 if (dvipost) {
978 features.require("ct-dvipost");
979 features.require("dvipost");
980 } else if (xcolorulem) {
981 features.require("ct-xcolor-ulem");
982 features.require("ulem");
983 features.require("xcolor");
984 } else {
985 features.require("ct-none");
987 break;
988 case OutputParams::PDFLATEX:
989 case OutputParams::XETEX:
990 if (xcolorulem) {
991 features.require("ct-xcolor-ulem");
992 features.require("ulem");
993 features.require("xcolor");
994 // improves color handling in PDF output
995 features.require("pdfcolmk");
996 } else {
997 features.require("ct-none");
999 break;
1000 default:
1001 break;
1005 // Floats with 'Here definitely' as default setting.
1006 if (float_placement.find('H') != string::npos)
1007 features.require("float");
1009 // AMS Style is at document level
1010 if (use_amsmath == package_on
1011 || documentClass().provides("amsmath"))
1012 features.require("amsmath");
1013 if (use_esint == package_on)
1014 features.require("esint");
1016 // Document-level line spacing
1017 if (spacing().getSpace() != Spacing::Single && !spacing().isDefault())
1018 features.require("setspace");
1020 // the bullet shapes are buffer level not paragraph level
1021 // so they are tested here
1022 for (int i = 0; i < 4; ++i) {
1023 if (user_defined_bullet(i) == ITEMIZE_DEFAULTS[i])
1024 continue;
1025 int const font = user_defined_bullet(i).getFont();
1026 if (font == 0) {
1027 int const c = user_defined_bullet(i).getCharacter();
1028 if (c == 16
1029 || c == 17
1030 || c == 25
1031 || c == 26
1032 || c == 31) {
1033 features.require("latexsym");
1035 } else if (font == 1) {
1036 features.require("amssymb");
1037 } else if (font >= 2 && font <= 5) {
1038 features.require("pifont");
1042 if (pdfoptions().use_hyperref) {
1043 features.require("hyperref");
1044 // due to interferences with babel and hyperref, the color package has to
1045 // be loaded after hyperref when hyperref is used with the colorlinks
1046 // option, see http://bugzilla.lyx.org/show_bug.cgi?id=5291
1047 if (pdfoptions().colorlinks)
1048 features.require("color");
1051 if (useXetex)
1052 features.require("xetex");
1054 if (language->lang() == "vietnamese")
1055 features.require("vietnamese");
1056 else if (language->lang() == "japanese")
1057 features.require("japanese");
1061 bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features,
1062 TexRow & texrow) const
1064 os << "\\documentclass";
1066 DocumentClass const & tclass = documentClass();
1068 ostringstream clsoptions; // the document class options.
1070 if (tokenPos(tclass.opt_fontsize(),
1071 '|', fontsize) >= 0) {
1072 // only write if existing in list (and not default)
1073 clsoptions << fontsize << "pt,";
1076 // custom, A3, B3 and B4 paper sizes need geometry
1077 bool nonstandard_papersize = papersize == PAPER_B3
1078 || papersize == PAPER_B4
1079 || papersize == PAPER_A3
1080 || papersize == PAPER_CUSTOM;
1082 if (!use_geometry) {
1083 switch (papersize) {
1084 case PAPER_A4:
1085 clsoptions << "a4paper,";
1086 break;
1087 case PAPER_USLETTER:
1088 clsoptions << "letterpaper,";
1089 break;
1090 case PAPER_A5:
1091 clsoptions << "a5paper,";
1092 break;
1093 case PAPER_B5:
1094 clsoptions << "b5paper,";
1095 break;
1096 case PAPER_USEXECUTIVE:
1097 clsoptions << "executivepaper,";
1098 break;
1099 case PAPER_USLEGAL:
1100 clsoptions << "legalpaper,";
1101 break;
1102 case PAPER_DEFAULT:
1103 case PAPER_A3:
1104 case PAPER_B3:
1105 case PAPER_B4:
1106 case PAPER_CUSTOM:
1107 break;
1111 // if needed
1112 if (sides != tclass.sides()) {
1113 switch (sides) {
1114 case OneSide:
1115 clsoptions << "oneside,";
1116 break;
1117 case TwoSides:
1118 clsoptions << "twoside,";
1119 break;
1123 // if needed
1124 if (columns != tclass.columns()) {
1125 if (columns == 2)
1126 clsoptions << "twocolumn,";
1127 else
1128 clsoptions << "onecolumn,";
1131 if (!use_geometry
1132 && orientation == ORIENTATION_LANDSCAPE)
1133 clsoptions << "landscape,";
1135 // language should be a parameter to \documentclass
1136 if (language->babel() == "hebrew"
1137 && default_language->babel() != "hebrew")
1138 // This seems necessary
1139 features.useLanguage(default_language);
1141 ostringstream language_options;
1142 bool const use_babel = features.useBabel();
1143 if (use_babel) {
1144 language_options << features.getLanguages();
1145 if (!language->babel().empty()) {
1146 if (!language_options.str().empty())
1147 language_options << ',';
1148 language_options << language->babel();
1150 // if Vietnamese is used, babel must directly be loaded
1151 // with language options, not in the class options, see
1152 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1153 size_t viet = language_options.str().find("vietnam");
1154 // viet = string::npos when not found
1155 // the same is for all other languages that are not directly supported by
1156 // babel, but where LaTeX-packages add babel support.
1157 // this is currently the case for Latvian, Lithuanian, and Mongolian
1158 size_t latvian = language_options.str().find("latvian");
1159 size_t lithu = language_options.str().find("lithuanian");
1160 size_t mongo = language_options.str().find("mongolian");
1161 // if Japanese is used, babel must directly be loaded
1162 // with language options, not in the class options, see
1163 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
1164 size_t japan = language_options.str().find("japanese");
1165 if (lyxrc.language_global_options && !language_options.str().empty()
1166 && viet == string::npos && japan == string::npos
1167 && latvian == string::npos && lithu == string::npos
1168 && mongo == string::npos)
1169 clsoptions << language_options.str() << ',';
1172 // the predefined options from the layout
1173 if (use_default_options && !tclass.options().empty())
1174 clsoptions << tclass.options() << ',';
1176 // the user-defined options
1177 if (!options.empty()) {
1178 clsoptions << options << ',';
1181 string strOptions(clsoptions.str());
1182 if (!strOptions.empty()) {
1183 strOptions = rtrim(strOptions, ",");
1184 // FIXME UNICODE
1185 os << '[' << from_utf8(strOptions) << ']';
1188 os << '{' << from_ascii(tclass.latexname()) << "}\n";
1189 texrow.newline();
1190 // end of \documentclass defs
1192 if (useXetex) {
1193 os << "\\usepackage{fontspec}\n";
1194 texrow.newline();
1197 // font selection must be done before loading fontenc.sty
1198 string const fonts =
1199 loadFonts(fontsRoman, fontsSans,
1200 fontsTypewriter, fontsSC, fontsOSF,
1201 fontsSansScale, fontsTypewriterScale, useXetex);
1202 if (!fonts.empty()) {
1203 os << from_ascii(fonts);
1204 texrow.newline();
1206 if (fontsDefaultFamily != "default")
1207 os << "\\renewcommand{\\familydefault}{\\"
1208 << from_ascii(fontsDefaultFamily) << "}\n";
1210 // set font encoding
1211 // this one is not per buffer
1212 // for arabic_arabi and farsi we also need to load the LAE and
1213 // LFE encoding
1214 // XeTeX works without fontenc
1215 if (lyxrc.fontenc != "default" && language->lang() != "japanese"
1216 && !useXetex) {
1217 if (language->lang() == "arabic_arabi"
1218 || language->lang() == "farsi") {
1219 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1220 << ",LFE,LAE]{fontenc}\n";
1221 texrow.newline();
1222 } else {
1223 os << "\\usepackage[" << from_ascii(lyxrc.fontenc)
1224 << "]{fontenc}\n";
1225 texrow.newline();
1229 // handle inputenc etc.
1230 writeEncodingPreamble(os, features, texrow);
1232 if (!listings_params.empty() || features.isRequired("listings")) {
1233 os << "\\usepackage{listings}\n";
1234 texrow.newline();
1236 if (!listings_params.empty()) {
1237 os << "\\lstset{";
1238 // do not test validity because listings_params is
1239 // supposed to be valid
1240 string par =
1241 InsetListingsParams(listings_params).separatedParams(true);
1242 // we can't support all packages, but we should load the color package
1243 if (par.find("\\color", 0) != string::npos)
1244 features.require("color");
1245 os << from_utf8(par);
1246 // count the number of newlines
1247 for (size_t i = 0; i < par.size(); ++i)
1248 if (par[i] == '\n')
1249 texrow.newline();
1250 os << "}\n";
1251 texrow.newline();
1253 if (!tclass.provides("geometry")
1254 && (use_geometry || nonstandard_papersize)) {
1255 odocstringstream ods;
1256 if (!getGraphicsDriver("geometry").empty())
1257 ods << getGraphicsDriver("geometry");
1258 if (orientation == ORIENTATION_LANDSCAPE)
1259 ods << ",landscape";
1260 switch (papersize) {
1261 case PAPER_CUSTOM:
1262 if (!paperwidth.empty())
1263 ods << ",paperwidth="
1264 << from_ascii(paperwidth);
1265 if (!paperheight.empty())
1266 ods << ",paperheight="
1267 << from_ascii(paperheight);
1268 break;
1269 case PAPER_USLETTER:
1270 ods << ",letterpaper";
1271 break;
1272 case PAPER_USLEGAL:
1273 ods << ",legalpaper";
1274 break;
1275 case PAPER_USEXECUTIVE:
1276 ods << ",executivepaper";
1277 break;
1278 case PAPER_A3:
1279 ods << ",a3paper";
1280 break;
1281 case PAPER_A4:
1282 ods << ",a4paper";
1283 break;
1284 case PAPER_A5:
1285 ods << ",a5paper";
1286 break;
1287 case PAPER_B3:
1288 ods << ",b3paper";
1289 break;
1290 case PAPER_B4:
1291 ods << ",b4paper";
1292 break;
1293 case PAPER_B5:
1294 ods << ",b5paper";
1295 break;
1296 default:
1297 // default papersize ie PAPER_DEFAULT
1298 switch (lyxrc.default_papersize) {
1299 case PAPER_DEFAULT: // keep compiler happy
1300 case PAPER_USLETTER:
1301 ods << ",letterpaper";
1302 break;
1303 case PAPER_USLEGAL:
1304 ods << ",legalpaper";
1305 break;
1306 case PAPER_USEXECUTIVE:
1307 ods << ",executivepaper";
1308 break;
1309 case PAPER_A3:
1310 ods << ",a3paper";
1311 break;
1312 case PAPER_A4:
1313 ods << ",a4paper";
1314 break;
1315 case PAPER_A5:
1316 ods << ",a5paper";
1317 break;
1318 case PAPER_B5:
1319 ods << ",b5paper";
1320 break;
1321 case PAPER_B3:
1322 case PAPER_B4:
1323 case PAPER_CUSTOM:
1324 break;
1327 docstring const g_options = trim(ods.str(), ",");
1328 os << "\\usepackage";
1329 if (!g_options.empty())
1330 os << '[' << g_options << ']';
1331 os << "{geometry}\n";
1332 texrow.newline();
1333 os << "\\geometry{verbose";
1334 if (!topmargin.empty())
1335 os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
1336 if (!bottommargin.empty())
1337 os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
1338 if (!leftmargin.empty())
1339 os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
1340 if (!rightmargin.empty())
1341 os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
1342 if (!headheight.empty())
1343 os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
1344 if (!headsep.empty())
1345 os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
1346 if (!footskip.empty())
1347 os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
1348 if (!columnsep.empty())
1349 os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
1350 os << "}\n";
1351 texrow.newline();
1352 } else if (orientation == ORIENTATION_LANDSCAPE) {
1353 features.require("papersize");
1356 if (tokenPos(tclass.opt_pagestyle(),
1357 '|', pagestyle) >= 0) {
1358 if (pagestyle == "fancy") {
1359 os << "\\usepackage{fancyhdr}\n";
1360 texrow.newline();
1362 os << "\\pagestyle{" << from_ascii(pagestyle) << "}\n";
1363 texrow.newline();
1366 // only output when the background color is not white
1367 if (backgroundcolor != lyx::rgbFromHexName("#ffffff")) {
1368 // only require color here, the background color will be defined
1369 // in LaTeXFeatures.cpp to avoid interferences with the LaTeX
1370 // package pdfpages
1371 features.require("color");
1372 features.require("pagecolor");
1375 // Only if class has a ToC hierarchy
1376 if (tclass.hasTocLevels()) {
1377 if (secnumdepth != tclass.secnumdepth()) {
1378 os << "\\setcounter{secnumdepth}{"
1379 << secnumdepth
1380 << "}\n";
1381 texrow.newline();
1383 if (tocdepth != tclass.tocdepth()) {
1384 os << "\\setcounter{tocdepth}{"
1385 << tocdepth
1386 << "}\n";
1387 texrow.newline();
1391 if (paragraph_separation) {
1392 // when skip separation
1393 switch (getDefSkip().kind()) {
1394 case VSpace::SMALLSKIP:
1395 os << "\\setlength{\\parskip}{\\smallskipamount}\n";
1396 break;
1397 case VSpace::MEDSKIP:
1398 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1399 break;
1400 case VSpace::BIGSKIP:
1401 os << "\\setlength{\\parskip}{\\bigskipamount}\n";
1402 break;
1403 case VSpace::LENGTH:
1404 os << "\\setlength{\\parskip}{"
1405 << from_utf8(getDefSkip().length().asLatexString())
1406 << "}\n";
1407 break;
1408 default: // should never happen // Then delete it.
1409 os << "\\setlength{\\parskip}{\\medskipamount}\n";
1410 break;
1412 texrow.newline();
1413 os << "\\setlength{\\parindent}{0pt}\n";
1414 texrow.newline();
1415 } else {
1416 // when separation by indentation
1417 // only output something when a width is given
1418 if (getIndentation().asLyXCommand() != "default") {
1419 os << "\\setlength{\\parindent}{"
1420 << from_utf8(getIndentation().asLatexCommand())
1421 << "}\n";
1422 texrow.newline();
1426 // Now insert the LyX specific LaTeX commands...
1427 docstring lyxpreamble;
1429 // due to interferences with babel and hyperref, the color package has to
1430 // be loaded (when it is not already loaded) before babel when hyperref
1431 // is used with the colorlinks option, see
1432 // http://bugzilla.lyx.org/show_bug.cgi?id=5291
1433 // we decided therefore to load color always before babel, see
1434 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg144349.html
1435 lyxpreamble += from_ascii(features.getColorOptions());
1437 // If we use hyperref, jurabib, japanese, or vietnamese, we have to call babel before them.
1438 if (use_babel
1439 && (features.isRequired("jurabib")
1440 || features.isRequired("hyperref")
1441 || features.isRequired("vietnamese")
1442 || features.isRequired("japanese") ) ) {
1443 // FIXME UNICODE
1444 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1445 lyxpreamble += from_utf8(features.getBabelOptions()) + '\n';
1448 // The optional packages;
1449 lyxpreamble += from_ascii(features.getPackages());
1451 // Additional Indices
1452 if (features.isRequired("splitidx")) {
1453 IndicesList::const_iterator iit = indiceslist().begin();
1454 IndicesList::const_iterator iend = indiceslist().end();
1455 for (; iit != iend; ++iit) {
1456 lyxpreamble += "\\newindex[";
1457 lyxpreamble += iit->index();
1458 lyxpreamble += "]{";
1459 lyxpreamble += iit->shortcut();
1460 lyxpreamble += "}\n";
1464 // Line spacing
1465 lyxpreamble += from_utf8(spacing().writePreamble(tclass.provides("SetSpace")));
1467 // PDF support.
1468 // * Hyperref manual: "Make sure it comes last of your loaded
1469 // packages, to give it a fighting chance of not being over-written,
1470 // since its job is to redefine many LaTeX commands."
1471 // * Email from Heiko Oberdiek: "It is usually better to load babel
1472 // before hyperref. Then hyperref has a chance to detect babel.
1473 // * Has to be loaded before the "LyX specific LaTeX commands" to
1474 // avoid errors with algorithm floats.
1475 // use hyperref explicitely when it is required
1476 if (features.isRequired("hyperref")) {
1477 odocstringstream oss;
1478 pdfoptions().writeLaTeX(oss, documentClass().provides("hyperref"));
1479 lyxpreamble += oss.str();
1482 // Will be surrounded by \makeatletter and \makeatother when not empty
1483 docstring atlyxpreamble;
1485 // Some macros LyX will need
1486 docstring tmppreamble(features.getMacros());
1488 if (!tmppreamble.empty())
1489 atlyxpreamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1490 "LyX specific LaTeX commands.\n"
1491 + tmppreamble + '\n';
1493 // the text class specific preamble
1494 tmppreamble = features.getTClassPreamble();
1495 if (!tmppreamble.empty())
1496 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1497 "Textclass specific LaTeX commands.\n"
1498 + tmppreamble + '\n';
1500 // suppress date if selected
1501 // use \@ifundefined because we cannot be sure that every document class
1502 // has a \date command
1503 if (suppress_date)
1504 atlyxpreamble += "\\@ifundefined{date}{}{\\date{}}\n";
1506 /* the user-defined preamble */
1507 if (!containsOnly(preamble, " \n\t"))
1508 // FIXME UNICODE
1509 atlyxpreamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% "
1510 "User specified LaTeX commands.\n"
1511 + from_utf8(preamble) + '\n';
1513 // subfig loads internally the LaTeX package "caption". As
1514 // caption is a very popular package, users will load it in
1515 // the preamble. Therefore we must load subfig behind the
1516 // user-defined preamble and check if the caption package was
1517 // loaded or not. For the case that caption is loaded before
1518 // subfig, there is the subfig option "caption=false". This
1519 // option also works when a koma-script class is used and
1520 // koma's own caption commands are used instead of caption. We
1521 // use \PassOptionsToPackage here because the user could have
1522 // already loaded subfig in the preamble.
1523 if (features.isRequired("subfig")) {
1524 atlyxpreamble += "\\@ifundefined{showcaptionsetup}{}{%\n"
1525 " \\PassOptionsToPackage{caption=false}{subfig}}\n"
1526 "\\usepackage{subfig}\n";
1529 // Itemize bullet settings need to be last in case the user
1530 // defines their own bullets that use a package included
1531 // in the user-defined preamble -- ARRae
1532 // Actually it has to be done much later than that
1533 // since some packages like frenchb make modifications
1534 // at \begin{document} time -- JMarc
1535 docstring bullets_def;
1536 for (int i = 0; i < 4; ++i) {
1537 if (user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
1538 if (bullets_def.empty())
1539 bullets_def += "\\AtBeginDocument{\n";
1540 bullets_def += " \\def\\labelitemi";
1541 switch (i) {
1542 // `i' is one less than the item to modify
1543 case 0:
1544 break;
1545 case 1:
1546 bullets_def += 'i';
1547 break;
1548 case 2:
1549 bullets_def += "ii";
1550 break;
1551 case 3:
1552 bullets_def += 'v';
1553 break;
1555 bullets_def += '{' +
1556 user_defined_bullet(i).getText()
1557 + "}\n";
1561 if (!bullets_def.empty())
1562 atlyxpreamble += bullets_def + "}\n\n";
1564 if (!atlyxpreamble.empty())
1565 lyxpreamble += "\n\\makeatletter\n"
1566 + atlyxpreamble + "\\makeatother\n\n";
1568 // We try to load babel late, in case it interferes with other packages.
1569 // Jurabib and Hyperref have to be called after babel, though.
1570 if (use_babel && !features.isRequired("jurabib")
1571 && !features.isRequired("hyperref")
1572 && !features.isRequired("vietnamese")
1573 && !features.isRequired("japanese")) {
1574 // FIXME UNICODE
1575 lyxpreamble += from_utf8(babelCall(language_options.str())) + '\n';
1576 lyxpreamble += from_utf8(features.getBabelOptions()) + '\n';
1579 docstring const i18npreamble = features.getTClassI18nPreamble(use_babel);
1580 if (!i18npreamble.empty())
1581 lyxpreamble += i18npreamble + '\n';
1583 int const nlines =
1584 int(count(lyxpreamble.begin(), lyxpreamble.end(), '\n'));
1585 for (int j = 0; j != nlines; ++j) {
1586 texrow.newline();
1589 os << lyxpreamble;
1591 // these packages (xunicode, for that matter) need to be loaded at least
1592 // after amsmath, amssymb, esint and the other packages that provide
1593 // special glyphs
1594 if (useXetex) {
1595 os << "\\usepackage{xunicode}\n";
1596 texrow.newline();
1597 os << "\\usepackage{xltxtra}\n";
1598 texrow.newline();
1600 return use_babel;
1604 void BufferParams::useClassDefaults()
1606 DocumentClass const & tclass = documentClass();
1608 sides = tclass.sides();
1609 columns = tclass.columns();
1610 pagestyle = tclass.pagestyle();
1611 use_default_options = true;
1612 // Only if class has a ToC hierarchy
1613 if (tclass.hasTocLevels()) {
1614 secnumdepth = tclass.secnumdepth();
1615 tocdepth = tclass.tocdepth();
1620 bool BufferParams::hasClassDefaults() const
1622 DocumentClass const & tclass = documentClass();
1624 return sides == tclass.sides()
1625 && columns == tclass.columns()
1626 && pagestyle == tclass.pagestyle()
1627 && use_default_options
1628 && secnumdepth == tclass.secnumdepth()
1629 && tocdepth == tclass.tocdepth();
1633 DocumentClass const & BufferParams::documentClass() const
1635 return *doc_class_;
1639 DocumentClass const * BufferParams::documentClassPtr() const {
1640 return doc_class_;
1644 void BufferParams::setDocumentClass(DocumentClass const * const tc) {
1645 // evil, but this function is evil
1646 doc_class_ = const_cast<DocumentClass *>(tc);
1650 bool BufferParams::setBaseClass(string const & classname)
1652 LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
1653 LayoutFileList & bcl = LayoutFileList::get();
1654 if (!bcl.haveClass(classname)) {
1655 docstring s =
1656 bformat(_("The document class %1$s could not be found. "
1657 "A default textclass with default layouts will be used. "
1658 "LyX might not be able to produce output unless a correct "
1659 "textclass is selected from the document settings dialog."),
1660 from_utf8(classname));
1661 frontend::Alert::error(_("Document class not found"), s);
1662 bcl.addEmptyClass(classname);
1665 bool const success = bcl[classname].load();
1666 if (!success) {
1667 docstring s =
1668 bformat(_("The document class %1$s could not be loaded."),
1669 from_utf8(classname));
1670 frontend::Alert::error(_("Could not load class"), s);
1671 return false;
1674 pimpl_->baseClass_ = classname;
1675 layoutModules_.adaptToBaseClass(baseClass(), removedModules_);
1676 return true;
1680 LayoutFile const * BufferParams::baseClass() const
1682 if (LayoutFileList::get().haveClass(pimpl_->baseClass_))
1683 return &(LayoutFileList::get()[pimpl_->baseClass_]);
1684 else
1685 return 0;
1689 LayoutFileIndex const & BufferParams::baseClassID() const
1691 return pimpl_->baseClass_;
1695 void BufferParams::makeDocumentClass()
1697 if (!baseClass())
1698 return;
1700 doc_class_ = &(DocumentClassBundle::get().makeDocumentClass(*baseClass(), layoutModules_));
1702 if (!local_layout.empty()) {
1703 if (!doc_class_->read(local_layout, TextClass::MODULE)) {
1704 docstring const msg = _("Error reading internal layout information");
1705 frontend::Alert::warning(_("Read Error"), msg);
1710 bool BufferParams::moduleCanBeAdded(string const & modName) const
1712 return layoutModules_.moduleCanBeAdded(modName, baseClass());
1716 bool BufferParams::addLayoutModule(string const & modName)
1718 LayoutModuleList::const_iterator it = layoutModules_.begin();
1719 LayoutModuleList::const_iterator end = layoutModules_.end();
1720 for (; it != end; it++)
1721 if (*it == modName)
1722 return false;
1723 layoutModules_.push_back(modName);
1724 return true;
1728 Font const BufferParams::getFont() const
1730 FontInfo f = documentClass().defaultfont();
1731 if (fontsDefaultFamily == "rmdefault")
1732 f.setFamily(ROMAN_FAMILY);
1733 else if (fontsDefaultFamily == "sfdefault")
1734 f.setFamily(SANS_FAMILY);
1735 else if (fontsDefaultFamily == "ttdefault")
1736 f.setFamily(TYPEWRITER_FAMILY);
1737 return Font(f, language);
1741 void BufferParams::readPreamble(Lexer & lex)
1743 if (lex.getString() != "\\begin_preamble")
1744 lyxerr << "Error (BufferParams::readPreamble):"
1745 "consistency check failed." << endl;
1747 preamble = lex.getLongString("\\end_preamble");
1751 void BufferParams::readLocalLayout(Lexer & lex)
1753 if (lex.getString() != "\\begin_local_layout")
1754 lyxerr << "Error (BufferParams::readLocalLayout):"
1755 "consistency check failed." << endl;
1757 local_layout = lex.getLongString("\\end_local_layout");
1761 void BufferParams::readLanguage(Lexer & lex)
1763 if (!lex.next()) return;
1765 string const tmptok = lex.getString();
1767 // check if tmptok is part of tex_babel in tex-defs.h
1768 language = languages.getLanguage(tmptok);
1769 if (!language) {
1770 // Language tmptok was not found
1771 language = default_language;
1772 lyxerr << "Warning: Setting language `"
1773 << tmptok << "' to `" << language->lang()
1774 << "'." << endl;
1779 void BufferParams::readGraphicsDriver(Lexer & lex)
1781 if (!lex.next())
1782 return;
1784 string const tmptok = lex.getString();
1785 // check if tmptok is part of tex_graphics in tex_defs.h
1786 int n = 0;
1787 while (true) {
1788 string const test = tex_graphics[n++];
1790 if (test == tmptok) {
1791 graphicsDriver = tmptok;
1792 break;
1794 if (test.empty()) {
1795 lex.printError(
1796 "Warning: graphics driver `$$Token' not recognized!\n"
1797 " Setting graphics driver to `default'.\n");
1798 graphicsDriver = "default";
1799 break;
1805 void BufferParams::readBullets(Lexer & lex)
1807 if (!lex.next())
1808 return;
1810 int const index = lex.getInteger();
1811 lex.next();
1812 int temp_int = lex.getInteger();
1813 user_defined_bullet(index).setFont(temp_int);
1814 temp_bullet(index).setFont(temp_int);
1815 lex >> temp_int;
1816 user_defined_bullet(index).setCharacter(temp_int);
1817 temp_bullet(index).setCharacter(temp_int);
1818 lex >> temp_int;
1819 user_defined_bullet(index).setSize(temp_int);
1820 temp_bullet(index).setSize(temp_int);
1824 void BufferParams::readBulletsLaTeX(Lexer & lex)
1826 // The bullet class should be able to read this.
1827 if (!lex.next())
1828 return;
1829 int const index = lex.getInteger();
1830 lex.next(true);
1831 docstring const temp_str = lex.getDocString();
1833 user_defined_bullet(index).setText(temp_str);
1834 temp_bullet(index).setText(temp_str);
1838 void BufferParams::readModules(Lexer & lex)
1840 if (!lex.eatLine()) {
1841 lyxerr << "Error (BufferParams::readModules):"
1842 "Unexpected end of input." << endl;
1843 return;
1845 while (true) {
1846 string mod = lex.getString();
1847 if (mod == "\\end_modules")
1848 break;
1849 addLayoutModule(mod);
1850 lex.eatLine();
1855 void BufferParams::readRemovedModules(Lexer & lex)
1857 if (!lex.eatLine()) {
1858 lyxerr << "Error (BufferParams::readRemovedModules):"
1859 "Unexpected end of input." << endl;
1860 return;
1862 while (true) {
1863 string mod = lex.getString();
1864 if (mod == "\\end_removed_modules")
1865 break;
1866 removedModules_.push_back(mod);
1867 lex.eatLine();
1869 // now we want to remove any removed modules that were previously
1870 // added. normally, that will be because default modules were added in
1871 // setBaseClass(), which gets called when \textclass is read at the
1872 // start of the read.
1873 list<string>::const_iterator rit = removedModules_.begin();
1874 list<string>::const_iterator const ren = removedModules_.end();
1875 for (; rit != ren; rit++) {
1876 LayoutModuleList::iterator const mit = layoutModules_.begin();
1877 LayoutModuleList::iterator const men = layoutModules_.end();
1878 LayoutModuleList::iterator found = find(mit, men, *rit);
1879 if (found == men)
1880 continue;
1881 layoutModules_.erase(found);
1886 string BufferParams::paperSizeName(PapersizePurpose purpose) const
1888 char real_papersize = papersize;
1889 if (real_papersize == PAPER_DEFAULT)
1890 real_papersize = lyxrc.default_papersize;
1892 switch (real_papersize) {
1893 case PAPER_DEFAULT:
1894 // could be anything, so don't guess
1895 return string();
1896 case PAPER_CUSTOM: {
1897 if (purpose == XDVI && !paperwidth.empty() &&
1898 !paperheight.empty()) {
1899 // heightxwidth<unit>
1900 string first = paperwidth;
1901 string second = paperheight;
1902 if (orientation == ORIENTATION_LANDSCAPE)
1903 first.swap(second);
1904 // cut off unit.
1905 return first.erase(first.length() - 2)
1906 + "x" + second;
1908 return string();
1910 case PAPER_A3:
1911 return "a3";
1912 case PAPER_A4:
1913 return "a4";
1914 case PAPER_A5:
1915 return "a5";
1916 case PAPER_B3:
1917 // dvips and dvipdfm do not know this
1918 if (purpose == DVIPS || purpose == DVIPDFM)
1919 return string();
1920 return "b3";
1921 case PAPER_B4:
1922 // dvipdfm does not know this
1923 if (purpose == DVIPDFM)
1924 return string();
1925 return "b4";
1926 case PAPER_B5:
1927 // dvipdfm does not know this
1928 if (purpose == DVIPDFM)
1929 return string();
1930 return "b5";
1931 case PAPER_USEXECUTIVE:
1932 // dvipdfm does not know this
1933 if (purpose == DVIPDFM)
1934 return string();
1935 return "foolscap";
1936 case PAPER_USLEGAL:
1937 return "legal";
1938 case PAPER_USLETTER:
1939 default:
1940 if (purpose == XDVI)
1941 return "us";
1942 return "letter";
1947 string const BufferParams::dvips_options() const
1949 string result;
1951 if (use_geometry
1952 && papersize == PAPER_CUSTOM
1953 && !lyxrc.print_paper_dimension_flag.empty()
1954 && !paperwidth.empty()
1955 && !paperheight.empty()) {
1956 // using a custom papersize
1957 result = lyxrc.print_paper_dimension_flag;
1958 result += ' ' + paperwidth;
1959 result += ',' + paperheight;
1960 } else {
1961 string const paper_option = paperSizeName(DVIPS);
1962 if (!paper_option.empty() && (paper_option != "letter" ||
1963 orientation != ORIENTATION_LANDSCAPE)) {
1964 // dvips won't accept -t letter -t landscape.
1965 // In all other cases, include the paper size
1966 // explicitly.
1967 result = lyxrc.print_paper_flag;
1968 result += ' ' + paper_option;
1971 if (orientation == ORIENTATION_LANDSCAPE &&
1972 papersize != PAPER_CUSTOM)
1973 result += ' ' + lyxrc.print_landscape_flag;
1974 return result;
1978 string BufferParams::babelCall(string const & lang_opts) const
1980 string lang_pack = lyxrc.language_package;
1981 if (lang_pack != "\\usepackage{babel}")
1982 return lang_pack;
1983 // suppress the babel call when there is no babel language defined
1984 // for the document language in the lib/languages file and if no
1985 // other languages are used (lang_opts is then empty)
1986 if (lang_opts.empty())
1987 return string();
1988 // If Vietnamese is used, babel must directly be loaded with the
1989 // language options, see
1990 // http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129417.html
1991 size_t viet = lang_opts.find("vietnam");
1992 // viet = string::npos when not found
1993 // the same is for all other languages that are not directly supported by
1994 // babel, but where LaTeX-packages add babel support.
1995 // this is currently the case for Latvian, Lithuanian, and Mongolian
1996 size_t latvian = lang_opts.find("latvian");
1997 size_t lithu = lang_opts.find("lithuanian");
1998 size_t mongo = lang_opts.find("mongolian");
1999 // If Japanese is used, babel must directly be loaded with the
2000 // language options, see
2001 // http://bugzilla.lyx.org/show_bug.cgi?id=4597#c4
2002 size_t japan = lang_opts.find("japanese");
2003 if (!lyxrc.language_global_options || viet != string::npos
2004 || japan != string::npos || latvian != string::npos
2005 || lithu != string::npos || mongo != string::npos)
2006 return "\\usepackage[" + lang_opts + "]{babel}";
2007 return lang_pack;
2011 docstring BufferParams::getGraphicsDriver(string const & package) const
2013 docstring result;
2015 if (package == "geometry") {
2016 if (graphicsDriver == "dvips"
2017 || graphicsDriver == "dvipdfm"
2018 || graphicsDriver == "pdftex"
2019 || graphicsDriver == "vtex")
2020 result = from_ascii(graphicsDriver);
2021 else if (graphicsDriver == "dvipdfmx")
2022 result = from_ascii("dvipdfm");
2025 return result;
2029 void BufferParams::writeEncodingPreamble(odocstream & os,
2030 LaTeXFeatures & features, TexRow & texrow) const
2032 if (useXetex)
2033 return;
2034 if (inputenc == "auto") {
2035 string const doc_encoding =
2036 language->encoding()->latexName();
2037 Encoding::Package const package =
2038 language->encoding()->package();
2040 // Create a list with all the input encodings used
2041 // in the document
2042 set<string> encodings =
2043 features.getEncodingSet(doc_encoding);
2045 // If the "japanese" package (i.e. pLaTeX) is used,
2046 // inputenc must be omitted.
2047 // see http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg129680.html
2048 if (package == Encoding::japanese)
2049 features.require("japanese");
2051 if ((!encodings.empty() || package == Encoding::inputenc)
2052 && !features.isRequired("japanese")) {
2053 os << "\\usepackage[";
2054 set<string>::const_iterator it = encodings.begin();
2055 set<string>::const_iterator const end = encodings.end();
2056 if (it != end) {
2057 os << from_ascii(*it);
2058 ++it;
2060 for (; it != end; ++it)
2061 os << ',' << from_ascii(*it);
2062 if (package == Encoding::inputenc) {
2063 if (!encodings.empty())
2064 os << ',';
2065 os << from_ascii(doc_encoding);
2067 os << "]{inputenc}\n";
2068 texrow.newline();
2070 if (package == Encoding::CJK || features.mustProvide("CJK")) {
2071 if (language->encoding()->name() == "utf8-cjk"
2072 && LaTeXFeatures::isAvailable("CJKutf8"))
2073 os << "\\usepackage{CJKutf8}\n";
2074 else
2075 os << "\\usepackage{CJK}\n";
2076 texrow.newline();
2078 } else if (inputenc != "default") {
2079 switch (encoding().package()) {
2080 case Encoding::none:
2081 case Encoding::japanese:
2082 break;
2083 case Encoding::inputenc:
2084 // do not load inputenc if japanese is used
2085 if (features.isRequired("japanese"))
2086 break;
2087 os << "\\usepackage[" << from_ascii(inputenc)
2088 << "]{inputenc}\n";
2089 texrow.newline();
2090 break;
2091 case Encoding::CJK:
2092 if (encoding().name() == "utf8-cjk"
2093 && LaTeXFeatures::isAvailable("CJKutf8"))
2094 os << "\\usepackage{CJKutf8}\n";
2095 else
2096 os << "\\usepackage{CJK}\n";
2097 texrow.newline();
2098 break;
2102 // The encoding "armscii8" (for Armenian) is only available when
2103 // the package "armtex" is loaded.
2104 if (language->encoding()->latexName() == "armscii8"
2105 || inputenc == "armscii8") {
2106 os << "\\usepackage{armtex}\n";
2107 texrow.newline();
2112 string const BufferParams::parseFontName(string const & name) const
2114 string mangled = name;
2115 size_t const idx = mangled.find('[');
2116 if (idx == string::npos || idx == 0)
2117 return mangled;
2118 else
2119 return mangled.substr(0, idx - 1);
2123 string const BufferParams::loadFonts(string const & rm,
2124 string const & sf, string const & tt,
2125 bool const & sc, bool const & osf,
2126 int const & sfscale, int const & ttscale,
2127 bool const & xetex) const
2129 /* The LaTeX font world is in a flux. In the PSNFSS font interface,
2130 several packages have been replaced by others, that might not
2131 be installed on every system. We have to take care for that
2132 (see psnfss.pdf). We try to support all psnfss fonts as well
2133 as the fonts that have become de facto standard in the LaTeX
2134 world (e.g. Latin Modern). We do not support obsolete fonts
2135 (like PSLatex). In general, it should be possible to mix any
2136 rm font with any sf or tt font, respectively. (JSpitzm)
2137 TODO:
2138 -- separate math fonts.
2141 if (rm == "default" && sf == "default" && tt == "default")
2142 //nothing to do
2143 return string();
2145 ostringstream os;
2147 if (xetex) {
2148 if (rm != "default")
2149 os << "\\setmainfont[Mapping=tex-text]{"
2150 << parseFontName(rm) << "}\n";
2151 if (sf != "default") {
2152 string const sans = parseFontName(sf);
2153 if (sfscale != 100)
2154 os << "\\setsansfont[Scale="
2155 << float(sfscale) / 100
2156 << ",Mapping=tex-text]{"
2157 << sans << "}\n";
2158 else
2159 os << "\\setsansfont[Mapping=tex-text]{"
2160 << sans << "}\n";
2162 if (tt != "default") {
2163 string const mono = parseFontName(tt);
2164 if (ttscale != 100)
2165 os << "\\setmonofont[Scale="
2166 << float(sfscale) / 100
2167 << "]{"
2168 << mono << "}\n";
2169 else
2170 os << "\\setmonofont[Mapping=tex-text]{"
2171 << mono << "}\n";
2173 if (osf)
2174 os << "\\defaultfontfeatures{Numbers=OldStyle}\n";
2175 return os.str();
2178 // ROMAN FONTS
2179 // Computer Modern (must be explicitely selectable -- there might be classes
2180 // that define a different default font!
2181 if (rm == "cmr") {
2182 os << "\\renewcommand{\\rmdefault}{cmr}\n";
2183 // osf for Computer Modern needs eco.sty
2184 if (osf)
2185 os << "\\usepackage{eco}\n";
2187 // Latin Modern Roman
2188 else if (rm == "lmodern")
2189 os << "\\usepackage{lmodern}\n";
2190 // AE
2191 else if (rm == "ae") {
2192 // not needed when using OT1 font encoding.
2193 if (lyxrc.fontenc != "default")
2194 os << "\\usepackage{ae,aecompl}\n";
2196 // Times
2197 else if (rm == "times") {
2198 // try to load the best available package
2199 if (LaTeXFeatures::isAvailable("mathptmx"))
2200 os << "\\usepackage{mathptmx}\n";
2201 else if (LaTeXFeatures::isAvailable("mathptm"))
2202 os << "\\usepackage{mathptm}\n";
2203 else
2204 os << "\\usepackage{times}\n";
2206 // Palatino
2207 else if (rm == "palatino") {
2208 // try to load the best available package
2209 if (LaTeXFeatures::isAvailable("mathpazo")) {
2210 os << "\\usepackage";
2211 if (osf || sc) {
2212 os << '[';
2213 if (!osf)
2214 os << "sc";
2215 else
2216 // "osf" includes "sc"!
2217 os << "osf";
2218 os << ']';
2220 os << "{mathpazo}\n";
2222 else if (LaTeXFeatures::isAvailable("mathpple"))
2223 os << "\\usepackage{mathpple}\n";
2224 else
2225 os << "\\usepackage{palatino}\n";
2227 // Utopia
2228 else if (rm == "utopia") {
2229 // fourier supersedes utopia.sty, but does
2230 // not work with OT1 encoding.
2231 if (LaTeXFeatures::isAvailable("fourier")
2232 && lyxrc.fontenc != "default") {
2233 os << "\\usepackage";
2234 if (osf || sc) {
2235 os << '[';
2236 if (sc)
2237 os << "expert";
2238 if (osf && sc)
2239 os << ',';
2240 if (osf)
2241 os << "oldstyle";
2242 os << ']';
2244 os << "{fourier}\n";
2246 else
2247 os << "\\usepackage{utopia}\n";
2249 // Bera (complete fontset)
2250 else if (rm == "bera" && sf == "default" && tt == "default")
2251 os << "\\usepackage{bera}\n";
2252 // everything else
2253 else if (rm != "default")
2254 os << "\\usepackage" << "{" << rm << "}\n";
2256 // SANS SERIF
2257 // Helvetica, Bera Sans
2258 if (sf == "helvet" || sf == "berasans") {
2259 if (sfscale != 100)
2260 os << "\\usepackage[scaled=" << float(sfscale) / 100
2261 << "]{" << sf << "}\n";
2262 else
2263 os << "\\usepackage{" << sf << "}\n";
2265 // Avant Garde
2266 else if (sf == "avant")
2267 os << "\\usepackage{" << sf << "}\n";
2268 // Computer Modern, Latin Modern, CM Bright
2269 else if (sf != "default")
2270 os << "\\renewcommand{\\sfdefault}{" << sf << "}\n";
2272 // monospaced/typewriter
2273 // Courier, LuxiMono
2274 if (tt == "luximono" || tt == "beramono") {
2275 if (ttscale != 100)
2276 os << "\\usepackage[scaled=" << float(ttscale) / 100
2277 << "]{" << tt << "}\n";
2278 else
2279 os << "\\usepackage{" << tt << "}\n";
2281 // Courier
2282 else if (tt == "courier" )
2283 os << "\\usepackage{" << tt << "}\n";
2284 // Computer Modern, Latin Modern, CM Bright
2285 else if (tt != "default")
2286 os << "\\renewcommand{\\ttdefault}{" << tt << "}\n";
2288 return os.str();
2292 Encoding const & BufferParams::encoding() const
2294 if (useXetex)
2295 return *(encodings.fromLaTeXName("utf8-plain"));
2296 if (inputenc == "auto" || inputenc == "default")
2297 return *language->encoding();
2298 Encoding const * const enc = encodings.fromLaTeXName(inputenc);
2299 if (enc)
2300 return *enc;
2301 LYXERR0("Unknown inputenc value `" << inputenc
2302 << "'. Using `auto' instead.");
2303 return *language->encoding();
2307 CiteEngine BufferParams::citeEngine() const
2309 // FIXME the class should provide the numerical/
2310 // authoryear choice
2311 if (documentClass().provides("natbib")
2312 && cite_engine_ != ENGINE_NATBIB_NUMERICAL)
2313 return ENGINE_NATBIB_AUTHORYEAR;
2314 return cite_engine_;
2318 void BufferParams::setCiteEngine(CiteEngine cite_engine)
2320 cite_engine_ = cite_engine;
2323 } // namespace lyx