char const * const known_fontsizes[] = { "10pt", "11pt", "12pt", 0 };
const char * const known_roman_font_packages[] = { "ae", "beraserif", "bookman",
-"ccfonts", "chancery", "charter", "cmr", "cochineal", "crimson", "DejaVuSerif", "DejaVuSerifCondensed", "fourier",
-"garamondx", "libertine", "libertineRoman", "libertine-type1", "lmodern", "mathdesign", "mathpazo",
-"mathptmx", "MinionPro", "newcent", "noto", "noto-serif", "PTSerif", "tgbonum", "tgchorus",
-"tgpagella", "tgschola", "tgtermes", "utopia", "xcharter", 0 };
+"ccfonts", "chancery", "charter", "cmr", "cochineal", "crimson", "CrimsonPro", "DejaVuSerif",
+"DejaVuSerifCondensed", "fourier", "garamondx", "libertine", "libertineRoman", "libertine-type1",
+"lmodern", "mathdesign", "mathpazo", "mathptmx", "MinionPro", "newcent", "noto", "noto-serif",
+"PTSerif", "tgbonum", "tgchorus", "tgpagella", "tgschola", "tgtermes", "utopia", "xcharter", 0 };
const char * const known_sans_font_packages[] = { "avant", "berasans", "biolinum",
-"biolinum-type1", "cmbr", "cmss", "DejaVuSans", "DejaVuSansCondensed", "helvet", "iwona", "iwonac", "iwonal", "iwonalc",
-"kurier", "kurierc", "kurierl", "kurierlc", "lmss", "noto", "noto-sans", "PTSans",
+"biolinum-type1", "cantarell", "Chivo", "cmbr", "cmss", "DejaVuSans", "DejaVuSansCondensed", "FiraSans", "helvet", "iwona",
+"iwonac", "iwonal", "iwonalc", "kurier", "kurierc", "kurierl", "kurierlc", "lmss", "noto-sans", "PTSans",
"tgadventor", "tgheros", "uop", 0 };
-const char * const known_typewriter_font_packages[] = { "beramono", "cmtl", "cmtt",
-"courier", "DejaVuSansMono", "lmtt", "luximono", "fourier", "libertineMono", "libertineMono-type1", "lmodern",
-"mathpazo", "mathptmx", "newcent", "noto", "noto-mono", "PTMono", "tgcursor", "txtt", 0 };
+const char * const known_typewriter_font_packages[] = { "beramono", "cmtl", "cmtt", "courier", "DejaVuSansMono",
+"FiraMono", "lmtt", "luximono", "libertineMono", "libertineMono-type1", "lmodern",
+"mathpazo", "mathptmx", "newcent", "noto-mono", "PTMono", "tgcursor", "txtt", 0 };
const char * const known_math_font_packages[] = { "eulervm", "newtxmath", 0};
-const char * const known_paper_sizes[] = { "a0paper", "b0paper", "c0paper",
+const char * const known_latex_paper_sizes[] = { "a0paper", "b0paper", "c0paper",
"a1paper", "b1paper", "c1paper", "a2paper", "b2paper", "c2paper", "a3paper",
"b3paper", "c3paper", "a4paper", "b4paper", "c4paper", "a5paper", "b5paper",
"c5paper", "a6paper", "b6paper", "c6paper", "executivepaper", "legalpaper",
"letterpaper", "b0j", "b1j", "b2j", "b3j", "b4j", "b5j", "b6j", 0};
-const char * const known_class_paper_sizes[] = { "a4paper", "a5paper",
-"executivepaper", "legalpaper", "letterpaper", 0};
-
const char * const known_paper_margins[] = { "lmargin", "tmargin", "rmargin",
"bmargin", "headheight", "headsep", "footskip", "columnsep", 0};
}
-void Preamble::registerAuthor(std::string const & name)
+void Preamble::registerAuthor(std::string const & name, string const & initials)
{
- Author author(from_utf8(name), empty_docstring());
+ Author author(from_utf8(name), empty_docstring(), from_utf8(initials));
author.setUsed(true);
authors_.record(author);
h_tracking_changes = "true";
Author const & Preamble::getAuthor(std::string const & name) const
{
- Author author(from_utf8(name), empty_docstring());
+ Author author(from_utf8(name), empty_docstring(), empty_docstring());
for (AuthorList::Authors::const_iterator it = authors_.begin();
it != authors_.end(); ++it)
if (*it == author)
namespace {
-// Given is a string like "scaled=0.9" or "Scale=0.9", return 0.9 * 100
+// Given is a string like "scaled=0.9" or "scale=0.9", return 0.9 * 100
bool scale_as_percentage(string const & scale, string & percentage)
{
- string::size_type pos = scale.find('=');
- if (pos != string::npos) {
- string value = scale.substr(pos + 1);
+ if (contains(scale, '=')) {
+ string const value = support::split(scale, '=');
if (isStrDbl(value)) {
percentage = convert<string>(
static_cast<int>(100 * convert<double>(value)));
Preamble::Preamble() : one_language(true), explicit_babel(false),
- title_layout_found(false), index_number(0), h_font_cjk_set(false),
- h_use_microtype("false")
+ title_layout_found(false), index_number(0), h_font_cjk_set(false)
{
//h_backgroundcolor;
//h_boxbgcolor;
h_font_default_family = "default";
h_use_non_tex_fonts = false;
h_font_sc = "false";
- h_font_osf = "false";
+ h_font_roman_osf = "false";
+ h_font_sans_osf = "false";
+ h_font_typewriter_osf = "false";
h_font_sf_scale[0] = "100";
h_font_sf_scale[1] = "100";
h_font_tt_scale[0] = "100";
h_font_tt_scale[1] = "100";
+ // h_font_roman_opts;
+ // h_font_sans_opts;
+ // h_font_typewriter_opts;
//h_font_cjk
h_is_mathindent = "0";
h_math_numbering_side = "default";
//h_notefontcolor;
//h_options;
h_output_changes = "false";
+ h_change_bars = "false";
h_output_sync = "0";
//h_output_sync_macro
h_papercolumns = "1";
h_use_default_options = "false";
h_use_hyperref = "false";
h_use_microtype = "false";
+ h_use_lineno = "false";
h_use_refstyle = false;
h_use_minted = false;
h_use_packages["amsmath"] = "1";
options.erase(it);
}
// paper size
- // keyval version: "paper=letter"
+ // keyval version: "paper=letter" or "paper=letterpaper"
string paper = process_keyval_opt(options, "paper");
if (!paper.empty())
- h_papersize = paper + "paper";
+ if (suffixIs(paper, "paper"))
+ paper = subst(paper, "paper", "");
// alternative version: "letterpaper"
- handle_opt(options, known_paper_sizes, h_papersize);
- delete_opt(options, known_paper_sizes);
+ handle_opt(options, known_latex_paper_sizes, paper);
+ if (suffixIs(paper, "paper"))
+ paper = subst(paper, "paper", "");
+ delete_opt(options, known_latex_paper_sizes);
+ if (!paper.empty())
+ h_papersize = paper;
// page margins
char const * const * margin = known_paper_margins;
for (; *margin; ++margin) {
p.setEncoding("UTF-8");
}
+ // vector of all options for easier parsing and
+ // skipping
+ vector<string> allopts = getVectorFromString(opts);
+ // this stores the potential extra options
+ string xopts;
+
+ //
// roman fonts
+ //
+
+ // By default, we use the package name as LyX font name,
+ // so this only needs to be reset if these names differ
if (is_known(name, known_roman_font_packages))
h_font_roman[0] = name;
+ if (name == "ccfonts") {
+ for (auto const & opt : allopts) {
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
+ }
+
+ if (name == "lmodern") {
+ for (auto const & opt : allopts) {
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
+ }
+
if (name == "fourier") {
h_font_roman[0] = "utopia";
- // when font uses real small capitals
- if (opts == "expert")
- h_font_sc = "true";
+ for (auto const & opt : allopts) {
+ if (opt == "osf") {
+ h_font_roman_osf = "true";
+ continue;
+ }
+ if (opt == "expert") {
+ h_font_sc = "true";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
}
if (name == "garamondx") {
- h_font_roman[0] = "garamondx";
- if (opts == "osfI")
- h_font_osf = "true";
+ for (auto const & opt : allopts) {
+ if (opt == "osfI") {
+ h_font_roman_osf = "true";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
}
if (name == "libertine") {
- h_font_roman[0] = "libertine";
// this automatically invokes biolinum
h_font_sans[0] = "biolinum";
// as well as libertineMono
h_font_typewriter[0] = "libertine-mono";
- if (opts == "osf")
- h_font_osf = "true";
- else if (opts == "lining")
- h_font_osf = "false";
+ for (auto const & opt : allopts) {
+ if (opt == "osf") {
+ h_font_roman_osf = "true";
+ continue;
+ }
+ if (opt == "lining") {
+ h_font_roman_osf = "false";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
}
if (name == "libertineRoman" || name == "libertine-type1") {
// and libertine-type1 do not automatically invoke
// biolinum and libertineMono
if (opts == "lining")
- h_font_osf = "false";
+ h_font_roman_osf = "false";
else if (opts == "osf")
- h_font_osf = "true";
+ h_font_roman_osf = "true";
}
if (name == "MinionPro") {
h_font_roman[0] = "minionpro";
- if (opts.find("lf") != string::npos)
- h_font_osf = "false";
- else
- h_font_osf = "true";
- if (opts.find("onlytext") != string::npos)
- h_font_math[0] = "default";
- else
- h_font_math[0] = "auto";
+ h_font_roman_osf = "true";
+ h_font_math[0] = "auto";
+ for (auto const & opt : allopts) {
+ if (opt == "lf") {
+ h_font_roman_osf = "false";
+ continue;
+ }
+ if (opt == "onlytext") {
+ h_font_math[0] = "default";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
}
if (name == "mathdesign") {
- if (opts.find("charter") != string::npos)
- h_font_roman[0] = "md-charter";
- if (opts.find("garamond") != string::npos)
- h_font_roman[0] = "md-garamond";
- if (opts.find("utopia") != string::npos)
- h_font_roman[0] = "md-utopia";
- if (opts.find("expert") != string::npos) {
- h_font_sc = "true";
- h_font_osf = "true";
+ for (auto const & opt : allopts) {
+ if (opt == "charter") {
+ h_font_roman[0] = "md-charter";
+ continue;
+ }
+ if (opt == "garamond") {
+ h_font_roman[0] = "md-garamond";
+ continue;
+ }
+ if (opt == "utopia") {
+ h_font_roman[0] = "md-utopia";
+ continue;
+ }
+ if (opt == "expert") {
+ h_font_sc = "true";
+ h_font_roman_osf = "true";
+ continue;
+ }
}
}
- else if (name == "mathpazo")
+ else if (name == "mathpazo") {
h_font_roman[0] = "palatino";
+ for (auto const & opt : allopts) {
+ if (opt == "osf") {
+ h_font_roman_osf = "true";
+ continue;
+ }
+ if (opt == "sc") {
+ h_font_sc = "true";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
+ }
- else if (name == "mathptmx")
+ else if (name == "mathptmx") {
h_font_roman[0] = "times";
+ for (auto const & opt : allopts) {
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
+ }
if (name == "crimson")
h_font_roman[0] = "cochineal";
if (name == "cochineal") {
- h_font_roman[0] = "cochineal";
- // cochineal can have several options, e.g. [proportional,osf]
- string::size_type pos = opts.find("osf");
- if (pos != string::npos)
- h_font_osf = "true";
+ for (auto const & opt : allopts) {
+ if (opt == "osf" || opt == "oldstyle") {
+ h_font_roman_osf = "true";
+ continue;
+ }
+ if (opt == "proportional" || opt == "p")
+ continue;
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
}
- if (name == "noto") {
- // noto can have several options
- if (opts.empty())
- h_font_roman[0] = "NotoSerif-TLF";
- string::size_type pos = opts.find("rm");
- if (pos != string::npos)
- h_font_roman[0] = "NotoSerif-TLF";
- pos = opts.find("sf");
- if (pos != string::npos)
- h_font_sans[0] = "NotoSans-TLF";
- pos = opts.find("nott");
- if (pos != string::npos) {
- h_font_roman[0] = "NotoSerif-TLF";
- h_font_sans[0] = "NotoSans-TLF";
- }
- // noto as typewriter is handled in handling of \ttdefault
- // special cases are handled in handling of \rmdefault and \sfdefault
+ if (name == "CrimsonPro") {
+ h_font_roman_osf = "true";
+ for (auto const & opt : allopts) {
+ if (opt == "lf" || opt == "lining") {
+ h_font_roman_osf = "false";
+ continue;
+ }
+ if (opt == "proportional" || opt == "p")
+ continue;
+ if (opt == "medium") {
+ h_font_roman[0] = "CrimsonProMedium";
+ continue;
+ }
+ if (opt == "extralight") {
+ h_font_roman[0] = "CrimsonProExtraLight";
+ continue;
+ }
+ if (opt == "light") {
+ h_font_roman[0] = "CrimsonProLight";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
}
+
+ if (name == "eco")
+ // font uses old-style figure
+ h_font_roman_osf = "true";
+
if (name == "paratype") {
// in this case all fonts are ParaType
h_font_roman[0] = "PTSerif-TLF";
if (name == "XCharter") {
h_font_roman[0] = "xcharter";
- if (opts == "osf")
- h_font_osf = "true";
+ for (auto const & opt : allopts) {
+ if (opt == "osf") {
+ h_font_roman_osf = "true";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
}
if (name == "plex-serif") {
- if (opts.empty())
- h_font_roman[0] = "IBMPlexSerif";
- else if (opts.find("thin") != string::npos)
- h_font_roman[0] = "IBMPlexSerifThin";
- else if (opts.find("extralight") != string::npos)
- h_font_roman[0] = "IBMPlexSerifExtraLight";
- else if (opts.find("light") != string::npos)
- h_font_roman[0] = "IBMPlexSerifLight";
- else if (opts.find("semibold") != string::npos)
- h_font_roman[0] = "IBMPlexSerifSemibold";
- }
- if (name == "noto-serif") {
- h_font_roman[0] = "NotoSerifRegular";
- if (!opts.empty()) {
- if (opts.find("thin") != string::npos)
+ h_font_roman[0] = "IBMPlexSerif";
+ for (auto const & opt : allopts) {
+ if (opt == "thin") {
+ h_font_roman[0] = "IBMPlexSerifThin";
+ continue;
+ }
+ if (opt == "extralight") {
+ h_font_roman[0] = "IBMPlexSerifExtraLight";
+ continue;
+ }
+ if (opt == "light") {
+ h_font_roman[0] = "IBMPlexSerifLight";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
+ }
+
+ if (name == "noto-serif" || name == "noto") {
+ bool rm = false;
+ bool rmx = false;
+ bool sf = false;
+ bool sfx = false;
+ bool tt = false;
+ bool thin = false;
+ bool extralight = false;
+ bool light = false;
+ bool medium = false;
+ bool osf = false;
+ string scl;
+ if (name == "noto") {
+ rm = true;
+ sf = true;
+ tt = true;
+ }
+ // Since the options might apply to different shapes,
+ // we need to parse all options first and then handle them.
+ for (auto const & opt : allopts) {
+ if (opt == "regular")
+ // skip
+ continue;
+ if (opt == "rm") {
+ rm = true;
+ rmx = true;
+ sf = sfx;
+ tt = false;
+ continue;
+ }
+ if (opt == "thin") {
+ thin = true;
+ continue;
+ }
+ if (opt == "extralight") {
+ extralight = true;
+ continue;
+ }
+ if (opt == "light") {
+ light = true;
+ continue;
+ }
+ if (opt == "medium") {
+ medium = true;
+ continue;
+ }
+ if (opt == "sf") {
+ sfx = true;
+ sf = true;
+ rm = rmx;
+ tt = false;
+ continue;
+ }
+ if (opt == "nott") {
+ tt = false;
+ continue;
+ }
+ if (opt == "osf") {
+ osf = true;
+ continue;
+ }
+ if (prefixIs(opt, "scaled=")) {
+ scl = opt;
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ options.clear();
+ // handle options that might affect different shapes
+ if (name == "noto-serif" || rm) {
+ if (thin)
h_font_roman[0] = "NotoSerifThin";
- else if (opts.find("medium") != string::npos)
- h_font_roman[0] = "NotoSerifMedium";
- else if (opts.find("extralight") != string::npos)
+ else if (extralight)
h_font_roman[0] = "NotoSerifExtralight";
- else if (opts.find("light") != string::npos)
+ else if (light)
h_font_roman[0] = "NotoSerifLight";
+ else if (medium)
+ h_font_roman[0] = "NotoSerifMedium";
+ else
+ h_font_roman[0] = "NotoSerifRegular";
+ if (osf)
+ h_font_roman_osf = "true";
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ }
+ if (name == "noto" && sf) {
+ if (thin)
+ h_font_sans[0] = "NotoSansThin";
+ else if (extralight)
+ h_font_sans[0] = "NotoSansExtralight";
+ else if (light)
+ h_font_sans[0] = "NotoSansLight";
+ else if (medium)
+ h_font_sans[0] = "NotoSansMedium";
+ else
+ h_font_sans[0] = "NotoSansRegular";
+ if (osf)
+ h_font_sans_osf = "true";
+ if (!scl.empty())
+ scale_as_percentage(scl, h_font_sf_scale[0]);
+ if (!xopts.empty())
+ h_font_sans_opts = xopts;
+ }
+ if (name == "noto" && tt) {
+ h_font_typewriter[0] = "NotoMonoRegular";
+ if (osf)
+ h_font_typewriter_osf = "true";
+ if (!scl.empty())
+ scale_as_percentage(scl, h_font_tt_scale[0]);
+ if (!xopts.empty())
+ h_font_typewriter_opts = xopts;
+ }
+ }
+
+ if (name == "sourceserifpro") {
+ h_font_roman[0] = "ADOBESourceSerifPro";
+ for (auto const & opt : allopts) {
+ if (opt == "osf") {
+ h_font_roman_osf = "true";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
}
+ if (!xopts.empty())
+ h_font_roman_opts = xopts;
+ options.clear();
}
+ //
// sansserif fonts
+ //
+
+ // By default, we use the package name as LyX font name,
+ // so this only needs to be reset if these names differ.
+ // Also, we handle the scaling option here generally.
if (is_known(name, known_sans_font_packages)) {
h_font_sans[0] = name;
- if (options.size() >= 1) {
- if (scale_as_percentage(opts, h_font_sf_scale[0]))
- options.clear();
+ if (contains(opts, "scale")) {
+ vector<string>::iterator it = allopts.begin();
+ for (; it != allopts.end() ; ++it) {
+ string const opt = *it;
+ if (prefixIs(opt, "scaled=") || prefixIs(opt, "scale=")) {
+ if (scale_as_percentage(opt, h_font_sf_scale[0])) {
+ allopts.erase(it);
+ break;
+ }
+ }
+ }
}
}
if (name == "biolinum" || name == "biolinum-type1") {
h_font_sans[0] = "biolinum";
- // biolinum can have several options, e.g. [osf,scaled=0.97]
- string::size_type pos = opts.find("osf");
- if (pos != string::npos)
- h_font_osf = "true";
+ for (auto const & opt : allopts) {
+ if (prefixIs(opt, "osf")) {
+ h_font_sans_osf = "true";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_sans_opts = xopts;
+ options.clear();
+ }
+
+ if (name == "cantarell") {
+ for (auto const & opt : allopts) {
+ if (opt == "defaultsans")
+ continue;
+ if (prefixIs(opt, "oldstyle")) {
+ h_font_sans_osf = "true";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_sans_opts = xopts;
+ options.clear();
+ }
+
+ if (name == "Chivo") {
+ for (auto const & opt : allopts) {
+ if (opt == "thin") {
+ h_font_roman[0] = "ChivoThin";
+ continue;
+ }
+ if (opt == "light") {
+ h_font_roman[0] = "ChivoLight";
+ continue;
+ }
+ if (opt == "regular") {
+ h_font_roman[0] = "Chivo";
+ continue;
+ }
+ if (opt == "medium") {
+ h_font_roman[0] = "ChivoMedium";
+ continue;
+ }
+ if (prefixIs(opt, "oldstyle")) {
+ h_font_sans_osf = "true";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_sans_opts = xopts;
+ options.clear();
}
if (name == "PTSans") {
h_font_sans[0] = "PTSans-TLF";
- if (options.size() >= 1) {
- if (scale_as_percentage(opts, h_font_sf_scale[0]))
- options.clear();
+ }
+
+ if (name == "FiraSans") {
+ h_font_sans_osf = "true";
+ for (auto const & opt : allopts) {
+ if (opt == "book") {
+ h_font_sans[0] = "FiraSansBook";
+ continue;
+ }
+ if (opt == "thin") {
+ continue;
+ }
+ if (opt == "extralight") {
+ h_font_sans[0] = "FiraSansExtralight";
+ continue;
+ }
+ if (opt == "light") {
+ h_font_sans[0] = "FiraSansLight";
+ continue;
+ }
+ if (opt == "ultralight") {
+ h_font_sans[0] = "FiraSansUltralight";
+ continue;
+ }
+ if (opt == "thin") {
+ h_font_sans[0] = "FiraSansThin";
+ continue;
+ }
+ if (opt == "lf" || opt == "lining") {
+ h_font_sans_osf = "false";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
}
+ if (!xopts.empty())
+ h_font_sans_opts = xopts;
+ options.clear();
}
if (name == "plex-sans") {
- if (opts.find("condensed") != string::npos)
- h_font_sans[0] = "IBMPlexSansCondensed";
- else if (opts.find("thin") != string::npos)
- h_font_sans[0] = "IBMPlexSansThin";
- else if (opts.find("extralight") != string::npos)
- h_font_sans[0] = "IBMPlexSansExtraLight";
- else if (opts.find("light") != string::npos)
- h_font_sans[0] = "IBMPlexSansLight";
- else if (opts.find("semibold") != string::npos)
- h_font_sans[0] = "IBMPlexSansSemibold";
- else
- h_font_sans[0] = "IBMPlexSans";
- // check if the option contains scaling, if yes, extract it
- string::size_type pos = opts.find("scale");
- if (pos != string::npos) {
- string scale;
- string::size_type i = opts.find(',', pos);
- if (i == string::npos)
- scale_as_percentage(opts.substr(pos + 1), scale);
- else
- scale_as_percentage(opts.substr(pos, i - pos), scale);
- if (!scale.empty())
- h_font_sf_scale[1] = scale;
+ h_font_sans[0] = "IBMPlexSans";
+ for (auto const & opt : allopts) {
+ if (opt == "condensed") {
+ h_font_sans[0] = "IBMPlexSansCondensed";
+ continue;
+ }
+ if (opt == "thin") {
+ h_font_sans[0] = "IBMPlexSansThin";
+ continue;
+ }
+ if (opt == "extralight") {
+ h_font_sans[0] = "IBMPlexSansExtraLight";
+ continue;
+ }
+ if (opt == "light") {
+ h_font_sans[0] = "IBMPlexSansLight";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
}
+ if (!xopts.empty())
+ h_font_sans_opts = xopts;
+ options.clear();
}
+
if (name == "noto-sans") {
h_font_sans[0] = "NotoSansRegular";
- if (!opts.empty()) {
- if (opts.find("medium") != string::npos)
+ for (auto const & opt : allopts) {
+ if (opt == "regular")
+ continue;
+ if (opt == "medium") {
h_font_sans[0] = "NotoSansMedium";
- else if (opts.find("thin") != string::npos)
+ continue;
+ }
+ if (opt == "thin") {
h_font_sans[0] = "NotoSansThin";
- else if (opts.find("extralight") != string::npos)
+ continue;
+ }
+ if (opt == "extralight") {
h_font_sans[0] = "NotoSansExtralight";
- else if (opts.find("light") != string::npos)
+ continue;
+ }
+ if (opt == "light") {
h_font_sans[0] = "NotoSansLight";
+ continue;
+ }
+ if (opt == "osf") {
+ h_font_sans_osf = "true";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
}
+ if (!xopts.empty())
+ h_font_sans_opts = xopts;
+ options.clear();
+ }
+ if (name == "sourcesanspro") {
+ h_font_sans[0] = "ADOBESourceSansPro";
+ for (auto const & opt : allopts) {
+ if (opt == "osf") {
+ h_font_sans_osf = "true";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_sans_opts = xopts;
+ options.clear();
}
+ //
// typewriter fonts
+ //
+
+ // By default, we use the package name as LyX font name,
+ // so this only needs to be reset if these names differ.
+ // Also, we handle the scaling option here generally.
if (is_known(name, known_typewriter_font_packages)) {
- // fourier can be set as roman font _only_
- // fourier as typewriter is handled in handling of \ttdefault
- if (name != "fourier") {
- h_font_typewriter[0] = name;
- if (options.size() >= 1) {
- if (scale_as_percentage(opts, h_font_tt_scale[0]))
- options.clear();
+ h_font_typewriter[0] = name;
+ if (contains(opts, "scale")) {
+ vector<string>::iterator it = allopts.begin();
+ for (; it != allopts.end() ; ++it) {
+ string const opt = *it;
+ if (prefixIs(opt, "scaled=") || prefixIs(opt, "scale=")) {
+ if (scale_as_percentage(opt, h_font_tt_scale[0])) {
+ allopts.erase(it);
+ break;
+ }
+ }
}
}
}
if (name == "libertineMono" || name == "libertineMono-type1")
h_font_typewriter[0] = "libertine-mono";
- if (name == "PTMono") {
- h_font_typewriter[0] = "PTMono-TLF";
- if (options.size() >= 1) {
- if (scale_as_percentage(opts, h_font_tt_scale[0]))
- options.clear();
+ if (name == "FiraMono") {
+ h_font_typewriter_osf = "true";
+ for (auto const & opt : allopts) {
+ if (opt == "lf" || opt == "lining") {
+ h_font_typewriter_osf = "false";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
}
+ if (!xopts.empty())
+ h_font_typewriter_opts = xopts;
+ options.clear();
}
+ if (name == "PTMono")
+ h_font_typewriter[0] = "PTMono-TLF";
+
if (name == "plex-mono") {
- if (opts.find("thin") != string::npos)
- h_font_typewriter[0] = "IBMPlexMonoThin";
- else if (opts.find("extralight") != string::npos)
- h_font_typewriter[0] = "IBMPlexMonoExtraLight";
- else if (opts.find("light") != string::npos)
- h_font_typewriter[0] = "IBMPlexMonoLight";
- else if (opts.find("semibold") != string::npos)
- h_font_typewriter[0] = "IBMPlexMonoSemibold";
- else
- h_font_typewriter[0] = "IBMPlexMono";
- // check if the option contains scaling, if yes, extract it
- string::size_type pos = opts.find("scale");
- if (pos != string::npos) {
- string scale;
- string::size_type i = opts.find(',', pos);
- if (i == string::npos)
- scale_as_percentage(opts.substr(pos + 1), scale);
- else
- scale_as_percentage(opts.substr(pos, i - pos), scale);
- if (!scale.empty())
- h_font_tt_scale[1] = scale;
+ h_font_typewriter[0] = "IBMPlexMono";
+ for (auto const & opt : allopts) {
+ if (opt == "thin") {
+ h_font_typewriter[0] = "IBMPlexMonoThin";
+ continue;
+ }
+ if (opt == "extralight") {
+ h_font_typewriter[0] = "IBMPlexMonoExtraLight";
+ continue;
+ }
+ if (opt == "light") {
+ h_font_typewriter[0] = "IBMPlexMonoLight";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
}
+ if (!xopts.empty())
+ h_font_typewriter_opts = xopts;
+ options.clear();
}
if (name == "noto-mono") {
h_font_typewriter[0] = "NotoMonoRegular";
+ for (auto const & opt : allopts) {
+ if (opt == "regular")
+ continue;
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_typewriter_opts = xopts;
+ options.clear();
}
- // font uses old-style figure
- if (name == "eco")
- h_font_osf = "true";
+ if (name == "sourcecodepro") {
+ h_font_typewriter[0] = "ADOBESourceCodePro";
+ for (auto const & opt : allopts) {
+ if (opt == "osf") {
+ h_font_typewriter_osf = "true";
+ continue;
+ }
+ if (!xopts.empty())
+ xopts += ", ";
+ xopts += opt;
+ }
+ if (!xopts.empty())
+ h_font_typewriter_opts = xopts;
+ options.clear();
+ }
+ //
// math fonts
+ //
+
+ // By default, we use the package name as LyX font name,
+ // so this only needs to be reset if these names differ.
if (is_known(name, known_math_font_packages))
h_font_math[0] = name;
h_preamble << "\\usepackage[" << opts << "]{microtype}";
}
+ else if (name == "lineno") {
+ h_use_lineno = "true";
+ if (!options.empty()) {
+ h_lineno_options = join(options, ",");
+ options.clear();
+ }
+ }
+
+ else if (name == "changebar")
+ h_output_changes = "true";
+
else if (!in_lyx_preamble) {
if (options.empty())
h_preamble << "\\usepackage{" << name << '}';
<< "\\font_default_family " << h_font_default_family << "\n"
<< "\\use_non_tex_fonts " << (h_use_non_tex_fonts ? "true" : "false") << '\n'
<< "\\font_sc " << h_font_sc << "\n"
- << "\\font_osf " << h_font_osf << "\n"
- << "\\font_sf_scale " << h_font_sf_scale[0]
- << ' ' << h_font_sf_scale[1] << '\n'
- << "\\font_tt_scale " << h_font_tt_scale[0]
+ << "\\font_roman_osf " << h_font_roman_osf << "\n"
+ << "\\font_sans_osf " << h_font_sans_osf << "\n"
+ << "\\font_typewriter_osf " << h_font_typewriter_osf << "\n";
+ if (!h_font_roman_opts.empty())
+ os << "\\font_roman_opts \"" << h_font_roman_opts << "\"" << '\n';
+ os << "\\font_sf_scale " << h_font_sf_scale[0]
+ << ' ' << h_font_sf_scale[1] << '\n';
+ if (!h_font_sans_opts.empty())
+ os << "\\font_sans_opts \"" << h_font_sans_opts << "\"" << '\n';
+ os << "\\font_tt_scale " << h_font_tt_scale[0]
<< ' ' << h_font_tt_scale[1] << '\n';
if (!h_font_cjk.empty())
os << "\\font_cjk " << h_font_cjk << '\n';
+ if (!h_font_typewriter_opts.empty())
+ os << "\\font_typewriter_opts \"" << h_font_typewriter_opts << "\"" << '\n';
os << "\\use_microtype " << h_use_microtype << '\n'
<< "\\use_dash_ligatures " << h_use_dash_ligatures << '\n'
<< "\\graphics " << h_graphics << '\n'
<< "\\suppress_date " << h_suppress_date << '\n'
<< "\\justification " << h_justification << '\n'
<< "\\use_refstyle " << h_use_refstyle << '\n'
- << "\\use_minted " << h_use_minted << '\n';
+ << "\\use_minted " << h_use_minted << '\n'
+ << "\\use_lineno " << h_use_lineno << '\n';
+ if (!h_lineno_options.empty())
+ os << "\\lineno_options " << h_lineno_options << '\n';
if (!h_fontcolor.empty())
os << "\\fontcolor " << h_fontcolor << '\n';
if (!h_notefontcolor.empty())
os << "\\listings_params " << h_listings_params << "\n";
os << "\\tracking_changes " << h_tracking_changes << "\n"
<< "\\output_changes " << h_output_changes << "\n"
+ << "\\change_bars " << h_change_bars << "\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"
}
if (t.cs() == "setmainfont") {
- // we don't care about the option
- p.hasOpt() ? p.getOpt() : string();
+ string fontopts = p.hasOpt() ? p.getArg('[', ']') : string();
h_font_roman[1] = p.getArg('{', '}');
+ if (!fontopts.empty()) {
+ vector<string> opts = getVectorFromString(fontopts);
+ fontopts.clear();
+ for (auto const & opt : opts) {
+ if (opt == "Mapping=tex-text" || opt == "Ligatures=TeX")
+ // ignore
+ continue;
+ if (!fontopts.empty())
+ fontopts += ", ";
+ fontopts += opt;
+ }
+ h_font_roman_opts = fontopts;
+ }
continue;
}
if (t.cs() == "setsansfont" || t.cs() == "setmonofont") {
// LyX currently only supports the scale option
- string scale;
+ string scale, fontopts;
if (p.hasOpt()) {
- string fontopts = p.getArg('[', ']');
- // check if the option contains a scaling, if yes, extract it
- string::size_type pos = fontopts.find("Scale");
- if (pos != string::npos) {
- string::size_type i = fontopts.find(',', pos);
- if (i == string::npos)
- scale_as_percentage(fontopts.substr(pos + 1), scale);
- else
- scale_as_percentage(fontopts.substr(pos, i - pos), scale);
+ fontopts = p.getArg('[', ']');
+ if (!fontopts.empty()) {
+ vector<string> opts = getVectorFromString(fontopts);
+ fontopts.clear();
+ for (auto const & opt : opts) {
+ if (opt == "Mapping=tex-text" || opt == "Ligatures=TeX")
+ // ignore
+ continue;
+ if (prefixIs(opt, "Scale=")) {
+ scale_as_percentage(opt, scale);
+ continue;
+ }
+ if (!fontopts.empty())
+ fontopts += ", ";
+ fontopts += opt;
+ }
}
}
if (t.cs() == "setsansfont") {
if (!scale.empty())
h_font_sf_scale[1] = scale;
h_font_sans[1] = p.getArg('{', '}');
+ if (!fontopts.empty())
+ h_font_sans_opts = fontopts;
} else {
if (!scale.empty())
h_font_tt_scale[1] = scale;
h_font_typewriter[1] = p.getArg('{', '}');
+ if (!fontopts.empty())
+ h_font_typewriter_opts = fontopts;
}
continue;
}
+ if (t.cs() == "babelfont") {
+ xetex = true;
+ h_use_non_tex_fonts = true;
+ h_language_package = "babel";
+ if (h_inputencoding == "auto-legacy")
+ p.setEncoding("UTF-8");
+ // we don't care about the lang option
+ string const lang = p.hasOpt() ? p.getArg('[', ']') : string();
+ string const family = p.getArg('{', '}');
+ string fontopts = p.hasOpt() ? p.getArg('[', ']') : string();
+ string const fontname = p.getArg('{', '}');
+ if (lang.empty() && family == "rm") {
+ h_font_roman[1] = fontname;
+ if (!fontopts.empty()) {
+ vector<string> opts = getVectorFromString(fontopts);
+ fontopts.clear();
+ for (auto const & opt : opts) {
+ if (opt == "Mapping=tex-text" || opt == "Ligatures=TeX")
+ // ignore
+ continue;
+ if (!fontopts.empty())
+ fontopts += ", ";
+ fontopts += opt;
+ }
+ h_font_roman_opts = fontopts;
+ }
+ continue;
+ } else if (lang.empty() && (family == "sf" || family == "tt")) {
+ string scale;
+ if (!fontopts.empty()) {
+ vector<string> opts = getVectorFromString(fontopts);
+ fontopts.clear();
+ for (auto const & opt : opts) {
+ if (opt == "Mapping=tex-text" || opt == "Ligatures=TeX")
+ // ignore
+ continue;
+ if (prefixIs(opt, "Scale=")) {
+ scale_as_percentage(opt, scale);
+ continue;
+ }
+ if (!fontopts.empty())
+ fontopts += ", ";
+ fontopts += opt;
+ }
+ }
+ if (family == "sf") {
+ if (!scale.empty())
+ h_font_sf_scale[1] = scale;
+ h_font_sans[1] = fontname;
+ if (!fontopts.empty())
+ h_font_sans_opts = fontopts;
+ } else {
+ if (!scale.empty())
+ h_font_tt_scale[1] = scale;
+ h_font_typewriter[1] = fontname;
+ if (!fontopts.empty())
+ h_font_typewriter_opts = fontopts;
+ }
+ continue;
+ } else {
+ // not rm, sf or tt or lang specific
+ h_preamble << '\\' << t.cs();
+ if (!lang.empty())
+ h_preamble << '[' << lang << ']';
+ h_preamble << '{' << family << '}';
+ if (!fontopts.empty())
+ h_preamble << '[' << fontopts << ']';
+ h_preamble << '{' << fontname << '}' << '\n';
+ continue;
+ }
+ }
+
if (t.cs() == "date") {
string argument = p.getArg('{', '}');
if (argument.empty())
if (t.cs() == "documentclass") {
vector<string>::iterator it;
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('{', '}');
+ 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);
+ }
+
+ // Font sizes.
+ // Try those who are (most likely) known to all packages first
handle_opt(opts, known_fontsizes, h_paperfontsize);
delete_opt(opts, known_fontsizes);
// delete "pt" at the end
string::size_type i = h_paperfontsize.find("pt");
if (i != string::npos)
h_paperfontsize.erase(i);
+ // Now those known specifically to the class
+ string fsize;
+ vector<string> class_fsizes = getVectorFromString(tc.opt_fontsize(), "|");
+ string const fsize_format = tc.fontsizeformat();
+ for (auto const fsize : class_fsizes) {
+ string latexsize = subst(fsize_format, "$$s", fsize);
+ vector<string>::iterator it = find(opts.begin(), opts.end(), latexsize);
+ if (it != opts.end()) {
+ h_paperfontsize = fsize;
+ opts.erase(it);
+ break;
+ }
+ }
+
// The documentclass options are always parsed before the options
// of the babel call so that a language cannot overwrite the babel
// options.
opts.erase(it);
}
// paper sizes
- // some size options are known to any document classes, other sizes
+ // some size options are known by the document class, other sizes
// are handled by the \geometry command of the geometry package
- handle_opt(opts, known_class_paper_sizes, h_papersize);
- delete_opt(opts, known_class_paper_sizes);
+ string paper;
+ vector<string> class_psizes = getVectorFromString(tc.opt_pagesize(), "|");
+ string const psize_format = tc.pagesizeformat();
+ for (auto const psize : class_psizes) {
+ string latexsize = subst(psize_format, "$$s", psize);
+ vector<string>::iterator it = find(opts.begin(), opts.end(), latexsize);
+ if (it != opts.end()) {
+ h_papersize = psize;
+ opts.erase(it);
+ break;
+ }
+ if (psize_format == "$$spaper")
+ continue;
+ // Also try with the default format since this is understood by
+ // most classes
+ latexsize = psize + "paper";
+ it = find(opts.begin(), opts.end(), latexsize);
+ if (it != opts.end()) {
+ h_papersize = psize;
+ opts.erase(it);
+ break;
+ }
+ }
// the remaining options
h_options = join(opts, ",");
- // FIXME This does not work for classes that have a
- // different name in LyX than in LaTeX
- h_textclass = p.getArg('{', '}');
- p.skip_spaces();
continue;
}
// remove the whitespace
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);
- }
if (h_papersides.empty()) {
ostringstream ss;
ss << tc.sides();