summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile12
-rw-r--r--luaotfload-database.lua103
-rwxr-xr-xluaotfload-tool.lua154
-rwxr-xr-xmktests69
4 files changed, 300 insertions, 38 deletions
diff --git a/Makefile b/Makefile
index 944fc12..2d618e7 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/mktests b/mktests
index 92d66be..f2d6a06 100755
--- a/mktests
+++ b/mktests
@@ -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