summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--luaotfload-database.lua27
-rw-r--r--luaotfload-diagnostics.lua8
-rw-r--r--luaotfload-features.lua260
-rw-r--r--luaotfload-parsers.lua311
-rwxr-xr-xluaotfload-tool.lua4
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