#include "Encoding.h"
#include "LayoutFile.h"
-#include "Layout.h"
#include "Lexer.h"
#include "TextClass.h"
#include "version.h"
#include "support/filetools.h"
#include "support/lstrings.h"
-#include "support/regex.h"
-
#include <algorithm>
#include <iostream>
+#include <regex>
using namespace std;
using namespace lyx::support;
const char * const known_polish_quotes_languages[] = {"afrikaans", "bosnian", "croatian",
"dutch", "magyar", "polish", "romanian", "serbian", "serbian-latin", 0};
+/// languages with hungarian quotes (.lyx names)
+const char * const known_hungarian_quotes_languages[] = {"magyar", 0};
+
/// languages with russian quotes (.lyx names)
const char * const known_russian_quotes_languages[] = {"azerbaijani", "oldrussian",
"russian", "ukrainian", 0};
const char * const known_sans_font_packages[] = { "avant", "berasans", "biolinum",
"biolinum-type1", "cantarell", "Chivo", "cmbr", "cmss", "DejaVuSans", "DejaVuSansCondensed", "FiraSans", "helvet", "iwona",
-"iwonac", "iwonal", "iwonalc", "kurier", "kurierc", "kurierl", "kurierlc", "lmss", "noto-sans", "PTSans",
+"iwonac", "iwonal", "iwonalc", "kurier", "kurierc", "kurierl", "kurierlc", "LibertinusSans-LF", "lmss", "noto-sans", "PTSans",
"tgadventor", "tgheros", "uop", 0 };
const char * const known_typewriter_font_packages[] = { "beramono", "cmtl", "cmtt", "courier", "DejaVuSansMono",
-"FiraMono", "lmtt", "luximono", "libertineMono", "libertineMono-type1", "lmodern",
+"FiraMono", "lmtt", "luximono", "libertineMono", "libertineMono-type1", "LibertinusMono-TLF", "lmodern",
"mathpazo", "mathptmx", "newcent", "noto-mono", "PTMono", "tgcursor", "txtt", 0 };
const char * const known_math_font_packages[] = { "eulervm", "newtxmath", 0};
const char * const known_lyx_packages[] = {"amsbsy", "amsmath", "amssymb",
"amstext", "amsthm", "array", "babel", "booktabs", "calc", "CJK", "color",
"float", "fontspec", "framed", "graphicx", "hhline", "ifthen", "longtable",
-"makeidx", "minted", "multirow", "nomencl", "pdfpages", "prettyref", "refstyle",
+"makeidx", "minted", "multirow", "nomencl", "parskip", "pdfpages", "prettyref", "refstyle",
"rotating", "rotfloat", "splitidx", "setspace", "subscript", "tabularx","textcomp", "tipa",
"tipx", "tone", "ulem", "url", "varioref", "verbatim", "wrapfig", "xcolor", "xltabular",
"xunicode", 0};
* \p options and return the value.
* The found option is also removed from \p options.
*/
-string process_keyval_opt(vector<string> & options, string name)
+string process_keyval_opt(vector<string> & options, string const & name)
{
for (size_t i = 0; i < options.size(); ++i) {
vector<string> option;
void Preamble::add_package(string const & name, vector<string> & options)
{
// every package inherits the global options
- if (used_packages.find(name) == used_packages.end())
- used_packages[name] = split_options(h_options);
+ used_packages.insert({name, split_options(h_options)});
// Insert options passed via PassOptionsToPackage
for (auto const & p : extra_package_options_) {
}
}
+void Preamble::setTextClass(string const & tclass, TeX2LyXDocClass & tc)
+{
+ h_textclass = tclass;
+ tc.setName(h_textclass);
+ if (!LayoutFileList::get().haveClass(h_textclass) || !tc.load()) {
+ cerr << "Error: Could not read layout file for textclass \"" << h_textclass << "\"." << endl;
+ exit(EXIT_FAILURE);
+ }
+}
+
namespace {
h_html_be_strict = "false";
h_html_css_as_file = "0";
h_html_math_output = "0";
+ h_docbook_table_output = "0";
+ h_docbook_mathml_prefix = "1";
h_index[0] = "Index";
h_index_command = "default";
h_inputencoding = "auto-legacy";
h_font_roman_osf = "true";
}
+ if (name == "libertinus" || name == "libertinus-type1") {
+ bool sf = true;
+ bool tt = true;
+ bool rm = true;
+ bool osf = false;
+ string scalesf;
+ string scalett;
+ for (auto const & opt : allopts) {
+ if (opt == "rm" || opt == "serif") {
+ tt = false;
+ sf = false;
+ continue;
+ }
+ if (opt == "sf" || opt == "sans") {
+ tt = false;
+ rm = false;
+ continue;
+ }
+ if (opt == "tt=false" || opt == "mono=false") {
+ tt = false;
+ continue;
+ }
+ if (opt == "osf") {
+ osf = true;
+ continue;
+ }
+ if (opt == "scaleSF") {
+ scalesf = opt;
+ continue;
+ }
+ if (opt == "scaleTT") {
+ scalett = opt;
+ continue;
+ }
+ if (opt == "lining") {
+ h_font_roman_osf = "false";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (rm) {
+ h_font_roman[0] = "libertinus";
+ if (osf)
+ h_font_roman_osf = "true";
+ else
+ h_font_roman_osf = "false";
+ }
+ if (sf) {
+ h_font_sans[0] = "LibertinusSans-LF";
+ if (osf)
+ h_font_sans_osf = "true";
+ else
+ h_font_sans_osf = "false";
+ if (!scalesf.empty())
+ scale_as_percentage(scalesf, h_font_sf_scale[0]);
+ }
+ if (tt) {
+ h_font_typewriter[0] = "LibertinusMono-TLF";
+ if (!scalett.empty())
+ scale_as_percentage(scalett, h_font_tt_scale[0]);
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
+ }
+
if (name == "MinionPro") {
h_font_roman[0] = "minionpro";
h_font_roman_osf = "true";
delete_opt(options, o);
}
+ else if (name == "parskip" && options.size() < 2 && (opts.empty() || prefixIs(opts, "skip="))) {
+ if (opts.empty())
+ h_paragraph_separation = "halfline";
+ else {
+ if (opts == "skip=\\smallskipamount")
+ h_defskip = "smallskip";
+ else if (opts == "skip=\\medskipamount")
+ h_defskip = "medskip";
+ else if (opts == "skip=\\bigskipamount")
+ h_defskip = "bigskip";
+ else if (opts == "skip=\\baselineskip")
+ h_defskip = "fullline";
+ else
+ h_defskip = "opts";
+ h_paragraph_separation = "skip";
+ }
+ }
+
else if (is_known(name, known_lyx_packages) && options.empty()) {
if (name == "splitidx")
h_use_indices = "true";
h_use_refstyle = true;
else if (name == "prettyref")
h_use_refstyle = false;
+
if (!in_lyx_preamble) {
h_preamble << package_beg_sep << name
<< package_mid_sep << "\\usepackage{"
<< "\\save_transient_properties " << h_save_transient_properties << "\n"
<< "\\origin " << origin << "\n"
<< "\\textclass " << h_textclass << "\n";
+ if (!h_doc_metadata.empty()) {
+ os << "\\begin_metadata\n"
+ << h_doc_metadata
+ << "\n\\end_metadata\n";
+ }
string const raw = subdoc ? empty_string() : h_preamble.str();
if (!raw.empty()) {
os << "\\begin_preamble\n";
<< "\\html_math_output " << h_html_math_output << "\n"
<< "\\html_css_as_file " << h_html_css_as_file << "\n"
<< "\\html_be_strict " << h_html_be_strict << "\n"
+ << "\\docbook_table_output " << h_docbook_table_output << "\n"
+ << "\\docbook_mathml_prefix " << h_docbook_mathml_prefix << "\n"
<< authors_
<< "\\end_header\n\n"
<< "\\begin_body\n";
bool is_full_document = false;
bool is_lyx_file = false;
bool in_lyx_preamble = false;
+ bool class_set = false;
// determine whether this is a full document or a fragment for inclusion
while (p.good()) {
if (detectEncoding && !is_full_document)
return;
+ // Force textclass if the user wanted it
+ if (!forceclass.empty()) {
+ setTextClass(forceclass, tc);
+ class_set = true;
+ }
+
while (is_full_document && p.good()) {
if (detectEncoding && h_inputencoding != "auto-legacy" &&
h_inputencoding != "auto-legacy-plain")
p.skip_spaces();
in_lyx_preamble = true;
}
- if (name == "\\sfdefault")
+ if (name == "\\sfdefault") {
if (is_known(body, known_sans_font_packages)) {
h_font_sans[0] = body;
p.skip_spaces();
in_lyx_preamble = true;
}
+ if (body == "LibertinusSans-OsF") {
+ h_font_sans[0] = "LibertinusSans-LF";
+ h_font_sans_osf = "true";
+ p.skip_spaces();
+ in_lyx_preamble = true;
+ }
+ }
if (name == "\\ttdefault")
if (is_known(body, known_typewriter_font_packages)) {
h_font_typewriter[0] = body;
p.skip_spaces();
in_lyx_preamble = true;
}
+ if (name == "\\LibertinusSans@scale") {
+ if (isStrDbl(body)) {
+ h_font_sf_scale[0] = convert<string>(
+ static_cast<int>(100 * convert<double>(body)));
+ }
+ }
+ if (name == "\\LibertinusMono@scale") {
+ if (isStrDbl(body)) {
+ h_font_tt_scale[0] = convert<string>(
+ static_cast<int>(100 * convert<double>(body)));
+ }
+ }
// remove LyX-specific definitions that are re-added by LyX
// if necessary
vector<string> opts = split_options(p.getArg('[', ']'));
// FIXME This does not work for classes that have a
// different name in LyX than in LaTeX
- h_textclass = p.getArg('{', '}');
+ string const tclass = p.getArg('{', '}');
p.skip_spaces();
- // Force textclass if the user wanted it
- if (!forceclass.empty())
- h_textclass = forceclass;
- tc.setName(h_textclass);
- if (!LayoutFileList::get().haveClass(h_textclass) || !tc.load()) {
- cerr << "Error: Could not read layout file for textclass \"" << h_textclass << "\"." << endl;
- exit(EXIT_FAILURE);
+ // Only set text class if a class hasn't been forced
+ // (this was set above)
+ if (!class_set) {
+ // textclass needs to be set at this place (if not already done)
+ // as we need to know it for other parameters
+ // (such as class-dependent paper size)
+ setTextClass(tclass, tc);
+ class_set = true;
}
// Font sizes.
// paper sizes
// some size options are known by the document class, other sizes
// are handled by the \geometry command of the geometry package
- string paper;
vector<string> class_psizes = getVectorFromString(tc.opt_pagesize(), "|");
string const psize_format = tc.pagesizeformat();
for (auto const & psize : class_psizes) {
continue;
}
+ if (t.cs() == "DocumentMetadata") {
+ h_doc_metadata = trimSpaceAndEol(p.getArg('{', '}'));
+ continue;
+ }
+
if (t.cs() == "usepackage") {
string const options = p.getArg('[', ']');
string const name = p.getArg('{', '}');
string const name = p.verbatim_item();
string const content = p.verbatim_item();
// the paragraphs are only not indented when \parindent is set to zero
- if (name == "\\parindent" && content != "") {
- if (content[0] == '0')
- h_paragraph_separation = "skip";
- else
- h_paragraph_indentation = translate_len(content);
- } else if (name == "\\parskip") {
+ if (name == "\\parindent" && content != "")
+ h_paragraph_indentation = translate_len(content);
+ else if (name == "\\parskip" && isPackageUsed("parskip")) {
if (content == "\\smallskipamount")
h_defskip = "smallskip";
else if (content == "\\medskipamount")
h_defskip = "medskip";
else if (content == "\\bigskipamount")
h_defskip = "bigskip";
+ else if (content == "\\baselineskip")
+ h_defskip = "fullline";
else
h_defskip = translate_len(content);
} else if (name == "\\mathindent") {
}
}
+ // set textclass if not yet done (snippets without \documentclass and forced class)
+ if (!class_set)
+ setTextClass(h_textclass, tc);
+
// remove the whitespace
p.skip_spaces();
// polish
else if (is_known(h_language, known_polish_quotes_languages))
h_quotes_style = "polish";
+ // hungarian
+ else if (is_known(h_language, known_hungarian_quotes_languages))
+ h_quotes_style = "hungarian";
// russian
else if (is_known(h_language, known_russian_quotes_languages))
h_quotes_style = "russian";