summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile53
-rw-r--r--NEWS4
-rw-r--r--luaotfload-auxiliary.lua2
-rw-r--r--luaotfload-colors.lua2
-rw-r--r--luaotfload-database.lua184
-rw-r--r--luaotfload-extralibs.lua2
-rw-r--r--luaotfload-features.lua2
-rw-r--r--luaotfload-letterspace.lua2
-rw-r--r--luaotfload-loaders.lua2
-rw-r--r--luaotfload-override.lua26
-rwxr-xr-xluaotfload-tool.lua548
-rw-r--r--luaotfload-tool.rst37
-rw-r--r--luaotfload.dtx14
-rwxr-xr-xmkstatus147
14 files changed, 849 insertions, 176 deletions
diff --git a/Makefile b/Makefile
index 3807ec5..4768d75 100644
--- a/Makefile
+++ b/Makefile
@@ -8,8 +8,9 @@ OTFL = $(wildcard luaotfload-*.lua) luaotfload-blacklist.cnf
GLYPHSCRIPT = mkglyphlist
GLYPHSOURCE = glyphlist.txt
CHARSCRIPT = mkcharacters
+STATUSSCRIPT = mkstatus
-RESOURCESCRIPTS = $(GLYPHSCRIPT) $(CHARSCRIPT)
+RESOURCESCRIPTS = $(GLYPHSCRIPT) $(CHARSCRIPT) $(STATUSSCRIPT)
SCRIPTNAME = luaotfload-tool
SCRIPT = $(SCRIPTNAME).lua
@@ -24,7 +25,8 @@ DOT = $(GRAPH).dot
# Files grouped by generation mode
GLYPHS = luaotfload-glyphlist.lua
CHARS = luaotfload-characters.lua
-RESOURCES = $(GLYPHS) $(CHARS)
+STATUS = luaotfload-status.lua
+RESOURCES = $(GLYPHS) $(CHARS) $(STATUS)
GRAPHED = $(DOTPDF)
MAN = $(MANPAGE)
COMPILED = $(DOC)
@@ -34,20 +36,20 @@ SOURCE = $(DTX) $(MANSOURCE) $(OTFL) README Makefile NEWS $(RESOURCESCRIPTS)
# test files
TESTDIR = tests
-TESTFILES = $(wildcard $(TESTDIR)/*.tex $(TESTDIR)/*.ltx)
-TESTFILES_SYS = $(TESTDIR)/systemfonts.tex $(TESTDIR)/fontconfig_conf_reading.tex
-TESTFILES_TL = $(filter-out $(TESTFILES_SYS), $(TESTFILES))
+TESTSTATUS = $(wildcard $(TESTDIR)/*.tex $(TESTDIR)/*.ltx)
+TESTSTATUS_SYS = $(TESTDIR)/systemfonts.tex $(TESTDIR)/fontconfig_conf_reading.tex
+TESTSTATUS_TL = $(filter-out $(TESTSTATUS_SYS), $(TESTSTATUS))
# Files grouped by installation location
-SCRIPTFILES = $(SCRIPT) $(OLDSCRIPT) $(RESOURCESCRIPTS)
-RUNFILES = $(UNPACKED) $(filter-out $(SCRIPTFILES),$(OTFL))
-DOCFILES = $(DOC) $(DOTPDF) README NEWS
-MANFILES = $(MANPAGE)
-SRCFILES = $(DTX) Makefile
+SCRIPTSTATUS = $(SCRIPT) $(OLDSCRIPT) $(RESOURCESCRIPTS)
+RUNSTATUS = $(UNPACKED) $(filter-out $(SCRIPTSTATUS),$(OTFL))
+DOCSTATUS = $(DOC) $(DOTPDF) README NEWS
+MANSTATUS = $(MANPAGE)
+SRCSTATUS = $(DTX) Makefile
# The following definitions should be equivalent
-# ALL_FILES = $(RUNFILES) $(DOCFILES) $(SRCFILES)
-ALL_FILES = $(GENERATED) $(SOURCE)
+# ALL_STATUS = $(RUNSTATUS) $(DOCSTATUS) $(SRCSTATUS)
+ALL_STATUS = $(GENERATED) $(SOURCE)
# Installation locations
FORMAT = luatex
@@ -70,6 +72,7 @@ DO_LATEX = latexmk -pdf -e '$$pdflatex = q(lualatex %O %S)' -silent $< >/dev
DO_GRAPHVIZ = dot -Tpdf -o $@ $< > /dev/null
DO_GLYPHS = $(LUA) $(GLYPHSCRIPT) > /dev/null
DO_CHARS = $(LUA) $(CHARSCRIPT) > /dev/null
+DO_STATUS = $(LUA) $(STATUSSCRIPT) > /dev/null
DO_DOCUTILS = rst2man $< >$@ 2>/dev/null
all: $(GENERATED)
@@ -79,6 +82,7 @@ manual: $(MAN)
unpack: $(UNPACKED)
resources: $(RESOURCES)
chars: $(CHARS)
+status: $(STATUS)
ctan: $(CTAN_ZIP)
tds: $(TDS_ZIP)
world: all ctan
@@ -89,6 +93,9 @@ $(GLYPHS): /dev/null
$(CHARS): /dev/null
$(DO_CHARS)
+$(STATUS): /dev/null
+ $(DO_STATUS)
+
$(GRAPHED): $(DOT)
$(DO_GRAPHVIZ)
@@ -107,15 +114,15 @@ $(CTAN_ZIP): $(SOURCE) $(COMPILED) $(TDS_ZIP)
@zip -9 $@ $^ >/dev/null
define run-install
-@mkdir -p $(SCRIPTDIR) && cp $(SCRIPTFILES) $(SCRIPTDIR)
-@mkdir -p $(RUNDIR) && cp $(RUNFILES) $(RUNDIR)
-@mkdir -p $(DOCDIR) && cp $(DOCFILES) $(DOCDIR)
-@mkdir -p $(SRCDIR) && cp $(SRCFILES) $(SRCDIR)
-@mkdir -p $(MANDIR) && cp $(MANFILES) $(MANDIR)
+@mkdir -p $(SCRIPTDIR) && cp $(SCRIPTSTATUS) $(SCRIPTDIR)
+@mkdir -p $(RUNDIR) && cp $(RUNSTATUS) $(RUNDIR)
+@mkdir -p $(DOCDIR) && cp $(DOCSTATUS) $(DOCDIR)
+@mkdir -p $(SRCDIR) && cp $(SRCSTATUS) $(SRCDIR)
+@mkdir -p $(MANDIR) && cp $(MANSTATUS) $(MANDIR)
endef
$(TDS_ZIP): TEXMFROOT=./tmp-texmf
-$(TDS_ZIP): $(ALL_FILES)
+$(TDS_ZIP): $(ALL_STATUS)
@echo "Making TDS-ready archive $@."
@$(RM) -- $@
$(run-install)
@@ -124,20 +131,20 @@ $(TDS_ZIP): $(ALL_FILES)
.PHONY: install manifest clean mrproper
-install: $(ALL_FILES)
+install: $(ALL_STATUS)
@echo "Installing in '$(TEXMFROOT)'."
$(run-install)
-check: $(RUNFILES) $(TESTFILES_TL)
+check: $(RUNSTATUS) $(TESTSTATUS_TL)
@rm -rf var
- @for f in $(TESTFILES_TL); do \
+ @for f in $(TESTSTATUS_TL); do \
echo "check: luatex $$f"; \
luatex --interaction=batchmode $$f \
> /dev/null || exit $$?; \
done
-check-all: $(TESTFILES_SYS) check
- @cd $(TESTDIR); for f in $(TESTFILES_SYS); do \
+check-all: $(TESTSTATUS_SYS) check
+ @cd $(TESTDIR); for f in $(TESTSTATUS_SYS); do \
echo "check: luatex $$f"; \
$(TESTENV) luatex --interaction=batchmode ../$$f \
> /dev/null || exit $$?; \
diff --git a/NEWS b/NEWS
index 8615d90..0875cfa 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,10 @@
Change History
--------------
+2013/07/10, luaotfload v2.3a
+ * Detect LuaJIT interpreter (LuaJITTeX)
+ * Self-test functionality for luaotfload-tool.lua (option ``--diagnose``)
+
2013/07/03, luaotfload v2.3:
* New experimental lookups: ``kpse`` (kpathsea), ``my`` (callback)
* Precedence of texmf over system fonts can be requested
diff --git a/luaotfload-auxiliary.lua b/luaotfload-auxiliary.lua
index 8fc8477..d6c8eaa 100644
--- a/luaotfload-auxiliary.lua
+++ b/luaotfload-auxiliary.lua
@@ -4,7 +4,7 @@
-- DESCRIPTION: part of luaotfload
-- REQUIREMENTS: luaotfload 2.3
-- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang
--- VERSION: 2.3
+-- VERSION: 2.3a
-- CREATED: 2013-05-01 14:40:50+0200
-----------------------------------------------------------------------
--
diff --git a/luaotfload-colors.lua b/luaotfload-colors.lua
index d3e77b0..b95e836 100644
--- a/luaotfload-colors.lua
+++ b/luaotfload-colors.lua
@@ -1,5 +1,5 @@
if not modules then modules = { } end modules ['luaotfload-colors'] = {
- version = 2.3,
+ version = "2.3a",
comment = "companion to luaotfload.lua (font color)",
author = "Khaled Hosny, Elie Roux, Philipp Gesang",
copyright = "Luaotfload Development Team",
diff --git a/luaotfload-database.lua b/luaotfload-database.lua
index c0aadaf..e0b977b 100644
--- a/luaotfload-database.lua
+++ b/luaotfload-database.lua
@@ -1,5 +1,5 @@
if not modules then modules = { } end modules ['luaotfload-database'] = {
- version = 2.3,
+ version = "2.3a",
comment = "companion to luaotfload.lua",
author = "Khaled Hosny, Elie Roux, Philipp Gesang",
copyright = "Luaotfload Development Team",
@@ -27,6 +27,7 @@ local require = require
local tonumber = tonumber
local unpack = table.unpack
+
local fontloaderinfo = fontloader.info
local fontloaderopen = fontloader.open
local iolines = io.lines
@@ -40,6 +41,7 @@ local lfsattributes = lfs.attributes
local lfsdir = lfs.dir
local mathabs = math.abs
local mathmin = math.min
+local osremove = os.remove
local stringfind = string.find
local stringformat = string.format
local stringgmatch = string.gmatch
@@ -52,8 +54,8 @@ local tablesort = table.sort
local texiowrite_nl = texio.write_nl
local utf8gsub = unicode.utf8.gsub
local utf8lower = unicode.utf8.lower
-
--- these come from Lualibs/Context
+local getwritablepath = caches.getwritablepath
local filebasename = file.basename
local filecollapsepath = file.collapsepath or file.collapse_path
local filedirname = file.dirname
@@ -95,27 +97,57 @@ end
names.version = 2.207
names.data = nil --- contains the loaded database
names.lookups = nil --- contains the lookup cache
-names.path = {
- dir = "", --- db and cache directory
- basename = config.luaotfload.names_file
+
+names.path = { index = { }, lookups = { } }
+names.path.globals = {
+ prefix = "", --- writable_path/names_dir
+ names_dir = config.luaotfload.names_dir or "names",
+ index_file = config.luaotfload.index_file
or "luaotfload-names.lua",
- path = "", --- full path to db file
- lookup_basename = "luaotfload-lookup-cache.lua", --- cache file name
- lookup_path = "", --- cache full path
+ lookups_file = "luaotfload-lookup-cache.lua",
}
--- We use the cache.* of ConTeXt (see luat-basics-gen), we can
--- use it safely (all checks and directory creations are already done). It
--- uses TEXMFCACHE or TEXMFVAR as starting points.
-local writable_path
+--- string -> (string * string)
+local make_luanames = function (path)
+ return filereplacesuffix(path, "lua"),
+ filereplacesuffix(path, "luc")
+end
+
+local report = logs.names_report
+
+--[[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
+ since most checks and directory creations are already done. It
+ uses TEXMFCACHE or TEXMFVAR as starting points.
+
+ There is one quirk, though: ``getwritablepath()`` will always
+ assume that files in subdirectories of the cache tree are writable.
+ It gives no feedback at all if it fails to open a file in write
+ mode. This may cause trouble when the index or lookup cache were
+ created by different user.
+--doc]]--
+
if caches then
- writable_path = caches.getwritablepath "names"
- if not writable_path then
- luaotfload.error("Impossible to find a suitable writeable cache...")
+ local globals = names.path.globals
+ local names_dir = globals.names_dir
+
+ prefix = getwritablepath (names_dir, "")
+ if not prefix then
+ luaotfload.error
+ ("Impossible to find a suitable writeable cache...")
+ else
+ report ("log", 0, "db",
+ "root cache directory is " .. prefix)
end
- names.path.dir = writable_path
- names.path.path = filejoin(writable_path, names.path.basename)
- names.path.lookup_path = filejoin(writable_path, names.path.lookup_basename)
+
+ globals.prefix = prefix
+ local lookups = names.path.lookups
+ local index = names.path.index
+ local lookups_file = filejoin (prefix, globals.lookups_file)
+ local index_file = filejoin (prefix, globals.index_file)
+ lookups.lua, lookups.luc = make_luanames (lookups_file)
+ index.lua, index.luc = make_luanames (index_file)
else --- running as script, inject some dummies
caches = { }
logs = { report = function () end }
@@ -126,9 +158,6 @@ end
Auxiliary functions
--doc]]--
-
-local report = logs.names_report
-
--- string -> string
local sanitize_string = function (str)
if str ~= nil then
@@ -267,12 +296,6 @@ local fontnames_init = function (keep_cache) --- returns dbobj
}
end
---- string -> (string * string)
-local make_savenames = function (path)
- return filereplacesuffix(path, "lua"),
- filereplacesuffix(path, "luc")
-end
-
--- When loading a lua file we try its binary complement first, which
--- is assumed to be located at an identical path, carrying the suffix
--- .luc.
@@ -330,7 +353,7 @@ local fuzzy_limit = 1 --- display closest only
--- bool? -> dbobj
load_names = function (dry_run)
local starttime = os.gettimeofday()
- local foundname, data = load_lua_file(names.path.path)
+ local foundname, data = load_lua_file(names.path.index.lua)
if data then
report("both", 2, "db",
@@ -352,7 +375,7 @@ load_names = function (dry_run)
report("both", 0, "db",
[[Font names database not found, generating new one.]])
report("both", 0, "db",
- [[This can take several minutes; please be patient.]])
+ [[This can take several minutes; please be patient.]])
data = update_names(fontnames_init(false), nil, dry_run)
local success = save_names(data)
if not success then
@@ -365,7 +388,7 @@ end
--- unit -> dbobj
load_lookups = function ( )
- local foundname, data = load_lua_file(names.path.lookup_path)
+ local foundname, data = load_lua_file(names.path.lookups.lua)
if data then
report("both", 3, "cache",
"Lookup cache loaded (%s)", foundname)
@@ -776,7 +799,7 @@ resolve = function (_, _, specification) -- the 1st two parameters are used by C
if facenames then
family = facenames.family
subfamily = facenames.subfamily
- prefmodifiers = facenames.prefmodifiers
+ prefmodifiers = facenames.prefmodifiers or facenames.subfamily
fullname = facenames.fullname
psname = facenames.psname
fontname = facenames.fontname
@@ -795,16 +818,19 @@ resolve = function (_, _, specification) -- the 1st two parameters are used by C
if continue == false then break end
elseif style == subfamily then
exact = add_to_match(exact, askedsize, face)
+ elseif synonym_set[style] and synonym_set[style][prefmodifiers]
+ or synonym_set.regular[prefmodifiers]
+ then
+ --- treat synonyms for prefmodifiers as first-class
+ --- (needed to prioritize DejaVu Book over Condensed)
+ exact = add_to_match(exact, askedsize, face)
elseif name == fullname
or name == pfullname
or name == fontname
or name == psname
then
- synonymous, continue = add_to_match(synonymous, askedsize, face)
- elseif synonym_set[style] and
- (synonym_set[style][prefmodifiers] or
- synonym_set[style][subfamily])
- or synonym_set.regular[prefmodifiers]
+ synonymous = add_to_match(synonymous, askedsize, face)
+ elseif synonym_set[style] and synonym_set[style][subfamily]
or synonym_set.regular[subfamily]
then
synonymous = add_to_match(synonymous, askedsize, face)
@@ -1909,15 +1935,6 @@ update_names = function (fontnames, force, dry_run)
return newfontnames
end
---- unit -> string
-local ensure_names_path = function ( )
- local path = names.path.dir
- if not lfsisdir(path) then
- lfsmkdirs(path)
- end
- return path
-end
-
--- The lookup cache is an experimental feature of version 2.2;
--- instead of incorporating it into the database it gets its own
--- file. As we update it after every single addition this saves us
@@ -1925,23 +1942,28 @@ end
--- unit -> bool
save_lookups = function ( )
- ---- this is boilerplate and should be refactored into something
- ---- usable by both the db and the cache writers
- local lookups = names.lookups
- local path = ensure_names_path()
- if fileiswritable(path) then
- local luaname, lucname = make_savenames(names.path.lookup_path)
- if luaname then
- tabletofile(luaname, lookups, true)
- if lucname and type(caches.compile) == "function" then
- os.remove(lucname)
- caches.compile(lookups, luaname, lucname)
- report("both", 3, "cache", "Lookup cache saved")
- return true
- end
+ local lookups = names.lookups
+ local path = names.path.lookups
+ local luaname, lucname = path.lua, path.luc
+ if fileiswritable (luaname) and fileiswritable (lucname) then
+ tabletofile (luaname, lookups, true)
+ osremove (lucname)
+ caches.compile (lookups, luaname, lucname)
+ --- double check ...
+ if lfsisfile (luaname) and lfsisfile (lucname) then
+ report ("both", 3, "cache", "Lookup cache saved")
+ return true
end
+ report ("info", 0, "cache", "Could not compile lookup cache")
+ return false
+ end
+ report ("info", 0, "cache", "Lookup cache file not writable")
+ if not fileiswritable (luaname) then
+ report ("info", 0, "cache", "Failed to write %s", luaname)
+ end
+ if not fileiswritable (lucname) then
+ report ("info", 0, "cache", "Failed to write %s", lucname)
end
- report("info", 0, "cache", "Could not write lookup cache")
return false
end
@@ -1949,23 +1971,28 @@ end
--- dbobj? -> bool
save_names = function (fontnames)
if not fontnames then fontnames = names.data end
- local path = ensure_names_path()
- if fileiswritable(path) then
- local luaname, lucname = make_savenames(names.path.path)
- if luaname then
- --tabletofile(luaname, fontnames, true, { reduce=true })
- tabletofile(luaname, fontnames, true)
- if lucname and type(caches.compile) == "function" then
- os.remove(lucname)
- caches.compile(fontnames, luaname, lucname)
- report("info", 1, "db", "Font names database saved")
- report("info", 3, "db", "Text: " .. luaname)
- report("info", 3, "db", "Byte: " .. lucname)
- return true
- end
+ local path = names.path.index
+ local luaname, lucname = path.lua, path.luc
+ if fileiswritable (luaname) and fileiswritable (lucname) then
+ tabletofile (luaname, fontnames, true)
+ osremove (lucname)
+ caches.compile (fontnames, luaname, lucname)
+ if lfsisfile (luaname) and lfsisfile (lucname) then
+ report ("info", 1, "db", "Font index saved")
+ report ("info", 3, "db", "Text: " .. luaname)
+ report ("info", 3, "db", "Byte: " .. lucname)
+ return true
end
+ report ("info", 0, "db", "Could not compile font index")
+ return false
+ end
+ report ("info", 0, "db", "Index file not writable")
+ if not fileiswritable (luaname) then
+ report ("info", 0, "db", "Failed to write %s", luaname)
+ end
+ if not fileiswritable (lucname) then
+ report ("info", 0, "db", "Failed to write %s", lucname)
end
- report("both", 0, "db", "Failed to save names database")
return false
end
@@ -1999,7 +2026,7 @@ local purge_from_cache = function (category, path, list, all)
if string.find(filename,"luatex%-cache") then -- safeguard
if all then
report("info", 5, "cache", "removing %s", filename)
- os.remove(filename)
+ osremove(filename)
n = n + 1
else
local suffix = file.suffix(filename)
@@ -2008,7 +2035,7 @@ local purge_from_cache = function (category, path, list, all)
filename, "lua", "luc")
if lfs.isfile(checkname) then
report("info", 5, "cache", "Removing %s", filename)
- os.remove(filename)
+ osremove(filename)
n = n + 1
end
end
@@ -2048,8 +2075,7 @@ end
local getwritablecachepath = function ( )
--- fonts.handlers.otf doesn’t exist outside a Luatex run,
--- so we have to improvise
- local writable = caches.getwritablepath
- (config.luaotfload.cache_dir)
+ local writable = getwritablepath (config.luaotfload.cache_dir)
if writable then
return writable
end
diff --git a/luaotfload-extralibs.lua b/luaotfload-extralibs.lua
index 3204229..3769e06 100644
--- a/luaotfload-extralibs.lua
+++ b/luaotfload-extralibs.lua
@@ -1,5 +1,5 @@
if not modules then modules = { } end modules ["extralibs"] = {
- version = 2.3,
+ version = "2.3a",
comment = "companion to luaotfload.lua",
author = "Hans Hagen, Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/luaotfload-features.lua b/luaotfload-features.lua
index 690a33c..a07992b 100644
--- a/luaotfload-features.lua
+++ b/luaotfload-features.lua
@@ -1,5 +1,5 @@
if not modules then modules = { } end modules ["features"] = {
- version = 2.3,
+ version = "2.3a",
comment = "companion to luaotfload.lua",
author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/luaotfload-letterspace.lua b/luaotfload-letterspace.lua
index e4ebf0b..880c7bd 100644
--- a/luaotfload-letterspace.lua
+++ b/luaotfload-letterspace.lua
@@ -1,5 +1,5 @@
if not modules then modules = { } end modules ['letterspace'] = {
- version = 2.3,
+ version = "2.3a",
comment = "companion to luaotfload.lua",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL; adapted by Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/luaotfload-loaders.lua b/luaotfload-loaders.lua
index 0ab1505..63e1d08 100644
--- a/luaotfload-loaders.lua
+++ b/luaotfload-loaders.lua
@@ -1,5 +1,5 @@
if not modules then modules = { } end modules ["loaders"] = {
- version = 2.3,
+ version = "2.3a",
comment = "companion to luaotfload.lua",
author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/luaotfload-override.lua b/luaotfload-override.lua
index 39cc172..f647826 100644
--- a/luaotfload-override.lua
+++ b/luaotfload-override.lua
@@ -1,5 +1,5 @@
if not modules then modules = { } end modules ['luat-ovr'] = {
- version = 2.3,
+ version = "2.3a",
comment = "companion to luatex-*.tex",
author = "Khaled Hosny, Elie Roux, Philipp Gesang",
copyright = "Luaotfload Development Team",
@@ -32,6 +32,12 @@ local texio_write = texio.write
local texiowrite = texio.write
local type = type
+local texjob = false
+if tex and (tex.jobname or tex.formatname) then
+ --- TeX
+ texjob = true
+end
+
--[[doc--
We recreate the verbosity levels previously implemented in font-nms:
@@ -136,10 +142,9 @@ end
logs.set_logout = set_logout
local log = function (category, fmt, ...)
- local res = { module_name, " |" }
- if category then res[#res+1] = " " .. category end
- if fmt then res[#res+1] = ": " .. stringformat(fmt, ...) end
- texiowrite_nl(logout, tableconcat(res))
+ local res = { module_name, "|", category, ":" }
+ if fmt then res[#res+1] = stringformat(fmt, ...) end
+ texiowrite_nl(logout, tableconcat(res, " "))
end
--- with faux db update with maximum verbosity:
@@ -156,11 +161,11 @@ end
io.stdout:setvbuf "no"
io.stderr:setvbuf "no"
-if tex and (tex.jobname or tex.formatname) then
- --- TeX
- writeln = texiowrite_nl
+if texjob == true then
+ writeln = function (str)
+ texiowrite_nl ("term", str)
+ end
else
- --- Lua interpreter
writeln = function (str)
iowrite(str)
iowrite "\n"
@@ -171,7 +176,8 @@ stdout = function (category, ...)
local res = { module_name, "|", category, ":" }
local nargs = select("#", ...)
if nargs == 0 then
- writeln (tableconcat ({...}))
+ --writeln tableconcat(res, " ")
+ --return
elseif nargs == 1 then
res[#res+1] = select(1, ...) -- around 30% faster than unpack()
else
diff --git a/luaotfload-tool.lua b/luaotfload-tool.lua
index 4d25d53..4afd9d1 100755
--- a/luaotfload-tool.lua
+++ b/luaotfload-tool.lua
@@ -4,7 +4,7 @@
-- DESCRIPTION: database functionality
-- REQUIREMENTS: luaotfload 2.2
-- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang
--- VERSION: 2.3
+-- VERSION: 2.3a
-- LICENSE: GPL v2
-- MODIFIED: 2013-06-02 19:23:54+0200
-----------------------------------------------------------------------
@@ -26,6 +26,8 @@ see the luaotfload documentation for more info. Report bugs to
--doc]]--
+kpse.set_program_name "luatex"
+
--[[doc--
We test for Lua 5.1 by means of capability detection to see if
@@ -36,7 +38,28 @@ see the luaotfload documentation for more info. Report bugs to
--doc]]--
-kpse.set_program_name "luatex"
+
+local ioopen = io.open
+local iowrite = io.write
+local kpsefind_file = kpse.find_file
+local lfsattributes = lfs.attributes
+local lfsisfile = lfs.isfile
+local lfsreadlink = lfs.readlink
+local md5sumhexa = md5.sumhexa
+local next = next
+local osdate = os.date
+local osremove = os.remove
+local ostype = os.type
+local stringexplode = string.explode
+local stringformat = string.format
+local stringlower = string.lower
+local stringrep = string.rep
+local stringsub = string.sub
+local tableconcat = table.concat
+local texiowrite_nl = texio.write_nl
+local texiowrite = texio.write
+local tonumber = tonumber
+local type = type
local runtime
if _G.getfenv ~= nil then -- 5.1 or LJ
@@ -44,26 +67,19 @@ if _G.getfenv ~= nil then -- 5.1 or LJ
runtime = { "jit", jit.version }
else
runtime = { "stock", _VERSION }
- local oldscript = kpse.find_file "luaotfload-legacy-tool.lua"
+ local oldscript = kpsefind_file "luaotfload-legacy-tool.lua"
return require (oldscript)
end
else -- 5.2
runtime = { "stock", _VERSION }
end
-local stringexplode = string.explode
-local stringformat = string.format
-local stringlower = string.lower
-local stringrep = string.rep
-local tableconcat = table.concat
-local texiowrite_nl = texio.write_nl
-local texiowrite = texio.write
-local C, Ct, P, S = lpeg.C, lpeg.Ct, lpeg.P, lpeg.S
+local C, Cg, Ct, P, S = lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.S
local lpegmatch = lpeg.match
local loader_file = "luatexbase.loader.lua"
-local loader_path = assert(kpse.find_file(loader_file, "lua"),
+local loader_path = assert(kpsefind_file(loader_file, "lua"),
"File '"..loader_file.."' not found")
@@ -93,7 +109,7 @@ local config = config
config.luaotfload = config.luaotfload or { }
config.luaotfload.names_dir = config.luaotfload.names_dir or "names"
config.luaotfload.cache_dir = config.luaotfload.cache_dir or "fonts"
-config.luaotfload.names_file = config.luaotfload.names_file
+config.luaotfload.index_file = config.luaotfload.index_file
or "luaotfload-names.lua"
do -- we don’t have file.basename and the likes yet, so inline parser ftw
@@ -117,9 +133,16 @@ end
config.lualibs = config.lualibs or { }
config.lualibs.verbose = false
config.lualibs.prefer_merged = true
-config.lualibs.load_extended = false
+config.lualibs.load_extended = true
require "lualibs"
+--- dofile "util-jsn.lua" --- awaiting fix
+
+local lua_of_json = utilities.json.tolua
+local ioloaddata = io.loaddata
+local tabletohash = table.tohash
+local fileiswritable = file.iswritable
+local fileisreadable = file.isreadable
--[[doc--
\fileent{luatex-basics-gen.lua} calls functions from the
@@ -143,17 +166,15 @@ local names = fonts.names
local sanitize_string = names.sanitize_string
---local db_src_out = names.path.dir.."/"..names.path.basename
-local names_plain = file.join (
- caches.getwritablepath (config.luaotfload.names_dir),
- config.luaotfload.names_file)
-local names_bin = file.replacesuffix (names_plain, "luc")
+local pathdata = names.path
+local names_plain = pathdata.index.lua
+local names_bin = pathdata.index.luc
local help_messages = {
["luaotfload-tool"] = [[
-Usage: %s [OPTION]...
-
+Usage: %s [OPTIONS...]
+
Operations on the LuaTeX font database.
This tool is part of the luaotfload package. Valid options are:
@@ -169,6 +190,8 @@ This tool is part of the luaotfload package. Valid options are:
-V --version print version and exit
-h --help print this message
+ --diagnose=CHECK run a self test procedure; one of “files”,
+ “permissions”, or “repository”
--alias=<name> force behavior of “luaotfload-tool” or legacy
“mkluatexfontdb”
@@ -214,7 +237,7 @@ The font cache will be written to
mkluatexfontdb = [[
Usage: %s [OPTION]...
-
+
Rebuild or update the LuaTeX font database.
Valid options:
@@ -233,17 +256,26 @@ The font database will be saved to
%s
]],
+ short = [[
+Usage: luaotfload-tool [--help] [--version] [--verbose=<lvl>]
+ [--update] [--force] [--prefer-texmf]
+ [--find=<font name>] [--fuzzy] [--info] [--inspect]
+ [--list=<criterion>] [--fields=<field list>]
+ [--cache=<directive>] [--flush-lookups]
+ [--show-blacklist] [--diagnose=<procedure>]
+
+Enter 'luaotfload-tool --help' for a larger list of options.
+]]
}
-local help_msg = function ( )
- local template = help_messages[config.luaotfload.self]
- or help_messages["luaotfload-tool"]
- texiowrite_nl(stringformat(template,
- config.luaotfload.self,
- names_plain,
- names_bin,
- caches.getwritablepath (
- config.luaotfload.cache_dir)))
+local help_msg = function (version)
+ local template = help_messages[version]
+ iowrite(stringformat(template,
+ config.luaotfload.self,
+ names_plain,
+ names_bin,
+ caches.getwritablepath (
+ config.luaotfload.cache_dir)))
end
local version_msg = function ( )
@@ -467,7 +499,7 @@ local display_general = function (fullinfo)
val = #fullinfo[key]
end
elseif mode == "d" then
- val = os.date("%F %T", fullinfo[key])
+ val = osdate("%F %T", fullinfo[key])
end
if not val then
val = "<none>"
@@ -648,10 +680,11 @@ set.
--]]--
local action_sequence = {
- "loglevel", "help", "version", "blacklist", "cache",
- "flush", "generate", "list", "query",
+ "loglevel", "help", "version", "diagnose",
+ "blacklist", "cache", "flush", "generate",
+ "list", "query",
}
-local action_pending = table.tohash(action_sequence, false)
+local action_pending = tabletohash(action_sequence, false)
action_pending.loglevel = true --- always set the loglevel
action_pending.generate = false --- this is the default action
@@ -662,7 +695,7 @@ actions.loglevel = function (job)
logs.set_loglevel(job.log_level)
logs.names_report("info", 3, "util",
"Setting log level", "%d", job.log_level)
- logs.names_report("log", 0, "util", "Lua=%s", _VERSION)
+ logs.names_report("log", 2, "util", "Lua=%s", _VERSION)
return true, true
end
@@ -672,7 +705,7 @@ actions.version = function (job)
end
actions.help = function (job)
- help_msg()
+ help_msg (job.help_version or "luaotfload-tool")
return true, false
end
@@ -915,6 +948,437 @@ actions.list = function (job)
return true, true
end
+do
+ local out = function (...)
+ logs.names_report (false, 0, "diagnose", ...)
+ end
+
+ local verify_files = function (errcnt, info)
+ out "================ verify files ================="
+ local hashes = info.hashes
+ local notes = info.notes
+ if not hashes or #hashes == 0 then
+ out ("FAILED: cannot read checksums from %s.", status_file)
+ return 1/0
+ elseif not notes then
+ out ("FAILED: cannot read commit metadata from %s.",
+ status_file)
+ return 1/0
+ end
+
+ out ("Luaotfload revision %s.", notes.revision)
+ out ("Committed by %s.", notes.committer)
+ out ("Timestamp %s.", notes.timestamp)
+
+ local nhashes = #hashes
+ out ("Testing %d files for integrity.", nhashes)
+ for i = 1, nhashes do
+ local fname, canonicalsum = unpack (hashes[i])
+ local location = kpsefind_file (fname)
+ or kpsefind_file (fname, "texmfscripts")
+ if not location then
+ errcnt = errcnt + 1
+ out ("FAILED: file %s missing.", fname)
+ else
+ out ("File: %s.", location)
+ local raw = ioloaddata (location)
+ if not raw then
+ errcnt = errcnt + 1
+ out ("FAILED: file %d not readable.", fname)
+ else
+ local sum = md5sumhexa (raw)
+ if sum ~= canonicalsum then
+ errcnt = errcnt + 1
+ out ("FAILED: checksum mismatch for file %s.",
+ fname)
+ out ("Expected %s.", canonicalsum)
+ out ("Got %s.", sum)
+ else
+ out ("Ok, %s passed.", fname)
+ end
+ end
+ end
+ end
+ return errcnt
+ end
+
+ local get_tentative_attributes = function (file)
+ if not lfsisfile (file) then
+ local chan = ioopen (file, "w")
+ if chan then
+ chan:close ()
+ local attributes = lfsattributes (file)
+ os.remove (file)
+ return attributes
+ end
+ end
+ end
+
+ local p_permissions = Ct(Cg(Ct(C(1) * C(1) * C(1)), "u")
+ * Cg(Ct(C(1) * C(1) * C(1)), "g")
+ * Cg(Ct(C(1) * C(1) * C(1)), "o"))
+
+ local analyze_permissions = function (raw)
+ return lpegmatch (p_permissions, raw)
+ end
+
+ local get_permissions = function (t, location)
+ local attributes = lfsattributes (location)
+ if not attributes and t == "f" then
+ attributes = get_tentative_attributes (location)
+ if not attributes then
+ return false
+ end
+ end
+
+ local permissions
+
+ if fileisreadable (location) then
+ --- link handling appears to be unnecessary because
+ --- lfs.attributes() will return the information on
+ --- the link target.
+ if mode == "link" then --follow and repeat
+ location = lfsreadlink (location)
+ attributes = lfsattributes (location)
+ end
+ end
+
+ permissions = analyze_permissions (attributes.permissions)
+
+ return {
+ location = location,
+ mode = attributes.mode,
+ owner = attributes.uid, --- useless on windows
+ permissions = permissions,
+ attributes = attributes,
+ }
+ end
+
+ local check_conformance = function (spec, permissions, errcnt)
+ local uid = permissions.attributes.uid
+ local gid = permissions.attributes.gid
+ local raw = permissions.attributes.permissions
+
+ out ("Owner: %d, group %d, permissions %s.", uid, gid, raw)
+ if ostype == "unix" then
+ if uid == 0 or gid == 0 then
+ out "Owned by the superuser, permission conflict likely."
+ errcnt = errcnt + 1
+ end
+ end
+
+ local user = permissions.permissions.u
+ if spec.r == true then
+ if user[1] == "r" then
+ out "Readable: ok."
+ else
+ out "Not readable: permissions need fixing."
+ errcnt = errcnt + 1
+ end
+ end
+
+ if spec.w == true then
+ if user[2] == "w"
+ or fileiswritable (permissions.location) then
+ out "Writable: ok."
+ else
+ out "Not writable: permissions need fixing."
+ errcnt = errcnt + 1
+ end
+ end
+
+ return errcnt
+ end
+
+ local path = names.path
+
+ local desired_permissions = {
+ { "d", {"r","w"}, function () return caches.getwritablepath () end },
+ { "d", {"r","w"}, path.globals.prefix },
+ { "f", {"r","w"}, path.index.lua },
+ { "f", {"r","w"}, path.index.luc },
+ { "f", {"r","w"}, path.lookups.lua },
+ { "f", {"r","w"}, path.lookups.luc },
+ }
+
+ local check_permissions = function (errcnt)
+ out [[=============== file permissions ==============]]
+ for i = 1, #desired_permissions do
+ local t, spec, path = unpack (desired_permissions[i])
+ if type (path) == "function" then
+ path = path ()
+ end
+
+ spec = tabletohash (spec)
+
+ out ("Checking permissions of %s.", path)
+
+ local permissions = get_permissions (t, path)
+ if permissions then
+ --inspect (permissions)
+ errcnt = check_conformance (spec, permissions, errcnt)
+ else
+ errcnt = errcnt + 1
+ end
+ end
+ return errcnt
+ end
+
+ local check_upstream
+
+ if kpsefind_file ("https.lua", "lua") == nil then
+ check_upstream = function (errcnt)
+ out [[============= upstream repository =============
+ Github API access requires the luasec library.
+ WARNING: Cannot retrieve repository data.
+ Grab it from <https://github.com/brunoos/luasec>
+ and retry.]]
+ return errcnt
+ end
+ else
+ --- github api stuff begin
+ local https = require "ssl.https"
+
+ local gh_api_root = [[https://api.github.com]]
+ local release_url = [[https://github.com/lualatex/luaotfload/releases]]
+ local luaotfload_repo = [[lualatex/luaotfload]]
+ local user_agent = [[lualatex/luaotfload integrity check]]
+ local shortbytes = 8
+
+ local gh_shortrevision = function (rev)
+ return stringsub (rev, 1, shortbytes)
+ end
+
+ local gh_encode_parameters = function (parameters)
+ local acc = {}
+ for field, value in next, parameters do
+ --- unsafe, non-urlencoded coz it’s all ascii chars
+ acc[#acc+1] = field .. "=" .. value
+ end
+ return "?" .. tableconcat (acc, "&")
+ end
+
+ local gh_make_url = function (components, parameters)
+ local url = tableconcat ({ gh_api_root,
+ unpack (components) },
+ "/")
+ if parameters then
+ url = url .. gh_encode_parameters (parameters)
+ end
+ return url
+ end
+
+ local alright = [[HTTP/1.1 200 OK]]
+
+ local gh_api_request = function (...)
+ local args = {...}
+ local nargs = #args
+ local final = args[nargs]
+ local request = {
+ url = "",
+ headers = { ["user-agent"] = user_agent },
+ }
+ if type (final) == "table" then
+ args[nargs] = nil
+ request = gh_make_url (args, final)
+ else
+ request = gh_make_url (args)
+ end
+
+ out ("Requesting <%s>.", request)
+ local response, code, headers, status
+ = https.request (request)
+ if status ~= alright then
+ out "Request failed!"
+ return false
+ end
+ return response
+ end
+
+ local gh_api_checklimit = function (headers)
+ local rawlimit = gh_api_request "rate_limit"
+ local limitdata = lua_of_json (rawlimit)
+ if not limitdata and limitdata.rate then
+ out "Cannot parse API rate limit."
+ return false
+ end
+ limitdata = limitdata.rate
+
+ local limit = tonumber (limitdata.limit)
+ local left = tonumber (limitdata.remaining)
+ local reset = tonumber (limitdata.reset)
+
+ out ("%d of %d Github API requests left.", left, limit)
+ if left == 0 then
+ out ("Cannot make any more API requests.")
+ out ("Try again later at %s.", osdate ("%F %T", reset))
+ end
+ return true
+ end
+
+ local gh_tags = function ()
+ out "Fetching tags from repository, please stand by."
+ local rawtags = gh_api_request ("repos",
+ luaotfload_repo,
+ "tags")
+ local taglist = lua_of_json (rawtags)
+ if not taglist or #taglist == 0 then
+ out "Cannot parse response."
+ return false
+ end
+
+ local ntags = #taglist
+ out ("Repository contains %d tags.", ntags)
+ local _idx, latest = next (taglist)
+ out ("The most recent release is %s (revision %s).",
+ latest.name,
+ gh_shortrevision (latest.commit.sha))
+ return latest
+ end
+
+ local gh_compare = function (head, base)
+ if base == nil then
+ base = "HEAD"
+ end
+ out ("Fetching comparison between %s and %s, \z
+ please stand by.",
+ gh_shortrevision (head),
+ gh_shortrevision (base))
+ local comparison = base .. "..." .. head
+ local rawstatus = gh_api_request ("repos",
+ luaotfload_repo,
+ "compare",
+ comparison)
+ local status = lua_of_json (rawstatus)
+ if not status then
+ out "Cannot parse response for status request."
+ return false
+ end
+ return status
+ end
+
+ local gh_news = function (since)
+ local compared = gh_compare (since)
+ if not compared then
+ return false
+ end
+ local behind_by = compared.behind_by
+ local ahead_by = compared.ahead_by
+ local status = compared.status
+ out ("Comparison state: %s.", status)
+ if behind_by > 0 then
+ out ("Your Luaotfload is %d \z
+ revisions behind upstream.",
+ behind_by)
+ return behind_by
+ elseif status == "ahead" then
+ out "Since you are obviously from the future \z
+ I assume you already know the repository state."
+ else
+ out "Everything up to date. \z
+ Luaotfload is in sync with upstream."
+ end
+ return false
+ end
+
+ local gh_catchup = function (current, latest)
+ local compared = gh_compare (latest, current)
+ local ahead_by = tonumber (compared.ahead_by)
+ if ahead_by > 0 then
+ local permalink_url = compared.permalink_url
+ out ("Your Luaotfload is %d revisions \z
+ behind the most recent release.",
+ ahead_by)
+ out ("To view the commit log, visit <%s>.",
+ permalink_url)
+ out ("You can grab an up to date tarball at <%s>.",
+ release_url)
+ return true
+ else
+ out "There weren’t any new releases in the meantime."
+ out "Luaotfload is up to date."
+ end
+ return false
+ end
+
+ check_upstream = function (current)
+ out "============= upstream repository ============="
+ local _succ = gh_api_checklimit ()
+ local behind = gh_news (current)
+ if behind then
+ local latest = gh_tags ()
+ local _behind = gh_catchup (current,
+ latest.commit.sha,
+ latest.name)
+ end
+ end
+
+ --- trivium: diff since the first revision as pushed by Élie
+ --- in 2009
+ --- local firstrevision = "c3ccb3ee07e0a67171c24960966ae974e0dd8e98"
+ --- check_upstream (firstrevision)
+ end
+ --- github api stuff end
+
+ local anamneses = { "files", "repository", "permissions" }
+ local status_file = "luaotfload-status"
+
+ actions.diagnose = function (job)
+ local errcnt = 0
+ local asked = job.asked_diagnostics
+ if asked == "all" or asked == "thorough" then
+ asked = tabletohash (anamneses, true)
+ else
+ asked = lpegmatch(split_comma, asked)
+ asked = tabletohash (asked, true)
+ end
+
+ out "Loading file hashes."
+ local info = require (status_file)
+
+ if asked.files == true then
+ errcnt = verify_files (errcnt, info)
+ end
+ if asked.permissions == true then
+ errcnt = check_permissions (errcnt)
+ end
+ if asked.repository == true then
+ --errcnt = check_upstream (info.notes.revision)
+ check_upstream (info.notes.revision)
+ end
+
+
+ if errcnt == 0 then --> success
+ out ("Everything appears to be in order, \z
+ you may sleep well.")
+ return true, false
+ end
+ out ( [[===============================================
+ WARNING
+ ===============================================
+
+ The diagnostic detected %d errors.
+
+ This version of luaotfload may have been
+ tampered with. Modified versions of the
+ luaotfload source are unsupported. Read the log
+ carefully and get a clean version from CTAN or
+ github:
+
+ × http://ctan.org/tex-archive/macros/luatex/generic/luaotfload
+ × https://github.com/lualatex/luaotfload/releases
+
+ If you are uncertain as to how to proceed, then
+ ask on the lualatex mailing list:
+
+ http://www.tug.org/mailman/listinfo/lualatex-dev
+
+ ===============================================
+]], errcnt)
+ return true, false
+ end
+end
+
--- stuff to be carried out prior to exit
local finalizers = { }
@@ -954,6 +1418,7 @@ local process_cmdline = function ( ) -- unit -> jobspec
local long_options = {
alias = 1,
cache = 1,
+ diagnose = 1,
["dry-run"] = "D",
["flush-lookups"] = "l",
fields = 1,
@@ -1049,13 +1514,20 @@ local process_cmdline = function ( ) -- unit -> jobspec
config.luaotfload.prioritize = "texmf"
elseif v == "b" then
action_pending["blacklist"] = true
+ elseif v == "diagnose" then
+ action_pending["diagnose"] = true
+ result.asked_diagnostics = optarg[n]
end
end
if config.luaotfload.self == "mkluatexfontdb" then
+ result.help_version = "mkluatexfontdb"
action_pending["generate"] = true
- result.log_level = math.max(2, result.log_level)
+ result.log_level = math.max(1, result.log_level)
logs.set_logout"stdout"
+ elseif nopts == 0 then
+ action_pending["help"] = true
+ result.help_version = "short"
end
return result
end
diff --git a/luaotfload-tool.rst b/luaotfload-tool.rst
index 31a1010..e81aa8d 100644
--- a/luaotfload-tool.rst
+++ b/luaotfload-tool.rst
@@ -6,32 +6,34 @@
generate and query the Luaotfload font names database
-----------------------------------------------------------------------
-:Date: 2013-06-02
+:Date: 2013-07-10
:Copyright: GPL v2.0
-:Version: 2.3
+:Version: 2.3a
:Manual section: 1
:Manual group: text processing
SYNOPSIS
=======================================================================
-**luaotfload** [ -bDcfFiIpquvVwh ]
+**luaotfload-tool** [ -bDcfFiIpquvVwh ]
-**luaotfload** --update [ --force ] [ --quiet ] [ --verbose ] [ --prefer-texmf ] [ --dry-run ]
+**luaotfload-tool** --update [ --force ] [ --quiet ] [ --verbose ] [ --prefer-texmf ] [ --dry-run ]
-**luaotfload** --find=FONTNAME [ --fuzzy ] [ --info ] [ --inspect ]
+**luaotfload-tool** --find=FONTNAME [ --fuzzy ] [ --info ] [ --inspect ]
-**luaotfload** --flush-lookups
+**luaotfload-tool** --flush-lookups
-**luaotfload** --cache=DIRECTIVE
+**luaotfload-tool** --cache=DIRECTIVE
-**luaotfload** --list=CRITERION[:VALUE] [ --fields=F1,F2,...,Fn ]
+**luaotfload-tool** --list=CRITERION[:VALUE] [ --fields=F1,F2,...,Fn ]
-**luaotfload** --help
+**luaotfload-tool** --help
-**luaotfload** --version
+**luaotfload-tool** --version
-**luaotfload** --show-blacklist
+**luaotfload-tool** --show-blacklist
+
+**luaotfload-tool** --diagnose=CHECK
DESCRIPTION
=======================================================================
@@ -43,8 +45,6 @@ the *Luaotfload* package. There are two general modes: **update** and
+ **update**: update the database or rebuild it entirely;
+ **query**: resolve a font name or display close matches.
-A third mode for clearing the lookup cache is currently experimental.
-
Note that if the script is named ``mkluatexfontdb`` it will behave like
earlier versions (<=1.3) and always update the database first. Also,
the verbosity level will be set to 2.
@@ -128,6 +128,17 @@ miscellaneous
--version, -V Show version number and exit.
--help, -h Show help message and exit.
+--diagnose=CHECK Run the diagnostic procedure *CHECK*. Available
+ procedures are:
+
+ 1) ``files`` -> check *Luaotfload* files for
+ modifications;
+ 2) ``permissions`` -> check permissions of
+ cache directories and files;
+ 3) ``repository`` -> check the git repository
+ for new releases.
+
+ Specify ``thorough`` to run all checks.
FILES
=======================================================================
diff --git a/luaotfload.dtx b/luaotfload.dtx
index b8bee75..d647efb 100644
--- a/luaotfload.dtx
+++ b/luaotfload.dtx
@@ -40,7 +40,7 @@
\input docstrip.tex
\Msg{************************************************************************}
\Msg{* Installation}
-\Msg{* Package: luaotfload v2.3 OpenType layout system}
+\Msg{* Package: luaotfload v2.3a OpenType layout system}
\Msg{************************************************************************}
\keepsilent
@@ -111,7 +111,7 @@ and the derived files
%<*driver>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{luaotfload.drv}%
- [2013/05/23 v2.3d OpenType layout system]%
+ [2013/07/10 v2.3a OpenType layout system]%
\documentclass{ltxdoc}
\usepackage{metalogo,multicol,mdwlist,fancyvrb,xspace}
\usepackage[x11names]{xcolor}
@@ -231,7 +231,7 @@ and the derived files
% \GetFileInfo{luaotfload.drv}
%
% \title{The \identifier{luaotfload} package}
-% \date{2013/05/23 v2.3d}
+% \date{2013/07/10 v2.3a}
% \author{Elie Roux · Khaled Hosny · Philipp Gesang\\
% Home: \url{https://github.com/lualatex/luaotfload}\\
% Support: \email{lualatex-dev@tug.org}}
@@ -1474,12 +1474,12 @@ config.luaotfload.color_callback = config.luaotfload.color_callback or "pre_l
config.luaotfload.prioritize = config.luaotfload.prioritize or "sys"
config.luaotfload.names_dir = config.luaotfload.names_dir or "names"
config.luaotfload.cache_dir = config.luaotfload.cache_dir or "fonts"
-config.luaotfload.names_file = config.luaotfload.names_file or "luaotfload-names.lua"
+config.luaotfload.index_file = config.luaotfload.index_file or "luaotfload-names.lua"
luaotfload.module = {
name = "luaotfload",
- version = 2.3,
- date = "2013/06/02",
+ version = 2.3001,
+ date = "2013/07/10",
description = "OpenType layout system.",
author = "Elie Roux & Hans Hagen",
copyright = "Elie Roux",
@@ -2069,7 +2069,7 @@ loadmodule"auxiliary.lua" --- additionaly high-level functionality (new)
\else
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{luaotfload}%
- [2013/05/23 v2.3d OpenType layout system]
+ [2013/07/10 v2.3a OpenType layout system]
\RequirePackage{luatexbase}
\fi
\ifnum\luatexversion<76
diff --git a/mkstatus b/mkstatus
new file mode 100755
index 0000000..97d9f04
--- /dev/null
+++ b/mkstatus
@@ -0,0 +1,147 @@
+#!/usr/bin/env texlua
+-----------------------------------------------------------------------
+-- FILE: mkstatus.lua
+-- USAGE: ./mkstatus.lua
+-- DESCRIPTION: writes the repository state
+-- REQUIREMENTS: luatex, the lualibs package
+-- AUTHOR: Philipp Gesang (Phg), <phg42.2a@gmail.com>
+-- VERSION: 1.0
+-- CREATED: 2013-07-07 14:01:12+0200
+-----------------------------------------------------------------------
+--
+-- This script generates a list of hashes that serves as the input
+-- for the file integrity check (option --diagnose). md5 is all we can
+-- assume in Luatex, so it’s really only a superficial test.
+
+kpse.set_program_name "luatex"
+
+local md5 = require "md5"
+
+require "lualibs"
+
+local stringformat = string.format
+local md5sumhexa = md5.sumhexa
+local ioloaddata = io.loaddata
+local iosavedata = io.savedata
+local iopopen = io.popen
+
+-----------------------------------------------------------------------
+-- settings
+-----------------------------------------------------------------------
+
+local filelist = "luaotfload-status.lua" --- result
+
+local names = {
+ --- only the runtime files and scripts
+ "luaotfload-auxiliary.lua",
+ "luaotfload-basics-gen.lua",
+ "luaotfload-basics-nod.lua",
+ "luaotfload-characters.lua",
+ "luaotfload-colors.lua",
+ "luaotfload-database.lua",
+ "luaotfload-extralibs.lua",
+ "luaotfload-features.lua",
+ "luaotfload-fonts-cbk.lua",
+ "luaotfload-fonts-def.lua",
+ "luaotfload-fonts-enc.lua",
+ "luaotfload-fonts-ext.lua",
+ "luaotfload-fonts-lua.lua",
+ "luaotfload-fonts-tfm.lua",
+ "luaotfload-glyphlist.lua",
+ "luaotfload-letterspace.lua",
+ "luaotfload-loaders.lua",
+ "luaotfload.lua",
+ "luaotfload-merged.lua",
+ "luaotfload-override.lua",
+ "luaotfload-tool.lua",
+ "luaotfload-typo-krn.lua",
+ "mkcharacters",
+ "mkglyphlist",
+ "mkstatus",
+}
+
+-----------------------------------------------------------------------
+-- helpers
+-----------------------------------------------------------------------
+
+local die = function (...)
+ io.stderr:write "[fatal error]: "
+ io.stderr:write (stringformat (...))
+ io.stderr:write "\naborting.\n"
+ os.exit (1)
+end
+
+local gitcmd = "git log -1 \z
+ --format=\"return {\z
+ %n revision = [[%H]],\z
+ %n timestamp = [[%cd]],\z
+ %n committer = [[%cn <%ce>]],\z
+ %n}\" \z
+ --date=iso"
+
+local git_info = function ()
+ --io.write (gitcmd)
+ --io.write "\n"
+ local chan = iopopen (gitcmd)
+ if not chan then
+ die ("this script needs to be run inside \z
+ the luaotfload git repository")
+ end
+
+ local data = chan:read "*all"
+ chan:close ()
+ if data and type (data) == "string" and data ~= "" then
+ data = load (data)
+ if not data then
+ die "cannot parse git information"
+ end
+ return data ()
+ end
+ die "cannot read from pipe"
+end
+
+-----------------------------------------------------------------------
+-- functionality
+-----------------------------------------------------------------------
+
+local hash_file = function (fname)
+ if not lfs.isfile (fname) then
+ die ("cannot find %s.", fname)
+ end
+ local raw = ioloaddata (fname)
+ if not raw then
+ die ("cannot read from %s.", fname)
+ end
+ return md5sumhexa (raw)
+end
+
+local hash_all
+hash_all = function (list, acc)
+ if list == nil then
+ return hash_all (table.fastcopy (names), { })
+ end
+
+ local fname = list[#list]
+ list[#list] = nil
+ if fname then
+ local sum = hash_file (fname)
+ acc[#acc+1] = { fname, sum }
+ return hash_all (list, acc)
+ end
+ return acc
+end
+
+local main = function ()
+ local hashes = hash_all ()
+ local notes = git_info ()
+ local serialized = table.serialize ({ notes = notes,
+ hashes = hashes }, true)
+ local success = io.savedata (filelist, serialized)
+ if success == false then
+ die ("could not write to %s.", filelist)
+ end
+ return 0
+end
+
+return main ()
+