diff options
| -rw-r--r-- | luaotfload-auxiliary.lua | 4 | ||||
| -rw-r--r-- | luaotfload-database.lua | 26 | ||||
| -rwxr-xr-x | luaotfload-tool.lua | 147 | 
3 files changed, 162 insertions, 15 deletions
| diff --git a/luaotfload-auxiliary.lua b/luaotfload-auxiliary.lua index 2d459d0..9f7974a 100644 --- a/luaotfload-auxiliary.lua +++ b/luaotfload-auxiliary.lua @@ -64,6 +64,10 @@ local add_fontdata_fallbacks = function (fontdata)        metadata = fontdata.shared.rawdata.metadata        fontdata.units   = fontparameters.units        local resources  = fontdata.resources +      --- the next line is a hack that fixes scaling of fonts with +      --- non-standard em-sizes (most ms fonts have 2048, others +      --- come with 256) +      --- this is considered a bug in the font loader        fontdata.size    = fontparameters.size * fontdata.units / 1000        --- for legacy fontspec.lua and unicode-math.lua        fontdata.shared.otfdata          = metadata diff --git a/luaotfload-database.lua b/luaotfload-database.lua index 576341f..96db195 100644 --- a/luaotfload-database.lua +++ b/luaotfload-database.lua @@ -146,10 +146,11 @@ This is a sketch of the luaotfload db:              psname     : string;              subfamily  : string;          } -        size        : int list; -        slant       : int; -        weight      : int; -        width       : int; +        size         : int list; +        slant        : int; +        weight       : int; +        width        : int; +        units_per_em : int;                      // mainly 1000, but also 2048 or 256      }      and filestatus = (fullname, { index : int list; timestamp : int }) dict @@ -836,13 +837,16 @@ font_fullinfo = function (filename, subfont)          report("log", 1, "db", "broken font rejected", "%s", basefile)          return      end -    tfmdata.fontname    = metadata.fontname -    tfmdata.fullname    = metadata.fullname -    tfmdata.familyname  = metadata.familyname -    tfmdata.filename    = { filename, subfont } -- always store full path -    tfmdata.weight      = metadata.pfminfo.weight -    tfmdata.width       = metadata.pfminfo.width -    tfmdata.slant       = metadata.italicangle +    tfmdata.fontname      = metadata.fontname +    tfmdata.fullname      = metadata.fullname +    tfmdata.familyname    = metadata.familyname +    tfmdata.filename      = { filename, subfont } -- always store full path +    tfmdata.weight        = metadata.pfminfo.weight +    tfmdata.width         = metadata.pfminfo.width +    tfmdata.slant         = metadata.italicangle +    --- this is for querying +    tfmdata.units_per_em  = metadata.units_per_em +    tfmdata.version       = metadata.version      -- don't waste the space with zero values      tfmdata.size = {          metadata.design_size         ~= 0 and metadata.design_size         or nil, diff --git a/luaotfload-tool.lua b/luaotfload-tool.lua index 0cd19b1..6662291 100755 --- a/luaotfload-tool.lua +++ b/luaotfload-tool.lua @@ -32,6 +32,8 @@ local stringformat    = string.format  local texiowrite_nl   = texio.write_nl  local stringlower     = string.lower +local C, Ct, P     = lpeg.C, lpeg.Ct, lpeg.P +local lpegmatch    = lpeg.match  local loader_file = "luatexbase.loader.lua"  local loader_path = assert(kpse.find_file(loader_file, "lua"), @@ -64,8 +66,6 @@ local config        = config  config.luaotfload   = config.luaotfload or { }  do -- we don’t have file.basename and the likes yet, so inline parser ftw -    local C, P         = lpeg.C, lpeg.P -    local lpegmatch    = lpeg.match      local slash        = P"/"      local dot          = P"."      local noslash      = 1 - slash @@ -228,7 +228,7 @@ set.  --]]--  local action_sequence = { -    "loglevel", "help", "version", "flush", "generate", "query" +    "loglevel", "help", "version", "flush", "generate", "list", "query"  }  local action_pending  = table.tohash(action_sequence, false) @@ -286,7 +286,7 @@ actions.query = function (job)          lookup        = "name",          specification = "name:" .. query,          optsize       = 0, -    } +   }      local foundname, subfont, success =          fonts.names.resolve(nil, nil, tmpspec) @@ -317,6 +317,137 @@ actions.query = function (job)      return true, true  end +---         --list=<criterion> +---         --list=<criterion>:<value> +--- +---         --list=<criterion>          --fields=<f1>,<f2>,<f3>,...<fn> + +local get_fields get_fields = function (entry, fields, acc, n) +    if not acc then +        return get_fields(entry, fields, { }, 1) +    end + +    local field = fields[n] +    if field then +        local value = entry[field] +        acc[#acc+1] = value or false +        return get_fields(entry, fields, acc, n+1) +    end +    return acc +end + +local comma       = P"," +local noncomma    = 1-comma +local split_comma = Ct((C(noncomma^1) + comma)^1) + +local texiowrite_nl     = texio.write_nl +local tableconcat       = table.concat +local stringexplode     = string.explode + +local separator = "\t" --- could be “,” for csv + +local format_fields format_fields = function (fields, acc, n) +    if not acc then +        return format_fields(fields, { }, 1) +    end + +    local field = fields[n] +    if field ~= nil then +        if field == false then +            acc[#acc+1] = "<none>" +        else +            acc[#acc+1] = tostring(field) +        end +        return format_fields(fields, acc, n+1) +    end +    return tableconcat(acc, separator) +end + +local set_primary_field +set_primary_field = function (fields, addme, acc, n) +    if not acc then +        return set_primary_field(fields, addme, { addme }, 1) +    end + +    local field = fields[n] +    if field then +        if field ~= addme then +            acc[#acc+1] = field +        end +        return set_primary_field(fields, addme, acc, n+1) +    end +    return acc +end + +actions.list = function (job) +    local criterion     = job.criterion + +    local asked_fields  = job.asked_fields +    if asked_fields then +        asked_fields = lpegmatch(split_comma, asked_fields) +    else +        --- some defaults +        asked_fields = { "fullname", "version", } +    end + +    if not names.data then +        names.data = names.load() +    end + +    local mappings  = names.data.mappings +    local nmappings = #mappings + +    if criterion == "*" then +        logs.names_report(false, 1, "list", "all %d entries", nmappings) +        for i=1, nmappings do +            local entry     = mappings[i] +            local fields    = get_fields(entry, asked_fields) +            --- we could collect these instead ... +            local formatted = format_fields(fields) +            texiowrite_nl(formatted) +        end + +    else +        criterion = stringexplode(criterion, ":") --> { field, value } +        local asked_value  = criterion[2] +        criterion          = criterion[1] +        asked_fields       = set_primary_field(asked_fields, criterion) + +        logs.names_report(false, 1, "list", "by %s", criterion) + +        --- firstly, build a list of fonts to operate on +        local targets, ntargets + +        if asked_value then +            logs.names_report(false, 2, "list", "restricting to value %s", asked_value) +            targets = { } +            for i=1, nmappings do +                local entry = mappings[i] +                if  entry[criterion] +                and tostring(entry[criterion]) == asked_value +                then +                    targets[#targets+1] = entry +                end +            end +            ntargets = #targets +        else --- all +            targets  = mappings +            ntargets = nmappings +        end +        logs.names_report(false, 2, "list", "%d entries", ntargets) + +        --- now, output the collection +        for i=1, ntargets do +            local entry         = targets[i] +            local fields        = get_fields(entry, asked_fields) +            local formatted     = format_fields(fields) +            texiowrite_nl(formatted) +        end +    end + +    return true, true +end +  --[[--  Command-line processing.  mkluatexfontdb.lua relies on the script alt_getopt to process argv and @@ -330,6 +461,7 @@ alt_getopt.  local process_cmdline = function ( ) -- unit -> jobspec      local result = { -- jobspec          force_reload = nil, +        criterion    = "",          query        = "",          log_level    = 1, --- 2 is approx. the old behavior      } @@ -337,12 +469,14 @@ local process_cmdline = function ( ) -- unit -> jobspec      local long_options = {          alias            = 1,          ["flush-cache"]  = "c", +        fields           = 1,          find             = 1,          force            = "f",          fuzzy            = "F",          help             = "h",          info             = "i",          limit            = 1, +        list             = 1,          log              = 1,          quiet            = "q",          update           = "u", @@ -401,6 +535,11 @@ local process_cmdline = function ( ) -- unit -> jobspec              config.luaotfload.self = optarg[n]          elseif v == "c" then              action_pending["flush"] = true +        elseif v == "list" then +            action_pending["list"] = true +            result.criterion = optarg[n] +        elseif v == "fields" then +            result.asked_fields = optarg[n]          end      end | 
