diff options
| author | Philipp Gesang <phg42.2a@gmail.com> | 2013-07-27 13:36:16 -0700 | 
|---|---|---|
| committer | Philipp Gesang <phg42.2a@gmail.com> | 2013-07-27 13:36:16 -0700 | 
| commit | 515a4cf2df2d070af12bf6e4d332cd906d4dd031 (patch) | |
| tree | 5fc53bfd3f2733b9867d32b0fde45c91dc49732e | |
| parent | daeb3c1fddf826deb325cbe2a6567083c828ca13 (diff) | |
| parent | c186e7575989bcf18cada97c0f4310aa287f44b8 (diff) | |
| download | luaotfload-515a4cf2df2d070af12bf6e4d332cd906d4dd031.tar.gz | |
Merge pull request #114 from phi-gamma/master
directory handling; environment variables
| -rw-r--r-- | Makefile | 12 | ||||
| -rw-r--r-- | luaotfload-database.lua | 103 | ||||
| -rwxr-xr-x | luaotfload-tool.lua | 154 | ||||
| -rwxr-xr-x | mktests | 69 | 
4 files changed, 300 insertions, 38 deletions
@@ -60,6 +60,9 @@ MANDIR    = $(TEXMFROOT)/doc/man/man1/  SRCDIR    = $(TEXMFROOT)/source/$(FORMAT)/$(NAME)  TEXMFROOT = $(shell kpsewhich --var-value TEXMFHOME) +# CTAN-friendly subdirectory for packaging +DISTDIR	  = ./luaotfload +  CTAN_ZIP = $(NAME).zip  TDS_ZIP  = $(NAME).tds.zip  ZIPS 	 = $(CTAN_ZIP) $(TDS_ZIP) @@ -110,10 +113,16 @@ $(UNPACKED): $(DTX)  $(MAN): $(MANSOURCE)  	$(DO_DOCUTILS) +define make-ctandir +@$(RM) -rf $(DISTDIR) +@mkdir -p $(DISTDIR) && cp $(SOURCE) $(COMPILED) $(DISTDIR) +endef +  $(CTAN_ZIP): $(SOURCE) $(COMPILED) $(TDS_ZIP)  	@echo "Making $@ for CTAN upload."  	@$(RM) -- $@ -	@zip -9 $@ $^ >/dev/null +	$(make-ctandir) +	@zip -r -9 $@ $(TDS_ZIP) $(DISTDIR) >/dev/null  define run-install  @mkdir -p $(SCRIPTDIR) && cp $(SCRIPTSTATUS) $(SCRIPTDIR) @@ -164,4 +173,5 @@ clean:  mrproper: clean  	@$(RM) -- $(GENERATED) $(ZIPS) $(GLYPHSOURCE) $(TESTDIR)/*.pdf +	@$(RM) -r -- $(DISTDIR) diff --git a/luaotfload-database.lua b/luaotfload-database.lua index 1b75458..a49e575 100644 --- a/luaotfload-database.lua +++ b/luaotfload-database.lua @@ -117,6 +117,10 @@ end  local report = logs.names_report +local trailingslashes   = P"/"^1 * P(-1) +local stripslashes      = C((1 - trailingslashes)^0) +names.patterns          = { stripslashes = stripslashes } +  --[[doc--      We use the functions in the cache.* namespace that come with the      fontloader (see luat-basics-gen). it’s safe to use for the most part @@ -139,6 +143,7 @@ if caches then          luaotfload.error              ("Impossible to find a suitable writeable cache...")      else +        prefix = lpegmatch (stripslashes, prefix)          report ("log", 0, "db",                  "root cache directory is " .. prefix)      end @@ -1438,7 +1443,9 @@ process_dir_tree = function (acc, dirs)                  then                      dirs[#dirs+1] = fullpath                  elseif lfsisfile (fullpath) then -                    if lpegmatch (p_font_extensions, stringlower(ent)) then +                    if lpegmatch (p_font_extensions, +                                  stringlower (ent)) +                    then                          newfiles[#newfiles+1] = fullpath                      end                  end @@ -1450,10 +1457,38 @@ process_dir_tree = function (acc, dirs)      return process_dir_tree (acc, dirs)  end ---- string -> string list -local find_font_files = function (root) +local process_dir = function (dir) +    local pwd = lfscurrentdir () +    if lfschdir (dir) then +        lfschdir (pwd) + +        local files = { } +        local blacklist = names.blacklist +        for ent in lfsdir (dir) do +            if ent ~= "." and ent ~= ".." and not blacklist[ent] then +                local fullpath = dir .. "/" .. ent +                if lfsisfile (fullpath) then +                    if lpegmatch (p_font_extensions, +                                  stringlower (ent)) +                    then +                        files[#files+1] = fullpath +                    end +                end +            end +        end +        return files +    end +    return { } +end + +--- string -> bool -> string list +local find_font_files = function (root, recurse)      if lfsisdir (root) then -        return process_dir_tree ({}, { root }) +        if recurse == true then +            return process_dir_tree ({}, { root }) +        else --- kpathsea already delivered the necessary subdirs +            return process_dir (root) +        end      end  end @@ -1478,7 +1513,7 @@ local scan_dir = function (dirname, fontnames, newfontnames,          --- ignore          return 0, 0      end -    local found = find_font_files (dirname) +    local found = find_font_files (dirname, texmf ~= true)      if not found then          report ("both", 3, "db",                  "No such directory: %q; skipping.", dirname) @@ -1511,23 +1546,55 @@ local scan_dir = function (dirname, fontnames, newfontnames,      return n_found, n_new  end +--- string list -> string list +local filter_out_pwd = function (dirs) +    local result = { } +    local pwd = path_normalize (lpegmatch (stripslashes, +                                           lfscurrentdir ())) +    for i = 1, #dirs do +        --- better safe than sorry +        local dir = path_normalize (lpegmatch (stripslashes, dirs[i])) +        if not (dir == "." or dir == pwd) then +            result[#result+1] = dir +        end +    end +    return result +end + +--[[doc-- +    scan_texmf_fonts() scans all fonts in the texmf tree through the +    kpathsea variables OPENTYPEFONTS and TTFONTS of texmf.cnf. +    The current working directory comes as “.” (texlive) or absolute +    path (miktex) and will always be filtered out. +--doc]]-- +  --- dbobj -> dbobj -> bool? -> (int * int)  local scan_texmf_fonts = function (fontnames, newfontnames, dry_run) -    local n_scanned, n_new = 0, 0 -    --[[ -    This function scans all fonts in the texmf tree, through kpathsea -    variables OPENTYPEFONTS and TTFONTS of texmf.cnf -    ]] -    if stringis_empty(kpseexpand_path("$OSFONTDIR")) then -        report("info", 2, "db", "Scanning TEXMF fonts...") +    local n_scanned, n_new, fontdirs = 0, 0 +    local osfontdir = kpseexpand_path "$OSFONTDIR" +    if stringis_empty (osfontdir) then +        report ("info", 2, "db", "Scanning TEXMF fonts...")      else -        report("info", 2, "db", "Scanning TEXMF and OS fonts...") +        report ("info", 2, "db", "Scanning TEXMF and OS fonts...") +        if logs.get_loglevel () > 3 then +            local osdirs = filesplitpath (osfontdir) +            report ("info", 0, "db", +                    "$OSFONTDIR has %d entries:", #osdirs) +            for i = 1, #osdirs do +                report ("info", 0, "db", "[%d] %s", i, osdirs[i]) +            end +        end      end -    local fontdirs = stringgsub(kpseexpand_path("$OPENTYPEFONTS"), "^%.", "") -    fontdirs       = fontdirs .. stringgsub(kpseexpand_path("$TTFONTS"), "^%.", "") -    if not stringis_empty(fontdirs) then -        for _,d in next, filesplitpath(fontdirs) do -            local found, new = scan_dir(d, fontnames, newfontnames, dry_run, true) +    fontdirs = kpseexpand_path "$OPENTYPEFONTS" +    fontdirs = fontdirs .. (ostype == "windows" and ";" or ":") +            .. kpseexpand_path "$TTFONTS" +    if not stringis_empty (fontdirs) then +        local tasks = filter_out_pwd (filesplitpath (fontdirs)) +        report ("info", 3, "db", +                "Initiating scan of %d directories.", #tasks) +        for _, d in next, tasks do +            local found, new = scan_dir (d, fontnames, newfontnames, +                                         dry_run, true)              n_scanned = n_scanned + found              n_new     = n_new     + new          end diff --git a/luaotfload-tool.lua b/luaotfload-tool.lua index 801ae72..cd64a75 100755 --- a/luaotfload-tool.lua +++ b/luaotfload-tool.lua @@ -42,13 +42,17 @@ kpse.set_program_name "luatex"  local ioopen          = io.open  local iowrite         = io.write  local kpsefind_file   = kpse.find_file +local kpseexpand_var  = kpse.expand_var +local kpseexpand_path = kpse.expand_path  local lfsattributes   = lfs.attributes  local lfsisfile       = lfs.isfile  local lfsreadlink     = lfs.readlink  local md5sumhexa      = md5.sumhexa  local next            = next  local osdate          = os.date +local osgetenv        = os.getenv  local osremove        = os.remove +local osname          = os.name  local ostype          = os.type  local stringexplode   = string.explode  local stringformat    = string.format @@ -136,13 +140,13 @@ config.lualibs.prefer_merged    = true  config.lualibs.load_extended    = true  require "lualibs" ---- dofile "util-jsn.lua" --- awaiting fix -local lua_of_json               = utilities.json.tolua +local fileisreadable            = file.isreadable +local fileiswritable            = file.iswritable +local filesplitpath             = file.splitpath  local ioloaddata                = io.loaddata +local lua_of_json               = utilities.json.tolua  local tabletohash               = table.tohash -local fileiswritable            = file.iswritable -local fileisreadable            = file.isreadable  --[[doc--  \fileent{luatex-basics-gen.lua} calls functions from the @@ -690,6 +694,7 @@ local action_sequence = {      "blacklist", "cache", "flush",   "generate",      "list",      "query",  } +  local action_pending  = tabletohash(action_sequence, false)  action_pending.loglevel = true  --- always set the loglevel @@ -1028,8 +1033,7 @@ do          return lpegmatch (p_permissions, raw)      end -    local trailingslashes   = P"/"^1 * P(-1) -    local stripslashes      = C((1 - trailingslashes)^0) +    local stripslashes = names.patterns.stripslashes      local get_permissions = function (t, location)          if stringsub (location, #location) == "/" then @@ -1334,7 +1338,136 @@ do      end      --- github api stuff end -    local anamneses   = { "files", "repository", "permissions" } +    local print_envvar = function (var) +        local val = osgetenv (var) +        if val then +            out ("%20s: %q", stringformat ("$%s", var), val) +            return val +        else +            out ("%20s: <unset>", stringformat ("$%s", var)) +        end +    end + +    local print_path = function (var) +        local val = osgetenv (var) +        if val then +            local paths = filesplitpath (val) +            if paths then +                local npaths = #paths +                if npaths == 1 then +                    out ("%20s: %q", stringformat ("$%s", var), val) +                elseif npaths > 1 then +                    out ("%20s: <%d items>", stringformat ("$%s", var), npaths) +                    for i = 1, npaths do +                        out ("                   +: %q", paths[i]) +                    end +                else +                    out ("%20s: <empty>") +                end +            end +        else +            out ("%20s: <unset>", stringformat ("$%s", var)) +        end +    end + +    local print_kpsevar = function (var) +        var = "$" .. var +        local val = kpseexpand_var (var) +        if val and val ~= var then +            out ("%20s: %q", var, val) +            return val +        else +            out ("%20s: <empty or unset>", var) +        end +    end + +    local print_kpsepath = function (var) +        var = "$" .. var +        local val = kpseexpand_path (var) +        if val and val ~= "" then +            local paths = filesplitpath (val) +            if paths then +                local npaths = #paths +                if npaths == 1 then +                    out ("%20s: %q", var, paths[1]) +                elseif npaths > 1 then +                    out ("%20s: <%d items>", var, npaths) +                    for i = 1, npaths do +                        out ("                   +: %q", paths[i]) +                    end +                else +                    out ("%20s: <empty>") +                end +            end +        else +            out ("%20s: <empty or unset>", var) +        end +    end + +    --- this test first if a variable is set and then expands the +    --- paths; this is necessitated by the fact that expand-path will +    --- return the empty string both if the variable is unset and if +    --- the directory does not exist + +    local print_kpsepathvar = function (var) +        local vvar = "$" .. var +        local val = kpseexpand_var (vvar) +        if val and val ~= vvar then +            out ("%20s: %q", vvar, val) +            print_kpsepath (var) +        else +            out ("%20s: <empty or unset>", var) +        end +    end + +    local check_environment = function (errcnt) +        out "============ environment settings =============" +        out ("system: %s/%s", ostype, osname) +        if ostype == "unix" and io.popen then +            local chan = io.popen ("uname -a", "r") +            if chan then +                out ("info: %s", chan:read "*all") +                chan:close () +            end +        end + +        out "1) *shell environment*" +        print_envvar "SHELL" +        print_path "PATH" +        print_path "OSFONTDIR" +        print_envvar "USER" +        if ostype == "windows" then +            print_envvar "WINDIR" +            print_envvar "CD" +            print_path "TEMP" +        elseif ostype == "unix" then +            print_envvar "HOME" +            print_envvar "PWD" +            print_path "TMPDIR" +        end + +        out "2) *kpathsea*" +        print_kpsepathvar "OPENTYPEFONTS" +        print_kpsepathvar "TTFONTS" + +        print_kpsepathvar "TEXMFCACHE" +        print_kpsepathvar "TEXMFVAR" + +        --- the expansion of these can be quite large; as they aren’t +        --- usually essential to luaotfload, we won’t dump every single +        --- path +        print_kpsevar "LUAINPUTS" +        print_kpsevar "CLUAINPUTS" + +        return errcnt +    end + +    local anamneses   = { +        "environment", +        "files", +        "repository", +        "permissions" +    }      actions.diagnose = function (job)          local errcnt = 0 @@ -1346,14 +1479,21 @@ do              asked = tabletohash (asked, true)          end +        if asked.environment == true then +            errcnt = check_environment (errcnt) +            asked.environment = nil +        end +          if asked.files == true then              errcnt = verify_files (errcnt, status)              asked.files = nil          end +          if asked.permissions == true then              errcnt = check_permissions (errcnt)              asked.permissions = nil          end +          if asked.repository == true then              check_upstream (status.notes.revision)              asked.repository = nil @@ -57,6 +57,12 @@ local pprint_result = function (name, failed, total)    end  end +local pprint_spec = function (spec) +  return string.format ("%s*%.2fpt", +                        spec.specification, +                        spec.optsize) +end +  -----------------------------------------------------------------------  --- font tests  ----------------------------------------------------------------------- @@ -72,8 +78,31 @@ local infer_regular_style = {    { "Garamond Premier Pro", "GaramondPremrPro-Capt.otf" },  } +local choose_optical_size = { +  { { name = "Latin Modern Roman", optsize =  0 }, "lmroman5-regular.otf" }, +  { { name = "Latin Modern Roman", optsize = 10 }, "lmroman10-regular.otf" }, +  { { name = "Latin Modern Roman", optsize = 12 }, "lmroman12-regular.otf" }, +  { { name = "Latin Modern Roman", optsize = 42 }, "lmroman17-regular.otf" }, +  { { name = "EB Garamond", optsize =  0 }, "EBGaramond08-Regular.otf" }, +  { { name = "EB Garamond", optsize =  8 }, "EBGaramond08-Regular.otf" }, +  { { name = "EB Garamond", optsize = 12 }, "EBGaramond12-Regular.otf" }, +  { { name = "EB Garamond", optsize = 42 }, "EBGaramond12-Regular.otf" }, +  { { name = "Garamond Premier Pro", optsize =  0 }, "GaramondPremrPro-Capt.otf" }, +  { { name = "Garamond Premier Pro", optsize = 10 }, "GaramondPremrPro.otf" }, +  { { name = "Garamond Premier Pro", optsize = 15 }, "GaramondPremrPro-Subh.otf" }, +  { { name = "Garamond Premier Pro", optsize = 42 }, "GaramondPremrPro-Disp.otf" }, +} +  local font_name_tests = { -    infer_regular_style, +  infer_regular_style, +  choose_optical_size, +} + +local default_spec = { +  name          = false, +  lookup        = "name", +  specification = false, +  optsize       = 0,  }  local resolve_font_name = function () @@ -81,21 +110,37 @@ local resolve_font_name = function ()    local resolve_name = names.resolve    for nset = 1, #font_name_tests do      local set = font_name_tests[nset] +      for ntest = 1, #set do        local test = set[ntest]        local input, output = test[1], test[2] -      local input_spec = { -          name          = input, -          lookup        = "name", -          specification = "name:" .. input, -          optsize       = 0, -      } -      local result = resolve_name (nil, nil, input_spec) == output -      total = total + 1 -      if not result then -        failed = failed + 1 + +      if type (input) == "string" then +        local input_spec = table.copy (default_spec) +        input_spec.name = input +        input_spec.specification = input_spec.lookup .. ":" .. input +        local result = resolve_name (nil, nil, input_spec) == output +        total = total + 1 +        if not result then +          failed = failed + 1 +        end +        pprint_resolve (input, output, result) + +      else +        local input_spec, output = test[1], test[2] +        input_spec.specification = (input_spec.lookup +                                    or default_spec.lookup) +                                .. ":" .. input_spec.name +        input_spec.optsize = input_spec.optsize or default_spec.optsize +        --print( resolve_name (nil, nil, input_spec) ) +        local result = resolve_name (nil, nil, input_spec) == output +        total = total + 1 +        if not result then +          failed = failed + 1 +        end +        pprint_resolve (pprint_spec (input_spec), output, result)        end -      pprint_resolve (input, output, result) +      end    end    return failed, total  | 
