diff options
Diffstat (limited to 'luaotfload-features.lua')
-rw-r--r-- | luaotfload-features.lua | 97 |
1 files changed, 69 insertions, 28 deletions
diff --git a/luaotfload-features.lua b/luaotfload-features.lua index 7ae035b..415d2ac 100644 --- a/luaotfload-features.lua +++ b/luaotfload-features.lua @@ -6,8 +6,9 @@ if not modules then modules = { } end modules ["features"] = { license = "see context related readme files" } -local format, insert = string.format, table.insert local type, next = type, next +local tonumber = tonumber +local tostring = tostring local lpegmatch = lpeg.match ---[[ begin included font-ltx.lua ]] @@ -28,15 +29,15 @@ function fonts.definers.getspecification(str) return "", str, "", ":", str end -local old_feature_list = { } - local report = logs.names_report local stringfind = string.find local stringlower = string.lower local stringgsub = string.gsub local stringsub = string.sub +local stringformat = string.format local stringis_empty = string.is_empty +local mathceil = math.ceil --- TODO an option to dump the default features for a script would make --- a nice addition to luaotfload-tool @@ -753,6 +754,7 @@ local support_incomplete = table.tohash({ --- (string, string) dict -> (string, string) dict local set_default_features = function (speclist) speclist = speclist or { } + speclist[""] = nil --- invalid options stub --- handle language tag local language = speclist.language @@ -877,22 +879,53 @@ end --doc]]-- -local strip_leading_sign = function (s) - --- handle option list keys - local first = stringsub(s, 1, 1) - if first == "+" or first == "-" then --- Xetex style - return stringsub(s, 2) +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 s + return key, val end -local toboolean = function (s) - --- handle option list values - if s == "true" then return true end - if s == "false" then return false end - --if s == "yes" then return true end --- Context style - --if s == "no" then return false end - return stringlower(s) +--[[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 “%s” unknown.", opt) + return "", false end --[[doc-- @@ -975,19 +1008,28 @@ local unprefixed = Cg(fontname, "anon") local path_lookup = lbrk * Cg(C((1-rbrk)^1), "path") * rbrk --- features ---------------------------------------------------------- -local field = (anum + S"+-.")^1 --- sic! +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 assignment = (field / strip_leading_sign) * ws - * equals * ws - * (field / toboolean) +local normal_option = C(field) * ws * equals * ws * C(field) * ws +local xetex_option = P"+" * ws * normal_option +local assignment = xetex_option / handle_xetex_option + + normal_option / handle_normal_option +----- assignment = (field / strip_leading_sign) * ws +----- * equals * ws +----- * (field / toboolean) local switch = P"+" * ws * C(field) * Cc(true) + P"-" * ws * C(field) * Cc(false) - + C(field) * Cc(true) -- catch crap +-- + C(field) * Cc(true) -- catch crap +local ignore = (1 - featuresep)^1 --- ignores one option + / handle_invalid_option local feature_expr = ws * Cg(assignment + switch) * ws +local option = feature_expr + ignore local feature_list = Cf(Ct"" - * feature_expr - * (featuresep * feature_expr)^0 + * option + * (featuresep * option)^0 , rawset) * featuresep^-1 @@ -1002,7 +1044,6 @@ local feature_list = Cf(Ct"" --- 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 ---- Who’s 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. @@ -1113,8 +1154,8 @@ local handle_request = function (specification) specification.lookup = "path" return specification end - local lookup, name = select_lookup(request) - request.features = set_default_features(request.features) + local lookup, name = select_lookup(request) + request.features = set_default_features(request.features) if name then specification.name = name @@ -1231,11 +1272,11 @@ local function addfeature(data,feature,specifications) local featuretype = types[specification.type or "substitution"] local featureflags = specification.flags or noflags local added = false - local featurename = format("ctx_%s_%s",feature,s) + local featurename = stringformat("ctx_%s_%s",feature,s) local st = { } for t=1,#subtables do local list = subtables[t] - local full = format("%s_%s",featurename,t) + local full = stringformat("%s_%s",featurename,t) st[t] = full if featuretype == "gsub_ligature" then lookuptypes[full] = "ligature" |