#include "ColorSet.h"
#include "Converter.h"
#include "Encoding.h"
-#include "HSpace.h"
#include "IndicesList.h"
#include "Language.h"
#include "LaTeXFeatures.h"
#include "LaTeXFonts.h"
+#include "Length.h"
#include "ModuleList.h"
#include "Font.h"
#include "Lexer.h"
return false;
}
-} // anon namespace
+} // namespace
class BufferParams::Impl
Bullet user_defined_bullets[4];
IndicesList indiceslist;
Spacing spacing;
+ Length parindent;
+ Length mathindent;
/** This is the amount of space used for paragraph_separation "skip",
* and for detached paragraphs in "indented" documents.
*/
- HSpace indentation;
VSpace defskip;
PDFOptions pdfoptions;
LayoutFileIndex baseClass_;
cite_engine_type_ = ENGINE_TYPE_DEFAULT;
makeDocumentClass();
paragraph_separation = ParagraphIndentSeparation;
+ is_math_indent = false;
+ math_numbering_side = DEFAULT;
quotes_style = InsetQuotesParams::EnglishQuotes;
dynamic_quotes = false;
fontsize = "default";
papersize = PAPER_DEFAULT;
orientation = ORIENTATION_PORTRAIT;
use_geometry = false;
- biblio_style = "plain";
+ biblio_style = string();
use_bibtopic = false;
multibib = string();
use_indices = false;
html_css_as_file = false;
display_pixel_ratio = 1.0;
+ shell_escape = false;
output_sync = false;
use_refstyle = true;
+ use_minted = false;
// map current author
author_map_[pimpl_->authorlist.get(0).bufferId()] = 0;
}
-HSpace const & BufferParams::getIndentation() const
+Length const & BufferParams::getMathIndent() const
{
- return pimpl_->indentation;
+ return pimpl_->mathindent;
}
-void BufferParams::setIndentation(HSpace const & indent)
+void BufferParams::setMathIndent(Length const & indent)
{
- pimpl_->indentation = indent;
+ pimpl_->mathindent = indent;
+}
+
+
+Length const & BufferParams::getParIndent() const
+{
+ return pimpl_->parindent;
+}
+
+
+void BufferParams::setParIndent(Length const & indent)
+{
+ pimpl_->parindent = indent;
}
}
+BufferParams::MathNumber BufferParams::getMathNumber() const
+{
+ if (math_numbering_side != DEFAULT)
+ return math_numbering_side;
+ // FIXME: do not hardcode language here
+ else if (language->lang() == "arabic_arabi"
+ || documentClass().provides("leqno"))
+ return LEFT;
+ else
+ return RIGHT;
+}
+
+
string BufferParams::readToken(Lexer & lex, string const & token,
FileName const & filepath)
{
paragraph_separation = parseptranslator().find(parsep);
} else if (token == "\\paragraph_indentation") {
lex.next();
- string indentation = lex.getString();
- pimpl_->indentation = HSpace(indentation);
+ string parindent = lex.getString();
+ if (parindent == "default")
+ pimpl_->parindent = Length();
+ else
+ pimpl_->parindent = Length(parindent);
} else if (token == "\\defskip") {
lex.next();
string const defskip = lex.getString();
if (pimpl_->defskip.kind() == VSpace::DEFSKIP)
// that is invalid
pimpl_->defskip = VSpace(VSpace::MEDSKIP);
+ } else if (token == "\\is_math_indent") {
+ lex >> is_math_indent;
+ } else if (token == "\\math_indentation") {
+ lex.next();
+ string mathindent = lex.getString();
+ if (mathindent == "default")
+ pimpl_->mathindent = Length();
+ else
+ pimpl_->mathindent = Length(mathindent);
+ } else if (token == "\\math_numbering_side") {
+ string tmp;
+ lex >> tmp;
+ if (tmp == "left")
+ math_numbering_side = LEFT;
+ else if (tmp == "right")
+ math_numbering_side = RIGHT;
+ else
+ math_numbering_side = DEFAULT;
} else if (token == "\\quotes_style") {
string qstyle;
lex >> qstyle;
lex >> output_sync_macro;
} else if (token == "\\use_refstyle") {
lex >> use_refstyle;
+ } else if (token == "\\use_minted") {
+ lex >> use_minted;
} else {
lyxerr << "BufferParams::readToken(): Unknown token: " <<
token << endl;
return "\"" + str + "\"";
return str;
}
-}
+} // namespace
void BufferParams::writeFile(ostream & os, Buffer const * buf) const
<< "\n\\suppress_date " << convert<string>(suppress_date)
<< "\n\\justification " << convert<string>(justification)
<< "\n\\use_refstyle " << use_refstyle
+ << "\n\\use_minted " << use_minted
<< '\n';
if (isbackgroundcolor == true)
os << "\\backgroundcolor " << lyx::X11hexname(backgroundcolor) << '\n';
<< "\n\\paragraph_separation "
<< string_paragraph_separation[paragraph_separation];
if (!paragraph_separation)
- os << "\n\\paragraph_indentation " << getIndentation().asLyXCommand();
+ os << "\n\\paragraph_indentation "
+ << (getParIndent().empty() ? "default" : getParIndent().asString());
else
os << "\n\\defskip " << getDefSkip().asLyXCommand();
+ os << "\n\\is_math_indent " << is_math_indent;
+ if (is_math_indent)
+ os << "\n\\math_indentation "
+ << (getMathIndent().empty() ? "default" : getMathIndent().asString());
+ os << "\n\\math_numbering_side ";
+ switch(math_numbering_side) {
+ case LEFT:
+ os << "left";
+ break;
+ case RIGHT:
+ os << "right";
+ break;
+ case DEFAULT:
+ os << "default";
+ }
os << "\n\\quotes_style "
<< string_quotes_style[quotes_style]
<< "\n\\dynamic_quotes " << dynamic_quotes
if (useNonTeXFonts && fontsMath() != "auto")
features.require("unicode-math");
-
+
if (use_microtype)
features.require("microtype");
&& papersize != PAPER_A5
&& papersize != PAPER_B5;
- if (!use_geometry) {
+ if (!use_geometry || features.isProvided("geometry-light")) {
switch (papersize) {
case PAPER_A4:
clsoptions << "a4paper,";
&& orientation == ORIENTATION_LANDSCAPE)
clsoptions << "landscape,";
+ if (is_math_indent)
+ clsoptions << "fleqn,";
+
+ switch(math_numbering_side) {
+ case LEFT:
+ clsoptions << "leqno,";
+ break;
+ case RIGHT:
+ clsoptions << "reqno,";
+ features.require("amsmath");
+ break;
+ case DEFAULT:
+ break;
+ }
+
// language should be a parameter to \documentclass
if (language->babel() == "hebrew"
&& default_language->babel() != "hebrew")
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) {
} else {
// when separation by indentation
// only output something when a width is given
- if (getIndentation().asLyXCommand() != "default") {
+ if (!getParIndent().empty()) {
os << "\\setlength{\\parindent}{"
- << from_utf8(getIndentation().asLatexCommand())
+ << from_utf8(getParIndent().asLatexString())
+ << "}\n";
+ }
+ }
+
+ if (is_math_indent) {
+ // when formula indentation
+ // only output something when it is not the default
+ if (!getMathIndent().empty()) {
+ os << "\\setlength{\\mathindent}{"
+ << from_utf8(getMathIndent().asString())
<< "}\n";
}
}
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
// http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg144349.html
os << from_ascii(features.getColorOptions());
- // If we use hyperref, jurabib, japanese, varioref or vietnamese,
+ // If we use hyperref, jurabib, japanese or varioref,
// we have to call babel before
if (use_babel
&& (features.isRequired("jurabib")
|| features.isRequired("hyperref")
|| features.isRequired("varioref")
- || features.isRequired("vietnamese")
|| features.isRequired("japanese"))) {
os << features.getBabelPresettings();
// FIXME UNICODE
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")
- && !features.isRequired("vietnamese")
+ && !features.isRequired("varioref")
&& !features.isRequired("japanese")) {
os << features.getBabelPresettings();
// FIXME UNICODE
}
if (features.isRequired("bicaption"))
os << "\\usepackage{bicaption}\n";
- if (!listings_params.empty() || features.mustProvide("listings"))
- os << "\\usepackage{listings}\n";
- if (!listings_params.empty()) {
- os << "\\lstset{";
+ if (!listings_params.empty()
+ || features.mustProvide("listings")
+ || features.mustProvide("minted")) {
+ if (use_minted)
+ os << "\\usepackage{minted}\n";
+ 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";
}
// (the rest is obsoleted by the new TU encoding).
// It needs to be loaded at least after amsmath, amssymb,
// esint and the other packages that provide special glyphs
- if (features.mustProvide("tipa") && useNonTeXFonts) {
+ if (features.mustProvide("tipa") && useNonTeXFonts
+ && !features.isProvided("xunicode")) {
// The package officially only supports XeTeX, but also works
// with LuaTeX. Thus we work around its XeTeX test.
if (features.runparams().flavor != OutputParams::XETEX) {
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
}
// ... but before biblatex (see #7065)
- if (features.mustProvide("biblatex")) {
+ if (features.mustProvide("biblatex")
+ && !features.isProvided("biblatex-natbib")
+ && !features.isProvided("natbib-internal")
+ && !features.isProvided("natbib")
+ && !features.isProvided("jurabib")) {
string delim = "";
string opts;
os << "\\usepackage";
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);
+ features.getTClassI18nPreamble(use_babel, use_polyglossia,
+ use_minted);
if (!i18npreamble.empty())
os << i18npreamble + '\n';
}
-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"
{
FormatList & cached = only_viewable ?
pimpl_->viewableFormatList : pimpl_->exportableFormatList;
- bool & valid = only_viewable ?
+ bool & valid = only_viewable ?
pimpl_->isViewCacheValid : pimpl_->isExportCacheValid;
if (valid)
return cached;
theConverters().getReachable(backs[0], only_viewable, true, excludes);
for (vector<string>::const_iterator it = backs.begin() + 1;
it != backs.end(); ++it) {
- FormatList r = theConverters().getReachable(*it, only_viewable,
+ FormatList r = theConverters().getReachable(*it, only_viewable,
false, excludes);
result.insert(result.end(), r.begin(), r.end());
}
v.push_back("luatex");
v.push_back("dviluatex");
}
- } else
- v.push_back(buffmt);
+ } else {
+ string rbuffmt = buffmt;
+ // If we use an OutputFormat in Japanese docs,
+ // we need special format in order to get the path
+ // via pLaTeX (#8823)
+ if (documentClass().hasOutputFormat()
+ && encoding().package() == Encoding::japanese)
+ rbuffmt += "-ja";
+ v.push_back(rbuffmt);
+ }
v.push_back("xhtml");
v.push_back("text");
if (!default_output_format.empty()
&& default_output_format != "default")
return default_output_format;
- if (isDocBook()
- || encoding().package() == Encoding::japanese) {
+ if (isDocBook()) {
FormatList const & formats = exportableFormats(true);
if (formats.empty())
return string();
// return the first we find
return formats.front()->name();
}
+ if (encoding().package() == Encoding::japanese)
+ return lyxrc.default_platex_view_format;
if (useNonTeXFonts)
return lyxrc.default_otf_view_format;
return lyxrc.default_view_format;
// 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
Encoding const & BufferParams::encoding() const
{
// Main encoding for LaTeX output.
- //
+ //
// Exception: XeTeX with 8-bit TeX fonts requires ASCII (see #9740).
// As the "flavor" is only known once export started, this
// cannot be handled here. Instead, runparams.encoding is set
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())
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