papersize = PAPER_DEFAULT;
orientation = ORIENTATION_PORTRAIT;
use_geometry = false;
- biblio_style = "plain";
+ biblio_style = string();
use_bibtopic = false;
multibib = string();
use_indices = false;
&& papersize != PAPER_A5
&& papersize != PAPER_B5;
- if (!use_geometry) {
+ if (!use_geometry || features.isProvided("geometry-light")) {
switch (papersize) {
case PAPER_A4:
clsoptions << "a4paper,";
if (!options.empty()) {
clsoptions << options << ',';
}
-
- string strOptions(clsoptions.str());
+
+ docstring const strOptions = from_utf8(clsoptions.str());
if (!strOptions.empty()) {
- strOptions = rtrim(strOptions, ",");
- // FIXME UNICODE
- os << '[' << from_utf8(strOptions) << ']';
+ // Check if class options contain uncodable glyphs
+ docstring uncodable_glyphs;
+ docstring options_encodable;
+ Encoding const * const enc = features.runparams().encoding;
+ if (enc) {
+ for (size_t n = 0; n < strOptions.size(); ++n) {
+ char_type c = strOptions[n];
+ if (!enc->encodable(c)) {
+ docstring const glyph(1, c);
+ LYXERR0("Uncodable character '"
+ << glyph
+ << "' in class options!");
+ uncodable_glyphs += glyph;
+ if (features.runparams().dryrun) {
+ options_encodable += "<" + _("LyX Warning: ")
+ + _("uncodable character") + " '";
+ options_encodable += c;
+ options_encodable += "'>";
+ }
+ } else
+ options_encodable += c;
+ }
+ } else
+ options_encodable = strOptions;
+
+ // On BUFFER_VIEW|UPDATE, warn user if we found uncodable glyphs
+ if (!features.runparams().dryrun && !uncodable_glyphs.empty()) {
+ frontend::Alert::warning(
+ _("Uncodable character in class options"),
+ support::bformat(
+ _("The class options of your document contain glyphs "
+ "that are unknown in the current document encoding "
+ "(namely %1$s).\nThese glyphs are omitted "
+ " from the output, which may result in "
+ "incomplete output."
+ "\n\nPlease select an appropriate "
+ "document encoding\n"
+ "(such as utf8) or change the "
+ "class options accordingly."),
+ uncodable_glyphs));
+ }
+ options_encodable = rtrim(options_encodable, ",");
+ os << '[' << options_encodable << ']';
}
os << '{' << from_ascii(tclass.latexname()) << "}\n";
// end of \documentclass defs
+ // The package options (via \PassOptionsToPackage)
+ os << from_ascii(features.getPackageOptions());
+
// if we use fontspec or newtxmath, we have to load the AMS packages here
string const ams = features.loadAMSPackages();
bool const ot1 = (main_font_encoding() == "default" || main_font_encoding() == "OT1");
}
if (!features.isProvided("geometry")
- && (use_geometry || nonstandard_papersize)) {
+ && (use_geometry || nonstandard_papersize)) {
odocstringstream ods;
if (!getGraphicsDriver("geometry").empty())
ods << getGraphicsDriver("geometry");
case PAPER_DEFAULT:
break;
}
- docstring const g_options = trim(ods.str(), ",");
+ docstring g_options = trim(ods.str(), ",");
os << "\\usepackage";
- if (!g_options.empty())
+ // geometry-light means that the class works with geometry, but overwrites
+ // the package options and paper sizes (memoir does this).
+ // In this case, all options need to go to \geometry
+ // and the standard paper sizes need to go to the class options.
+ if (!g_options.empty() && !features.isProvided("geometry-light")) {
os << '[' << g_options << ']';
+ g_options.clear();
+ }
os << "{geometry}\n";
- // output this only if use_geometry is true
- if (use_geometry) {
+ if (use_geometry || features.isProvided("geometry-light")) {
os << "\\geometry{verbose";
- if (!topmargin.empty())
- os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
- if (!bottommargin.empty())
- os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
- if (!leftmargin.empty())
- os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
- if (!rightmargin.empty())
- os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
- if (!headheight.empty())
- os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
- if (!headsep.empty())
- os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
- if (!footskip.empty())
- os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
- if (!columnsep.empty())
- os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
- os << "}\n";
+ if (!g_options.empty())
+ // Output general options here with "geometry light".
+ os << "," << g_options;
+ // output this only if use_geometry is true
+ if (use_geometry) {
+ if (!topmargin.empty())
+ os << ",tmargin=" << from_ascii(Length(topmargin).asLatexString());
+ if (!bottommargin.empty())
+ os << ",bmargin=" << from_ascii(Length(bottommargin).asLatexString());
+ if (!leftmargin.empty())
+ os << ",lmargin=" << from_ascii(Length(leftmargin).asLatexString());
+ if (!rightmargin.empty())
+ os << ",rmargin=" << from_ascii(Length(rightmargin).asLatexString());
+ if (!headheight.empty())
+ os << ",headheight=" << from_ascii(Length(headheight).asLatexString());
+ if (!headsep.empty())
+ os << ",headsep=" << from_ascii(Length(headsep).asLatexString());
+ if (!footskip.empty())
+ os << ",footskip=" << from_ascii(Length(footskip).asLatexString());
+ if (!columnsep.empty())
+ os << ",columnsep=" << from_ascii(Length(columnsep).asLatexString());
+ }
+ os << "}\n";
}
} else if (orientation == ORIENTATION_LANDSCAPE
|| papersize != PAPER_DEFAULT) {
os << "\\synctex=-1\n";
}
- // The package options (via \PassOptionsToPackage)
- os << from_ascii(features.getPackageOptions());
-
// due to interferences with babel and hyperref, the color package has to
// be loaded (when it is not already loaded) before babel when hyperref
// is used with the colorlinks option, see
OutputParams tmp_params = features.runparams();
pdfoptions().writeLaTeX(tmp_params, os,
features.isProvided("hyperref"));
- // correctly break URLs with hyperref and dvi output
- if (features.runparams().flavor == OutputParams::LATEX
+ // correctly break URLs with hyperref and dvi/ps output
+ if (features.runparams().hyperref_driver == "dvips"
&& features.isAvailable("breakurl"))
os << "\\usepackage{breakurl}\n";
} else if (features.isRequired("nameref"))
<< "\\makeatother\n\n";
// We try to load babel late, in case it interferes with other packages.
- // Jurabib, hyperref, varioref, bicaption and listings (bug 8995) have to be
- // called after babel, though.
+ // Jurabib, hyperref, varioref, bicaption, menukeys and listings (bug 8995)
+ // have to be called after babel, though.
if (use_babel && !features.isRequired("jurabib")
&& !features.isRequired("hyperref")
&& !features.isRequired("varioref")
if (!listings_params.empty()
|| features.mustProvide("listings")
|| features.mustProvide("minted")) {
- if (features.mustProvide("listings"))
- os << "\\usepackage{listings}\n";
- else
+ if (use_minted)
os << "\\usepackage{minted}\n";
- }
- if (!listings_params.empty()) {
- if (features.mustProvide("listings"))
- os << "\\lstset{";
else
+ os << "\\usepackage{listings}\n";
+ }
+ string lst_params = listings_params;
+ // If minted, do not output the language option (bug 11203)
+ if (use_minted && contains(lst_params, "language=")) {
+ vector<string> opts =
+ getVectorFromString(lst_params, ",", false);
+ for (size_t i = 0; i < opts.size(); ++i) {
+ if (prefixIs(opts[i], "language="))
+ opts.erase(opts.begin() + i--);
+ }
+ lst_params = getStringFromVector(opts, ",");
+ }
+ if (!lst_params.empty()) {
+ if (use_minted)
os << "\\setminted{";
+ else
+ os << "\\lstset{";
// do not test validity because listings_params is
// supposed to be valid
string par =
- InsetListingsParams(listings_params).separatedParams(true);
+ InsetListingsParams(lst_params).separatedParams(true);
os << from_utf8(par);
os << "}\n";
}
os << "\\usepackage{xunicode}\n";
}
+ // covington must be loaded after beamerarticle
+ if (features.isRequired("covington"))
+ os << "\\usepackage{covington}\n";
+
// Polyglossia must be loaded last ...
if (use_polyglossia) {
// call the package
os << '\n';
}
+ // Since menukeys uses catoptions, which does some heavy changes on key-value options,
+ // it is recommended to load menukeys as the last package (even after hyperref)
+ if (features.isRequired("menukeys"))
+ os << "\\usepackage{menukeys}\n";
+
docstring const i18npreamble =
features.getTClassI18nPreamble(use_babel, use_polyglossia,
use_minted);
}
-bool BufferParams::setBaseClass(string const & classname)
+bool BufferParams::setBaseClass(string const & classname, string const & path)
{
LYXERR(Debug::TCLASS, "setBaseClass: " << classname);
LayoutFileList & bcl = LayoutFileList::get();
bcl.addEmptyClass(classname);
}
- bool const success = bcl[classname].load();
+ bool const success = bcl[classname].load(path);
if (!success) {
docstring s =
bformat(_("Due to some error in it, the layout file:\n"
// Load the CJK package if needed by a secondary language.
// If the main encoding is some variant of UTF8, use CJKutf8.
if (encoding().package() != Encoding::CJK && features.mustProvide("CJK")) {
- if (encoding().iconvName() == "UTF-8"
+ if (language->encoding()->name() == "utf8-cjk"
&& LaTeXFeatures::isAvailable("CJKutf8"))
os << "\\usepackage{CJKutf8}\n";
else
string const & BufferParams::defaultBiblioStyle() const
{
+ if (!biblio_style.empty())
+ return biblio_style;
+
map<string, string> const & bs = documentClass().defaultBiblioStyle();
auto cit = bs.find(theCiteEnginesList.getTypeAsString(citeEngineType()));
if (cit != bs.end())
}
-string const BufferParams::bibtexCommand() const
+string const BufferParams::getBibtexCommand(string const cmd, bool const warn) const
+{
+ // split from options
+ string command_in;
+ split(cmd, command_in, ' ');
+
+ // Look if the requested command is available. If so, use that.
+ for (auto const & alts : lyxrc.bibtex_alternatives) {
+ string command_prov;
+ split(alts, command_prov, ' ');
+ if (command_in == command_prov)
+ return cmd;
+ }
+
+ // If not, find the most suitable fallback for the current cite framework,
+ // and warn. Note that we omit options in any such case.
+ string fallback;
+ if (useBiblatex()) {
+ // For Biblatex, we prefer biber (also for Japanese)
+ // and try to fall back to bibtex8
+ if (lyxrc.bibtex_alternatives.find("biber") != lyxrc.bibtex_alternatives.end())
+ fallback = "biber";
+ else if (lyxrc.bibtex_alternatives.find("bibtex8") != lyxrc.bibtex_alternatives.end())
+ fallback = "bibtex8";
+ }
+ // For classic BibTeX and as last resort for biblatex, try bibtex
+ if (fallback.empty()) {
+ if (lyxrc.bibtex_alternatives.find("bibtex") != lyxrc.bibtex_alternatives.end())
+ fallback = "bibtex";
+ }
+
+ if (!warn)
+ return fallback;
+
+ if (fallback.empty()) {
+ frontend::Alert::warning(
+ _("No bibliography processor found!"),
+ support::bformat(
+ _("The bibliography processor requested by this document "
+ "(%1$s) is not available and no appropriate "
+ "alternative has been found. "
+ "No bibliography and references will be generated.\n"
+ "Please fix your installation!"),
+ from_utf8(cmd)));
+ } else {
+ frontend::Alert::warning(
+ _("Requested bibliography processor not found!"),
+ support::bformat(
+ _("The bibliography processor requested by this document "
+ "(%1$s) is not available. "
+ "As a fallback, '%2$s' will be used, options are omitted. "
+ "This might result in errors or unwanted changes in "
+ "the bibliography. Please check carefully!\n"
+ "It is suggested to install the missing processor."),
+ from_utf8(cmd), from_utf8(fallback)));
+ }
+ return fallback;
+}
+
+
+string const BufferParams::bibtexCommand(bool const warn) const
{
// Return document-specific setting if available
if (bibtex_command != "default")
- return bibtex_command;
+ return getBibtexCommand(bibtex_command, warn);
// If we have "default" in document settings, consult the prefs
// 1. Japanese (uses a specific processor)
// 2. All other languages
else if (lyxrc.bibtex_command != "automatic")
// Return the specified program, if "automatic" is not set
- return lyxrc.bibtex_command;
+ return getBibtexCommand(lyxrc.bibtex_command, warn);
// 3. Automatic: find the most suitable for the current cite framework
if (useBiblatex()) {
pimpl_->isViewCacheValid = false;
}
+
+// We shouldn't need to reset the params here, since anything
+// we need will be recopied.
+void BufferParams::copyForAdvFR(const BufferParams & bp)
+{
+ string const & lang = bp.language->lang();
+ setLanguage(lang);
+ layout_modules_ = bp.layout_modules_;
+ string const & doc_class = bp.documentClass().name();
+ setBaseClass(doc_class);
+}
+
} // namespace lyx