diff options
-rw-r--r-- | luaotfload-database.lua | 27 | ||||
-rw-r--r-- | luaotfload-diagnostics.lua | 8 | ||||
-rw-r--r-- | luaotfload-features.lua | 260 | ||||
-rw-r--r-- | luaotfload-parsers.lua | 311 | ||||
-rwxr-xr-x | luaotfload-tool.lua | 4 |
5 files changed, 312 insertions, 298 deletions
diff --git a/luaotfload-database.lua b/luaotfload-database.lua index 32197cc..3f321d2 100644 --- a/luaotfload-database.lua +++ b/luaotfload-database.lua @@ -36,15 +36,13 @@ if not modules then modules = { } end modules ['luaotfload-database'] = { --doc]]-- -local lpeg = require "lpeg" +local lpeg = require "lpeg" +local P, Cc, lpegmatch = lpeg.P, lpeg.Cc, lpeg.match -local P, R, S, lpegmatch - = lpeg.P, lpeg.R, lpeg.S, lpeg.match - -local C, Cc, Cf, Cg, Cs, Ct - = lpeg.C, lpeg.Cc, lpeg.Cf, lpeg.Cg, lpeg.Cs, lpeg.Ct - -local read_fonts_conf = luaotfload.parsers.read_fonts_conf +local parsers = luaotfload.parsers +local read_fonts_conf = parsers.read_fonts_conf +local stripslashes = parsers.stripslashes +local splitcomma = parsers.splitcomma --- Luatex builtins local load = load @@ -62,7 +60,6 @@ local iolines = io.lines local ioopen = io.open local iopopen = io.popen local kpseexpand_path = kpse.expand_path -local kpseexpand_var = kpse.expand_var local kpsefind_file = kpse.find_file local kpselookup = kpse.lookup local kpsereadable_file = kpse.readable_file @@ -183,18 +180,6 @@ if not luaotfloadconfig.termwidth then luaotfloadconfig.termwidth = tw end -names.patterns = { } -local patterns = names.patterns - -local trailingslashes = P"/"^1 * P(-1) -local stripslashes = C((1 - trailingslashes)^0) -patterns.stripslashes = stripslashes - -local comma = P"," -local noncomma = 1-comma -local splitcomma = Ct((C(noncomma^1) + comma)^1) -patterns.splitcomma = splitcomma - local format_precedence = { "otf", "ttc", "ttf", "dfont", "afm", "pfb", diff --git a/luaotfload-diagnostics.lua b/luaotfload-diagnostics.lua index 1f29e3d..1ae9a90 100644 --- a/luaotfload-diagnostics.lua +++ b/luaotfload-diagnostics.lua @@ -53,6 +53,10 @@ local out = function (...) logs.names_report (false, 0, "diagnose", ...) end +local parsers = luaotfload.parsers +local stripslashes = parsers.stripslashes +local splitcomma = parsers.splitcomma + local check_index = function (errcnt) out "================= font names ==================" @@ -163,8 +167,6 @@ local analyze_permissions = function (raw) return lpegmatch (p_permissions, raw) end -local stripslashes = names.patterns.stripslashes - local get_permissions = function (t, location) if stringsub (location, #location) == "/" then --- strip trailing slashes (lfs idiosyncrasy on Win) @@ -605,8 +607,6 @@ local anamneses = { "permissions" } -local splitcomma = names.patterns.splitcomma - local diagnose = function (job) local errcnt = 0 local asked = job.asked_diagnostics diff --git a/luaotfload-features.lua b/luaotfload-features.lua index dc6b8a4..d786549 100644 --- a/luaotfload-features.lua +++ b/luaotfload-features.lua @@ -9,7 +9,12 @@ if not modules then modules = { } end modules ["features"] = { local type, next = type, next local tonumber = tonumber local tostring = tostring + +local lpeg = require "lpeg" local lpegmatch = lpeg.match +local P = lpeg.P +local R = lpeg.R +local C = lpeg.C ---[[ begin included font-ltx.lua ]] --- this appears to be based in part on luatex-fonts-def.lua @@ -822,259 +827,6 @@ local set_default_features = function (speclist) return speclist end ------------------------------------------------------------------------ ---- request syntax parser 2.2 ------------------------------------------------------------------------ ---- the luaotfload font request syntax (see manual) ---- has a canonical form: ---- ---- \font<csname>=<prefix>:<identifier>:<features> ---- ---- where ---- <csname> is the control sequence that activates the font ---- <prefix> is either “file” or “name”, determining the lookup ---- <identifer> is either a file name (no path) or a font ---- name, depending on the lookup ---- <features> is a list of switches or options, separated by ---- semicolons or commas; a switch is of the form “+” foo ---- or “-” foo, options are of the form lhs “=” rhs ---- ---- however, to ensure backward compatibility we also have ---- support for Xetex-style requests. ---- ---- for the Xetex emulation see: ---- · The XeTeX Reference Guide by Will Robertson, 2011 ---- · The XeTeX Companion by Michel Goosens, 2010 ---- · About XeTeX by Jonathan Kew, 2005 ---- ---- ---- caueat emptor. ---- the request is parsed into one of **four** different ---- lookup categories: the regular ones, file and name, ---- as well as the Xetex compatibility ones, path and anon. ---- (maybe a better choice of identifier would be “ambig”.) ---- ---- according to my reconstruction, the correct chaining ---- of the lookups for each category is as follows: ---- ---- | File -> ( db/filename lookup ) ---- ---- | Name -> ( db/name lookup, ---- db/filename lookup ) ---- ---- | Path -> ( db/filename lookup, ---- fullpath lookup ) ---- ---- | Anon -> ( kpse.find_file(), // <- for tfm, ofm ---- db/name lookup, ---- db/filename lookup, ---- fullpath lookup ) ---- ---- caching of successful lookups is essential. we now ---- as of v2.2 have an experimental lookup cache that is ---- stored in a separate file. it pertains only to name: ---- lookups, and is described in more detail in ---- luaotfload-database.lua. ---- ------------------------------------------------------------------------ - ---[[doc-- - - One further incompatibility between Xetex and Luatex-Fonts consists - in their option list syntax: apparently, Xetex requires key-value - options to be prefixed by a "+" (ascii “plus”) character. We - silently accept this as well, dropping the first byte if it is a - plus or minus character. - - Reference: https://github.com/lualatex/luaotfload/issues/79#issuecomment-18104483 - ---doc]]-- - -local handle_normal_option = function (key, val) - val = stringlower(val) - --- the former “toboolean()” handler - if val == "true" then - val = true - elseif val == "false" then - val = false - end - return key, val -end - ---[[doc-- - - Xetex style indexing begins at zero which we just increment before - passing it along to the font loader. Ymmv. - ---doc]]-- - -local handle_xetex_option = function (key, val) - val = stringlower(val) - local numeric = tonumber(val) --- decimal only; keeps colors intact - if numeric then --- ugh - if mathceil(numeric) == numeric then -- integer, possible index - val = tostring(numeric + 1) - end - elseif val == "true" then - val = true - elseif val == "false" then - val = false - end - return key, val -end - ---[[doc-- - - Instead of silently ignoring invalid options we emit a warning to - the log. - - Note that we have to return a pair to please rawset(). This creates - an entry on the resulting features hash which will later be removed - during set_default_features(). - ---doc]]-- - -local handle_invalid_option = function (opt) - report("log", 0, "load", "font option %q unknown.", opt) - return "", false -end - ---[[doc-- - - Dirty test if a file: request is actually a path: lookup; don’t - ask! Note this fails on Windows-style absolute paths. These will - *really* have to use the correct request. - ---doc]]-- - -local check_garbage = function (_,i, garbage) - if stringfind(garbage, "/") then - report("log", 0, "load", --- ffs use path! - "warning: path in file: lookups is deprecated; ") - report("log", 0, "load", "use bracket syntax instead!") - report("log", 0, "load", - "position: %d; full match: %q", - i, garbage) - return true - end - return false -end - -local lpegmatch = lpeg.match -local P, S, R = lpeg.P, lpeg.S, lpeg.R -local C, Cc, Cf, Cg, Cmt, Cs, Ct - = lpeg.C, lpeg.Cc, lpeg.Cf, lpeg.Cg, lpeg.Cmt, lpeg.Cs, lpeg.Ct - ---- terminals and low-level classes ----------------------------------- ---- note we could use the predefined ones from lpeg.patterns -local dot = P"." -local colon = P":" -local featuresep = S",;" -local slash = P"/" -local equals = P"=" -local lbrk, rbrk = P"[", P"]" - -local spacing = S" \t\v" -local ws = spacing^0 - -local digit = R"09" -local alpha = R("az", "AZ") -local anum = alpha + digit -local decimal = digit^1 * (dot * digit^0)^-1 - ---- modifiers --------------------------------------------------------- ---[[doc-- - The slash notation: called “modifiers” (Kew) or “font options” - (Robertson, Goosens) - we only support the shorthands for italic / bold / bold italic - shapes, as well as setting optical size, the rest is ignored. ---doc]]-- -local style_modifier = (P"BI" + P"IB" + P"bi" + P"ib" + S"biBI") - / stringlower -local size_modifier = S"Ss" * P"=" --- optical size - * Cc"optsize" * C(decimal) -local other_modifier = P"AAT" + P"aat" --- apple stuff; unsupported - + P"ICU" + P"icu" --- not applicable - + P"GR" + P"gr" --- sil stuff; unsupported -local garbage_modifier = ((1 - colon - slash)^0 * Cc(false)) -local modifier = slash * (other_modifier --> ignore - + Cs(style_modifier) --> collect - + Ct(size_modifier) --> collect - + garbage_modifier) --> warn -local modifier_list = Cg(Ct(modifier^0), "modifiers") - ---- lookups ----------------------------------------------------------- -local fontname = C((1-S":(/")^1) --- like luatex-fonts -local unsupported = Cmt((1-S":(")^1, check_garbage) -local prefixed = P"name:" * ws * Cg(fontname, "name") ---- initially we intended file: to emulate the behavior of ---- luatex-fonts, i.e. no paths allowed. after all, we do have XeTeX ---- emulation with the path lookup and it interferes with db lookups. ---- turns out fontspec and other widely used packages rely on file: ---- with paths already, so we’ll add a less strict rule here. anyways, ---- we’ll emit a warning. - + P"file:" * ws * Cg(unsupported, "path") - + P"file:" * ws * Cg(fontname, "file") ---- EXPERIMENTAL: kpse lookup - + P"kpse:" * ws * Cg(fontname, "kpse") ---- EXPERIMENTAL: custom lookup - + P"my:" * ws * Cg(fontname, "my") -local unprefixed = Cg(fontname, "anon") -local path_lookup = lbrk * Cg(C((1-rbrk)^1), "path") * rbrk - ---- features ---------------------------------------------------------- -local field_char = anum + S"+-." --- sic! -local field = field_char^1 ---- assignments are “lhs=rhs” ---- or “+lhs=rhs” (Xetex-style) ---- switches are “+key” | “-key” -local normal_option = C(field) * ws * equals * ws * C(field) * ws -local xetex_option = P"+" * ws * normal_option -local ignore_option = (1 - equals - featuresep)^1 - * equals - * (1 - featuresep)^1 -local assignment = xetex_option / handle_xetex_option - + normal_option / handle_normal_option - + ignore_option / handle_invalid_option -local switch = P"+" * ws * C(field) * Cc(true) - + P"-" * ws * C(field) * Cc(false) - + C(field) * Cc(true) --- default -local feature_expr = ws * Cg(assignment + switch) * ws -local option = feature_expr -local feature_list = Cf(Ct"" - * option - * (featuresep * option^-1)^0 - , rawset) - * featuresep^-1 - ---- other ------------------------------------------------------------- ---- This rule is present in the original parser. It sets the “sub” ---- field of the specification which allows addressing a specific ---- font inside a TTC container. Neither in Luatex-Fonts nor in ---- Luaotfload is this documented, so we might as well silently drop ---- it. However, as backward compatibility is one of our prime goals we ---- just insert it here and leave it undocumented until someone cares ---- to ask. (Note: afair subfonts are numbered, but this rule matches a ---- string; I won’t mess with it though until someone reports a ---- problem.) ---- local subvalue = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim ---- Note to self: subfonts apparently start at index 0. Tested with ---- Cambria.ttc that includes “Cambria Math” at 0 and “Cambria” at 1. ---- Other values cause luatex to segfault. -local subfont = P"(" * Cg((1 - S"()")^1, "sub") * P")" ---- top-level rules --------------------------------------------------- ---- \font\foo=<specification>:<features> -local features = Cg(feature_list, "features") -local specification = (prefixed + unprefixed) - * subfont^-1 - * modifier_list^-1 -local font_request = Ct(path_lookup * (colon^-1 * features)^-1 - + specification * (colon * features)^-1) - --- lpeg.print(font_request) ---- new parser: 657 rules ---- old parser: 230 rules - local import_values = { --- That’s what the 1.x parser did, not quite as graciously, --- with an array of branch expressions. @@ -1138,7 +890,7 @@ end --- spec -> spec local handle_request = function (specification) - local request = lpegmatch(font_request, + local request = lpegmatch(luaotfload.parsers.font_request, specification.specification) if not request then --- happens when called with an absolute path diff --git a/luaotfload-parsers.lua b/luaotfload-parsers.lua index 89e3bc9..e6db21f 100644 --- a/luaotfload-parsers.lua +++ b/luaotfload-parsers.lua @@ -1,12 +1,12 @@ #!/usr/bin/env texlua ------------------------------------------------------------------------ +------------------------------------------------------------------------------- -- FILE: luaotfload-parsers.lua -- DESCRIPTION: various lpeg-based parsers used in Luaotfload -- REQUIREMENTS: Luaotfload > 2.4 -- AUTHOR: Philipp Gesang (Phg), <phg42.2a@gmail.com> -- VERSION: same as Luaotfload -- CREATED: 2014-01-14 10:15:20+0100 ------------------------------------------------------------------------ +------------------------------------------------------------------------------- -- if not modules then modules = { } end modules ['luaotfload-parsers'] = { @@ -25,7 +25,7 @@ local lpeg = require "lpeg" local P, R, S = lpeg.P, lpeg.R, lpeg.S local lpegmatch = lpeg.match local C, Cc, Cf = lpeg.C, lpeg.Cc, lpeg.Cf -local Cg, Cs, Ct = lpeg.Cg, lpeg.Cs, lpeg.Ct +local Cg, Cmt, Cs, Ct = lpeg.Cg, lpeg.Cmt, lpeg.Cs, lpeg.Ct local kpse = kpse local kpseexpand_path = kpse.expand_path @@ -44,11 +44,39 @@ local report = logs.report local string = string local stringsub = string.sub local stringfind = string.find +local stringlower = string.lower local lfs = lfs local lfsisfile = lfs.isfile local lfsisdir = lfs.isdir +------------------------------------------------------------------------------- +--- COMMON PATTERNS +------------------------------------------------------------------------------- + +local dot = P"." +local colon = P":" +local comma = P"," +local noncomma = 1 - comma +local slash = P"/" +local equals = P"=" +local lbrk, rbrk = P"[", P"]" + +local spacing = S" \t\v" +local linebreak = S"\n\r" +local whitespace = spacing + linebreak +local ws = spacing^0 +local xmlws = whitespace^1 + +local digit = R"09" +local alpha = R("az", "AZ") +local anum = alpha + digit +local decimal = digit^1 * (dot * digit^0)^-1 + +------------------------------------------------------------------------------- +--- FONTCONFIG +------------------------------------------------------------------------------- + --[[doc-- For fonts installed on the operating system, there are several @@ -75,31 +103,27 @@ local lfsisdir = lfs.isdir --doc]]-- -local alpha = R("az", "AZ") -local digit = R"09" local tag_name = C(alpha^1) -local whitespace = S" \n\r\t\v" -local ws = whitespace^1 local comment = P"<!--" * (1 - P"--")^0 * P"-->" ---> header specifica local xml_declaration = P"<?xml" * (1 - P"?>")^0 * P"?>" -local xml_doctype = P"<!DOCTYPE" * ws +local xml_doctype = P"<!DOCTYPE" * xmlws * "fontconfig" * (1 - P">")^0 * P">" local header = xml_declaration^-1 - * (xml_doctype + comment + ws)^0 + * (xml_doctype + comment + xmlws)^0 ---> enforce root node -local root_start = P"<" * ws^-1 * P"fontconfig" * ws^-1 * P">" -local root_stop = P"</" * ws^-1 * P"fontconfig" * ws^-1 * P">" +local root_start = P"<" * xmlws^-1 * P"fontconfig" * xmlws^-1 * P">" +local root_stop = P"</" * xmlws^-1 * P"fontconfig" * xmlws^-1 * P">" local dquote, squote = P[["]], P"'" local xml_namestartchar = S":_" + alpha --- ascii only, funk the rest local xml_namechar = S":._" + alpha + digit -local xml_name = ws^-1 +local xml_name = xmlws^-1 * C(xml_namestartchar * xml_namechar^0) -local xml_attvalue = dquote * C((1 - S[[%&"]])^1) * dquote * ws^-1 - + squote * C((1 - S[[%&']])^1) * squote * ws^-1 +local xml_attvalue = dquote * C((1 - S[[%&"]])^1) * dquote * xmlws^-1 + + squote * C((1 - S[[%&']])^1) * squote * xmlws^-1 local xml_attr = Cg(xml_name * P"=" * xml_attvalue) local xml_attr_list = Cf(Ct"" * xml_attr^1, rawset) @@ -113,11 +137,11 @@ local scan_node = function (tag) local p_tag = P(tag) local with_attributes = P"<" * p_tag * Cg(xml_attr_list, "attributes")^-1 - * ws^-1 + * xmlws^-1 * P">" - local plain = P"<" * p_tag * ws^-1 * P">" + local plain = P"<" * p_tag * xmlws^-1 * P">" local node_start = plain + with_attributes - local node_stop = P"</" * p_tag * ws^-1 * P">" + local node_stop = P"</" * p_tag * xmlws^-1 * P">" --- there is no nesting, the earth is flat ... local node = node_start * Cc(tag) * C(comment + (1 - node_stop)^1) @@ -296,3 +320,256 @@ end luaotfload.parsers.read_fonts_conf = read_fonts_conf + +------------------------------------------------------------------------------- +--- MISC PARSERS +------------------------------------------------------------------------------- + + +local trailingslashes = slash^1 * P(-1) +local stripslashes = C((1 - trailingslashes)^0) +parsers.stripslashes = stripslashes + +local splitcomma = Ct((C(noncomma^1) + comma)^1) +parsers.splitcomma = splitcomma + + + +------------------------------------------------------------------------------- +--- FONT REQUEST +------------------------------------------------------------------------------- + + +--[[doc------------------------------------------------------------------------ + + The luaotfload font request syntax (see manual) + has a canonical form: + + \font<csname>=<prefix>:<identifier>:<features> + + where + <csname> is the control sequence that activates the font + <prefix> is either “file” or “name”, determining the lookup + <identifer> is either a file name (no path) or a font + name, depending on the lookup + <features> is a list of switches or options, separated by + semicolons or commas; a switch is of the form “+” foo + or “-” foo, options are of the form lhs “=” rhs + + however, to ensure backward compatibility we also have + support for Xetex-style requests. + + for the Xetex emulation see: + · The XeTeX Reference Guide by Will Robertson, 2011 + · The XeTeX Companion by Michel Goosens, 2010 + · About XeTeX by Jonathan Kew, 2005 + + + caueat emptor. + + the request is parsed into one of **four** different lookup + categories: the regular ones, file and name, as well as the + Xetex compatibility ones, path and anon. (maybe a better choice + of identifier would be “ambig”.) + + according to my reconstruction, the correct chaining of the + lookups for each category is as follows: + + | File -> ( db/filename lookup ) + + | Name -> ( db/name lookup, + db/filename lookup ) + + | Path -> ( db/filename lookup, + fullpath lookup ) + + | Anon -> ( kpse.find_file(), // <- for tfm, ofm + db/name lookup, + db/filename lookup, + fullpath lookup ) + + caching of successful lookups is essential. we now as of v2.2 + have a lookup cache that is stored in a separate file. it + pertains only to name: lookups, and is described in more detail + in luaotfload-database.lua. + +------------------------------------------------------------------------------- + + One further incompatibility between Xetex and Luatex-Fonts consists + in their option list syntax: apparently, Xetex requires key-value + options to be prefixed by a "+" (ascii “plus”) character. We + silently accept this as well, dropping the first byte if it is a + plus or minus character. + + Reference: https://github.com/lualatex/luaotfload/issues/79#issuecomment-18104483 + +--doc]]------------------------------------------------------------------------ + + +local handle_normal_option = function (key, val) + val = stringlower(val) + --- the former “toboolean()” handler + if val == "true" then + val = true + elseif val == "false" then + val = false + end + return key, val +end + +--[[doc-- + + Xetex style indexing begins at zero which we just increment before + passing it along to the font loader. Ymmv. + +--doc]]-- + +local handle_xetex_option = function (key, val) + val = stringlower(val) + local numeric = tonumber(val) --- decimal only; keeps colors intact + if numeric then --- ugh + if mathceil(numeric) == numeric then -- integer, possible index + val = tostring(numeric + 1) + end + elseif val == "true" then + val = true + elseif val == "false" then + val = false + end + return key, val +end + +--[[doc-- + + Instead of silently ignoring invalid options we emit a warning to + the log. + + Note that we have to return a pair to please rawset(). This creates + an entry on the resulting features hash which will later be removed + during set_default_features(). + +--doc]]-- + +local handle_invalid_option = function (opt) + report("log", 0, "load", "font option %q unknown.", opt) + return "", false +end + +--[[doc-- + + Dirty test if a file: request is actually a path: lookup; don’t + ask! Note this fails on Windows-style absolute paths. These will + *really* have to use the correct request. + +--doc]]-- + +local check_garbage = function (_,i, garbage) + if stringfind(garbage, "/") then + report("log", 0, "load", --- ffs use path! + "warning: path in file: lookups is deprecated; ") + report("log", 0, "load", "use bracket syntax instead!") + report("log", 0, "load", + "position: %d; full match: %q", + i, garbage) + return true + end + return false +end + +local featuresep = comma + +--- modifiers --------------------------------------------------------- +--[[doc-- + The slash notation: called “modifiers” (Kew) or “font options” + (Robertson, Goosens) + we only support the shorthands for italic / bold / bold italic + shapes, as well as setting optical size, the rest is ignored. +--doc]]-- +local style_modifier = (P"BI" + P"IB" + P"bi" + P"ib" + S"biBI") + / stringlower +local size_modifier = S"Ss" * P"=" --- optical size + * Cc"optsize" * C(decimal) +local other_modifier = P"AAT" + P"aat" --- apple stuff; unsupported + + P"ICU" + P"icu" --- not applicable + + P"GR" + P"gr" --- sil stuff; unsupported +local garbage_modifier = ((1 - colon - slash)^0 * Cc(false)) +local modifier = slash * (other_modifier --> ignore + + Cs(style_modifier) --> collect + + Ct(size_modifier) --> collect + + garbage_modifier) --> warn +local modifier_list = Cg(Ct(modifier^0), "modifiers") + +--- lookups ----------------------------------------------------------- +local fontname = C((1-S":(/")^1) --- like luatex-fonts +local unsupported = Cmt((1-S":(")^1, check_garbage) +local prefixed = P"name:" * ws * Cg(fontname, "name") +--- initially we intended file: to emulate the behavior of +--- luatex-fonts, i.e. no paths allowed. after all, we do have XeTeX +--- emulation with the path lookup and it interferes with db lookups. +--- turns out fontspec and other widely used packages rely on file: +--- with paths already, so we’ll add a less strict rule here. anyways, +--- we’ll emit a warning. + + P"file:" * ws * Cg(unsupported, "path") + + P"file:" * ws * Cg(fontname, "file") +--- EXPERIMENTAL: kpse lookup + + P"kpse:" * ws * Cg(fontname, "kpse") +--- EXPERIMENTAL: custom lookup + + P"my:" * ws * Cg(fontname, "my") +local unprefixed = Cg(fontname, "anon") +local path_lookup = lbrk * Cg(C((1-rbrk)^1), "path") * rbrk + +--- features ---------------------------------------------------------- +local field_char = anum + S"+-." --- sic! +local field = field_char^1 +--- assignments are “lhs=rhs” +--- or “+lhs=rhs” (Xetex-style) +--- switches are “+key” | “-key” +local normal_option = C(field) * ws * equals * ws * C(field) * ws +local xetex_option = P"+" * ws * normal_option +local ignore_option = (1 - equals - featuresep)^1 + * equals + * (1 - featuresep)^1 +local assignment = xetex_option / handle_xetex_option + + normal_option / handle_normal_option + + ignore_option / handle_invalid_option +local switch = P"+" * ws * C(field) * Cc(true) + + P"-" * ws * C(field) * Cc(false) + + C(field) * Cc(true) --- default +local feature_expr = ws * Cg(assignment + switch) * ws +local option = feature_expr +local feature_list = Cf(Ct"" + * option + * (featuresep * option^-1)^0 + , rawset) + * featuresep^-1 + +--- other ------------------------------------------------------------- +--- This rule is present in the original parser. It sets the “sub” +--- field of the specification which allows addressing a specific +--- font inside a TTC container. Neither in Luatex-Fonts nor in +--- Luaotfload is this documented, so we might as well silently drop +--- it. However, as backward compatibility is one of our prime goals we +--- just insert it here and leave it undocumented until someone cares +--- to ask. (Note: afair subfonts are numbered, but this rule matches a +--- string; I won’t mess with it though until someone reports a +--- problem.) +--- local subvalue = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim +--- Note to self: subfonts apparently start at index 0. Tested with +--- Cambria.ttc that includes “Cambria Math” at 0 and “Cambria” at 1. +--- Other values cause luatex to segfault. +local subfont = P"(" * Cg((1 - S"()")^1, "sub") * P")" +--- top-level rules --------------------------------------------------- +--- \font\foo=<specification>:<features> +local features = Cg(feature_list, "features") +local specification = (prefixed + unprefixed) + * subfont^-1 + * modifier_list^-1 +local font_request = Ct(path_lookup * (colon^-1 * features)^-1 + + specification * (colon * features)^-1) + +-- lpeg.print(font_request) +--- v2.5 parser: 1065 rules +--- v1.2 parser: 230 rules + +luaotfload.parsers.font_request = font_request + diff --git a/luaotfload-tool.lua b/luaotfload-tool.lua index 18e9f9e..32086e1 100755 --- a/luaotfload-tool.lua +++ b/luaotfload-tool.lua @@ -6,7 +6,7 @@ -- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang -- VERSION: 2.5 -- LICENSE: GPL v2.0 --- MODIFIED: 2014-01-02 21:21:10+0100 +-- MODIFIED: 2014-01-14 13:17:04+0100 ----------------------------------------------------------------------- local version = "2.5" --- <int: major>.<int: minor><alpha: fixes> @@ -950,7 +950,7 @@ set_primary_field = function (fields, addme, acc, n) return acc end -local splitcomma = names.patterns.splitcomma +local splitcomma = luaotfload.parsers.splitcomma actions.list = function (job) local criterion = job.criterion |