summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2009-11-18 21:51:00 +0100
committerHans Hagen <pragma@wxs.nl>2009-11-18 21:51:00 +0100
commitb309379ef546b7fa819f493fa3cb1dc559d4c3b8 (patch)
treef7244cebdc52206c3a35767ed9eb834dc901313b
parent9cf4a9e0a6642da57b94730bf7104335735a7ace (diff)
downloadcontext-b309379ef546b7fa819f493fa3cb1dc559d4c3b8.tar.gz
beta 2009.11.18 21:51
-rw-r--r--scripts/context/lua/luatools.lua395
-rw-r--r--scripts/context/lua/mtx-context.lua23
-rw-r--r--scripts/context/lua/mtx-fonts.lua214
-rw-r--r--scripts/context/lua/mtxrun.lua147
-rw-r--r--scripts/context/stubs/mswin/luatools.lua395
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua147
-rwxr-xr-xscripts/context/stubs/unix/luatools395
-rwxr-xr-xscripts/context/stubs/unix/mtxrun147
-rw-r--r--tex/context/base/colo-hex.mkii4
-rw-r--r--tex/context/base/colo-ini.mkiv7
-rw-r--r--tex/context/base/colo-x11.tex677
-rw-r--r--tex/context/base/cont-new.mkiv2
-rw-r--r--tex/context/base/cont-new.tex2
-rw-r--r--tex/context/base/context.tex2
-rw-r--r--tex/context/base/core-def.mkiv2
-rw-r--r--tex/context/base/data-res.lua32
-rw-r--r--tex/context/base/data-tmp.lua1
-rw-r--r--tex/context/base/font-afm.lua3
-rw-r--r--tex/context/base/font-ctx.lua4
-rw-r--r--tex/context/base/font-dum.lua26
-rw-r--r--tex/context/base/font-ini.mkiv22
-rw-r--r--tex/context/base/font-mis.lua2
-rw-r--r--tex/context/base/font-otf.lua10
-rw-r--r--tex/context/base/font-otn.lua127
-rw-r--r--tex/context/base/font-pat.lua11
-rw-r--r--tex/context/base/font-syn.lua1314
-rw-r--r--tex/context/base/font-tfm.lua29
-rw-r--r--tex/context/base/grph-inc.lua7
-rw-r--r--tex/context/base/lang-ini.lua13
-rw-r--r--tex/context/base/lang-ini.mkiv4
-rw-r--r--tex/context/base/m-pstric.tex3
-rw-r--r--tex/context/base/math-vfu.lua59
-rw-r--r--tex/context/base/mlib-pps.lua2
-rw-r--r--tex/context/base/node-ref.lua2
-rw-r--r--tex/context/base/node-res.lua48
-rw-r--r--tex/context/base/node-rul.lua35
-rw-r--r--tex/context/base/node-rul.mkiv31
-rw-r--r--tex/context/base/node-tra.lua2
-rw-r--r--tex/context/base/pack-rul.mkiv2
-rw-r--r--tex/context/base/spec-fdf.mkii20
-rw-r--r--tex/context/base/strc-not.mkiv1
-rw-r--r--tex/context/base/tabl-tbl.mkiv8
-rw-r--r--tex/context/base/task-ini.lua24
-rw-r--r--tex/context/base/type-otf.mkiv18
-rw-r--r--tex/context/base/typo-krn.lua5
-rw-r--r--tex/context/base/typo-spa.lua17
-rw-r--r--tex/context/base/typo-spa.mkiv3
-rw-r--r--tex/generic/context/luatex-fonts-merged.lua242
48 files changed, 3511 insertions, 1175 deletions
diff --git a/scripts/context/lua/luatools.lua b/scripts/context/lua/luatools.lua
index 2bc943210..abd80b8b4 100644
--- a/scripts/context/lua/luatools.lua
+++ b/scripts/context/lua/luatools.lua
@@ -308,7 +308,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
license = "see context related readme files"
}
-local P, S, Ct, C, Cs, Cc = lpeg.P, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
+local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
--~ l-lpeg.lua :
@@ -415,6 +415,41 @@ end
--~ return p
--~ end
+--~ from roberto's site:
+--~
+--~ -- decode a two-byte UTF-8 sequence
+--~ local function f2 (s)
+--~ local c1, c2 = string.byte(s, 1, 2)
+--~ return c1 * 64 + c2 - 12416
+--~ end
+--~
+--~ -- decode a three-byte UTF-8 sequence
+--~ local function f3 (s)
+--~ local c1, c2, c3 = string.byte(s, 1, 3)
+--~ return (c1 * 64 + c2) * 64 + c3 - 925824
+--~ end
+--~
+--~ -- decode a four-byte UTF-8 sequence
+--~ local function f4 (s)
+--~ local c1, c2, c3, c4 = string.byte(s, 1, 4)
+--~ return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168
+--~ end
+--~
+--~ local cont = lpeg.R("\128\191") -- continuation byte
+--~
+--~ local utf8 = lpeg.R("\0\127") / string.byte
+--~ + lpeg.R("\194\223") * cont / f2
+--~ + lpeg.R("\224\239") * cont * cont / f3
+--~ + lpeg.R("\240\244") * cont * cont * cont / f4
+--~
+--~ local decode_pattern = lpeg.Ct(utf8^0) * -1
+
+
+local cont = R("\128\191") -- continuation byte
+
+lpeg.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
+
+
end -- of closure
@@ -431,9 +466,9 @@ if not modules then modules = { } end modules ['l-table'] = {
table.join = table.concat
local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove
-local format, find, gsub, lower, dump = string.format, string.find, string.gsub, string.lower, string.dump
+local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match
local getmetatable, setmetatable = getmetatable, setmetatable
-local type, next, tostring, ipairs = type, next, tostring, ipairs
+local type, next, tostring, tonumber, ipairs, pairs = type, next, tostring, tonumber, ipairs, pairs
function table.strip(tab)
local lst = { }
@@ -721,6 +756,8 @@ end
--
-- local propername = lpeg.P(lpeg.R("AZ","az","__") * lpeg.R("09","AZ","az", "__")^0 * lpeg.P(-1) )
+-- problem: there no good number_to_string converter with the best resolution
+
local function do_serialize(root,name,depth,level,indexed)
if level > 0 then
depth = depth .. " "
@@ -743,6 +780,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s{",depth))
end
end
+ -- we could check for k (index) being number (cardinal)
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
@@ -765,10 +803,10 @@ local function do_serialize(root,name,depth,level,indexed)
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
- handle(format("%s %s,",depth,v))
+ handle(format("%s %s,",depth,v)) -- %.99g
end
elseif t == "string" then
- if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ if reduce and tonumber(v) then
handle(format("%s %s,",depth,v))
else
handle(format("%s %q,",depth,v))
@@ -805,29 +843,29 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if hexify then
--~ handle(format("%s %s=0x%04X,",depth,key(k),v))
--~ else
- --~ handle(format("%s %s=%s,",depth,key(k),v))
+ --~ handle(format("%s %s=%s,",depth,key(k),v)) -- %.99g
--~ end
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
else
- handle(format("%s [%s]=%s,",depth,k,v))
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
if hexify then
handle(format("%s %s=0x%04X,",depth,k,v))
else
- handle(format("%s %s=%s,",depth,k,v))
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%04X,",depth,k,v))
else
- handle(format("%s [%q]=%s,",depth,k,v))
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
elseif t == "string" then
- if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ if reduce and tonumber(v) then
--~ handle(format("%s %s=%s,",depth,key(k),v))
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
@@ -1036,7 +1074,7 @@ function table.tofile(filename,root,name,reduce,noquotes,hexify)
end
end
-local function flatten(t,f,complete)
+local function flatten(t,f,complete) -- is this used? meybe a variant with next, ...
for i=1,#t do
local v = t[i]
if type(v) == "table" then
@@ -1065,6 +1103,24 @@ end
table.flatten_one_level = table.unnest
+-- a better one:
+
+local function flattened(t,f)
+ if not f then
+ f = { }
+ end
+ for k, v in next, t do
+ if type(v) == "table" then
+ flattened(v,f)
+ else
+ f[k] = v
+ end
+ end
+ return f
+end
+
+table.flattened = flattened
+
-- the next three may disappear
function table.remove_value(t,value) -- todo: n
@@ -1200,7 +1256,7 @@ function table.clone(t,p) -- t is optional or nil or table
elseif not t then
t = { }
end
- setmetatable(t, { __index = function(_,key) return p[key] end })
+ setmetatable(t, { __index = function(_,key) return p[key] end }) -- why not __index = p ?
return t
end
@@ -1615,7 +1671,8 @@ if not modules then modules = { } end modules ['l-os'] = {
license = "see context related readme files"
}
-local find = string.find
+local find, format = string.find, string.format
+local random, ceil = math.random, math.ceil
function os.resultof(command)
return io.popen(command,"r"):read("*all")
@@ -1712,6 +1769,8 @@ function os.currentplatform(name,default)
elseif name == "macosx" then
if find(architecture,"i386") then
platform = "osx-intel"
+ elseif find(architecture,"x86_64") then
+ platform = "osx-64"
else
platform = "osx-ppc"
end
@@ -1738,6 +1797,29 @@ function os.currentplatform(name,default)
return platform
end
+-- beware, we set the randomseed
+--
+
+-- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the
+-- version number as well as two reserved bits. All other bits are set using a random or pseudorandom
+-- data source. Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal
+-- digits x and hexadecimal digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479.
+--
+-- as we don't call this function too often there is not so much risk on repetition
+
+
+local t = { 8, 9, "a", "b" }
+
+function os.uuid()
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
+end
+
end -- of closure
@@ -1778,8 +1860,12 @@ function file.dirname(name,default)
return match(name,"^(.+)[/\\].-$") or (default or "")
end
+--~ function file.basename(name)
+--~ return match(name,"^.+[/\\](.-)$") or name
+--~ end
+
function file.basename(name)
- return match(name,"^.+[/\\](.-)$") or name
+ return match(name,"^.*[/\\](.-)$") or name
end
function file.nameonly(name)
@@ -1857,6 +1943,7 @@ function file.collapse_path(str)
return str
end
+--~ print(file.collapse_path("/a"))
--~ print(file.collapse_path("a/./b/.."))
--~ print(file.collapse_path("a/aa/../b/bb"))
--~ print(file.collapse_path("a/../.."))
@@ -3028,9 +3115,9 @@ function aux.make_settings_to_hash_pattern(set,how)
end
end
-function aux.settings_to_hash(str)
+function aux.settings_to_hash(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
if moretolerant then
pattern_b_s:match(str)
else
@@ -3042,9 +3129,9 @@ function aux.settings_to_hash(str)
end
end
-function aux.settings_to_hash_tolerant(str)
+function aux.settings_to_hash_tolerant(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
pattern_b_s:match(str)
return hash
else
@@ -3052,9 +3139,9 @@ function aux.settings_to_hash_tolerant(str)
end
end
-function aux.settings_to_hash_strict(str)
+function aux.settings_to_hash_strict(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
pattern_c_s:match(str)
return next(hash) and hash
else
@@ -3142,7 +3229,7 @@ function aux.getparameters(self,class,parentclass,settings)
sc = table.clone(self[parent])
self[class] = sc
end
- aux.add_settings_to_array(sc, settings)
+ aux.settings_to_hash(settings,sc)
end
-- temporary here
@@ -3230,12 +3317,15 @@ if not modules then modules = { } end modules ['trac-tra'] = {
-- bound to a variable, like node.new, node.copy etc (contrary to for instance
-- node.has_attribute which is bound to a has_attribute local variable in mkiv)
+local getinfo = debug.getinfo
+local type, next = type, next
+local concat = table.concat
+local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub
+
debugger = debugger or { }
local counters = { }
local names = { }
-local getinfo = debug.getinfo
-local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub
-- one
@@ -3363,11 +3453,11 @@ end
--~ print("")
--~ debugger.showstats(print,3)
-trackers = trackers or { }
+setters = setters or { }
+setters.data = setters.data or { }
-local data, done = { }, { }
-
-local function set(what,value)
+local function set(t,what,value)
+ local data, done = t.data, t.done
if type(what) == "string" then
what = aux.settings_to_array(what) -- inefficient but ok
end
@@ -3386,28 +3476,30 @@ local function set(what,value)
end
end
-local function reset()
- for d, f in next, data do
+local function reset(t)
+ for d, f in next, t.data do
for i=1,#f do
f[i](false)
end
end
end
-local function enable(what)
- set(what,true)
+local function enable(t,what)
+ set(t,what,true)
end
-local function disable(what)
+local function disable(t,what)
+ local data = t.data
if not what or what == "" then
- done = { }
- reset()
+ t.done = { }
+ reset(t)
else
- set(what,false)
+ set(t,what,false)
end
end
-function trackers.register(what,...)
+function setters.register(t,what,...)
+ local data = t.data
what = lower(what)
local w = data[what]
if not w then
@@ -3419,32 +3511,32 @@ function trackers.register(what,...)
if typ == "function" then
w[#w+1] = fnc
elseif typ == "string" then
- w[#w+1] = function(value) set(fnc,value,nesting) end
+ w[#w+1] = function(value) set(t,fnc,value,nesting) end
end
end
end
-function trackers.enable(what)
- local e = trackers.enable
- trackers.enable, done = enable, { }
- enable(string.simpleesc(what))
- trackers.enable, done = e, { }
+function setters.enable(t,what)
+ local e = t.enable
+ t.enable, t.done = enable, { }
+ enable(t,string.simpleesc(what))
+ t.enable, t.done = e, { }
end
-function trackers.disable(what)
- local e = trackers.disable
- trackers.disable, done = disable, { }
- disable(string.simpleesc(what))
- trackers.disable, done = e, { }
+function setters.disable(t,what)
+ local e = t.disable
+ t.disable, t.done = disable, { }
+ disable(t,string.simpleesc(what))
+ t.disable, t.done = e, { }
end
-function trackers.reset()
- done = { }
- reset()
+function setters.reset(t)
+ t.done = { }
+ reset(t)
end
-function trackers.list() -- pattern
- local list = table.sortedkeys(data)
+function setters.list(t) -- pattern
+ local list = table.sortedkeys(t.data)
local user, system = { }, { }
for l=1,#list do
local what = list[l]
@@ -3457,6 +3549,139 @@ function trackers.list() -- pattern
return user, system
end
+function setters.show(t)
+ commands.writestatus("","")
+ for k,v in ipairs(setters.list(t)) do
+ commands.writestatus(t.name,v)
+ end
+ commands.writestatus("","")
+end
+
+-- we could have used a bit of oo and the trackers:enable syntax but
+-- there is already a lot of code around using the singluar tracker
+
+function setters.new(name)
+ local t
+ t = {
+ data = { },
+ name = name,
+ enable = function(...) setters.enable (t,...) end,
+ disable = function(...) setters.disable (t,...) end,
+ register = function(...) setters.register(t,...) end,
+ list = function(...) setters.list (t,...) end,
+ show = function(...) setters.show (t,...) end,
+ }
+ setters.data[name] = t
+ return t
+end
+
+trackers = setters.new("trackers")
+directives = setters.new("directives")
+
+-- nice trick: we overload two of the directives related functions with variants that
+-- do tracing (itself using a tracker) .. proof of concept
+
+local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end)
+
+local e = directives.enable
+local d = directives.disable
+
+function directives.enable(...)
+ commands.writestatus("directives","enabling: %s",concat({...}," "))
+ e(...)
+end
+
+function directives.disable(...)
+ commands.writestatus("directives","disabling: %s",concat({...}," "))
+ d(...)
+end
+
+--~ -- old code:
+--
+--~ trackers = trackers or { }
+--~ local data, done = { }, { }
+--~ local function set(what,value)
+--~ if type(what) == "string" then
+--~ what = aux.settings_to_array(what) -- inefficient but ok
+--~ end
+--~ for i=1,#what do
+--~ local w = what[i]
+--~ for d, f in next, data do
+--~ if done[d] then
+--~ -- prevent recursion due to wildcards
+--~ elseif find(d,w) then
+--~ done[d] = true
+--~ for i=1,#f do
+--~ f[i](value)
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ local function reset()
+--~ for d, f in next, data do
+--~ for i=1,#f do
+--~ f[i](false)
+--~ end
+--~ end
+--~ end
+--~ local function enable(what)
+--~ set(what,true)
+--~ end
+--~ local function disable(what)
+--~ if not what or what == "" then
+--~ done = { }
+--~ reset()
+--~ else
+--~ set(what,false)
+--~ end
+--~ end
+--~ function trackers.register(what,...)
+--~ what = lower(what)
+--~ local w = data[what]
+--~ if not w then
+--~ w = { }
+--~ data[what] = w
+--~ end
+--~ for _, fnc in next, { ... } do
+--~ local typ = type(fnc)
+--~ if typ == "function" then
+--~ w[#w+1] = fnc
+--~ elseif typ == "string" then
+--~ w[#w+1] = function(value) set(fnc,value,nesting) end
+--~ end
+--~ end
+--~ end
+--~ function trackers.enable(what)
+--~ local e = trackers.enable
+--~ trackers.enable, done = enable, { }
+--~ enable(string.simpleesc(what))
+--~ trackers.enable, done = e, { }
+--~ end
+--~ function trackers.disable(what)
+--~ local e = trackers.disable
+--~ trackers.disable, done = disable, { }
+--~ disable(string.simpleesc(what))
+--~ trackers.disable, done = e, { }
+--~ end
+--~ function trackers.reset()
+--~ done = { }
+--~ reset()
+--~ end
+--~ function trackers.list() -- pattern
+--~ local list = table.sortedkeys(data)
+--~ local user, system = { }, { }
+--~ for l=1,#list do
+--~ local what = list[l]
+--~ if find(what,"^%*") then
+--~ system[#system+1] = what
+--~ else
+--~ user[#user+1] = what
+--~ end
+--~ end
+--~ return user, system
+--~ end
+
end -- of closure
@@ -3908,6 +4133,7 @@ function statistics.timed(action,report)
end
+
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -4241,6 +4467,8 @@ local format, gsub, find, lower, upper, match, gmatch = string.format, string.gs
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
local next, type = next, type
+local collapse_path = file.collapse_path
+
local trace_locating, trace_detail, trace_verbose = false, false, false
trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
@@ -4629,7 +4857,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
end
if ok then
local function validate(s)
- s = file.collapse_path(s)
+ s = collapse_path(s)
return s ~= "" and not find(s,dummy_path_expr) and s
end
for k=1,#pathlist do
@@ -4638,7 +4866,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
else
for k=1,#pathlist do
for p in gmatch(pathlist[k],"([^,]+)") do
- p = file.collapse_path(p)
+ p = collapse_path(p)
if p ~= "" then newlist[#newlist+1] = p end
end
end
@@ -4703,9 +4931,9 @@ local function identify_own()
local ownpath = resolvers.getownpath() or lfs.currentdir()
local ie = instance.environment
if ownpath then
- if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = collapse_path(ownpath .. "/../..") end
else
logs.report("fileio","error: unable to locate ownpath")
os.exit()
@@ -4734,7 +4962,7 @@ function resolvers.identify_cnf()
local function locate(filename,list)
for i=1,#t do
local ti = t[i]
- local texmfcnf = file.collapse_path(file.join(ti,filename))
+ local texmfcnf = collapse_path(file.join(ti,filename))
if lfs.isfile(texmfcnf) then
list[#list+1] = texmfcnf
end
@@ -4746,11 +4974,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -4815,13 +5043,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -4829,12 +5061,12 @@ function resolvers.load_cnf()
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.cnffiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
if instance.diskcache and not instance.renewcache then
resolvers.loadoldconfig(instance.cnffiles)
if instance.loaderror then
@@ -4858,12 +5090,12 @@ function resolvers.load_lua()
else
instance.rootpath = instance.luafiles[1]
for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.luafiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
resolvers.loadnewconfig()
collapse_cnf_data()
end
@@ -4925,7 +5157,7 @@ function resolvers.locatelists()
if trace_verbose then
logs.report("fileio","locating list of %s",path)
end
- resolvers.locatedatabase(file.collapse_path(path))
+ resolvers.locatedatabase(collapse_path(path))
end
end
@@ -5184,6 +5416,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -5206,6 +5439,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -5213,6 +5452,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -5467,7 +5707,7 @@ function resolvers.clean_path_list(str)
local t = resolvers.expanded_path_list(str)
if t then
for i=1,#t do
- t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ t[i] = collapse_path(resolvers.clean_path(t[i]))
end
end
return t
@@ -5664,8 +5904,8 @@ end
local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
local result = collected or { }
local stamp = nil
- filename = file.collapse_path(filename) -- elsewhere
- filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ filename = collapse_path(filename) -- elsewhere
+ filename = collapse_path(gsub(filename,"\\","/")) -- elsewhere
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -5896,7 +6136,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
end
for k=1,#result do
- result[k] = file.collapse_path(result[k])
+ result[k] = collapse_path(result[k])
end
if instance.remember then
instance.found[stamp] = result
@@ -6048,9 +6288,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
@@ -6397,6 +6637,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua
index 344ff42c5..22abf74b1 100644
--- a/scripts/context/lua/mtx-context.lua
+++ b/scripts/context/lua/mtx-context.lua
@@ -992,24 +992,29 @@ local loaded = false
function scripts.context.metapost()
local filename = environment.files[1] or ""
---~ local tempname = "mtx-context-metapost.tex"
---~ local tempdata = string.format(template,"metafun",filename)
---~ io.savedata(tempname,tempdata)
---~ environment.files[1] = tempname
---~ environment.setargument("result",file.removesuffix(filename))
---~ environment.setargument("once",true)
---~ scripts.context.run()
if not loaded then
dofile(resolvers.find_file("mlib-run.lua"))
loaded = true
commands = commands or { }
commands.writestatus = logs.report
end
- local formatname = environment.arguments("format") or "metafun"
+ local formatname = environment.argument("format") or "metafun"
if formatname == "" or type(format) == "boolean" then
formatname = "metafun"
end
- if environment.arguments("svg") then
+ if environment.argument("pdf") then
+ local basename = file.removesuffix(filename)
+ local resultname = environment.argument("result") or basename
+ local jobname = "mtx-context-metapost"
+ local tempname = file.addsuffix(jobname,"tex")
+ io.savedata(tempname,string.format(template,"metafun",filename))
+ environment.files[1] = tempname
+ environment.setargument("result",resultname)
+ environment.setargument("once",true)
+ scripts.context.run()
+ scripts.context.purge_job(jobname,true)
+ scripts.context.purge_job(resultname,true)
+ elseif environment.argument("svg") then
metapost.directrun(formatname,filename,"svg")
else
metapost.directrun(formatname,filename,"mps")
diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua
index 0cd9a3270..67c48d0a8 100644
--- a/scripts/context/lua/mtx-fonts.lua
+++ b/scripts/context/lua/mtx-fonts.lua
@@ -20,23 +20,46 @@ function scripts.fonts.reload(verbose)
end
function scripts.fonts.names(name)
+ local simpleversion = 1.001
+ local simplelist = { "ttf", "otf", "ttc", "dfont" }
name = name or "luatex-fonts-names.lua"
+ fonts.names.filters.list = simplelist
+ fonts.names.version = simpleversion -- this number is the same as in font-dum.lua
+ logs.report("fontnames","generating font database for 'luatex-fonts' version %s",fonts.names.version)
fonts.names.identify(true)
local data = fonts.names.data
if data then
- data.fallback_mapping = nil
+ local simplemappings = { }
+ local simplified = {
+ mappings = simplemappings,
+ version = simpleversion,
+ }
+ local specifications = data.specifications
+ for _, format in ipairs(simplelist) do
+ for tag, index in pairs(data.mappings[format]) do
+ local s = specifications[index]
+ simplemappings[tag] = { s.rawname, s.filename, s.subfont }
+ end
+ end
logs.report("fontnames","saving names in '%s'",name)
- io.savedata(name,table.serialize(data,true))
+ io.savedata(name,table.serialize(simplified,true))
+ local data = io.loaddata(resolvers.find_file("font-dum.lua","tex"))
+ local dummy = string.match(data,"fonts%.names%.version%s*=%s*([%d%.]+)")
+ if tonumber(dummy) ~= simpleversion then
+ logs.report("fontnames","warning: version number %s in 'font-dum' does not match database version number %s",dummy or "?",simpleversion)
+ end
elseif lfs.isfile(name) then
os.remove(name)
end
end
-local function showfeatures(v,n,f,s,t)
- logs.simple("fontname: %s",v)
- logs.simple("fullname: %s",n)
- logs.simple("filename: %s",f)
- local features = fonts.get_features(f,t)
+local function showfeatures(tag,specification)
+ logs.simple("mapping : %s",tag)
+ logs.simple("fontname: %s",specification.fontname)
+ logs.simple("fullname: %s",specification.fullname)
+ logs.simple("filename: %s",specification.filename)
+ -- maybe more
+ local features = fonts.get_features(specification.filename,specification.format)
if features then
for what, v in table.sortedpairs(features) do
local data = features[what]
@@ -61,6 +84,10 @@ local function showfeatures(v,n,f,s,t)
end
end
end
+ else
+ logs.simple()
+ logs.simple("no features")
+ logs.simple()
end
logs.reportline()
end
@@ -74,7 +101,7 @@ local function make_pattern(pattern) -- will become helper in string
if pattern == "" then
pattern = ".*"
else
- pattern = "^" .. pattern .. "$"
+--~ pattern = "^" .. pattern .. "$"
end
return pattern
end
@@ -87,53 +114,120 @@ local function reloadbase(reload)
end
end
-function scripts.fonts.list_by_pattern(pattern,reload,all,info)
- reloadbase(reload)
- local t = fonts.names.list(make_pattern(pattern))
+local function subfont(sf)
+ if sf then
+ return string.format("index: % 2s", sf)
+ else
+ return ""
+ end
+end
+local function fontweight(fw)
+ if fw then
+ return string.format("conflict: %s", fw)
+ else
+ return ""
+ end
+end
+
+local function list_specifications(t)
if t then
local s, w = table.sortedkeys(t), { 0, 0, 0 }
for k,v in ipairs(s) do
local entry = t[v]
- local n = #v if n > w[1] then w[1] = n end
- local n = #entry[2] if n > w[2] then w[2] = n end
- local n = #entry[3] if n > w[3] then w[3] = n end
+ s[k] = {
+ entry.familyname or "<nofamily>",
+ entry.weight or "<noweight>",
+ entry.style or "<nostyle>",
+ entry.width or "<nowidth>",
+ entry.fontname,
+ entry.filename,
+ subfont(entry.subfont),
+ fontweight(entry.fontweight),
+ }
end
- local template = "%-" .. w[1] .. "s %-" .. w[2] .. "s %-" .. w[3] .. "s %s"
+ table.formatcolumns(s)
for k,v in ipairs(s) do
- local entry = t[v]
- local tag, fontname, filename, sub = v, entry[2], entry[3], entry[4]
- if sub then sub = "(sub)" else sub = "" end
- if info then
- showfeatures(tag,fontname,filename,sub,t)
- else
- print(string.format(template,tag,fontname,filename,sub))
+ texio.write_nl(v)
+ end
+ end
+end
+
+local function list_matches(t)
+ if t then
+ local s, w = table.sortedkeys(t), { 0, 0, 0 }
+ if info then
+ for k,v in ipairs(s) do
+ showfeatures(v,t[v])
+ end
+ else
+ for k,v in ipairs(s) do
+ local entry = t[v]
+ s[k] = {
+ v,
+ entry.fontname,
+ entry.filename,
+ subfont(entry.subfont)
+ }
+ end
+ table.formatcolumns(s)
+ for k,v in ipairs(s) do
+ texio.write_nl(v)
end
end
end
end
-function scripts.fonts.list_by_specification(specification,reload,all,info)
+function scripts.fonts.list()
+
+ local all = environment.argument("all")
+ local info = environment.argument("info")
+ local reload = environment.argument("reload")
+ local pattern = environment.argument("pattern")
+ local filter = environment.argument("filter")
+ local given = environment.files[1]
+
reloadbase(reload)
- local t = fonts.names.collectspec(specification)
- if t then
- local w, tags = { 0, 0, 0 }, { }
- for k,entry in ipairs(t) do
- local s = entry[5] .. "-" .. (entry[6] or "noweight") .. "-" .. (entry[7] or "nostyle") .. "-" .. (entry[8] or "nowidth")
- local n = #s if n > w[1] then w[1] = n end
- local n = #entry[2] if n > w[2] then w[2] = n end
- local n = #entry[3] if n > w[3] then w[3] = n end
- tags[k] = s
+
+ if environment.argument("name") then
+ if pattern then
+ --~ mtxrun --script font --list --name --pattern=*somename*
+ list_matches(fonts.names.list(make_pattern(pattern),reload,all))
+ elseif filter then
+ logs.report("fontnames","not supported: --list --name --filter",name)
+ elseif given then
+ --~ mtxrun --script font --list --name somename
+ list_matches(fonts.names.list(given,reload,all))
+ else
+ logs.report("fontnames","not supported: --list --name <no specification>",name)
end
- local template = "%-" .. w[1] .."s %-" .. w[2] .. "s %-" .. w[3] .. "s %s"
- for k,entry in ipairs(t) do
- local tag, fontname, filename, sub, name, weight, style = tags[k], entry[2], entry[3], entry[4], entry[5], entry[6], entry[7]
- if sub then sub = "(sub)" else sub = "" end
- print(string.format(template,tag,fontname,filename,sub))
+ elseif environment.argument("spec") then
+ if pattern then
+ --~ mtxrun --script font --list --spec --pattern=*somename*
+ logs.report("fontnames","not supported: --list --spec --pattern",name)
+ elseif filter then
+ --~ mtxrun --script font --list --spec --filter="fontname=somename"
+ list_specifications(fonts.names.getlookups(filter),nil,reload)
+ elseif given then
+ --~ mtxrun --script font --list --spec somename
+ list_specifications(fonts.names.collectspec(given,reload,all))
+ else
+ logs.report("fontnames","not supported: --list --spec <no specification>",name)
end
+ elseif pattern then
+ --~ mtxrun --script font --list --pattern=*somename*
+ list_matches(fonts.names.list(make_pattern(pattern),reload,all))
+ elseif given then
+ --~ mtxrun --script font --list somename
+ list_matches(fonts.names.list(given,reload,all))
+ else
+ logs.report("fontnames","not supported: --list <no specification>",name)
end
+
end
-function scripts.fonts.save(name,sub)
+function scripts.fonts.save()
+ local name = environment.files[1] or ""
+ local sub = environment.files[2] or ""
local function save(savename,fontblob)
if fontblob then
savename = savename:lower() .. ".lua"
@@ -171,37 +265,49 @@ function scripts.fonts.save(name,sub)
end
end
-logs.extendbanner("Font Tools 0.20",true)
+logs.extendbanner("Font Tools 0.21",true)
messages.help = [[
--reload generate new font database
---list [--info] list installed fonts (show info)
--save save open type font in raw table
--names generate 'luatex-fonts-names.lua' (not for context!)
+--list list installed fonts (show info)
+
+--name filter by name
+--spec filter by spec
--pattern=str filter files using pattern
+--filter=list key-value pairs
--all provide alternatives
+--info give more details
+--track=list enable trackers
+
+examples:
+
+mtxrun --script font --list somename (== --pattern=*somename*)
+
+mtxrun --script font --list --name somename
+mtxrun --script font --list --name --pattern=*somename*
+
+mtxrun --script font --list --spec somename
+mtxrun --script font --list --spec somename-bold-italic
+mtxrun --script font --list --spec --pattern=*somename*
+mtxrun --script font --list --spec --filter="fontname=somename"
+mtxrun --script font --list --spec --filter="familyname=somename,weight=bold,style=italic,width=condensed"
]]
+local track = environment.argument("track")
+
+if track then trackers.enable(track) end
+
if environment.argument("reload") then
scripts.fonts.reload(true)
elseif environment.argument("names") then
scripts.fonts.names()
-elseif environment.argument("list") then
- local all = environment.argument("all")
- local info = environment.argument("info")
- local reload = environment.argument("reload")
- if environment.argument("pattern") then
- scripts.fonts.list_by_pattern(environment.argument("pattern"),reload,all,info)
- elseif environment.files[1] then
- scripts.fonts.list_by_specification(environment.files[1],reload,all,info)
- else
- scripts.fonts.list_by_pattern("",reload,all,info) -- wildcard
- end
elseif environment.argument("save") then
- local name = environment.files[1] or ""
- local sub = environment.files[2] or ""
- scripts.fonts.save(name,sub)
+ scripts.fonts.save()
+elseif environment.argument("list") then
+ scripts.fonts.list()
else
logs.help(messages.help)
end
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 130ad493c..0d3f08025 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -789,6 +789,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s{",depth))
end
end
+ -- we could check for k (index) being number (cardinal)
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
@@ -811,7 +812,7 @@ local function do_serialize(root,name,depth,level,indexed)
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
- handle(format("%s %.99g,",depth,v))
+ handle(format("%s %s,",depth,v)) -- %.99g
end
elseif t == "string" then
if reduce and tonumber(v) then
@@ -851,25 +852,25 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if hexify then
--~ handle(format("%s %s=0x%04X,",depth,key(k),v))
--~ else
- --~ handle(format("%s %s=%.99g,",depth,key(k),v))
+ --~ handle(format("%s %s=%s,",depth,key(k),v)) -- %.99g
--~ end
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
else
- handle(format("%s [%s]=%.99g,",depth,k,v))
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
if hexify then
handle(format("%s %s=0x%04X,",depth,k,v))
else
- handle(format("%s %s=%.99g,",depth,k,v))
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%04X,",depth,k,v))
else
- handle(format("%s [%q]=%.99g,",depth,k,v))
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
elseif t == "string" then
@@ -1868,8 +1869,12 @@ function file.dirname(name,default)
return match(name,"^(.+)[/\\].-$") or (default or "")
end
+--~ function file.basename(name)
+--~ return match(name,"^.+[/\\](.-)$") or name
+--~ end
+
function file.basename(name)
- return match(name,"^.+[/\\](.-)$") or name
+ return match(name,"^.*[/\\](.-)$") or name
end
function file.nameonly(name)
@@ -4872,7 +4877,7 @@ local noparent = 1 - (lparent+rparent)
local nested = lpeg.P{lparent * (noparent + lpeg.V(1))^0 * rparent}
local value = lpeg.P(lparent * lpeg.C((noparent + nested)^0) * rparent) -- lpeg.P{"("*C(((1-S("()"))+V(1))^0)*")"}
-local lp_child = Cc("expr.child(e,'") * R("az","AZ","--","__")^1 * Cc("')")
+local lp_child = Cc("expr.child(ll,'") * R("az","AZ","--","__")^1 * Cc("')")
local lp_string = Cc("'") * R("az","AZ","--","__")^1 * Cc("'")
local lp_content = (P("'") * (1-P("'"))^0 * P("'") + P('"') * (1-P('"'))^0 * P('"'))
@@ -4882,9 +4887,9 @@ local lp_special = (C(P("name")+P("text")+P("tag")+P("count")+P("child"))) * val
if expressions[t] then
s = s and s ~= "" and cleaner:match(s)
if s and s ~= "" then
- return "expr." .. t .. "(e," .. s ..")"
+ return "expr." .. t .. "(ll," .. s ..")"
else
- return "expr." .. t .. "(e)"
+ return "expr." .. t .. "(ll)"
end
else
return "expr.error(" .. t .. ")"
@@ -5434,38 +5439,42 @@ expressions.name = function(e,n) -- ns + tg
end
expressions.tag = function(e,n) -- only tg
- local found = false
- n = tonumber(n) or 0
- if n == 0 then
- found = (type(e) == "table") and e -- seems to fail
- elseif n < 0 then
- local d, k = e.__p__.dt, e.ni
- for i=k-1,1,-1 do
- local di = d[i]
- if type(di) == "table" then
- if n == -1 then
- found = di
- break
- else
- n = n + 1
+ if not e then
+ return ""
+ else
+ local found = false
+ n = tonumber(n) or 0
+ if n == 0 then
+ found = (type(e) == "table") and e -- seems to fail
+ elseif n < 0 then
+ local d, k = e.__p__.dt, e.ni
+ for i=k-1,1,-1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == -1 then
+ found = di
+ break
+ else
+ n = n + 1
+ end
end
end
- end
- else
- local d, k = e.__p__.dt, e.ni
- for i=k+1,#d,1 do
- local di = d[i]
- if type(di) == "table" then
- if n == 1 then
- found = di
- break
- else
- n = n - 1
+ else
+ local d, k = e.__p__.dt, e.ni
+ for i=k+1,#d,1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == 1 then
+ found = di
+ break
+ else
+ n = n - 1
+ end
end
end
end
+ return (found and found.tg) or ""
end
- return (found and found.tg) or ""
end
--[[ldx--
@@ -5992,7 +6001,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)
--~ local settings = xmldata.settings
--~ settings.parent_root = xmldata -- to be tested
--~ local xi = xmlconvert(data,settings)
- local xi = xml.inheritedconvert(element,xmldata)
+ local xi = xml.inheritedconvert(data,xmldata)
if not xi then
epdt[ek.ni] = "" -- xml.empty(d,k)
else
@@ -7046,7 +7055,6 @@ end
local name, banner = 'report', 'context'
local function report(category,fmt,...)
---~ print(fmt,...)
if fmt then
write_nl(format("%s | %s: %s",name,category,format(fmt,...)))
elseif category then
@@ -7187,6 +7195,8 @@ local format, gsub, find, lower, upper, match, gmatch = string.format, string.gs
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
local next, type = next, type
+local collapse_path = file.collapse_path
+
local trace_locating, trace_detail, trace_verbose = false, false, false
trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
@@ -7575,7 +7585,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
end
if ok then
local function validate(s)
- s = file.collapse_path(s)
+ s = collapse_path(s)
return s ~= "" and not find(s,dummy_path_expr) and s
end
for k=1,#pathlist do
@@ -7584,7 +7594,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
else
for k=1,#pathlist do
for p in gmatch(pathlist[k],"([^,]+)") do
- p = file.collapse_path(p)
+ p = collapse_path(p)
if p ~= "" then newlist[#newlist+1] = p end
end
end
@@ -7649,9 +7659,9 @@ local function identify_own()
local ownpath = resolvers.getownpath() or lfs.currentdir()
local ie = instance.environment
if ownpath then
- if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = collapse_path(ownpath .. "/../..") end
else
logs.report("fileio","error: unable to locate ownpath")
os.exit()
@@ -7680,7 +7690,7 @@ function resolvers.identify_cnf()
local function locate(filename,list)
for i=1,#t do
local ti = t[i]
- local texmfcnf = file.collapse_path(file.join(ti,filename))
+ local texmfcnf = collapse_path(file.join(ti,filename))
if lfs.isfile(texmfcnf) then
list[#list+1] = texmfcnf
end
@@ -7692,11 +7702,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -7761,13 +7771,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -7775,12 +7789,12 @@ function resolvers.load_cnf()
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.cnffiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
if instance.diskcache and not instance.renewcache then
resolvers.loadoldconfig(instance.cnffiles)
if instance.loaderror then
@@ -7804,12 +7818,12 @@ function resolvers.load_lua()
else
instance.rootpath = instance.luafiles[1]
for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.luafiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
resolvers.loadnewconfig()
collapse_cnf_data()
end
@@ -7871,7 +7885,7 @@ function resolvers.locatelists()
if trace_verbose then
logs.report("fileio","locating list of %s",path)
end
- resolvers.locatedatabase(file.collapse_path(path))
+ resolvers.locatedatabase(collapse_path(path))
end
end
@@ -8130,6 +8144,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -8152,6 +8167,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -8159,6 +8180,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -8413,7 +8435,7 @@ function resolvers.clean_path_list(str)
local t = resolvers.expanded_path_list(str)
if t then
for i=1,#t do
- t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ t[i] = collapse_path(resolvers.clean_path(t[i]))
end
end
return t
@@ -8610,8 +8632,8 @@ end
local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
local result = collected or { }
local stamp = nil
- filename = file.collapse_path(filename) -- elsewhere
- filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ filename = collapse_path(filename) -- elsewhere
+ filename = collapse_path(gsub(filename,"\\","/")) -- elsewhere
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -8842,7 +8864,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
end
for k=1,#result do
- result[k] = file.collapse_path(result[k])
+ result[k] = collapse_path(result[k])
end
if instance.remember then
instance.found[stamp] = result
@@ -8994,9 +9016,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
@@ -9343,6 +9365,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else
diff --git a/scripts/context/stubs/mswin/luatools.lua b/scripts/context/stubs/mswin/luatools.lua
index 2bc943210..abd80b8b4 100644
--- a/scripts/context/stubs/mswin/luatools.lua
+++ b/scripts/context/stubs/mswin/luatools.lua
@@ -308,7 +308,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
license = "see context related readme files"
}
-local P, S, Ct, C, Cs, Cc = lpeg.P, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
+local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
--~ l-lpeg.lua :
@@ -415,6 +415,41 @@ end
--~ return p
--~ end
+--~ from roberto's site:
+--~
+--~ -- decode a two-byte UTF-8 sequence
+--~ local function f2 (s)
+--~ local c1, c2 = string.byte(s, 1, 2)
+--~ return c1 * 64 + c2 - 12416
+--~ end
+--~
+--~ -- decode a three-byte UTF-8 sequence
+--~ local function f3 (s)
+--~ local c1, c2, c3 = string.byte(s, 1, 3)
+--~ return (c1 * 64 + c2) * 64 + c3 - 925824
+--~ end
+--~
+--~ -- decode a four-byte UTF-8 sequence
+--~ local function f4 (s)
+--~ local c1, c2, c3, c4 = string.byte(s, 1, 4)
+--~ return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168
+--~ end
+--~
+--~ local cont = lpeg.R("\128\191") -- continuation byte
+--~
+--~ local utf8 = lpeg.R("\0\127") / string.byte
+--~ + lpeg.R("\194\223") * cont / f2
+--~ + lpeg.R("\224\239") * cont * cont / f3
+--~ + lpeg.R("\240\244") * cont * cont * cont / f4
+--~
+--~ local decode_pattern = lpeg.Ct(utf8^0) * -1
+
+
+local cont = R("\128\191") -- continuation byte
+
+lpeg.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
+
+
end -- of closure
@@ -431,9 +466,9 @@ if not modules then modules = { } end modules ['l-table'] = {
table.join = table.concat
local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove
-local format, find, gsub, lower, dump = string.format, string.find, string.gsub, string.lower, string.dump
+local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match
local getmetatable, setmetatable = getmetatable, setmetatable
-local type, next, tostring, ipairs = type, next, tostring, ipairs
+local type, next, tostring, tonumber, ipairs, pairs = type, next, tostring, tonumber, ipairs, pairs
function table.strip(tab)
local lst = { }
@@ -721,6 +756,8 @@ end
--
-- local propername = lpeg.P(lpeg.R("AZ","az","__") * lpeg.R("09","AZ","az", "__")^0 * lpeg.P(-1) )
+-- problem: there no good number_to_string converter with the best resolution
+
local function do_serialize(root,name,depth,level,indexed)
if level > 0 then
depth = depth .. " "
@@ -743,6 +780,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s{",depth))
end
end
+ -- we could check for k (index) being number (cardinal)
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
@@ -765,10 +803,10 @@ local function do_serialize(root,name,depth,level,indexed)
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
- handle(format("%s %s,",depth,v))
+ handle(format("%s %s,",depth,v)) -- %.99g
end
elseif t == "string" then
- if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ if reduce and tonumber(v) then
handle(format("%s %s,",depth,v))
else
handle(format("%s %q,",depth,v))
@@ -805,29 +843,29 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if hexify then
--~ handle(format("%s %s=0x%04X,",depth,key(k),v))
--~ else
- --~ handle(format("%s %s=%s,",depth,key(k),v))
+ --~ handle(format("%s %s=%s,",depth,key(k),v)) -- %.99g
--~ end
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
else
- handle(format("%s [%s]=%s,",depth,k,v))
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
if hexify then
handle(format("%s %s=0x%04X,",depth,k,v))
else
- handle(format("%s %s=%s,",depth,k,v))
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%04X,",depth,k,v))
else
- handle(format("%s [%q]=%s,",depth,k,v))
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
elseif t == "string" then
- if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ if reduce and tonumber(v) then
--~ handle(format("%s %s=%s,",depth,key(k),v))
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
@@ -1036,7 +1074,7 @@ function table.tofile(filename,root,name,reduce,noquotes,hexify)
end
end
-local function flatten(t,f,complete)
+local function flatten(t,f,complete) -- is this used? meybe a variant with next, ...
for i=1,#t do
local v = t[i]
if type(v) == "table" then
@@ -1065,6 +1103,24 @@ end
table.flatten_one_level = table.unnest
+-- a better one:
+
+local function flattened(t,f)
+ if not f then
+ f = { }
+ end
+ for k, v in next, t do
+ if type(v) == "table" then
+ flattened(v,f)
+ else
+ f[k] = v
+ end
+ end
+ return f
+end
+
+table.flattened = flattened
+
-- the next three may disappear
function table.remove_value(t,value) -- todo: n
@@ -1200,7 +1256,7 @@ function table.clone(t,p) -- t is optional or nil or table
elseif not t then
t = { }
end
- setmetatable(t, { __index = function(_,key) return p[key] end })
+ setmetatable(t, { __index = function(_,key) return p[key] end }) -- why not __index = p ?
return t
end
@@ -1615,7 +1671,8 @@ if not modules then modules = { } end modules ['l-os'] = {
license = "see context related readme files"
}
-local find = string.find
+local find, format = string.find, string.format
+local random, ceil = math.random, math.ceil
function os.resultof(command)
return io.popen(command,"r"):read("*all")
@@ -1712,6 +1769,8 @@ function os.currentplatform(name,default)
elseif name == "macosx" then
if find(architecture,"i386") then
platform = "osx-intel"
+ elseif find(architecture,"x86_64") then
+ platform = "osx-64"
else
platform = "osx-ppc"
end
@@ -1738,6 +1797,29 @@ function os.currentplatform(name,default)
return platform
end
+-- beware, we set the randomseed
+--
+
+-- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the
+-- version number as well as two reserved bits. All other bits are set using a random or pseudorandom
+-- data source. Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal
+-- digits x and hexadecimal digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479.
+--
+-- as we don't call this function too often there is not so much risk on repetition
+
+
+local t = { 8, 9, "a", "b" }
+
+function os.uuid()
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
+end
+
end -- of closure
@@ -1778,8 +1860,12 @@ function file.dirname(name,default)
return match(name,"^(.+)[/\\].-$") or (default or "")
end
+--~ function file.basename(name)
+--~ return match(name,"^.+[/\\](.-)$") or name
+--~ end
+
function file.basename(name)
- return match(name,"^.+[/\\](.-)$") or name
+ return match(name,"^.*[/\\](.-)$") or name
end
function file.nameonly(name)
@@ -1857,6 +1943,7 @@ function file.collapse_path(str)
return str
end
+--~ print(file.collapse_path("/a"))
--~ print(file.collapse_path("a/./b/.."))
--~ print(file.collapse_path("a/aa/../b/bb"))
--~ print(file.collapse_path("a/../.."))
@@ -3028,9 +3115,9 @@ function aux.make_settings_to_hash_pattern(set,how)
end
end
-function aux.settings_to_hash(str)
+function aux.settings_to_hash(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
if moretolerant then
pattern_b_s:match(str)
else
@@ -3042,9 +3129,9 @@ function aux.settings_to_hash(str)
end
end
-function aux.settings_to_hash_tolerant(str)
+function aux.settings_to_hash_tolerant(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
pattern_b_s:match(str)
return hash
else
@@ -3052,9 +3139,9 @@ function aux.settings_to_hash_tolerant(str)
end
end
-function aux.settings_to_hash_strict(str)
+function aux.settings_to_hash_strict(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
pattern_c_s:match(str)
return next(hash) and hash
else
@@ -3142,7 +3229,7 @@ function aux.getparameters(self,class,parentclass,settings)
sc = table.clone(self[parent])
self[class] = sc
end
- aux.add_settings_to_array(sc, settings)
+ aux.settings_to_hash(settings,sc)
end
-- temporary here
@@ -3230,12 +3317,15 @@ if not modules then modules = { } end modules ['trac-tra'] = {
-- bound to a variable, like node.new, node.copy etc (contrary to for instance
-- node.has_attribute which is bound to a has_attribute local variable in mkiv)
+local getinfo = debug.getinfo
+local type, next = type, next
+local concat = table.concat
+local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub
+
debugger = debugger or { }
local counters = { }
local names = { }
-local getinfo = debug.getinfo
-local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub
-- one
@@ -3363,11 +3453,11 @@ end
--~ print("")
--~ debugger.showstats(print,3)
-trackers = trackers or { }
+setters = setters or { }
+setters.data = setters.data or { }
-local data, done = { }, { }
-
-local function set(what,value)
+local function set(t,what,value)
+ local data, done = t.data, t.done
if type(what) == "string" then
what = aux.settings_to_array(what) -- inefficient but ok
end
@@ -3386,28 +3476,30 @@ local function set(what,value)
end
end
-local function reset()
- for d, f in next, data do
+local function reset(t)
+ for d, f in next, t.data do
for i=1,#f do
f[i](false)
end
end
end
-local function enable(what)
- set(what,true)
+local function enable(t,what)
+ set(t,what,true)
end
-local function disable(what)
+local function disable(t,what)
+ local data = t.data
if not what or what == "" then
- done = { }
- reset()
+ t.done = { }
+ reset(t)
else
- set(what,false)
+ set(t,what,false)
end
end
-function trackers.register(what,...)
+function setters.register(t,what,...)
+ local data = t.data
what = lower(what)
local w = data[what]
if not w then
@@ -3419,32 +3511,32 @@ function trackers.register(what,...)
if typ == "function" then
w[#w+1] = fnc
elseif typ == "string" then
- w[#w+1] = function(value) set(fnc,value,nesting) end
+ w[#w+1] = function(value) set(t,fnc,value,nesting) end
end
end
end
-function trackers.enable(what)
- local e = trackers.enable
- trackers.enable, done = enable, { }
- enable(string.simpleesc(what))
- trackers.enable, done = e, { }
+function setters.enable(t,what)
+ local e = t.enable
+ t.enable, t.done = enable, { }
+ enable(t,string.simpleesc(what))
+ t.enable, t.done = e, { }
end
-function trackers.disable(what)
- local e = trackers.disable
- trackers.disable, done = disable, { }
- disable(string.simpleesc(what))
- trackers.disable, done = e, { }
+function setters.disable(t,what)
+ local e = t.disable
+ t.disable, t.done = disable, { }
+ disable(t,string.simpleesc(what))
+ t.disable, t.done = e, { }
end
-function trackers.reset()
- done = { }
- reset()
+function setters.reset(t)
+ t.done = { }
+ reset(t)
end
-function trackers.list() -- pattern
- local list = table.sortedkeys(data)
+function setters.list(t) -- pattern
+ local list = table.sortedkeys(t.data)
local user, system = { }, { }
for l=1,#list do
local what = list[l]
@@ -3457,6 +3549,139 @@ function trackers.list() -- pattern
return user, system
end
+function setters.show(t)
+ commands.writestatus("","")
+ for k,v in ipairs(setters.list(t)) do
+ commands.writestatus(t.name,v)
+ end
+ commands.writestatus("","")
+end
+
+-- we could have used a bit of oo and the trackers:enable syntax but
+-- there is already a lot of code around using the singluar tracker
+
+function setters.new(name)
+ local t
+ t = {
+ data = { },
+ name = name,
+ enable = function(...) setters.enable (t,...) end,
+ disable = function(...) setters.disable (t,...) end,
+ register = function(...) setters.register(t,...) end,
+ list = function(...) setters.list (t,...) end,
+ show = function(...) setters.show (t,...) end,
+ }
+ setters.data[name] = t
+ return t
+end
+
+trackers = setters.new("trackers")
+directives = setters.new("directives")
+
+-- nice trick: we overload two of the directives related functions with variants that
+-- do tracing (itself using a tracker) .. proof of concept
+
+local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end)
+
+local e = directives.enable
+local d = directives.disable
+
+function directives.enable(...)
+ commands.writestatus("directives","enabling: %s",concat({...}," "))
+ e(...)
+end
+
+function directives.disable(...)
+ commands.writestatus("directives","disabling: %s",concat({...}," "))
+ d(...)
+end
+
+--~ -- old code:
+--
+--~ trackers = trackers or { }
+--~ local data, done = { }, { }
+--~ local function set(what,value)
+--~ if type(what) == "string" then
+--~ what = aux.settings_to_array(what) -- inefficient but ok
+--~ end
+--~ for i=1,#what do
+--~ local w = what[i]
+--~ for d, f in next, data do
+--~ if done[d] then
+--~ -- prevent recursion due to wildcards
+--~ elseif find(d,w) then
+--~ done[d] = true
+--~ for i=1,#f do
+--~ f[i](value)
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ local function reset()
+--~ for d, f in next, data do
+--~ for i=1,#f do
+--~ f[i](false)
+--~ end
+--~ end
+--~ end
+--~ local function enable(what)
+--~ set(what,true)
+--~ end
+--~ local function disable(what)
+--~ if not what or what == "" then
+--~ done = { }
+--~ reset()
+--~ else
+--~ set(what,false)
+--~ end
+--~ end
+--~ function trackers.register(what,...)
+--~ what = lower(what)
+--~ local w = data[what]
+--~ if not w then
+--~ w = { }
+--~ data[what] = w
+--~ end
+--~ for _, fnc in next, { ... } do
+--~ local typ = type(fnc)
+--~ if typ == "function" then
+--~ w[#w+1] = fnc
+--~ elseif typ == "string" then
+--~ w[#w+1] = function(value) set(fnc,value,nesting) end
+--~ end
+--~ end
+--~ end
+--~ function trackers.enable(what)
+--~ local e = trackers.enable
+--~ trackers.enable, done = enable, { }
+--~ enable(string.simpleesc(what))
+--~ trackers.enable, done = e, { }
+--~ end
+--~ function trackers.disable(what)
+--~ local e = trackers.disable
+--~ trackers.disable, done = disable, { }
+--~ disable(string.simpleesc(what))
+--~ trackers.disable, done = e, { }
+--~ end
+--~ function trackers.reset()
+--~ done = { }
+--~ reset()
+--~ end
+--~ function trackers.list() -- pattern
+--~ local list = table.sortedkeys(data)
+--~ local user, system = { }, { }
+--~ for l=1,#list do
+--~ local what = list[l]
+--~ if find(what,"^%*") then
+--~ system[#system+1] = what
+--~ else
+--~ user[#user+1] = what
+--~ end
+--~ end
+--~ return user, system
+--~ end
+
end -- of closure
@@ -3908,6 +4133,7 @@ function statistics.timed(action,report)
end
+
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -4241,6 +4467,8 @@ local format, gsub, find, lower, upper, match, gmatch = string.format, string.gs
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
local next, type = next, type
+local collapse_path = file.collapse_path
+
local trace_locating, trace_detail, trace_verbose = false, false, false
trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
@@ -4629,7 +4857,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
end
if ok then
local function validate(s)
- s = file.collapse_path(s)
+ s = collapse_path(s)
return s ~= "" and not find(s,dummy_path_expr) and s
end
for k=1,#pathlist do
@@ -4638,7 +4866,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
else
for k=1,#pathlist do
for p in gmatch(pathlist[k],"([^,]+)") do
- p = file.collapse_path(p)
+ p = collapse_path(p)
if p ~= "" then newlist[#newlist+1] = p end
end
end
@@ -4703,9 +4931,9 @@ local function identify_own()
local ownpath = resolvers.getownpath() or lfs.currentdir()
local ie = instance.environment
if ownpath then
- if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = collapse_path(ownpath .. "/../..") end
else
logs.report("fileio","error: unable to locate ownpath")
os.exit()
@@ -4734,7 +4962,7 @@ function resolvers.identify_cnf()
local function locate(filename,list)
for i=1,#t do
local ti = t[i]
- local texmfcnf = file.collapse_path(file.join(ti,filename))
+ local texmfcnf = collapse_path(file.join(ti,filename))
if lfs.isfile(texmfcnf) then
list[#list+1] = texmfcnf
end
@@ -4746,11 +4974,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -4815,13 +5043,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -4829,12 +5061,12 @@ function resolvers.load_cnf()
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.cnffiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
if instance.diskcache and not instance.renewcache then
resolvers.loadoldconfig(instance.cnffiles)
if instance.loaderror then
@@ -4858,12 +5090,12 @@ function resolvers.load_lua()
else
instance.rootpath = instance.luafiles[1]
for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.luafiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
resolvers.loadnewconfig()
collapse_cnf_data()
end
@@ -4925,7 +5157,7 @@ function resolvers.locatelists()
if trace_verbose then
logs.report("fileio","locating list of %s",path)
end
- resolvers.locatedatabase(file.collapse_path(path))
+ resolvers.locatedatabase(collapse_path(path))
end
end
@@ -5184,6 +5416,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -5206,6 +5439,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -5213,6 +5452,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -5467,7 +5707,7 @@ function resolvers.clean_path_list(str)
local t = resolvers.expanded_path_list(str)
if t then
for i=1,#t do
- t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ t[i] = collapse_path(resolvers.clean_path(t[i]))
end
end
return t
@@ -5664,8 +5904,8 @@ end
local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
local result = collected or { }
local stamp = nil
- filename = file.collapse_path(filename) -- elsewhere
- filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ filename = collapse_path(filename) -- elsewhere
+ filename = collapse_path(gsub(filename,"\\","/")) -- elsewhere
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -5896,7 +6136,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
end
for k=1,#result do
- result[k] = file.collapse_path(result[k])
+ result[k] = collapse_path(result[k])
end
if instance.remember then
instance.found[stamp] = result
@@ -6048,9 +6288,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
@@ -6397,6 +6637,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 130ad493c..0d3f08025 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -789,6 +789,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s{",depth))
end
end
+ -- we could check for k (index) being number (cardinal)
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
@@ -811,7 +812,7 @@ local function do_serialize(root,name,depth,level,indexed)
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
- handle(format("%s %.99g,",depth,v))
+ handle(format("%s %s,",depth,v)) -- %.99g
end
elseif t == "string" then
if reduce and tonumber(v) then
@@ -851,25 +852,25 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if hexify then
--~ handle(format("%s %s=0x%04X,",depth,key(k),v))
--~ else
- --~ handle(format("%s %s=%.99g,",depth,key(k),v))
+ --~ handle(format("%s %s=%s,",depth,key(k),v)) -- %.99g
--~ end
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
else
- handle(format("%s [%s]=%.99g,",depth,k,v))
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
if hexify then
handle(format("%s %s=0x%04X,",depth,k,v))
else
- handle(format("%s %s=%.99g,",depth,k,v))
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%04X,",depth,k,v))
else
- handle(format("%s [%q]=%.99g,",depth,k,v))
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
elseif t == "string" then
@@ -1868,8 +1869,12 @@ function file.dirname(name,default)
return match(name,"^(.+)[/\\].-$") or (default or "")
end
+--~ function file.basename(name)
+--~ return match(name,"^.+[/\\](.-)$") or name
+--~ end
+
function file.basename(name)
- return match(name,"^.+[/\\](.-)$") or name
+ return match(name,"^.*[/\\](.-)$") or name
end
function file.nameonly(name)
@@ -4872,7 +4877,7 @@ local noparent = 1 - (lparent+rparent)
local nested = lpeg.P{lparent * (noparent + lpeg.V(1))^0 * rparent}
local value = lpeg.P(lparent * lpeg.C((noparent + nested)^0) * rparent) -- lpeg.P{"("*C(((1-S("()"))+V(1))^0)*")"}
-local lp_child = Cc("expr.child(e,'") * R("az","AZ","--","__")^1 * Cc("')")
+local lp_child = Cc("expr.child(ll,'") * R("az","AZ","--","__")^1 * Cc("')")
local lp_string = Cc("'") * R("az","AZ","--","__")^1 * Cc("'")
local lp_content = (P("'") * (1-P("'"))^0 * P("'") + P('"') * (1-P('"'))^0 * P('"'))
@@ -4882,9 +4887,9 @@ local lp_special = (C(P("name")+P("text")+P("tag")+P("count")+P("child"))) * val
if expressions[t] then
s = s and s ~= "" and cleaner:match(s)
if s and s ~= "" then
- return "expr." .. t .. "(e," .. s ..")"
+ return "expr." .. t .. "(ll," .. s ..")"
else
- return "expr." .. t .. "(e)"
+ return "expr." .. t .. "(ll)"
end
else
return "expr.error(" .. t .. ")"
@@ -5434,38 +5439,42 @@ expressions.name = function(e,n) -- ns + tg
end
expressions.tag = function(e,n) -- only tg
- local found = false
- n = tonumber(n) or 0
- if n == 0 then
- found = (type(e) == "table") and e -- seems to fail
- elseif n < 0 then
- local d, k = e.__p__.dt, e.ni
- for i=k-1,1,-1 do
- local di = d[i]
- if type(di) == "table" then
- if n == -1 then
- found = di
- break
- else
- n = n + 1
+ if not e then
+ return ""
+ else
+ local found = false
+ n = tonumber(n) or 0
+ if n == 0 then
+ found = (type(e) == "table") and e -- seems to fail
+ elseif n < 0 then
+ local d, k = e.__p__.dt, e.ni
+ for i=k-1,1,-1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == -1 then
+ found = di
+ break
+ else
+ n = n + 1
+ end
end
end
- end
- else
- local d, k = e.__p__.dt, e.ni
- for i=k+1,#d,1 do
- local di = d[i]
- if type(di) == "table" then
- if n == 1 then
- found = di
- break
- else
- n = n - 1
+ else
+ local d, k = e.__p__.dt, e.ni
+ for i=k+1,#d,1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == 1 then
+ found = di
+ break
+ else
+ n = n - 1
+ end
end
end
end
+ return (found and found.tg) or ""
end
- return (found and found.tg) or ""
end
--[[ldx--
@@ -5992,7 +6001,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)
--~ local settings = xmldata.settings
--~ settings.parent_root = xmldata -- to be tested
--~ local xi = xmlconvert(data,settings)
- local xi = xml.inheritedconvert(element,xmldata)
+ local xi = xml.inheritedconvert(data,xmldata)
if not xi then
epdt[ek.ni] = "" -- xml.empty(d,k)
else
@@ -7046,7 +7055,6 @@ end
local name, banner = 'report', 'context'
local function report(category,fmt,...)
---~ print(fmt,...)
if fmt then
write_nl(format("%s | %s: %s",name,category,format(fmt,...)))
elseif category then
@@ -7187,6 +7195,8 @@ local format, gsub, find, lower, upper, match, gmatch = string.format, string.gs
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
local next, type = next, type
+local collapse_path = file.collapse_path
+
local trace_locating, trace_detail, trace_verbose = false, false, false
trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
@@ -7575,7 +7585,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
end
if ok then
local function validate(s)
- s = file.collapse_path(s)
+ s = collapse_path(s)
return s ~= "" and not find(s,dummy_path_expr) and s
end
for k=1,#pathlist do
@@ -7584,7 +7594,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
else
for k=1,#pathlist do
for p in gmatch(pathlist[k],"([^,]+)") do
- p = file.collapse_path(p)
+ p = collapse_path(p)
if p ~= "" then newlist[#newlist+1] = p end
end
end
@@ -7649,9 +7659,9 @@ local function identify_own()
local ownpath = resolvers.getownpath() or lfs.currentdir()
local ie = instance.environment
if ownpath then
- if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = collapse_path(ownpath .. "/../..") end
else
logs.report("fileio","error: unable to locate ownpath")
os.exit()
@@ -7680,7 +7690,7 @@ function resolvers.identify_cnf()
local function locate(filename,list)
for i=1,#t do
local ti = t[i]
- local texmfcnf = file.collapse_path(file.join(ti,filename))
+ local texmfcnf = collapse_path(file.join(ti,filename))
if lfs.isfile(texmfcnf) then
list[#list+1] = texmfcnf
end
@@ -7692,11 +7702,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -7761,13 +7771,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -7775,12 +7789,12 @@ function resolvers.load_cnf()
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.cnffiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
if instance.diskcache and not instance.renewcache then
resolvers.loadoldconfig(instance.cnffiles)
if instance.loaderror then
@@ -7804,12 +7818,12 @@ function resolvers.load_lua()
else
instance.rootpath = instance.luafiles[1]
for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.luafiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
resolvers.loadnewconfig()
collapse_cnf_data()
end
@@ -7871,7 +7885,7 @@ function resolvers.locatelists()
if trace_verbose then
logs.report("fileio","locating list of %s",path)
end
- resolvers.locatedatabase(file.collapse_path(path))
+ resolvers.locatedatabase(collapse_path(path))
end
end
@@ -8130,6 +8144,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -8152,6 +8167,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -8159,6 +8180,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -8413,7 +8435,7 @@ function resolvers.clean_path_list(str)
local t = resolvers.expanded_path_list(str)
if t then
for i=1,#t do
- t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ t[i] = collapse_path(resolvers.clean_path(t[i]))
end
end
return t
@@ -8610,8 +8632,8 @@ end
local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
local result = collected or { }
local stamp = nil
- filename = file.collapse_path(filename) -- elsewhere
- filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ filename = collapse_path(filename) -- elsewhere
+ filename = collapse_path(gsub(filename,"\\","/")) -- elsewhere
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -8842,7 +8864,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
end
for k=1,#result do
- result[k] = file.collapse_path(result[k])
+ result[k] = collapse_path(result[k])
end
if instance.remember then
instance.found[stamp] = result
@@ -8994,9 +9016,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
@@ -9343,6 +9365,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else
diff --git a/scripts/context/stubs/unix/luatools b/scripts/context/stubs/unix/luatools
index 2bc943210..abd80b8b4 100755
--- a/scripts/context/stubs/unix/luatools
+++ b/scripts/context/stubs/unix/luatools
@@ -308,7 +308,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
license = "see context related readme files"
}
-local P, S, Ct, C, Cs, Cc = lpeg.P, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
+local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
--~ l-lpeg.lua :
@@ -415,6 +415,41 @@ end
--~ return p
--~ end
+--~ from roberto's site:
+--~
+--~ -- decode a two-byte UTF-8 sequence
+--~ local function f2 (s)
+--~ local c1, c2 = string.byte(s, 1, 2)
+--~ return c1 * 64 + c2 - 12416
+--~ end
+--~
+--~ -- decode a three-byte UTF-8 sequence
+--~ local function f3 (s)
+--~ local c1, c2, c3 = string.byte(s, 1, 3)
+--~ return (c1 * 64 + c2) * 64 + c3 - 925824
+--~ end
+--~
+--~ -- decode a four-byte UTF-8 sequence
+--~ local function f4 (s)
+--~ local c1, c2, c3, c4 = string.byte(s, 1, 4)
+--~ return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168
+--~ end
+--~
+--~ local cont = lpeg.R("\128\191") -- continuation byte
+--~
+--~ local utf8 = lpeg.R("\0\127") / string.byte
+--~ + lpeg.R("\194\223") * cont / f2
+--~ + lpeg.R("\224\239") * cont * cont / f3
+--~ + lpeg.R("\240\244") * cont * cont * cont / f4
+--~
+--~ local decode_pattern = lpeg.Ct(utf8^0) * -1
+
+
+local cont = R("\128\191") -- continuation byte
+
+lpeg.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
+
+
end -- of closure
@@ -431,9 +466,9 @@ if not modules then modules = { } end modules ['l-table'] = {
table.join = table.concat
local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove
-local format, find, gsub, lower, dump = string.format, string.find, string.gsub, string.lower, string.dump
+local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match
local getmetatable, setmetatable = getmetatable, setmetatable
-local type, next, tostring, ipairs = type, next, tostring, ipairs
+local type, next, tostring, tonumber, ipairs, pairs = type, next, tostring, tonumber, ipairs, pairs
function table.strip(tab)
local lst = { }
@@ -721,6 +756,8 @@ end
--
-- local propername = lpeg.P(lpeg.R("AZ","az","__") * lpeg.R("09","AZ","az", "__")^0 * lpeg.P(-1) )
+-- problem: there no good number_to_string converter with the best resolution
+
local function do_serialize(root,name,depth,level,indexed)
if level > 0 then
depth = depth .. " "
@@ -743,6 +780,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s{",depth))
end
end
+ -- we could check for k (index) being number (cardinal)
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
@@ -765,10 +803,10 @@ local function do_serialize(root,name,depth,level,indexed)
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
- handle(format("%s %s,",depth,v))
+ handle(format("%s %s,",depth,v)) -- %.99g
end
elseif t == "string" then
- if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ if reduce and tonumber(v) then
handle(format("%s %s,",depth,v))
else
handle(format("%s %q,",depth,v))
@@ -805,29 +843,29 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if hexify then
--~ handle(format("%s %s=0x%04X,",depth,key(k),v))
--~ else
- --~ handle(format("%s %s=%s,",depth,key(k),v))
+ --~ handle(format("%s %s=%s,",depth,key(k),v)) -- %.99g
--~ end
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
else
- handle(format("%s [%s]=%s,",depth,k,v))
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
if hexify then
handle(format("%s %s=0x%04X,",depth,k,v))
else
- handle(format("%s %s=%s,",depth,k,v))
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%04X,",depth,k,v))
else
- handle(format("%s [%q]=%s,",depth,k,v))
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
elseif t == "string" then
- if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ if reduce and tonumber(v) then
--~ handle(format("%s %s=%s,",depth,key(k),v))
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
@@ -1036,7 +1074,7 @@ function table.tofile(filename,root,name,reduce,noquotes,hexify)
end
end
-local function flatten(t,f,complete)
+local function flatten(t,f,complete) -- is this used? meybe a variant with next, ...
for i=1,#t do
local v = t[i]
if type(v) == "table" then
@@ -1065,6 +1103,24 @@ end
table.flatten_one_level = table.unnest
+-- a better one:
+
+local function flattened(t,f)
+ if not f then
+ f = { }
+ end
+ for k, v in next, t do
+ if type(v) == "table" then
+ flattened(v,f)
+ else
+ f[k] = v
+ end
+ end
+ return f
+end
+
+table.flattened = flattened
+
-- the next three may disappear
function table.remove_value(t,value) -- todo: n
@@ -1200,7 +1256,7 @@ function table.clone(t,p) -- t is optional or nil or table
elseif not t then
t = { }
end
- setmetatable(t, { __index = function(_,key) return p[key] end })
+ setmetatable(t, { __index = function(_,key) return p[key] end }) -- why not __index = p ?
return t
end
@@ -1615,7 +1671,8 @@ if not modules then modules = { } end modules ['l-os'] = {
license = "see context related readme files"
}
-local find = string.find
+local find, format = string.find, string.format
+local random, ceil = math.random, math.ceil
function os.resultof(command)
return io.popen(command,"r"):read("*all")
@@ -1712,6 +1769,8 @@ function os.currentplatform(name,default)
elseif name == "macosx" then
if find(architecture,"i386") then
platform = "osx-intel"
+ elseif find(architecture,"x86_64") then
+ platform = "osx-64"
else
platform = "osx-ppc"
end
@@ -1738,6 +1797,29 @@ function os.currentplatform(name,default)
return platform
end
+-- beware, we set the randomseed
+--
+
+-- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the
+-- version number as well as two reserved bits. All other bits are set using a random or pseudorandom
+-- data source. Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal
+-- digits x and hexadecimal digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479.
+--
+-- as we don't call this function too often there is not so much risk on repetition
+
+
+local t = { 8, 9, "a", "b" }
+
+function os.uuid()
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
+end
+
end -- of closure
@@ -1778,8 +1860,12 @@ function file.dirname(name,default)
return match(name,"^(.+)[/\\].-$") or (default or "")
end
+--~ function file.basename(name)
+--~ return match(name,"^.+[/\\](.-)$") or name
+--~ end
+
function file.basename(name)
- return match(name,"^.+[/\\](.-)$") or name
+ return match(name,"^.*[/\\](.-)$") or name
end
function file.nameonly(name)
@@ -1857,6 +1943,7 @@ function file.collapse_path(str)
return str
end
+--~ print(file.collapse_path("/a"))
--~ print(file.collapse_path("a/./b/.."))
--~ print(file.collapse_path("a/aa/../b/bb"))
--~ print(file.collapse_path("a/../.."))
@@ -3028,9 +3115,9 @@ function aux.make_settings_to_hash_pattern(set,how)
end
end
-function aux.settings_to_hash(str)
+function aux.settings_to_hash(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
if moretolerant then
pattern_b_s:match(str)
else
@@ -3042,9 +3129,9 @@ function aux.settings_to_hash(str)
end
end
-function aux.settings_to_hash_tolerant(str)
+function aux.settings_to_hash_tolerant(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
pattern_b_s:match(str)
return hash
else
@@ -3052,9 +3139,9 @@ function aux.settings_to_hash_tolerant(str)
end
end
-function aux.settings_to_hash_strict(str)
+function aux.settings_to_hash_strict(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
pattern_c_s:match(str)
return next(hash) and hash
else
@@ -3142,7 +3229,7 @@ function aux.getparameters(self,class,parentclass,settings)
sc = table.clone(self[parent])
self[class] = sc
end
- aux.add_settings_to_array(sc, settings)
+ aux.settings_to_hash(settings,sc)
end
-- temporary here
@@ -3230,12 +3317,15 @@ if not modules then modules = { } end modules ['trac-tra'] = {
-- bound to a variable, like node.new, node.copy etc (contrary to for instance
-- node.has_attribute which is bound to a has_attribute local variable in mkiv)
+local getinfo = debug.getinfo
+local type, next = type, next
+local concat = table.concat
+local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub
+
debugger = debugger or { }
local counters = { }
local names = { }
-local getinfo = debug.getinfo
-local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub
-- one
@@ -3363,11 +3453,11 @@ end
--~ print("")
--~ debugger.showstats(print,3)
-trackers = trackers or { }
+setters = setters or { }
+setters.data = setters.data or { }
-local data, done = { }, { }
-
-local function set(what,value)
+local function set(t,what,value)
+ local data, done = t.data, t.done
if type(what) == "string" then
what = aux.settings_to_array(what) -- inefficient but ok
end
@@ -3386,28 +3476,30 @@ local function set(what,value)
end
end
-local function reset()
- for d, f in next, data do
+local function reset(t)
+ for d, f in next, t.data do
for i=1,#f do
f[i](false)
end
end
end
-local function enable(what)
- set(what,true)
+local function enable(t,what)
+ set(t,what,true)
end
-local function disable(what)
+local function disable(t,what)
+ local data = t.data
if not what or what == "" then
- done = { }
- reset()
+ t.done = { }
+ reset(t)
else
- set(what,false)
+ set(t,what,false)
end
end
-function trackers.register(what,...)
+function setters.register(t,what,...)
+ local data = t.data
what = lower(what)
local w = data[what]
if not w then
@@ -3419,32 +3511,32 @@ function trackers.register(what,...)
if typ == "function" then
w[#w+1] = fnc
elseif typ == "string" then
- w[#w+1] = function(value) set(fnc,value,nesting) end
+ w[#w+1] = function(value) set(t,fnc,value,nesting) end
end
end
end
-function trackers.enable(what)
- local e = trackers.enable
- trackers.enable, done = enable, { }
- enable(string.simpleesc(what))
- trackers.enable, done = e, { }
+function setters.enable(t,what)
+ local e = t.enable
+ t.enable, t.done = enable, { }
+ enable(t,string.simpleesc(what))
+ t.enable, t.done = e, { }
end
-function trackers.disable(what)
- local e = trackers.disable
- trackers.disable, done = disable, { }
- disable(string.simpleesc(what))
- trackers.disable, done = e, { }
+function setters.disable(t,what)
+ local e = t.disable
+ t.disable, t.done = disable, { }
+ disable(t,string.simpleesc(what))
+ t.disable, t.done = e, { }
end
-function trackers.reset()
- done = { }
- reset()
+function setters.reset(t)
+ t.done = { }
+ reset(t)
end
-function trackers.list() -- pattern
- local list = table.sortedkeys(data)
+function setters.list(t) -- pattern
+ local list = table.sortedkeys(t.data)
local user, system = { }, { }
for l=1,#list do
local what = list[l]
@@ -3457,6 +3549,139 @@ function trackers.list() -- pattern
return user, system
end
+function setters.show(t)
+ commands.writestatus("","")
+ for k,v in ipairs(setters.list(t)) do
+ commands.writestatus(t.name,v)
+ end
+ commands.writestatus("","")
+end
+
+-- we could have used a bit of oo and the trackers:enable syntax but
+-- there is already a lot of code around using the singluar tracker
+
+function setters.new(name)
+ local t
+ t = {
+ data = { },
+ name = name,
+ enable = function(...) setters.enable (t,...) end,
+ disable = function(...) setters.disable (t,...) end,
+ register = function(...) setters.register(t,...) end,
+ list = function(...) setters.list (t,...) end,
+ show = function(...) setters.show (t,...) end,
+ }
+ setters.data[name] = t
+ return t
+end
+
+trackers = setters.new("trackers")
+directives = setters.new("directives")
+
+-- nice trick: we overload two of the directives related functions with variants that
+-- do tracing (itself using a tracker) .. proof of concept
+
+local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end)
+
+local e = directives.enable
+local d = directives.disable
+
+function directives.enable(...)
+ commands.writestatus("directives","enabling: %s",concat({...}," "))
+ e(...)
+end
+
+function directives.disable(...)
+ commands.writestatus("directives","disabling: %s",concat({...}," "))
+ d(...)
+end
+
+--~ -- old code:
+--
+--~ trackers = trackers or { }
+--~ local data, done = { }, { }
+--~ local function set(what,value)
+--~ if type(what) == "string" then
+--~ what = aux.settings_to_array(what) -- inefficient but ok
+--~ end
+--~ for i=1,#what do
+--~ local w = what[i]
+--~ for d, f in next, data do
+--~ if done[d] then
+--~ -- prevent recursion due to wildcards
+--~ elseif find(d,w) then
+--~ done[d] = true
+--~ for i=1,#f do
+--~ f[i](value)
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ local function reset()
+--~ for d, f in next, data do
+--~ for i=1,#f do
+--~ f[i](false)
+--~ end
+--~ end
+--~ end
+--~ local function enable(what)
+--~ set(what,true)
+--~ end
+--~ local function disable(what)
+--~ if not what or what == "" then
+--~ done = { }
+--~ reset()
+--~ else
+--~ set(what,false)
+--~ end
+--~ end
+--~ function trackers.register(what,...)
+--~ what = lower(what)
+--~ local w = data[what]
+--~ if not w then
+--~ w = { }
+--~ data[what] = w
+--~ end
+--~ for _, fnc in next, { ... } do
+--~ local typ = type(fnc)
+--~ if typ == "function" then
+--~ w[#w+1] = fnc
+--~ elseif typ == "string" then
+--~ w[#w+1] = function(value) set(fnc,value,nesting) end
+--~ end
+--~ end
+--~ end
+--~ function trackers.enable(what)
+--~ local e = trackers.enable
+--~ trackers.enable, done = enable, { }
+--~ enable(string.simpleesc(what))
+--~ trackers.enable, done = e, { }
+--~ end
+--~ function trackers.disable(what)
+--~ local e = trackers.disable
+--~ trackers.disable, done = disable, { }
+--~ disable(string.simpleesc(what))
+--~ trackers.disable, done = e, { }
+--~ end
+--~ function trackers.reset()
+--~ done = { }
+--~ reset()
+--~ end
+--~ function trackers.list() -- pattern
+--~ local list = table.sortedkeys(data)
+--~ local user, system = { }, { }
+--~ for l=1,#list do
+--~ local what = list[l]
+--~ if find(what,"^%*") then
+--~ system[#system+1] = what
+--~ else
+--~ user[#user+1] = what
+--~ end
+--~ end
+--~ return user, system
+--~ end
+
end -- of closure
@@ -3908,6 +4133,7 @@ function statistics.timed(action,report)
end
+
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -4241,6 +4467,8 @@ local format, gsub, find, lower, upper, match, gmatch = string.format, string.gs
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
local next, type = next, type
+local collapse_path = file.collapse_path
+
local trace_locating, trace_detail, trace_verbose = false, false, false
trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
@@ -4629,7 +4857,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
end
if ok then
local function validate(s)
- s = file.collapse_path(s)
+ s = collapse_path(s)
return s ~= "" and not find(s,dummy_path_expr) and s
end
for k=1,#pathlist do
@@ -4638,7 +4866,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
else
for k=1,#pathlist do
for p in gmatch(pathlist[k],"([^,]+)") do
- p = file.collapse_path(p)
+ p = collapse_path(p)
if p ~= "" then newlist[#newlist+1] = p end
end
end
@@ -4703,9 +4931,9 @@ local function identify_own()
local ownpath = resolvers.getownpath() or lfs.currentdir()
local ie = instance.environment
if ownpath then
- if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = collapse_path(ownpath .. "/../..") end
else
logs.report("fileio","error: unable to locate ownpath")
os.exit()
@@ -4734,7 +4962,7 @@ function resolvers.identify_cnf()
local function locate(filename,list)
for i=1,#t do
local ti = t[i]
- local texmfcnf = file.collapse_path(file.join(ti,filename))
+ local texmfcnf = collapse_path(file.join(ti,filename))
if lfs.isfile(texmfcnf) then
list[#list+1] = texmfcnf
end
@@ -4746,11 +4974,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -4815,13 +5043,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -4829,12 +5061,12 @@ function resolvers.load_cnf()
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.cnffiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
if instance.diskcache and not instance.renewcache then
resolvers.loadoldconfig(instance.cnffiles)
if instance.loaderror then
@@ -4858,12 +5090,12 @@ function resolvers.load_lua()
else
instance.rootpath = instance.luafiles[1]
for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.luafiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
resolvers.loadnewconfig()
collapse_cnf_data()
end
@@ -4925,7 +5157,7 @@ function resolvers.locatelists()
if trace_verbose then
logs.report("fileio","locating list of %s",path)
end
- resolvers.locatedatabase(file.collapse_path(path))
+ resolvers.locatedatabase(collapse_path(path))
end
end
@@ -5184,6 +5416,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -5206,6 +5439,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -5213,6 +5452,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -5467,7 +5707,7 @@ function resolvers.clean_path_list(str)
local t = resolvers.expanded_path_list(str)
if t then
for i=1,#t do
- t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ t[i] = collapse_path(resolvers.clean_path(t[i]))
end
end
return t
@@ -5664,8 +5904,8 @@ end
local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
local result = collected or { }
local stamp = nil
- filename = file.collapse_path(filename) -- elsewhere
- filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ filename = collapse_path(filename) -- elsewhere
+ filename = collapse_path(gsub(filename,"\\","/")) -- elsewhere
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -5896,7 +6136,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
end
for k=1,#result do
- result[k] = file.collapse_path(result[k])
+ result[k] = collapse_path(result[k])
end
if instance.remember then
instance.found[stamp] = result
@@ -6048,9 +6288,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
@@ -6397,6 +6637,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 130ad493c..0d3f08025 100755
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -789,6 +789,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s{",depth))
end
end
+ -- we could check for k (index) being number (cardinal)
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
@@ -811,7 +812,7 @@ local function do_serialize(root,name,depth,level,indexed)
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
- handle(format("%s %.99g,",depth,v))
+ handle(format("%s %s,",depth,v)) -- %.99g
end
elseif t == "string" then
if reduce and tonumber(v) then
@@ -851,25 +852,25 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if hexify then
--~ handle(format("%s %s=0x%04X,",depth,key(k),v))
--~ else
- --~ handle(format("%s %s=%.99g,",depth,key(k),v))
+ --~ handle(format("%s %s=%s,",depth,key(k),v)) -- %.99g
--~ end
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
else
- handle(format("%s [%s]=%.99g,",depth,k,v))
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
if hexify then
handle(format("%s %s=0x%04X,",depth,k,v))
else
- handle(format("%s %s=%.99g,",depth,k,v))
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%04X,",depth,k,v))
else
- handle(format("%s [%q]=%.99g,",depth,k,v))
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
elseif t == "string" then
@@ -1868,8 +1869,12 @@ function file.dirname(name,default)
return match(name,"^(.+)[/\\].-$") or (default or "")
end
+--~ function file.basename(name)
+--~ return match(name,"^.+[/\\](.-)$") or name
+--~ end
+
function file.basename(name)
- return match(name,"^.+[/\\](.-)$") or name
+ return match(name,"^.*[/\\](.-)$") or name
end
function file.nameonly(name)
@@ -4872,7 +4877,7 @@ local noparent = 1 - (lparent+rparent)
local nested = lpeg.P{lparent * (noparent + lpeg.V(1))^0 * rparent}
local value = lpeg.P(lparent * lpeg.C((noparent + nested)^0) * rparent) -- lpeg.P{"("*C(((1-S("()"))+V(1))^0)*")"}
-local lp_child = Cc("expr.child(e,'") * R("az","AZ","--","__")^1 * Cc("')")
+local lp_child = Cc("expr.child(ll,'") * R("az","AZ","--","__")^1 * Cc("')")
local lp_string = Cc("'") * R("az","AZ","--","__")^1 * Cc("'")
local lp_content = (P("'") * (1-P("'"))^0 * P("'") + P('"') * (1-P('"'))^0 * P('"'))
@@ -4882,9 +4887,9 @@ local lp_special = (C(P("name")+P("text")+P("tag")+P("count")+P("child"))) * val
if expressions[t] then
s = s and s ~= "" and cleaner:match(s)
if s and s ~= "" then
- return "expr." .. t .. "(e," .. s ..")"
+ return "expr." .. t .. "(ll," .. s ..")"
else
- return "expr." .. t .. "(e)"
+ return "expr." .. t .. "(ll)"
end
else
return "expr.error(" .. t .. ")"
@@ -5434,38 +5439,42 @@ expressions.name = function(e,n) -- ns + tg
end
expressions.tag = function(e,n) -- only tg
- local found = false
- n = tonumber(n) or 0
- if n == 0 then
- found = (type(e) == "table") and e -- seems to fail
- elseif n < 0 then
- local d, k = e.__p__.dt, e.ni
- for i=k-1,1,-1 do
- local di = d[i]
- if type(di) == "table" then
- if n == -1 then
- found = di
- break
- else
- n = n + 1
+ if not e then
+ return ""
+ else
+ local found = false
+ n = tonumber(n) or 0
+ if n == 0 then
+ found = (type(e) == "table") and e -- seems to fail
+ elseif n < 0 then
+ local d, k = e.__p__.dt, e.ni
+ for i=k-1,1,-1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == -1 then
+ found = di
+ break
+ else
+ n = n + 1
+ end
end
end
- end
- else
- local d, k = e.__p__.dt, e.ni
- for i=k+1,#d,1 do
- local di = d[i]
- if type(di) == "table" then
- if n == 1 then
- found = di
- break
- else
- n = n - 1
+ else
+ local d, k = e.__p__.dt, e.ni
+ for i=k+1,#d,1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == 1 then
+ found = di
+ break
+ else
+ n = n - 1
+ end
end
end
end
+ return (found and found.tg) or ""
end
- return (found and found.tg) or ""
end
--[[ldx--
@@ -5992,7 +6001,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)
--~ local settings = xmldata.settings
--~ settings.parent_root = xmldata -- to be tested
--~ local xi = xmlconvert(data,settings)
- local xi = xml.inheritedconvert(element,xmldata)
+ local xi = xml.inheritedconvert(data,xmldata)
if not xi then
epdt[ek.ni] = "" -- xml.empty(d,k)
else
@@ -7046,7 +7055,6 @@ end
local name, banner = 'report', 'context'
local function report(category,fmt,...)
---~ print(fmt,...)
if fmt then
write_nl(format("%s | %s: %s",name,category,format(fmt,...)))
elseif category then
@@ -7187,6 +7195,8 @@ local format, gsub, find, lower, upper, match, gmatch = string.format, string.gs
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
local next, type = next, type
+local collapse_path = file.collapse_path
+
local trace_locating, trace_detail, trace_verbose = false, false, false
trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
@@ -7575,7 +7585,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
end
if ok then
local function validate(s)
- s = file.collapse_path(s)
+ s = collapse_path(s)
return s ~= "" and not find(s,dummy_path_expr) and s
end
for k=1,#pathlist do
@@ -7584,7 +7594,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
else
for k=1,#pathlist do
for p in gmatch(pathlist[k],"([^,]+)") do
- p = file.collapse_path(p)
+ p = collapse_path(p)
if p ~= "" then newlist[#newlist+1] = p end
end
end
@@ -7649,9 +7659,9 @@ local function identify_own()
local ownpath = resolvers.getownpath() or lfs.currentdir()
local ie = instance.environment
if ownpath then
- if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = collapse_path(ownpath .. "/../..") end
else
logs.report("fileio","error: unable to locate ownpath")
os.exit()
@@ -7680,7 +7690,7 @@ function resolvers.identify_cnf()
local function locate(filename,list)
for i=1,#t do
local ti = t[i]
- local texmfcnf = file.collapse_path(file.join(ti,filename))
+ local texmfcnf = collapse_path(file.join(ti,filename))
if lfs.isfile(texmfcnf) then
list[#list+1] = texmfcnf
end
@@ -7692,11 +7702,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -7761,13 +7771,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -7775,12 +7789,12 @@ function resolvers.load_cnf()
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.cnffiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
if instance.diskcache and not instance.renewcache then
resolvers.loadoldconfig(instance.cnffiles)
if instance.loaderror then
@@ -7804,12 +7818,12 @@ function resolvers.load_lua()
else
instance.rootpath = instance.luafiles[1]
for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.luafiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
resolvers.loadnewconfig()
collapse_cnf_data()
end
@@ -7871,7 +7885,7 @@ function resolvers.locatelists()
if trace_verbose then
logs.report("fileio","locating list of %s",path)
end
- resolvers.locatedatabase(file.collapse_path(path))
+ resolvers.locatedatabase(collapse_path(path))
end
end
@@ -8130,6 +8144,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -8152,6 +8167,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -8159,6 +8180,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -8413,7 +8435,7 @@ function resolvers.clean_path_list(str)
local t = resolvers.expanded_path_list(str)
if t then
for i=1,#t do
- t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ t[i] = collapse_path(resolvers.clean_path(t[i]))
end
end
return t
@@ -8610,8 +8632,8 @@ end
local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
local result = collected or { }
local stamp = nil
- filename = file.collapse_path(filename) -- elsewhere
- filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ filename = collapse_path(filename) -- elsewhere
+ filename = collapse_path(gsub(filename,"\\","/")) -- elsewhere
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -8842,7 +8864,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
end
for k=1,#result do
- result[k] = file.collapse_path(result[k])
+ result[k] = collapse_path(result[k])
end
if instance.remember then
instance.found[stamp] = result
@@ -8994,9 +9016,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
@@ -9343,6 +9365,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else
diff --git a/tex/context/base/colo-hex.mkii b/tex/context/base/colo-hex.mkii
index 7cef6e8a2..db67f1841 100644
--- a/tex/context/base/colo-hex.mkii
+++ b/tex/context/base/colo-hex.mkii
@@ -11,8 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\ifx\dodododefinecolor\undefined \else
- \endinput
+\ifdefined \hexcolorprefix
+ \expandafter \endinput
\fi
\writestatus{loading}{ConTeXt Color Macros / Hexadecimal}
diff --git a/tex/context/base/colo-ini.mkiv b/tex/context/base/colo-ini.mkiv
index 5f3cdf372..cde9f5820 100644
--- a/tex/context/base/colo-ini.mkiv
+++ b/tex/context/base/colo-ini.mkiv
@@ -143,7 +143,7 @@
\unexpanded\def\color [#1]{\groupedcommand{\doactivatecolor{#1}}{}}
\unexpanded\def\startcolor [#1]{\begingroup\doactivatecolor{#1}}
\unexpanded\def\stopcolor {\endgroup}
-\unexpanded\def\graycolor [#1]{\groupedcommand{\setcolormodel{gray}\getvalue{#1}}{}}
+\unexpanded\def\graycolor [#1]{\groupedcommand{\dosetcolormodel{gray}\getvalue{#1}}{}}
\unexpanded\def\colored [#1]{\groupedcommand{\definecolor[@colored@][#1]\doactivatecolor{@colored@}}{}}
\unexpanded\def\fastcolored [#1]#2{\begingroup\dodefinefastcolor[@colored@][#1]\doactivatecolor{@colored@}#2\endgroup}
\def\predefinecolor [#1]{\flushatshipout{\hbox{\color[#1]{}}}}
@@ -693,7 +693,10 @@
\def\setcolormodel#1%
{\showcolormessage\m!colors1{#1}%
- \currentcolormodel\ctxlua{tex.print(colors.setmodel('#1',\ifweightGRAY true\else false\fi))}%
+ \dosetcolormodel{#1}}
+
+\def\dosetcolormodel#1% no message
+ {\currentcolormodel\ctxlua{tex.print(colors.setmodel('#1',\ifweightGRAY true\else false\fi))}%
\dosetattribute{colormodel}{\the\currentcolormodel}}
\setcolormodel{all}
diff --git a/tex/context/base/colo-x11.tex b/tex/context/base/colo-x11.tex
new file mode 100644
index 000000000..45d3aac62
--- /dev/null
+++ b/tex/context/base/colo-x11.tex
@@ -0,0 +1,677 @@
+%D \module
+%D [ file=colo-x11,
+%D version=2009.11.13,
+%D title=\CONTEXT\ Color Macros,
+%D subtitle=X11,
+%D author=Alan Braslau]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Standard X11 rgb colors (from \type {/usr/share/X11/rgb.txt}):
+
+\doifnotmode{mkiv} {
+ \input colo-hex.mkii
+}
+
+\definecolor [snow] [h=fffafa]
+\definecolor [ghostwhite] [h=f8f8ff]
+\definecolor [whitesmoke] [s=0.96]
+\definecolor [gainsboro] [s=0.86]
+\definecolor [floralwhite] [h=fffaf0]
+\definecolor [oldlace] [h=fdf5e6]
+\definecolor [linen] [h=faf0e6]
+\definecolor [antiquewhite] [h=faebd7]
+\definecolor [papayawhip] [h=ffefd5]
+\definecolor [blanchedalmond] [h=ffebcd]
+\definecolor [bisque] [h=ffe4c4]
+\definecolor [peachpuff] [h=ffdab9]
+\definecolor [navajowhite] [h=ffdead]
+\definecolor [moccasin] [h=ffe4b5]
+\definecolor [cornsilk] [h=fff8dc]
+\definecolor [ivory] [h=fffff0]
+\definecolor [lemonchiffon] [h=fffacd]
+\definecolor [seashell] [h=fff5ee]
+\definecolor [honeydew] [h=f0fff0]
+\definecolor [mintcream] [h=f5fffa]
+\definecolor [azure] [h=f0ffff]
+\definecolor [aliceblue] [h=f0f8ff]
+\definecolor [lavender] [h=e6e6fa]
+\definecolor [lavenderblush] [h=fff0f5]
+\definecolor [mistyrose] [h=ffe4e1]
+\definecolor [white] [s=1]
+\definecolor [black] [s=0]
+\definecolor [darkslategray] [h=2f4f4f]
+\definecolor [darkslategrey] [darkslategray]
+\definecolor [dimgray] [s=0.41]
+\definecolor [dimgrey] [dimgray]
+\definecolor [slategray] [h=708090]
+\definecolor [slategrey] [slategray]
+\definecolor [lightslategray] [h=778899]
+\definecolor [lightslategrey] [lightslategray]
+\definecolor [gray] [s=0.75]
+\definecolor [grey] [gray]
+\definecolor [lightgrey] [s=0.83]
+\definecolor [lightgray] [lightgrey]
+\definecolor [midnightblue] [h=191970]
+\definecolor [navy] [h=000080]
+\definecolor [navyblue] [navy]
+\definecolor [cornflowerblue] [h=6495ed]
+\definecolor [darkslateblue] [h=483d8b]
+\definecolor [slateblue] [h=6a5acd]
+\definecolor [mediumslateblue] [h=7b68ee]
+\definecolor [lightslateblue] [h=8470ff]
+\definecolor [mediumblue] [h=0000cd]
+\definecolor [royalblue] [h=4169e1]
+\definecolor [blue] [h=0000ff]
+\definecolor [dodgerblue] [h=1e90ff]
+\definecolor [deepskyblue] [h=00bfff]
+\definecolor [skyblue] [h=87ceeb]
+\definecolor [lightskyblue] [h=87cefa]
+\definecolor [steelblue] [h=4682b4]
+\definecolor [lightsteelblue] [h=b0c4de]
+\definecolor [lightblue] [h=add8e6]
+\definecolor [powderblue] [h=b0e0e6]
+\definecolor [paleturquoise] [h=afeeee]
+\definecolor [darkturquoise] [h=00ced1]
+\definecolor [mediumturquoise] [h=48d1cc]
+\definecolor [turquoise] [h=40e0d0]
+\definecolor [cyan] [h=00ffff]
+\definecolor [lightcyan] [h=e0ffff]
+\definecolor [cadetblue] [h=5f9ea0]
+\definecolor [mediumaquamarine] [h=66cdaa]
+\definecolor [aquamarine] [h=7fffd4]
+\definecolor [darkgreen] [h=006400]
+\definecolor [darkolivegreen] [h=556b2f]
+\definecolor [darkseagreen] [h=8fbc8f]
+\definecolor [seagreen] [h=2e8b57]
+\definecolor [mediumseagreen] [h=3cb371]
+\definecolor [lightseagreen] [h=20b2aa]
+\definecolor [palegreen] [h=98fb98]
+\definecolor [springgreen] [h=00ff7f]
+\definecolor [lawngreen] [h=7cfc00]
+\definecolor [green] [h=00ff00]
+\definecolor [chartreuse] [h=7fff00]
+\definecolor [mediumspringgreen] [h=00fa9a]
+\definecolor [greenyellow] [h=adff2f]
+\definecolor [limegreen] [h=32cd32]
+\definecolor [yellowgreen] [h=9acd32]
+\definecolor [forestgreen] [h=228b22]
+\definecolor [olivedrab] [h=6b8e23]
+\definecolor [darkkhaki] [h=bdb76b]
+\definecolor [khaki] [h=f0e68c]
+\definecolor [palegoldenrod] [h=eee8aa]
+\definecolor [lightgoldenrodyellow] [h=fafad2]
+\definecolor [lightyellow] [h=ffffe0]
+\definecolor [yellow] [h=ffff00]
+\definecolor [gold] [h=ffd700]
+\definecolor [lightgoldenrod] [h=eedd82]
+\definecolor [goldenrod] [h=daa520]
+\definecolor [darkgoldenrod] [h=b8860b]
+\definecolor [rosybrown] [h=bc8f8f]
+\definecolor [indianred] [h=cd5c5c]
+\definecolor [saddlebrown] [h=8b4513]
+\definecolor [sienna] [h=a0522d]
+\definecolor [peru] [h=cd853f]
+\definecolor [burlywood] [h=deb887]
+\definecolor [beige] [h=f5f5dc]
+\definecolor [wheat] [h=f5deb3]
+\definecolor [sandybrown] [h=f4a460]
+\definecolor [tan] [h=d2b48c]
+\definecolor [chocolate] [h=d2691e]
+\definecolor [firebrick] [h=b22222]
+\definecolor [brown] [h=a52a2a]
+\definecolor [darksalmon] [h=e9967a]
+\definecolor [salmon] [h=fa8072]
+\definecolor [lightsalmon] [h=ffa07a]
+\definecolor [orange] [h=ffa500]
+\definecolor [darkorange] [h=ff8c00]
+\definecolor [coral] [h=ff7f50]
+\definecolor [lightcoral] [h=f08080]
+\definecolor [tomato] [h=ff6347]
+\definecolor [orangered] [h=ff4500]
+\definecolor [red] [h=ff0000]
+\definecolor [hotpink] [h=ff69b4]
+\definecolor [deeppink] [h=ff1493]
+\definecolor [pink] [h=ffc0cb]
+\definecolor [lightpink] [h=ffb6c1]
+\definecolor [palevioletred] [h=db7093]
+\definecolor [maroon] [h=b03060]
+\definecolor [mediumvioletred] [h=c71585]
+\definecolor [violetred] [h=d02090]
+\definecolor [magenta] [h=ff00ff]
+\definecolor [violet] [h=ee82ee]
+\definecolor [plum] [h=dda0dd]
+\definecolor [orchid] [h=da70d6]
+\definecolor [mediumorchid] [h=ba55d3]
+\definecolor [darkorchid] [h=9932cc]
+\definecolor [darkviolet] [h=9400d3]
+\definecolor [blueviolet] [h=8a2be2]
+\definecolor [purple] [h=a020f0]
+\definecolor [mediumpurple] [h=9370db]
+\definecolor [thistle] [h=d8bfd8]
+\definecolor [snow1] [h=fffafa]
+\definecolor [snow2] [h=eee9e9]
+\definecolor [snow3] [h=cdc9c9]
+\definecolor [snow4] [h=8b8989]
+\definecolor [seashell1] [h=fff5ee]
+\definecolor [seashell2] [h=eee5de]
+\definecolor [seashell3] [h=cdc5bf]
+\definecolor [seashell4] [h=8b8682]
+\definecolor [antiquewhite1] [h=ffefdb]
+\definecolor [antiquewhite2] [h=eedfcc]
+\definecolor [antiquewhite3] [h=cdc0b0]
+\definecolor [antiquewhite4] [h=8b8378]
+\definecolor [bisque1] [h=ffe4c4]
+\definecolor [bisque2] [h=eed5b7]
+\definecolor [bisque3] [h=cdb79e]
+\definecolor [bisque4] [h=8b7d6b]
+\definecolor [peachpuff1] [h=ffdab9]
+\definecolor [peachpuff2] [h=eecbad]
+\definecolor [peachpuff3] [h=cdaf95]
+\definecolor [peachpuff4] [h=8b7765]
+\definecolor [navajowhite1] [h=ffdead]
+\definecolor [navajowhite2] [h=eecfa1]
+\definecolor [navajowhite3] [h=cdb38b]
+\definecolor [navajowhite4] [h=8b795e]
+\definecolor [lemonchiffon1] [h=fffacd]
+\definecolor [lemonchiffon2] [h=eee9bf]
+\definecolor [lemonchiffon3] [h=cdc9a5]
+\definecolor [lemonchiffon4] [h=8b8970]
+\definecolor [cornsilk1] [h=fff8dc]
+\definecolor [cornsilk2] [h=eee8cd]
+\definecolor [cornsilk3] [h=cdc8b1]
+\definecolor [cornsilk4] [h=8b8878]
+\definecolor [ivory1] [h=fffff0]
+\definecolor [ivory2] [h=eeeee0]
+\definecolor [ivory3] [h=cdcdc1]
+\definecolor [ivory4] [h=8b8b83]
+\definecolor [honeydew1] [h=f0fff0]
+\definecolor [honeydew2] [h=e0eee0]
+\definecolor [honeydew3] [h=c1cdc1]
+\definecolor [honeydew4] [h=838b83]
+\definecolor [lavenderblush1] [h=fff0f5]
+\definecolor [lavenderblush2] [h=eee0e5]
+\definecolor [lavenderblush3] [h=cdc1c5]
+\definecolor [lavenderblush4] [h=8b8386]
+\definecolor [mistyrose1] [h=ffe4e1]
+\definecolor [mistyrose2] [h=eed5d2]
+\definecolor [mistyrose3] [h=cdb7b5]
+\definecolor [mistyrose4] [h=8b7d7b]
+\definecolor [azure1] [h=f0ffff]
+\definecolor [azure2] [h=e0eeee]
+\definecolor [azure3] [h=c1cdcd]
+\definecolor [azure4] [h=838b8b]
+\definecolor [slateblue1] [h=836fff]
+\definecolor [slateblue2] [h=7a67ee]
+\definecolor [slateblue3] [h=6959cd]
+\definecolor [slateblue4] [h=473c8b]
+\definecolor [royalblue1] [h=4876ff]
+\definecolor [royalblue2] [h=436eee]
+\definecolor [royalblue3] [h=3a5fcd]
+\definecolor [royalblue4] [h=27408b]
+\definecolor [blue1] [h=0000ff]
+\definecolor [blue2] [h=0000ee]
+\definecolor [blue3] [h=0000cd]
+\definecolor [blue4] [h=00008b]
+\definecolor [dodgerblue1] [h=1e90ff]
+\definecolor [dodgerblue2] [h=1c86ee]
+\definecolor [dodgerblue3] [h=1874cd]
+\definecolor [dodgerblue4] [h=104e8b]
+\definecolor [steelblue1] [h=63b8ff]
+\definecolor [steelblue2] [h=5cacee]
+\definecolor [steelblue3] [h=4f94cd]
+\definecolor [steelblue4] [h=36648b]
+\definecolor [deepskyblue1] [h=00bfff]
+\definecolor [deepskyblue2] [h=00b2ee]
+\definecolor [deepskyblue3] [h=009acd]
+\definecolor [deepskyblue4] [h=00688b]
+\definecolor [skyblue1] [h=87ceff]
+\definecolor [skyblue2] [h=7ec0ee]
+\definecolor [skyblue3] [h=6ca6cd]
+\definecolor [skyblue4] [h=4a708b]
+\definecolor [lightskyblue1] [h=b0e2ff]
+\definecolor [lightskyblue2] [h=a4d3ee]
+\definecolor [lightskyblue3] [h=8db6cd]
+\definecolor [lightskyblue4] [h=607b8b]
+\definecolor [slategray1] [h=c6e2ff]
+\definecolor [slategray2] [h=b9d3ee]
+\definecolor [slategray3] [h=9fb6cd]
+\definecolor [slategray4] [h=6c7b8b]
+\definecolor [lightsteelblue1] [h=cae1ff]
+\definecolor [lightsteelblue2] [h=bcd2ee]
+\definecolor [lightsteelblue3] [h=a2b5cd]
+\definecolor [lightsteelblue4] [h=6e7b8b]
+\definecolor [lightblue1] [h=bfefff]
+\definecolor [lightblue2] [h=b2dfee]
+\definecolor [lightblue3] [h=9ac0cd]
+\definecolor [lightblue4] [h=68838b]
+\definecolor [lightcyan1] [h=e0ffff]
+\definecolor [lightcyan2] [h=d1eeee]
+\definecolor [lightcyan3] [h=b4cdcd]
+\definecolor [lightcyan4] [h=7a8b8b]
+\definecolor [paleturquoise1] [h=bbffff]
+\definecolor [paleturquoise2] [h=aeeeee]
+\definecolor [paleturquoise3] [h=96cdcd]
+\definecolor [paleturquoise4] [h=668b8b]
+\definecolor [cadetblue1] [h=98f5ff]
+\definecolor [cadetblue2] [h=8ee5ee]
+\definecolor [cadetblue3] [h=7ac5cd]
+\definecolor [cadetblue4] [h=53868b]
+\definecolor [turquoise1] [h=00f5ff]
+\definecolor [turquoise2] [h=00e5ee]
+\definecolor [turquoise3] [h=00c5cd]
+\definecolor [turquoise4] [h=00868b]
+\definecolor [cyan1] [h=00ffff]
+\definecolor [cyan2] [h=00eeee]
+\definecolor [cyan3] [h=00cdcd]
+\definecolor [cyan4] [h=008b8b]
+\definecolor [darkslategray1] [h=97ffff]
+\definecolor [darkslategray2] [h=8deeee]
+\definecolor [darkslategray3] [h=79cdcd]
+\definecolor [darkslategray4] [h=528b8b]
+\definecolor [aquamarine1] [h=7fffd4]
+\definecolor [aquamarine2] [h=76eec6]
+\definecolor [aquamarine3] [h=66cdaa]
+\definecolor [aquamarine4] [h=458b74]
+\definecolor [darkseagreen1] [h=c1ffc1]
+\definecolor [darkseagreen2] [h=b4eeb4]
+\definecolor [darkseagreen3] [h=9bcd9b]
+\definecolor [darkseagreen4] [h=698b69]
+\definecolor [seagreen1] [h=54ff9f]
+\definecolor [seagreen2] [h=4eee94]
+\definecolor [seagreen3] [h=43cd80]
+\definecolor [seagreen4] [h=2e8b57]
+\definecolor [palegreen1] [h=9aff9a]
+\definecolor [palegreen2] [h=90ee90]
+\definecolor [palegreen3] [h=7ccd7c]
+\definecolor [palegreen4] [h=548b54]
+\definecolor [springgreen1] [h=00ff7f]
+\definecolor [springgreen2] [h=00ee76]
+\definecolor [springgreen3] [h=00cd66]
+\definecolor [springgreen4] [h=008b45]
+\definecolor [green1] [h=00ff00]
+\definecolor [green2] [h=00ee00]
+\definecolor [green3] [h=00cd00]
+\definecolor [green4] [h=008b00]
+\definecolor [chartreuse1] [h=7fff00]
+\definecolor [chartreuse2] [h=76ee00]
+\definecolor [chartreuse3] [h=66cd00]
+\definecolor [chartreuse4] [h=458b00]
+\definecolor [olivedrab1] [h=c0ff3e]
+\definecolor [olivedrab2] [h=b3ee3a]
+\definecolor [olivedrab3] [h=9acd32]
+\definecolor [olivedrab4] [h=698b22]
+\definecolor [darkolivegreen1] [h=caff70]
+\definecolor [darkolivegreen2] [h=bcee68]
+\definecolor [darkolivegreen3] [h=a2cd5a]
+\definecolor [darkolivegreen4] [h=6e8b3d]
+\definecolor [khaki1] [h=fff68f]
+\definecolor [khaki2] [h=eee685]
+\definecolor [khaki3] [h=cdc673]
+\definecolor [khaki4] [h=8b864e]
+\definecolor [lightgoldenrod1] [h=ffec8b]
+\definecolor [lightgoldenrod2] [h=eedc82]
+\definecolor [lightgoldenrod3] [h=cdbe70]
+\definecolor [lightgoldenrod4] [h=8b814c]
+\definecolor [lightyellow1] [h=ffffe0]
+\definecolor [lightyellow2] [h=eeeed1]
+\definecolor [lightyellow3] [h=cdcdb4]
+\definecolor [lightyellow4] [h=8b8b7a]
+\definecolor [yellow1] [h=ffff00]
+\definecolor [yellow2] [h=eeee00]
+\definecolor [yellow3] [h=cdcd00]
+\definecolor [yellow4] [h=8b8b00]
+\definecolor [gold1] [h=ffd700]
+\definecolor [gold2] [h=eec900]
+\definecolor [gold3] [h=cdad00]
+\definecolor [gold4] [h=8b7500]
+\definecolor [goldenrod1] [h=ffc125]
+\definecolor [goldenrod2] [h=eeb422]
+\definecolor [goldenrod3] [h=cd9b1d]
+\definecolor [goldenrod4] [h=8b6914]
+\definecolor [darkgoldenrod1] [h=ffb90f]
+\definecolor [darkgoldenrod2] [h=eead0e]
+\definecolor [darkgoldenrod3] [h=cd950c]
+\definecolor [darkgoldenrod4] [h=8b6508]
+\definecolor [rosybrown1] [h=ffc1c1]
+\definecolor [rosybrown2] [h=eeb4b4]
+\definecolor [rosybrown3] [h=cd9b9b]
+\definecolor [rosybrown4] [h=8b6969]
+\definecolor [indianred1] [h=ff6a6a]
+\definecolor [indianred2] [h=ee6363]
+\definecolor [indianred3] [h=cd5555]
+\definecolor [indianred4] [h=8b3a3a]
+\definecolor [sienna1] [h=ff8247]
+\definecolor [sienna2] [h=ee7942]
+\definecolor [sienna3] [h=cd6839]
+\definecolor [sienna4] [h=8b4726]
+\definecolor [burlywood1] [h=ffd39b]
+\definecolor [burlywood2] [h=eec591]
+\definecolor [burlywood3] [h=cdaa7d]
+\definecolor [burlywood4] [h=8b7355]
+\definecolor [wheat1] [h=ffe7ba]
+\definecolor [wheat2] [h=eed8ae]
+\definecolor [wheat3] [h=cdba96]
+\definecolor [wheat4] [h=8b7e66]
+\definecolor [tan1] [h=ffa54f]
+\definecolor [tan2] [h=ee9a49]
+\definecolor [tan3] [h=cd853f]
+\definecolor [tan4] [h=8b5a2b]
+\definecolor [chocolate1] [h=ff7f24]
+\definecolor [chocolate2] [h=ee7621]
+\definecolor [chocolate3] [h=cd661d]
+\definecolor [chocolate4] [h=8b4513]
+\definecolor [firebrick1] [h=ff3030]
+\definecolor [firebrick2] [h=ee2c2c]
+\definecolor [firebrick3] [h=cd2626]
+\definecolor [firebrick4] [h=8b1a1a]
+\definecolor [brown1] [h=ff4040]
+\definecolor [brown2] [h=ee3b3b]
+\definecolor [brown3] [h=cd3333]
+\definecolor [brown4] [h=8b2323]
+\definecolor [salmon1] [h=ff8c69]
+\definecolor [salmon2] [h=ee8262]
+\definecolor [salmon3] [h=cd7054]
+\definecolor [salmon4] [h=8b4c39]
+\definecolor [lightsalmon1] [h=ffa07a]
+\definecolor [lightsalmon2] [h=ee9572]
+\definecolor [lightsalmon3] [h=cd8162]
+\definecolor [lightsalmon4] [h=8b5742]
+\definecolor [orange1] [h=ffa500]
+\definecolor [orange2] [h=ee9a00]
+\definecolor [orange3] [h=cd8500]
+\definecolor [orange4] [h=8b5a00]
+\definecolor [darkorange1] [h=ff7f00]
+\definecolor [darkorange2] [h=ee7600]
+\definecolor [darkorange3] [h=cd6600]
+\definecolor [darkorange4] [h=8b4500]
+\definecolor [coral1] [h=ff7256]
+\definecolor [coral2] [h=ee6a50]
+\definecolor [coral3] [h=cd5b45]
+\definecolor [coral4] [h=8b3e2f]
+\definecolor [tomato1] [h=ff6347]
+\definecolor [tomato2] [h=ee5c42]
+\definecolor [tomato3] [h=cd4f39]
+\definecolor [tomato4] [h=8b3626]
+\definecolor [orangered1] [h=ff4500]
+\definecolor [orangered2] [h=ee4000]
+\definecolor [orangered3] [h=cd3700]
+\definecolor [orangered4] [h=8b2500]
+\definecolor [red1] [h=ff0000]
+\definecolor [red2] [h=ee0000]
+\definecolor [red3] [h=cd0000]
+\definecolor [red4] [h=8b0000]
+\definecolor [debianred] [h=d70751]
+\definecolor [deeppink1] [h=ff1493]
+\definecolor [deeppink2] [h=ee1289]
+\definecolor [deeppink3] [h=cd1076]
+\definecolor [deeppink4] [h=8b0a50]
+\definecolor [hotpink1] [h=ff6eb4]
+\definecolor [hotpink2] [h=ee6aa7]
+\definecolor [hotpink3] [h=cd6090]
+\definecolor [hotpink4] [h=8b3a62]
+\definecolor [pink1] [h=ffb5c5]
+\definecolor [pink2] [h=eea9b8]
+\definecolor [pink3] [h=cd919e]
+\definecolor [pink4] [h=8b636c]
+\definecolor [lightpink1] [h=ffaeb9]
+\definecolor [lightpink2] [h=eea2ad]
+\definecolor [lightpink3] [h=cd8c95]
+\definecolor [lightpink4] [h=8b5f65]
+\definecolor [palevioletred1] [h=ff82ab]
+\definecolor [palevioletred2] [h=ee799f]
+\definecolor [palevioletred3] [h=cd6889]
+\definecolor [palevioletred4] [h=8b475d]
+\definecolor [maroon1] [h=ff34b3]
+\definecolor [maroon2] [h=ee30a7]
+\definecolor [maroon3] [h=cd2990]
+\definecolor [maroon4] [h=8b1c62]
+\definecolor [violetred1] [h=ff3e96]
+\definecolor [violetred2] [h=ee3a8c]
+\definecolor [violetred3] [h=cd3278]
+\definecolor [violetred4] [h=8b2252]
+\definecolor [magenta1] [h=ff00ff]
+\definecolor [magenta2] [h=ee00ee]
+\definecolor [magenta3] [h=cd00cd]
+\definecolor [magenta4] [h=8b008b]
+\definecolor [orchid1] [h=ff83fa]
+\definecolor [orchid2] [h=ee7ae9]
+\definecolor [orchid3] [h=cd69c9]
+\definecolor [orchid4] [h=8b4789]
+\definecolor [plum1] [h=ffbbff]
+\definecolor [plum2] [h=eeaeee]
+\definecolor [plum3] [h=cd96cd]
+\definecolor [plum4] [h=8b668b]
+\definecolor [mediumorchid1] [h=e066ff]
+\definecolor [mediumorchid2] [h=d15fee]
+\definecolor [mediumorchid3] [h=b452cd]
+\definecolor [mediumorchid4] [h=7a378b]
+\definecolor [darkorchid1] [h=bf3eff]
+\definecolor [darkorchid2] [h=b23aee]
+\definecolor [darkorchid3] [h=9a32cd]
+\definecolor [darkorchid4] [h=68228b]
+\definecolor [purple1] [h=9b30ff]
+\definecolor [purple2] [h=912cee]
+\definecolor [purple3] [h=7d26cd]
+\definecolor [purple4] [h=551a8b]
+\definecolor [mediumpurple1] [h=ab82ff]
+\definecolor [mediumpurple2] [h=9f79ee]
+\definecolor [mediumpurple3] [h=8968cd]
+\definecolor [mediumpurple4] [h=5d478b]
+\definecolor [thistle1] [h=ffe1ff]
+\definecolor [thistle2] [h=eed2ee]
+\definecolor [thistle3] [h=cdb5cd]
+\definecolor [thistle4] [h=8b7b8b]
+\definecolor [gray0] [s=0.00]
+\definecolor [grey0] [gray0]
+\definecolor [gray1] [s=0.01]
+\definecolor [grey1] [gray1]
+\definecolor [gray2] [s=0.02]
+\definecolor [grey2] [gray2]
+\definecolor [gray3] [s=0.03]
+\definecolor [grey3] [gray3]
+\definecolor [gray4] [s=0.04]
+\definecolor [grey4] [gray4]
+\definecolor [gray5] [s=0.05]
+\definecolor [grey5] [gray5]
+\definecolor [gray6] [s=0.06]
+\definecolor [grey6] [gray6]
+\definecolor [gray7] [s=0.07]
+\definecolor [grey7] [gray7]
+\definecolor [gray8] [s=0.08]
+\definecolor [grey8] [gray8]
+\definecolor [gray9] [s=0.09]
+\definecolor [grey9] [gray9]
+\definecolor [gray10] [s=0.10]
+\definecolor [grey10] [gray10]
+\definecolor [gray11] [s=0.11]
+\definecolor [grey11] [gray11]
+\definecolor [gray12] [s=0.12]
+\definecolor [grey12] [gray12]
+\definecolor [gray13] [s=0.13]
+\definecolor [grey13] [gray13]
+\definecolor [gray14] [s=0.14]
+\definecolor [grey14] [gray14]
+\definecolor [gray15] [s=0.15]
+\definecolor [grey15] [gray15]
+\definecolor [gray16] [s=0.16]
+\definecolor [grey16] [gray16]
+\definecolor [gray17] [s=0.17]
+\definecolor [grey17] [gray17]
+\definecolor [gray18] [s=0.18]
+\definecolor [grey18] [gray18]
+\definecolor [gray19] [s=0.19]
+\definecolor [grey19] [gray19]
+\definecolor [gray20] [s=0.20]
+\definecolor [grey20] [gray20]
+\definecolor [gray21] [s=0.21]
+\definecolor [grey21] [gray21]
+\definecolor [gray22] [s=0.22]
+\definecolor [grey22] [gray22]
+\definecolor [gray23] [s=0.23]
+\definecolor [grey23] [gray23]
+\definecolor [gray24] [s=0.24]
+\definecolor [grey24] [gray24]
+\definecolor [gray25] [s=0.25]
+\definecolor [grey25] [gray25]
+\definecolor [gray26] [s=0.26]
+\definecolor [grey26] [gray26]
+\definecolor [gray27] [s=0.27]
+\definecolor [grey27] [gray27]
+\definecolor [gray28] [s=0.28]
+\definecolor [grey28] [gray28]
+\definecolor [gray29] [s=0.29]
+\definecolor [grey29] [gray29]
+\definecolor [gray30] [s=0.30]
+\definecolor [grey30] [gray30]
+\definecolor [gray31] [s=0.31]
+\definecolor [grey31] [gray31]
+\definecolor [gray32] [s=0.32]
+\definecolor [grey32] [gray32]
+\definecolor [gray33] [s=0.33]
+\definecolor [grey33] [gray33]
+\definecolor [gray34] [s=0.34]
+\definecolor [grey34] [gray34]
+\definecolor [gray35] [s=0.35]
+\definecolor [grey35] [gray35]
+\definecolor [gray36] [s=0.36]
+\definecolor [grey36] [gray36]
+\definecolor [gray37] [s=0.37]
+\definecolor [grey37] [gray37]
+\definecolor [gray38] [s=0.38]
+\definecolor [grey38] [gray38]
+\definecolor [gray39] [s=0.39]
+\definecolor [grey39] [gray39]
+\definecolor [gray40] [s=0.40]
+\definecolor [grey40] [gray40]
+\definecolor [gray41] [s=0.41]
+\definecolor [grey41] [gray41]
+\definecolor [gray42] [s=0.42]
+\definecolor [grey42] [gray42]
+\definecolor [gray43] [s=0.43]
+\definecolor [grey43] [gray43]
+\definecolor [gray44] [s=0.44]
+\definecolor [grey44] [gray44]
+\definecolor [gray45] [s=0.45]
+\definecolor [grey45] [gray45]
+\definecolor [gray46] [s=0.46]
+\definecolor [grey46] [gray46]
+\definecolor [gray47] [s=0.47]
+\definecolor [grey47] [gray47]
+\definecolor [gray48] [s=0.48]
+\definecolor [grey48] [gray48]
+\definecolor [gray49] [s=0.49]
+\definecolor [grey49] [gray49]
+\definecolor [gray50] [s=0.50]
+\definecolor [grey50] [gray50]
+\definecolor [gray51] [s=0.51]
+\definecolor [grey51] [gray51]
+\definecolor [gray52] [s=0.52]
+\definecolor [grey52] [gray52]
+\definecolor [gray53] [s=0.53]
+\definecolor [grey53] [gray53]
+\definecolor [gray54] [s=0.54]
+\definecolor [grey54] [gray54]
+\definecolor [gray55] [s=0.55]
+\definecolor [grey55] [gray55]
+\definecolor [gray56] [s=0.56]
+\definecolor [grey56] [gray56]
+\definecolor [gray57] [s=0.57]
+\definecolor [grey57] [gray57]
+\definecolor [gray58] [s=0.58]
+\definecolor [grey58] [gray58]
+\definecolor [gray59] [s=0.59]
+\definecolor [grey59] [gray59]
+\definecolor [gray60] [s=0.60]
+\definecolor [grey60] [gray60]
+\definecolor [gray61] [s=0.61]
+\definecolor [grey61] [gray61]
+\definecolor [gray62] [s=0.62]
+\definecolor [grey62] [gray62]
+\definecolor [gray63] [s=0.63]
+\definecolor [grey63] [gray63]
+\definecolor [gray64] [s=0.64]
+\definecolor [grey64] [gray64]
+\definecolor [gray65] [s=0.65]
+\definecolor [grey65] [gray65]
+\definecolor [gray66] [s=0.66]
+\definecolor [grey66] [gray66]
+\definecolor [gray67] [s=0.67]
+\definecolor [grey67] [gray67]
+\definecolor [gray68] [s=0.68]
+\definecolor [grey68] [gray68]
+\definecolor [gray69] [s=0.69]
+\definecolor [grey69] [gray69]
+\definecolor [gray70] [s=0.70]
+\definecolor [grey70] [gray70]
+\definecolor [gray71] [s=0.71]
+\definecolor [grey71] [gray71]
+\definecolor [gray72] [s=0.72]
+\definecolor [grey72] [gray72]
+\definecolor [gray73] [s=0.73]
+\definecolor [grey73] [gray73]
+\definecolor [gray74] [s=0.74]
+\definecolor [grey74] [gray74]
+\definecolor [gray75] [s=0.75]
+\definecolor [grey75] [gray75]
+\definecolor [gray76] [s=0.76]
+\definecolor [grey76] [gray76]
+\definecolor [gray77] [s=0.77]
+\definecolor [grey77] [gray77]
+\definecolor [gray78] [s=0.78]
+\definecolor [grey78] [gray78]
+\definecolor [gray79] [s=0.79]
+\definecolor [grey79] [gray79]
+\definecolor [gray80] [s=0.80]
+\definecolor [grey80] [gray80]
+\definecolor [gray81] [s=0.81]
+\definecolor [grey81] [gray81]
+\definecolor [gray82] [s=0.82]
+\definecolor [grey82] [gray82]
+\definecolor [gray83] [s=0.83]
+\definecolor [grey83] [gray83]
+\definecolor [gray84] [s=0.84]
+\definecolor [grey84] [gray84]
+\definecolor [gray85] [s=0.85]
+\definecolor [grey85] [gray85]
+\definecolor [gray86] [s=0.86]
+\definecolor [grey86] [gray86]
+\definecolor [gray87] [s=0.87]
+\definecolor [grey87] [gray87]
+\definecolor [gray88] [s=0.88]
+\definecolor [grey88] [gray88]
+\definecolor [gray89] [s=0.89]
+\definecolor [grey89] [gray89]
+\definecolor [gray90] [s=0.90]
+\definecolor [grey90] [gray90]
+\definecolor [gray91] [s=0.91]
+\definecolor [grey91] [gray91]
+\definecolor [gray92] [s=0.92]
+\definecolor [grey92] [gray92]
+\definecolor [gray93] [s=0.93]
+\definecolor [grey93] [gray93]
+\definecolor [gray94] [s=0.94]
+\definecolor [grey94] [gray94]
+\definecolor [gray95] [s=0.95]
+\definecolor [grey95] [gray95]
+\definecolor [gray96] [s=0.96]
+\definecolor [grey96] [gray96]
+\definecolor [gray97] [s=0.97]
+\definecolor [grey97] [gray97]
+\definecolor [gray98] [s=0.98]
+\definecolor [grey98] [gray98]
+\definecolor [gray99] [s=0.99]
+\definecolor [grey99] [gray99]
+\definecolor [gray100] [s=1.00]
+\definecolor [grey100] [gray100]
+\definecolor [darkgrey] [s=0.66]
+\definecolor [darkgray] [darkgrey]
+\definecolor [darkblue] [h=00008b]
+\definecolor [darkcyan] [h=008b8b]
+\definecolor [darkmagenta] [h=8b008b]
+\definecolor [darkred] [h=8b0000]
+\definecolor [lightgreen] [h=90ee90]
+
+\endinput
diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index 35b716ed4..93a1c17c2 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -25,6 +25,8 @@
%
% \setbreakpoints[compound]
+\ctxlua{logs.report=function(s,...) commands.writestatus("!"..s,...) end}
+
\unprotect
% % % % % % needs testing but saves runtime
diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex
index 1eecb06fe..b6b633877 100644
--- a/tex/context/base/cont-new.tex
+++ b/tex/context/base/cont-new.tex
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2009.11.13 12:45}
+\newcontextversion{2009.11.18 21:51}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/context.tex b/tex/context/base/context.tex
index 95b945f26..76233c43d 100644
--- a/tex/context/base/context.tex
+++ b/tex/context/base/context.tex
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2009.11.13 12:45}
+\edef\contextversion{2009.11.18 21:51}
%D For those who want to use this:
diff --git a/tex/context/base/core-def.mkiv b/tex/context/base/core-def.mkiv
index d3d24acd7..bc1b6b2bf 100644
--- a/tex/context/base/core-def.mkiv
+++ b/tex/context/base/core-def.mkiv
@@ -61,6 +61,8 @@
\appendtoks \the\everybackendshipout \to \everyshipout
\prependtoks \the\everylastbackendshipout \to \everylastshipout
+\prependtoks \lefttoright \to \everybeforeoutput
+
% temporary here:
\ifdefined\in \let\normalmathin \in \unexpanded\def\in {\mathortext\normalmathin \dospecialin } \else \let\in \dospecialin \fi
diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua
index 7181f5a17..9964af421 100644
--- a/tex/context/base/data-res.lua
+++ b/tex/context/base/data-res.lua
@@ -544,11 +544,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -613,13 +613,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -982,6 +986,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -1004,6 +1009,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -1011,6 +1022,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -1846,9 +1858,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
diff --git a/tex/context/base/data-tmp.lua b/tex/context/base/data-tmp.lua
index 802af6e4e..ba338b5a4 100644
--- a/tex/context/base/data-tmp.lua
+++ b/tex/context/base/data-tmp.lua
@@ -157,6 +157,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else
diff --git a/tex/context/base/font-afm.lua b/tex/context/base/font-afm.lua
index 72b36600c..2ba73be26 100644
--- a/tex/context/base/font-afm.lua
+++ b/tex/context/base/font-afm.lua
@@ -720,7 +720,8 @@ function tfm.read_from_afm(specification)
if filename then
tfmtable.encodingbytes = 2
tfmtable.filename = resolvers.findbinfile(filename,"") or filename
- tfmtable.fullname = afmdata.metadata.fontname or afmdata.metadata.fullname
+ tfmtable.fontname = afmdata.metadata.fontname or afmdata.metadata.fullname
+ tfmtable.fullname = afmdata.metadata.fullname or afmdata.metadata.fontname
tfmtable.format = 'type1'
tfmtable.name = afmdata.luatex.filename or tfmtable.fullname
end
diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua
index c18fbe0ff..3845ae5b9 100644
--- a/tex/context/base/font-ctx.lua
+++ b/tex/context/base/font-ctx.lua
@@ -405,9 +405,9 @@ local dimenfactors = number.dimenfactors
function fonts.dimenfactor(unit,tfmdata)
if unit == "ex" then
- return tfmdata.parameters.x_height
+ return (tfmdata and tfmdata.parameters.x_height) or 655360
elseif unit == "em" then
- return tfmdata.parameters.em_height
+ return (tfmdata and tfmdata.parameters.em_height) or 655360
else
return dimenfactors[unit] or unit
end
diff --git a/tex/context/base/font-dum.lua b/tex/context/base/font-dum.lua
index c585c18b5..d6fee5598 100644
--- a/tex/context/base/font-dum.lua
+++ b/tex/context/base/font-dum.lua
@@ -39,10 +39,15 @@ function fonts.logger.save()
end
-- names
+--
+-- Watch out, the version number is the same as the one used in
+-- the mtx-fonts.lua function scripts.fonts.names as we use a
+-- simplified font database in the plain solution and by using
+-- a different number we're less dependent on context.
fonts.names = fonts.names or { }
-fonts.names.version = 1.014
+fonts.names.version = 1.001 -- not the same as in context
fonts.names.basename = "luatex-fonts-names.lua"
fonts.names.new_to_old = { }
fonts.names.old_to_new = { }
@@ -57,16 +62,6 @@ function fonts.names.resolve(name,sub)
local foundname = resolvers.find_file(basename,format) or ""
if foundname ~= "" then
data = dofile(foundname)
- if data then
- local d = { }
- for k, v in pairs(data.mapping) do
- local t = v[1]
- if t == "ttf" or t == "otf" or t == "ttc" or t == "dfont" then
- d[k] = v
- end
- end
- data.mapping = d
- end
break
end
end
@@ -77,9 +72,12 @@ function fonts.names.resolve(name,sub)
local condensed = string.gsub(string.lower(name),"[^%a%d]","")
local found = data.mapping and data.mapping[condensed]
if found then
- local filename, is_sub = found[3], found[4]
- if is_sub then is_sub = found[2] end
- return filename, is_sub
+ local fontname, filename, subfont = found[1], found[2], found[3]
+ if subfont then
+ return filename, fontname
+ else
+ return filename, false
+ end
else
return name, false -- fallback to filename
end
diff --git a/tex/context/base/font-ini.mkiv b/tex/context/base/font-ini.mkiv
index 3ce821a39..e36485319 100644
--- a/tex/context/base/font-ini.mkiv
+++ b/tex/context/base/font-ini.mkiv
@@ -4010,6 +4010,28 @@
\def\showchardata#1{\ctxlua{fonts.show_char_data("#1")}}
\def\showfontdata {\ctxlua{fonts.show_font_parameters()}}
+%D some low level helpers
+%D
+%D \starttyping
+%D \def\TestLookup#1%
+%D {pattern: #1, found: \dolookupnoffound
+%D \blank
+%D \dolookupfontbyspec{#1}
+%D \dorecurse {\dolookupnoffound} {%
+%D \recurselevel:~\dolookupgetkeyofindex{fontname}{\recurselevel}\quad
+%D }%
+%D \blank}
+%D
+%D \TestLookup{familyname=helveticaneue}
+%D \TestLookup{familyname=helveticaneue,weight=bold}
+%D \TestLookup{familyname=helveticaneue,weight=bold,style=italic}
+%D \stoptyping
+
+\def\dolookupfontbyspec #1{\ctxlua{fonts.names.lookup("#1")}}
+\def\dolookupnoffound {\ctxlua{tex.write(fonts.names.noflookups())}}
+\def\dolookupgetkeyofindex#1#2{\ctxlua{tex.write(fonts.names.getlookupkey("#1",#2))}}
+\def\dolookupgetkey #1{\ctxlua{tex.write(fonts.names.getlookupkey("#1"))}}
+
\protect \endinput
% \startluacode
diff --git a/tex/context/base/font-mis.lua b/tex/context/base/font-mis.lua
index dc60cf2a2..40160e49d 100644
--- a/tex/context/base/font-mis.lua
+++ b/tex/context/base/font-mis.lua
@@ -35,7 +35,7 @@ end
function fonts.get_features(name,t,script,language)
local t = lower(t or (name and file.extname(name)) or "")
- if t == "otf" or t == "ttf" or t == "ttc" then
+ if t == "otf" or t == "ttf" or t == "ttc" or t == "dfont" then
local filename = resolvers.find_file(name,t) or ""
if filename ~= "" then
local data = fonts.otf.loadcached(filename)
diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua
index b5f7cb431..7929dfb02 100644
--- a/tex/context/base/font-otf.lua
+++ b/tex/context/base/font-otf.lua
@@ -1497,8 +1497,9 @@ function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder th
tfm.units = metadata.units_per_em or 1000
-- we need a runtime lookup because of running from cdrom or zip, brrr
tfm.filename = resolvers.findbinfile(luatex.filename,"") or luatex.filename
- tfm.fullname = metadata.fontname or metadata.fullname
- tfm.psname = tfm.fullname
+ tfm.fullname = metadata.fullname
+ tfm.fontname = metadata.fontname
+ tfm.psname = tfm.fontname or tfm.fullname
tfm.encodingbytes = 2
tfm.cidinfo = data.cidinfo
tfm.cidinfo.registry = tfm.cidinfo.registry or ""
@@ -1622,7 +1623,8 @@ function tfm.read_from_open_type(specification)
if filename then
tfmtable.encodingbytes = 2
tfmtable.filename = resolvers.findbinfile(filename,"") or filename
- tfmtable.fullname = tfmtable.fullname or otfdata.metadata.fontname or otfdata.metadata.fullname
+ tfmtable.fontname = tfmtable.fontname or otfdata.metadata.fontname
+ tfmtable.fullname = tfmtable.fullname or otfdata.metadata.fullname or tfmtable.fontname
local order = otfdata and otfdata.metadata.order2
if order == 0 then
tfmtable.format = 'opentype'
@@ -1631,7 +1633,7 @@ function tfm.read_from_open_type(specification)
else
tfmtable.format = specification.format
end
- tfmtable.name = tfmtable.filename or tfmtable.fullname
+ tfmtable.name = tfmtable.filename or tfmtable.fullname or tfmtable.fontname
end
fonts.logger.save(tfmtable,file.extname(specification.filename),specification)
end
diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua
index 77d67d4b5..fb04b367e 100644
--- a/tex/context/base/font-otn.lua
+++ b/tex/context/base/font-otn.lua
@@ -117,7 +117,7 @@ results in different tables.</p>
-- remark: the 'not implemented yet' variants will be done when we have fonts that use them
-- remark: we need to check what to do with discretionaries
-local concat = table.concat
+local concat, insert, remove = table.concat, table.insert, table.remove
local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip
local type, next, tonumber, tostring = type, next, tonumber, tostring
@@ -139,6 +139,7 @@ local trace_details = false trackers.register("otf.details", function
local trace_applied = false trackers.register("otf.applied", function(v) trace_applied = v end)
local trace_steps = false trackers.register("otf.steps", function(v) trace_steps = v end)
local trace_skips = false trackers.register("otf.skips", function(v) trace_skips = v end)
+local trace_directions = false trackers.register("otf.directions", function(v) trace_directions = v end)
trackers.register("otf.verbose_chain", function(v) otf.setcontextchain(v and "verbose") end)
trackers.register("otf.normal_chain", function(v) otf.setcontextchain(v and "normal") end)
@@ -743,7 +744,7 @@ function handlers.gpos_cursive(start,kind,lookupname,exitanchors,sequence) -- to
if exit then
local dx, dy, bound = set_cursive(start,nxt,tfmdata.factor,rlmode,exit,entry,characters[startchar],characters[nextchar])
if trace_cursive then
- logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound)
+ logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode)
end
done = true
break
@@ -1395,7 +1396,7 @@ function chainprocs.gpos_cursive(start,stop,kind,chainname,currentcontext,cache,
if exit then
local dx, dy, bound = set_cursive(start,nxt,tfmdata.factor,rlmode,exit,entry,characters[startchar],characters[nextchar])
if trace_cursive then
- logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound)
+ logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode)
end
done = true
break
@@ -1832,6 +1833,9 @@ local resolved = { } -- we only resolve a font,script,language pair once
-- todo: pass all these 'locals' in a table
+-- maybe some day i'll make an alternative that works on 'sub direction runs' which might be
+-- more efficient for arabic but it has quite some consequences
+
function fonts.methods.node.otf.features(head,font,attr)
if trace_steps then
checkstep(head)
@@ -1875,6 +1879,7 @@ function fonts.methods.node.otf.features(head,font,attr)
local ra = rl [attr] if ra == nil then ra = { } rl [attr] = ra end -- attr can be false
-- sequences always > 1 so no need for optimization
for s=1,#sequences do
+ local pardir, txtdir = 0, { }
local success = false
local sequence = sequences[s]
local r = ra[s] -- cache
@@ -1974,7 +1979,7 @@ function fonts.methods.node.otf.features(head,font,attr)
local ns = #subtables
local thecache = featuredata[typ] or { }
start = head -- local ?
- rlmode = 0
+ rlmode = 0 -- to be checked ?
if ns == 1 then
local lookupname = subtables[1]
local lookupcache = thecache[lookupname]
@@ -2016,24 +2021,57 @@ function fonts.methods.node.otf.features(head,font,attr)
-- start = start.next
-- end
elseif id == whatsit then
+--~ if subtype == 7 then
+--~ local dir = start.dir
+--~ if dir == "+TRT" then
+--~ rlmode = -1
+--~ elseif dir == "+TLT" then
+--~ rlmode = 1
+--~ else
+--~ rlmode = 0
+--~ end
+--~ elseif subtype == 6 then
+--~ local dir = start.dir
+--~ if dir == "TRT" then
+--~ rlmode = -1
+--~ elseif dir == "TLT" then
+--~ rlmode = 1
+--~ else
+--~ rlmode = 0
+--~ end
+--~ end
local subtype = start.subtype
if subtype == 7 then
local dir = start.dir
- if dir == "+TRT" then
+ if dir == "+TRT" or dir == "+TLT" then
+ insert(txtdir,dir)
+ elseif dir == "-TRT" or dir == "-TLT" then
+ remove(txtdir)
+ end
+ local d = txtdir[#txtdir]
+ if d == "+TRT" then
rlmode = -1
- elseif dir == "+TLT" then
+ elseif d == "+TLT" then
rlmode = 1
else
- rlmode = 0
+ rlmode = pardir
+ end
+ if trace_directions then
+ logs.report("fonts","directions after textdir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode)
end
elseif subtype == 6 then
local dir = start.dir
if dir == "TRT" then
- rlmode = -1
+ pardir = -1
elseif dir == "TLT" then
- rlmode = 1
+ pardir = 1
else
- rlmode = 0
+ pardir = 0
+ end
+ rlmode = pardir
+ --~ txtdir = { }
+ if trace_directions then
+ logs.report("fonts","directions after pardir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode)
end
end
start = start.next
@@ -2041,7 +2079,6 @@ function fonts.methods.node.otf.features(head,font,attr)
start = start.next
end
end
-
end
else
while start do
@@ -2088,25 +2125,59 @@ function fonts.methods.node.otf.features(head,font,attr)
-- end
elseif id == whatsit then
local subtype = start.subtype
- if subtype == 7 then
- local dir = start.dir
- if dir == "+TRT" then
- rlmode = -1
- elseif dir == "+TLT" then
- rlmode = 1
- else
- rlmode = 0
+--~ if subtype == 7 then
+--~ local dir = start.dir
+--~ if dir == "+TRT" then
+--~ rlmode = -1
+--~ elseif dir == "+TLT" then
+--~ rlmode = 1
+--~ else
+--~ rlmode = 0
+--~ end
+--~ elseif subtype == 6 then
+--~ local dir = start.dir
+--~ if dir == "TRT" then
+--~ rlmode = -1
+--~ elseif dir == "TLT" then
+--~ rlmode = 1
+--~ else
+--~ rlmode = 0
+--~ end
+--~ end
+ local subtype = start.subtype
+ if subtype == 7 then
+ local dir = start.dir
+ if dir == "+TRT" or dir == "+TLT" then
+ insert(txtdir,dir)
+ elseif dir == "-TRT" or dir == "-TLT" then
+ remove(txtdir)
+ end
+ local d = txtdir[#txtdir]
+ if d == "+TRT" then
+ rlmode = -1
+ elseif d == "+TLT" then
+ rlmode = 1
+ else
+ rlmode = pardir
+ end
+ if trace_directions then
+ logs.report("fonts","directions after textdir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode)
+ end
+ elseif subtype == 6 then
+ local dir = start.dir
+ if dir == "TRT" then
+ pardir = -1
+ elseif dir == "TLT" then
+ pardir = 1
+ else
+ pardir = 0
+ end
+ rlmode = pardir
+ --~ txtdir = { }
+ if trace_directions then
+ logs.report("fonts","directions after pardir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode)
end
- elseif subtype == 6 then
- local dir = start.dir
- if dir == "TRT" then
- rlmode = -1
- elseif dir == "TLT" then
- rlmode = 1
- else
- rlmode = 0
end
- end
start = start.next
else
start = start.next
diff --git a/tex/context/base/font-pat.lua b/tex/context/base/font-pat.lua
index f2b86a48a..96b5fe870 100644
--- a/tex/context/base/font-pat.lua
+++ b/tex/context/base/font-pat.lua
@@ -95,17 +95,18 @@ end
patches["palatino.*arabic"] = patch
-local function patch(data,filename)
+local function patch_domh(data,filename,threshold)
local m = data.math
if m then
local d = m.DisplayOperatorMinHeight or 0
- if d < 2800 then
+ if d < threshold then
if trace_loading then
- logs.report("load otf","patching DisplayOperatorMinHeight(%s -> 2800)",d)
+ logs.report("load otf","patching DisplayOperatorMinHeight(%s -> %s)",d,threshold)
end
- m.DisplayOperatorMinHeight = 2800
+ m.DisplayOperatorMinHeight = threshold
end
end
end
-patches["cambria"] = patch
+patches["cambria"] = function(data,filename) patch_domh(data,filename,2800) end
+patches["asana"] = function(data,filename) patch_domh(data,filename,1350) end
diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua
index f184fe2e5..0b74cc73c 100644
--- a/tex/context/base/font-syn.lua
+++ b/tex/context/base/font-syn.lua
@@ -6,8 +6,11 @@ if not modules then modules = { } end modules ['font-syn'] = {
license = "see context related readme files"
}
-local next = next
+-- todo: subs in lookups requests
+
+local next, tonumber = next, tonumber
local gsub, lower, match, find, lower, upper = string.gsub, string.lower, string.match, string.find, string.lower, string.upper
+local find, gmatch = string.find, string.gmatch
local concat, sort, format = table.concat, table.sort, string.format
local trace_names = false trackers.register("fonts.names", function(v) trace_names = v end)
@@ -30,7 +33,7 @@ fonts.names.data = fonts.names.data or { }
local names = fonts.names
local filters = fonts.names.filters
-names.version = 1.014 -- when adapting this, also changed font-dum.lua
+names.version = 1.100
names.basename = "names"
names.saved = false
names.loaded = false
@@ -40,6 +43,91 @@ names.autoreload = toboolean(os.env['MTX.FONTS.AUTOLOAD'] or os.env['MTX_FONTS_A
names.cache = containers.define("fonts","data",names.version,true)
--[[ldx--
+<p>A few helpers.</p>
+--ldx]]--
+
+local P, C, Cc, Cs, Carg = lpeg.P, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Carg
+
+local weights = Cs ( -- not extra
+ P("demibold")
+ + P("semibold")
+ + P("mediumbold")
+ + P("ultrabold")
+ + P("extrabold")
+ + P("ultralight")
+ + P("bold")
+ + P("demi")
+ + P("semi")
+ + P("light")
+ + P("medium")
+ + P("heavy")
+ + P("ultra")
+ + P("black")
+ + P("bol")
+ + P("regular") / "normal"
+)
+
+local styles = Cs (
+ P("reverseoblique") / "reverseitalic"
+ + P("regular") / "normal"
+ + P("italic")
+ + P("oblique") / "italic"
+ + P("slanted")
+ + P("roman") / "normal"
+ + P("ital") / "italic"
+ + P("ita") / "italic"
+)
+
+local widths = Cs(
+ P("condensed")
+ + P("thin")
+ + P("expanded")
+ + P("cond") / "condensed"
+ + P("normal")
+ + P("book") / "normal"
+)
+
+local any = P(1)
+
+local analysed_table
+
+local analyser = Cs (
+ (
+ weights / function(s) analysed_table[1] = s return "" end
+ + styles / function(s) analysed_table[2] = s return "" end
+ + widths / function(s) analysed_table[3] = s return "" end
+ + any
+ )^0
+)
+
+local splitter = lpeg.splitat("-")
+
+function names.splitspec(askedname)
+ local name, weight, style, width = splitter:match(askedname)
+ weight = weight and weights:match(weight) or weight
+ style = style and styles :match(style) or style
+ width = width and widths :match(width) or width
+ if trace_names then
+ logs.report("fonts","requested name '%s' split in name '%s', weight '%s', style '%s' and width '%s'",askedname,name or '',weight or '',style or '',width or '')
+ end
+ if not weight or not weight or not width then
+ weight, style, width = weight or "normal", style or "normal", width or "normal"
+ if trace_names then
+ logs.report("fonts","request '%s' normalized to '%s-%s-%s-%s'",askedname,name,weight,style,width)
+ end
+ end
+ return name or askedname, weight, style, width
+end
+
+local function analysespec(somename)
+ if somename then
+ analysed_table = { }
+ local name = analyser:match(somename)
+ return name, analysed_table[1], analysed_table[2],analysed_table[3]
+ end
+end
+
+--[[ldx--
<p>It would make sense to implement the filters in the related modules,
but to keep the overview, we define them here.</p>
--ldx]]--
@@ -104,16 +192,6 @@ filters.list = {
"otf", "ttf", "ttc", "dfont", "afm",
}
-filters.fixes = { -- can be lpeg
- { "bolita$", "bolditalic", },
- { "ital$", "italic", },
- { "cond$", "condensed", },
- { "book$", "", },
- { "reg$", "regular", },
- { "ita$", "italic", },
- { "bol$", "bold", },
-}
-
names.xml_configuration_file = "fonts.conf" -- a bit weird format, bonus feature
names.environment_path_variable = "OSFONTDIR" -- the official way, in minimals etc
@@ -149,7 +227,7 @@ function names.getpaths(trace)
end
end
if name ~= "" and lfs.isfile(name) then
- if trace then
+ if trace_names then
logs.report("fontnames","loading fontconfig file: %s",name)
end
local xmldata = xml.load(name)
@@ -162,17 +240,17 @@ function names.getpaths(trace)
end
end
if lfs.isfile(incname) then
- if trace then
+ if trace_names then
logs.report("fontnames","merging included fontconfig file: %s",incname)
end
return io.loaddata(incname)
- elseif trace then
+ elseif trace_names then
logs.report("fontnames","ignoring included fontconfig file: %s",incname)
end
end)
-- end of untested mess
local fontdirs = xml.collect_texts(xmldata,"dir",true)
- if trace then
+ if trace_names then
logs.report("fontnames","%s dirs found in fontconfig",#fontdirs)
end
collect(fontdirs)
@@ -185,77 +263,299 @@ function names.getpaths(trace)
return result
end
-function names.cleanname(name)
+local function cleanname(name)
return (gsub(lower(name),"[^%a%d]",""))
end
-function names.identify(verbose) -- lsr is for kpse
- names.data = {
- version = names.version,
- mapping = { },
- -- sorted = { },
- fallback_mapping = { },
- -- fallback_sorted = { },
+names.cleanname = cleanname
+
+local function check_names(result)
+ local names = result.names
+ if names then
+ for i=1,#names do
+ local name = names[i]
+ if name.lang == "English (US)" then
+ return name.names
+ end
+ end
+ end
+end
+
+local function walk_tree(pathlist,suffix,identify)
+ if pathlist then
+ for _, path in ipairs(pathlist) do
+ path = resolvers.clean_path(path .. "/")
+ path = gsub(path,"/+","/")
+ local pattern = path .. "**." .. suffix -- ** forces recurse
+ logs.report("fontnames", "globbing path %s",pattern)
+ local t = dir.glob(pattern)
+ for _, completename in pairs(t) do -- ipairs
+ identify(completename,file.basename(completename),suffix,completename)
+ end
+ end
+ end
+end
+
+local function check_name(data,result,filename,suffix,subfont)
+ -- shortcuts
+ local specifications = data.specifications
+ local families = data.families
+ -- prepare
+ local names = check_names(result)
+ -- fetch
+ local familyname = (names and names.preffamilyname) or result.familyname
+ local fullname = (names and names.fullname) or result.fullname
+ local fontname = result.fontname
+ local subfamily = (names and names.subfamily)
+ local modifiers = (names and names.prefmodifiers)
+ local weight = (names and names.weight) or result.weight
+ local italicangle = tonumber(result.italicangle)
+ local subfont = subfont or nil
+ local rawname = fullname or fontname or familyname
+ -- normalize
+ familyname = familyname and cleanname(familyname)
+ fullname = fullname and cleanname(fullname)
+ fontname = fontname and cleanname(fontname)
+ subfamily = subfamily and cleanname(subfamily)
+ modifiers = modifiers and cleanname(modifiers)
+ weight = weight and cleanname(weight)
+ italicangle = (italicangle == 0) and nil
+ -- analyse
+ local a_name, a_weight, a_style, a_width = analysespec(fullname or fontname or familyname)
+ -- check
+ local width = a_width
+ local style = modifiers and gsub(modifiers,"[^%a]","")
+ if not style and italicangle then
+ style = "italic"
+ end
+ if not weight or weight == "" then
+ weight = a_weight
+ end
+ if not style or style == "" then
+ style = a_style
+ end
+ if not familyname then
+ familyname = a_name
+ end
+ fontname = fontname or fullname or familyname or basename
+ fullname = fullname or fontname
+ familyname = familyname or fontname
+ -- register
+ local index = #specifications + 1
+ specifications[index] = {
+ filename = filename,
+ format = lower(suffix),
+ subfont = subfont,
+ rawname = rawname,
+ familyname = familyname,
+ fullname = fullname,
+ fontname = fontname,
+ subfamily = subfamily,
+ modifiers = modifiers,
+ weight = weight,
+ style = style,
+ width = width,
}
- local done, mapping, fallback_mapping, nofread, nofok = { }, names.data.mapping, names.data.fallback_mapping, 0, 0
- local cleanname = names.cleanname
- local function check(result, filename, suffix, is_sub) -- unlocal this one
- local fontname = result.fullname
- if fontname then
- local n = cleanname(result.fullname)
- if not mapping[n] then
- mapping[n], nofok = { lower(suffix), fontname, filename, is_sub }, nofok + 1
- end
- end
- if result.fontname then
- fontname = result.fontname or fontname
- local n = cleanname(result.fontname)
- if not mapping[n] then
- mapping[n], nofok = { lower(suffix), fontname, filename, is_sub }, nofok + 1
- end
- end
- if result.familyname and result.weight and result.italicangle == 0 then
- local madename = result.familyname .. " " .. result.weight
- fontname = madename or fontname
- local n = cleanname(fontname)
- if not mapping[n] and not fallback_mapping[n] then
- fallback_mapping[n], nofok = { lower(suffix), fontname, filename, is_sub }, nofok + 1
- end
- end
- if result.names then
- for k, v in ipairs(result.names) do
- local lang, names = v.lang, v.names
- if lang == "English (US)" then
- local family, subfamily, fullnamet = names.family, names.subfamily, names.fullname
- local preffamilyname, prefmodifiers, weight = names.preffamilyname, names.prefmodifiers, names.weight
- if preffamilyname then
- if subfamily then
- local n = cleanname(preffamilyname .. " " .. subfamily)
- if not mapping[n] and not fallback_mapping[n] then
- fallback_mapping[n], nofok = { lower(suffix), fontname, filename, is_sub }, nofok + 1
- end
- end
- -- okay?
- local n = cleanname(preffamilyname)
- if not mapping[n] and not fallback_mapping[n] then
- fallback_mapping[n], nofok = { lower(suffix), fontname, filename, is_sub }, nofok + 1
+ local family = families[familyname]
+ if not family then
+ families[familyname] = { index }
+ else
+ family[#family+1] = index
+ end
+end
+
+local function cleanupkeywords()
+ local data = names.data
+ local specifications = names.data.specifications
+ if specifications then
+ local weights, styles, widths, variants = { }, { }, { }, { }
+ for i=1,#specifications do
+ local s = specifications[i]
+ -- fix (sofar styles are taken from the name, and widths from the specification)
+ local b_variant, b_weight, b_style, b_width = analysespec(s.weight)
+ local c_variant, c_weight, c_style, c_width = analysespec(s.style)
+ local d_variant, d_weight, d_style, d_width = analysespec(s.width)
+ local e_variant, e_weight, e_style, e_width = analysespec(s.fullname or "")
+ local weight = b_weight or c_weight or d_weight or e_weight or "normal"
+ local style = b_style or c_style or d_style or e_style or "normal"
+ local width = b_width or c_width or d_width or e_width or "normal"
+ local variant = b_variant or c_variant or d_variant or e_variant or "normal"
+ if weight then weights [weight ] = (weights [weight ] or 0) + 1 end
+ if style then styles [style ] = (styles [style ] or 0) + 1 end
+ if width then widths [width ] = (widths [width ] or 0) + 1 end
+ if variant then variants[variant] = (variants[variant] or 0) + 1 end
+ if weight ~= s.weight then
+ s.fontweight = s.weight
+ end
+ s.weight, s.style, s.width, s.variant = weight, style, width, variant
+ end
+ local stats = data.statistics
+ stats.used_weights, stats.used_styles, stats.used_widths, stats.used_variants = weights, styles, widths, variants
+ end
+end
+
+local function collectstatistics()
+ local data = names.data
+ local specifications = data.specifications
+ if specifications then
+ local weights, styles, widths = { }, { }, { }
+ for i=1,#specifications do
+ local s = specifications[i]
+ local weight, style, width = s.weight, s.style, s.width
+ if weight then weights[weight] = (weights[weight] or 0) + 1 end
+ if style then styles [style ] = (styles [style ] or 0) + 1 end
+ if width then widths [width ] = (widths [width ] or 0) + 1 end
+ end
+ local stats = data.statistics
+ stats.weights, stats.styles, stats.widths, stats.fonts = weights, styles, widths, #specifications
+ end
+end
+
+local function collecthashes()
+ local data = names.data
+ local mappings = data.mappings
+ local fallbacks = data.fallbacks
+ local specifications = data.specifications
+ local nofmappings, noffallbacks = 0, 0
+ if specifications then
+ for index=1,#specifications do
+ local s = specifications[index]
+ local format, fullname, fontname, familyname, weight, subfamily = s.format, s.fullname, s.fontname, s.familyname, s.weight, s.subfamily
+ local mf, ff = mappings[format], fallbacks[format]
+ if fullname and not mf[fullname] then
+ mf[fullname], nofmappings = index, nofmappings + 1
+ end
+ if fontname and not mf[fontname] then
+ mf[fontname], nofmappings = index, nofmappings + 1
+ end
+ if familyname and weight then
+ local madename = familyname .. weight
+ if not mf[madename] and not ff[madename] then
+ ff[madename], noffallbacks = index, noffallbacks + 1
+ end
+ end
+ if familyname and subfamily then
+ local extraname = familyname .. subfamily
+ if not mf[extraname] and not ff[extraname] then
+ ff[extraname], noffallbacks = index, noffallbacks + 1
+ end
+ end
+ if familyname and subfamily then
+ if not mf[familyname] and not ff[familyname] then
+ ff[familyname], noffallbacks = index, noffallbacks + 1
+ end
+ end
+ end
+ end
+ return nofmappings, noffallbacks
+end
+
+local function checkduplicate(mapping) -- fails on "Romantik" but that's a border case anyway
+ local data = names.data
+ local mapping = data[mapping]
+ local specifications, loaded = data.specifications, { }
+ if specifications and mapping then
+ for _, m in next, mapping do
+ for k, v in next, m do
+ local s = specifications[v]
+ local hash = format("%s-%s-%s-%s",s.familyname,s.weight or "*",s.style or "*",s.width or "*")
+ local h = loaded[hash]
+ if h then
+ local ok = true
+ local fn = s.filename
+ for i=1,#h do
+ local hn = s.filename
+ if h[i] == fn then
+ ok = false
+ break
end
end
+ if ok then
+ h[#h+1] = fn
+ end
+ else
+ loaded[hash] = { s.filename }
end
end
end
end
- local trace = verbose or trace_names
- local skip_paths = filters.paths
- local skip_names = filters.names
+ for k, v in table.sortedpairs(loaded) do
+ if #v > 1 then
+ logs.report("fontnames", "double lookup: %s => %s",k,concat(v," | "))
+ end
+ end
+end
+
+local function checkduplicates()
+ checkduplicate("mappings")
+ checkduplicate("fallbacks")
+end
+
+local sorter = function(a,b)
+ return #a < #b and a < b
+end
+
+local function sorthashes()
+ local data, list = names.data, filters.list
+ local mappings, fallbacks, sorted_mappings, sorted_fallbacks = data.mappings, data.fallbacks, { }, { }
+ data.sorted_mappings, data.sorted_fallbacks = sorted_mappings, sorted_fallbacks
+ for i=1,#list do
+ local l = list[i]
+ sorted_mappings[l], sorted_fallbacks[l] = table.keys(mappings[l]), table.keys(fallbacks[l])
+ sort(sorted_mappings[l],sorter)
+ sort(sorted_fallbacks[l],sorter)
+ end
+ data.sorted_families = table.keys(data.families)
+ sort(data.sorted_families,sorter)
+end
+
+local function unpackreferences()
+ local data = names.data
+ local specifications = data.specifications
+ if specifications then
+ for k, v in next, data.families do
+ for i=1,#v do
+ v[i] = specifications[v[i]]
+ end
+ end
+ end
+ local mappings = data.mappings
+ if mappings then
+ for _, m in next, mappings do
+ for k, v in next, m do
+ m[k] = specifications[v]
+ end
+ end
+ end
+ local fallbacks = data.fallbacks
+ if fallbacks then
+ for _, f in next, fallbacks do
+ for k, v in next, f do
+ f[k] = specifications[v]
+ end
+ end
+ end
+end
+
+local function analysefiles()
+ local data = names.data
+ local done, totalnofread, totalnofskipped = { }, 0, 0
+ local skip_paths, skip_names = filters.paths, filters.names
local function identify(completename,name,suffix,storedname)
- if not done[name] and io.exists(completename) then
+ local basename = file.basename(completename)
+ local basepath = file.dirname(completename)
+ if done[name] then
+ -- already done (avoid otf afm clash)
+ elseif not io.exists(completename) then
+ -- weird error
+ elseif not file.is_qualified_path(completename) and resolvers.find_file(completename,suffix) == "" then
+ -- not locateble by backend anyway
+ else
nofread = nofread + 1
if #skip_paths > 0 then
- local path = file.dirname(completename)
for i=1,#skip_paths do
- if find(path,skip_paths[i]) then
- if trace then
+ if find(basepath,skip_paths[i]) then
+ if trace_names then
logs.report("fontnames","rejecting path of %s font %s",suffix,completename)
logs.push()
end
@@ -264,11 +564,10 @@ function names.identify(verbose) -- lsr is for kpse
end
end
if #skip_names > 0 then
- local base = file.basename(completename)
for i=1,#skip_paths do
- if find(base,skip_names[i]) then
+ if find(basename,skip_names[i]) then
done[name] = true
- if trace then
+ if trace_names then
logs.report("fontnames","rejecting name of %s font %s",suffix,completename)
logs.push()
end
@@ -281,15 +580,21 @@ function names.identify(verbose) -- lsr is for kpse
logs.push()
end
local result, message = filters[lower(suffix)](completename)
- if trace then
+ if trace_names then
logs.pop()
end
if result then
if not result[1] then
- check(result,storedname,suffix,false) -- was name
+ local ok = check_name(data,result,storedname,suffix)
+ if not ok then
+ nofskipped = nofskipped + 1
+ end
else
for r=1,#result do
- check(result[r],storedname,suffix,true) -- was name
+ local ok = check_name(data,result[r],storedname,suffix,r-1) -- subfonts start at zero
+ if not ok then
+ nofskipped = nofskipped + 1
+ end
end
end
if message and message ~= "" then
@@ -301,33 +606,19 @@ function names.identify(verbose) -- lsr is for kpse
done[name] = true
end
end
- local totalread, totalok = 0, 0
local function traverse(what, method)
for n, suffix in ipairs(filters.list) do
- nofread, nofok = 0, 0
local t = os.gettimeofday() -- use elapser
+ nofread, nofskipped = 0, 0
suffix = lower(suffix)
logs.report("fontnames", "identifying %s font files with suffix %s",what,suffix)
method(suffix)
suffix = upper(suffix)
logs.report("fontnames", "identifying %s font files with suffix %s",what,suffix)
method(suffix)
- logs.report("fontnames", "%s %s files identified, %s hash entries added, runtime %0.3f seconds",nofread,what,nofok,os.gettimeofday()-t)
- totalread, totalok = totalread + nofread, totalok + nofok
- end
- end
- local function walk_tree(pathlist,suffix)
- if pathlist then
- for _, path in ipairs(pathlist) do
- path = resolvers.clean_path(path .. "/")
- path = gsub(path,"/+","/")
- local pattern = path .. "**." .. suffix -- ** forces recurse
- logs.report("fontnames", "globbing path %s",pattern)
- local t = dir.glob(pattern)
- for _, completename in pairs(t) do -- ipairs
- identify(completename,file.basename(completename),suffix,completename)
- end
- end
+ totalnofread, totalnofskipped = totalnofread + nofread, totalnofskipped + nofskipped
+ local elapsed = os.gettimeofday() - t
+ logs.report("fontnames", "%s %s files identified, %s hash entries added, runtime %0.3f seconds",nofread,what,nofread-nofskipped,elapsed)
end
end
traverse("tree", function(suffix) -- TEXTREE only
@@ -343,43 +634,42 @@ function names.identify(verbose) -- lsr is for kpse
-- using the vars is to clumsy so we just stick to a full scan instead
traverse("lsr", function(suffix) -- all trees
local pathlist = resolvers.split_path(resolvers.show_path("ls-R") or "")
- walk_tree(pathlist,suffix)
+ walk_tree(pathlist,suffix,identify)
end)
else
traverse("system", function(suffix) -- OSFONTDIR cum suis
- walk_tree(names.getpaths(trace),suffix)
+ walk_tree(names.getpaths(trace),suffix,identify)
end)
end
- local t = { }
- for _, f in ipairs(filters.fixes) do
- local expression, replacement = f[1], f[2]
- for k,v in next, mapping do
- local fix, pos = gsub(k,expression,replacement)
- if pos > 0 and not mapping[fix] then
- t[fix] = v
- end
- end
- end
- local n = 0
- for k,v in next, t do
- mapping[k] = v
- n = n + 1
- end
- local rejected = 0
- for k, v in next, mapping do
- local kind, filename = v[1], v[3]
- if not file.is_qualified_path(filename) and resolvers.find_file(filename,kind) == "" then
- mapping[k] = nil
- rejected = rejected + 1
- end
- end
- if n > 0 then
- logs.report("fontnames", "%s files read, %s normal and %s extra entries added, %s rejected, %s valid",totalread,totalok,n,rejected,totalok+n-rejected)
+ data.statistics.readfiles, data.statistics.skippedfiles = totalnofread, totalnofskipped
+end
+
+local function resetdata()
+ local mappings, fallbacks = { }, { }
+ for _, k in next, filters.list do
+ mappings[k], fallbacks[k] = { }, { }
end
- names.analyse(mapping)
- names.analyse(fallback_mapping)
- names.checkduplicates(mapping)
- names.checkduplicates(fallback_mapping)
+ names.data = {
+ version = names.version,
+ mappings = mappings,
+ fallbacks = fallbacks,
+ specifications = { },
+ families = { },
+ statistics = { },
+ data_state = resolvers.data_state(),
+ }
+end
+
+function names.identify()
+ resetdata()
+ analysefiles()
+ collectstatistics()
+ cleanupkeywords()
+ collecthashes()
+ checkduplicates()
+ -- sorthashes() -- will be resorted when saved
+
+ --~ logs.report("fontnames", "%s files read, %s normal and %s extra entries added, %s rejected, %s valid",totalread,totalok,added,rejected,totalok+added-rejected)
end
function names.is_permitted(name)
@@ -392,120 +682,6 @@ function names.read_data(name)
return containers.read(names.cache(),name)
end
-local sorter = function(a,b) return #a < #b and a < b end
-
-function names.sorted(t)
- local s = table.keys(t or { }) or { }
- sort(s,sorted)
- return s
-end
-
---~ local P, C, Cc = lpeg.P, lpeg.C, lpeg.Cc
---~
---~ local weight = C(P("demibold") + P("semibold") + P("mediumbold") + P("ultrabold") + P("bold") + P("demi") + P("semi") + P("light") + P("medium") + P("heavy") + P("ultra") + P("black"))
---~ local style = C(P("regular") + P("italic") + P("oblique") + P("slanted") + P("roman") + P("ital"))
---~ local width = C(P("condensed") + P("normal") + P("expanded") + P("cond"))
---~ local special = P("roman")
---~ local reserved = style + weight + width
---~ local any = (1-reserved)
---~ local name = C((special + any)^1)
---~ local crap = any^0
---~ local dummy = Cc(false)
---~ local normal = Cc("normal")
---~ local analyser = name * (weight + normal) * crap * (style + normal) * crap * (width + normal) * crap
---~
---~ function names.analyse(mapping)
---~ for k, v in next, mapping do
---~ -- fails on "Romantik" but that's a border case anyway
---~ local name, weight, style, width = analyser:match(k)
---~ v[5], v[6], v[7], v[8] = name or k, weight or "normal", style or "normal", width or "normal"
---~ end
---~ end
-
-local P, C, Cc, Cs, Carg = lpeg.P, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Carg
-
-local weight = C(P("demibold") + P("semibold") + P("mediumbold") + P("ultrabold") + P("bold") + P("demi") + P("semi") + P("light") + P("medium") + P("heavy") + P("ultra") + P("black"))
-local style = C(P("regular") + P("italic") + P("oblique") + P("slanted") + P("roman") + P("ital"))
-local width = C(P("condensed") + P("normal") + P("expanded") + P("cond"))
-local strip = P("book") + P("roman")
-local any = P(1)
-
-local t
-
-local analyser = Cs (
- (
- strip / "" +
- weight / function(s) t[6] = s return "" end +
- style / function(s) t[7] = s return "" end +
- width / function(s) t[8] = s return "" end +
- any
- )^0
-)
-
-local stripper = Cs (
- (
- strip / "" +
- any
- )^0
-)
-
-function names.analyse(mapping) -- fails on "Romantik" but that's a border case anyway
- for k, v in next, mapping do
- t = v
- t[5] = analyser:match(k) -- somehow Carg fails
- v[5], v[6], v[7], v[8] = t[5] or k, t[6] or "normal", t[7] or "normal", t[8] or "normal"
- end
-end
-
-local splitter = lpeg.splitat("-")
-
-function names.splitspec(askedname)
- local name, weight, style, width = splitter:match(stripper:match(askedname) or askedname)
- if trace_names then
- logs.report("fonts","requested name '%s' split in name '%s', weight '%s', style '%s' and width '%s'",askedname,name or '',weight or '',style or '',width or '')
- end
- if not weight or not weight or not width then
- weight, style, width = weight or "normal", style or "normal", width or "normal"
- if trace_names then
- logs.report("fonts","request '%s' normalized to '%s-%s-%s-%s'",askedname,name,weight,style,width)
- end
- end
- return name or askedname, weight, style, width
-end
-
-function names.checkduplicates(mapping) -- fails on "Romantik" but that's a border case anyway
- local loaded = { }
- for k, v in next, mapping do
- local hash = format("%s-%s-%s-%s",v[5],v[6],v[7],v[8])
- local h = loaded[hash]
- if h then
- local ok = true
- local fn = v[3]
- for i=1,#h do
- local hn = mapping[h[i]][3]
- if hn == fn then
- ok = false
- break
- end
- end
- if ok then
- h[#h+1] = k
- end
- else
- loaded[hash] = { h }
- end
- end
- for k, v in table.sortedpairs(loaded) do
- if #v > 1 then
- for i=1,#v do
- local vi = v[i]
- v[i] = format("%s = %s",vi,mapping[vi][3])
- end
- logs.report("fonts", "double lookup: %s => %s",k,concat(v," | "))
- end
- end
-end
-
function names.load(reload,verbose)
if not names.loaded then
if reload then
@@ -516,51 +692,85 @@ function names.load(reload,verbose)
logs.report("font table", "unable to access database cache")
end
names.saved = true
- else
- names.data = names.read_data(names.basename)
- if not names.saved then
- if table.is_empty(names.data) or table.is_empty(names.data.mapping) then
- names.load(true)
- end
- names.saved = true
+ end
+ local data = names.read_data(names.basename)
+ names.data = data
+ if not names.saved then
+ if not next(data) or not next(data.specifications) then
+ names.load(true)
end
+ names.saved = true
end
- local data = names.data
- -- names.analyse(data.mapping)
- -- names.analyse(data.fallback_mapping)
- if data then
- data.sorted = names.sorted(data.mapping)
- data.fallback_sorted = names.sorted(data.fallback_mapping)
- else
+ if not data then
logs.report("font table", "accessing the data table failed")
+ else
+ unpackreferences()
+ sorthashes()
end
names.loaded = true
end
end
-function names.list(pattern,reload)
+local function list_them(mapping,sorted,pattern,t,all)
+ if mapping[pattern] then
+ t[pattern] = mapping[pattern]
+ else
+ for k=1,#sorted do
+ local v = sorted[k]
+ if find(v,pattern) then
+ t[v] = mapping[v]
+ if not all then
+ return
+ end
+ end
+ end
+ end
+end
+
+function names.list(pattern,reload,all) -- here?
names.load(reload)
if names.loaded then
local t = { }
- local function list_them(mapping,sorted)
- if mapping[pattern] then
- t[pattern] = mapping[pattern]
- else
- for k,v in ipairs(sorted) do
- if find(v,pattern) then
- t[v] = mapping[v]
- end
+ local data = names.data
+ if data then
+ local list = filters.list
+ local mappings, sorted_mappings = data.mappings, data.sorted_mappings
+ local fallbacks, sorted_fallbacks = data.fallbacks, data.sorted_fallbacks
+ for i=1,#list do
+ local format = list[i]
+ list_them(mappings[format],sorted_mappings[format],pattern,t,all)
+ if next(t) and not all then
+ return t
+ end
+ list_them(fallbacks[format],sorted_fallbacks[format],pattern,t,all)
+ if next(t) and not all then
+ return t
end
end
end
+ return t
+ end
+end
+
+local reloaded = false
+
+local function is_reloaded()
+ if not reloaded then
local data = names.data
- if data then
- list_them(data.mapping,data.sorted)
- list_them(data.fallback_mapping,data.fallback_sorted)
+ if names.autoreload then
+ local c_status = table.serialize(resolvers.data_state())
+ local f_status = table.serialize(data.data_state)
+ if c_status == f_status then
+ logs.report("fonts","font database matches configuration and file hashes")
+ return
+ else
+ logs.report("fonts","font database does not match configuration and file hashes")
+ end
end
- return t
- else
- return nil
+ names.loaded = false
+ reloaded = true
+ io.flush()
+ names.load(true)
end
end
@@ -570,231 +780,326 @@ here is for testing purposes only (it deals with names prefixed by an
encoding name).</p>
--ldx]]--
-local function found_indeed(mapping,sorted,name)
- local mn = mapping[name]
- if mn then
- return mn[2], mn[3], mn[4]
+-- if names.be_clever then -- this will become obsolete
+-- local encoding, tag = match(name,"^(.-)[%-%:](.+)$")
+-- local mt = mapping[tag]
+-- if tag and fonts.enc.is_known(encoding) and mt then
+-- return mt[1], encoding .. "-" .. mt[3], mt[4]
+-- end
+-- end
+
+-- simple search
+
+local function found(mapping,sorted,name,sub)
+ local found = mapping[name]
+ -- obsolete: old encoding test
+ if not found then
+ for k,v in next, mapping do
+ if find(k,name) then
+ found = v
+ break
+ end
+ end
+ if not found then
+ local condensed = gsub(name,"[^%a%d]","")
+ found = mapping[condensed]
+ if not found then
+ for k=1,#sorted do
+ local v = sorted[k]
+ if find(v,condensed) then
+ found = mapping[v]
+ break
+ end
+ end
+ end
+ end
+ end
+ return found
+end
+
+local function foundname(name,sub)
+ local data = names.data
+ local mappings, sorted_mappings = data.mappings, data.sorted_mappings
+ local fallbacks, sorted_fallbacks = data.fallbacks, data.sorted_fallbacks
+ local list = filters.list
+ for i=1,#list do
+ local l = list[i]
+ local okay = found(mappings[l],sorted_mappings[l],name,sub) or found(fallbacks[l],sorted_fallbacks[l],name,sub)
+ if okay then
+ return okay
+ end
+ end
+end
+
+function names.resolve(askedname,sub)
+ if askedname and askedname ~= "" and names.enabled then
+ askedname = cleanname(askedname)
+ names.load()
+ local found = foundname(askedname,sub)
+ if not found and is_reloaded() then
+ found = foundname(askedname,sub)
+ end
+ if found then
+ return found.filename, found.subfont and found.rawname
+ end
+ end
+end
+
+-- specified search
+
+local function s_collect_weight_style_width(found,done,all,weight,style,width,family)
+ if family then
+ for i=1,#family do
+ local f = family[i]
+ if f and weight == f.weight and style == f.style and width == f.width then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
+ end
end
- if names.be_clever then -- this will become obsolete
- local encoding, tag = match(name,"^(.-)[%-%:](.+)$")
- local mt = mapping[tag]
- if tag and fonts.enc.is_known(encoding) and mt then
- return mt[1], encoding .. "-" .. mt[3], mt[4]
+end
+local function m_collect_weight_style_width(found,done,all,weight,style,width,families,sorted,strictname)
+ for i=1,#sorted do
+ local k = sorted[i]
+ local family = families[k]
+ for i=1,#family do
+ local f = family[i]
+ if not done[f] and weight == f.weight and style == f.style and width == f.width and find(f.fontname,strictname) then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
+ end
+ end
+end
+
+local function s_collect_weight_style(found,done,all,weight,style,family)
+ if family then
+ for i=1,#family do local f = family[i]
+ if f and weight == f.weight and style == f.style then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
end
end
- -- name, type, file
- for k,v in next, mapping do
- if find(k,name) then
- return v[2], v[3], v[4]
+end
+local function m_collect_weight_style(found,done,all,weight,style,families,sorted,strictname)
+ for i=1,#sorted do
+ local k = sorted[i]
+ local family = families[k]
+ for i=1,#family do
+ local f = family[i]
+ if not done[f] and weight == f.weight and style == f.style and find(f.fontname,strictname) then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
end
end
- local condensed = gsub(name,"[^%a%d]","")
- local mc = mapping[condensed]
- if mc then
- return mc[2], mc[3], mc[4]
+end
+
+local function s_collect_style_width(found,done,all,style,width,family)
+ if family then
+ for i=1,#family do local f = family[i]
+ if f and style == f.style and width == f.width then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
+ end
end
- for k=1,#sorted do
- local v = sorted[k]
- if find(v,condensed) then
- v = mapping[v]
- return v[2], v[3], v[4]
+end
+local function m_collect_style_width(found,done,all,style,width,families,sorted,strictname)
+ for i=1,#sorted do
+ local k = sorted[i]
+ local family = families[k]
+ for i=1,#family do
+ local f = family[i]
+ if not done[f] and style == f.style and width == f.width and find(f.fontname,strictname) then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
end
end
- return nil, nil, nil
end
-local function found(name)
- if name and name ~= "" and names.data then
- name = names.cleanname(name)
- local data = names.data
- local fontname, filename, is_sub = found_indeed(data.mapping, data.sorted, name)
- if not fontname or not filename then
- fontname, filename, is_sub = found_indeed(data.fallback_mapping, data.fallback_sorted, name)
+local function s_collect_weight(found,done,all,weight,family)
+ if family then
+ for i=1,#family do local f = family[i]
+ if f and weight == f.weight then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
+ end
+ end
+end
+local function m_collect_weight(found,done,all,weight,families,sorted,strictname)
+ for i=1,#sorted do
+ local k = sorted[i]
+ local family = families[k]
+ for i=1,#family do
+ local f = family[i]
+ if not done[f] and weight == f.weight and find(f.fontname,strictname) then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
end
- return fontname, filename, is_sub
- else
- return nil, nil, nil
end
end
-local function collect(stage,mapping,sorted,found,done,name,weight,style,width,all)
- if not mapping or not sorted then
- return
+local function s_collect_style(found,done,all,style,family)
+ if family then
+ for i=1,#family do local f = family[i]
+ if f and style == f.style then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
+ end
+ end
+end
+local function m_collect_style(found,done,all,style,families,sorted,strictname)
+ for i=1,#sorted do
+ local k = sorted[i]
+ local family = families[k]
+ for i=1,#family do
+ local f = family[i]
+ if not done[f] and style == f.style and find(f.fontname,strictname) then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
+ end
end
-strictname = "^".. name
- local f = mapping[name]
- if weight ~= "" then
- if style ~= "" then
- if width ~= "" then
+end
+
+local function s_collect_width(found,done,all,width,family)
+ if family then
+ for i=1,#family do local f = family[i]
+ if f and width == f.width then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
+ end
+ end
+end
+local function m_collect_width(found,done,all,width,families,sorted,strictname)
+ for i=1,#sorted do
+ local k = sorted[i]
+ local family = families[k]
+ for i=1,#family do
+ local f = family[i]
+ if not done[f] and width == f.width and find(f.fontname,strictname) then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
+ end
+ end
+end
+
+local function s_collect(found,done,all,family)
+ if family then
+ for i=1,#family do local f = family[i]
+ if f then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
+ end
+ end
+end
+local function m_collect(found,done,all,families,sorted,strictname)
+ for i=1,#sorted do
+ local k = sorted[i]
+ local family = families[k]
+ for i=1,#family do
+ local f = family[i]
+ if not done[f] and find(f.fontname,strictname) then
+ found[#found+1], done[f] = f, true
+ if not all then return end
+ end
+ end
+ end
+end
+
+local function collect(stage,found,done,name,weight,style,width,all)
+ local data = names.data
+ local families, sorted = data.families, data.sorted_families
+ strictname = "^".. name -- to be checked
+ local family = families[name]
+ if trace_names then
+ logs.report("fonts","resolving name '%s', weight '%s', style '%s', width '%s'",name or "?",tostring(weight),tostring(style),tostring(width))
+ end
+ if weight and weight ~= "" then
+ if style and style ~= "" then
+ if width and width ~= "" then
if trace_names then
logs.report("fonts","resolving stage %s, name '%s', weight '%s', style '%s', width '%s'",stage,name,weight,style,width)
end
- if f and width ~= f[8] and style == f[7] and weight == f[6] then
- found[#found+1], done[name] = f, true
- if not all then return end
- end
- for i=1,#sorted do
- local k = sorted[i]
- if not done[k] then
- local v = mapping[k]
- if v[6] == weight and v[7] == style and v[8] == width and find(v[5],strictname) then
- found[#found+1], done[k] = v, true
- if not all then return end
- end
- end
- end
+ s_collect_weight_style_width(found,done,all,weight,style,width,family)
+ m_collect_weight_style_width(found,done,all,weight,style,width,families,sorted,strictname)
else
if trace_names then
logs.report("fonts","resolving stage %s, name '%s', weight '%s', style '%s'",stage,name,weight,style)
end
- if f and style == f[7] and weight == f[6] then
- found[#found+1], done[name] = f, true
- if not all then return end
- end
- for i=1,#sorted do
- local k = sorted[i]
- if not done[k] then
- local v = mapping[k]
- if v[6] == weight and v[7] == style and find(v[5],strictname) then
- found[#found+1], done[k] = v, true
- if not all then return end
- end
- end
- end
+ s_collect_weight_style(found,done,all,weight,style,family)
+ m_collect_weight_style(found,done,all,weight,style,families,sorted,strictname)
end
else
if trace_names then
logs.report("fonts","resolving stage %s, name '%s', weight '%s'",stage,name,weight)
end
- if f and weight == f[6] then
- found[#found+1], done[name] = f, true
- if not all then return end
- end
- for i=1,#sorted do
- local k = sorted[i]
- if not done[k] then
- local v = mapping[k]
- if v[6] == weight and find(v[5],strictname) then
- found[#found+1], done[k] = v, true
- if not all then return end
- end
- end
- end
+ s_collect_weight(found,done,all,weight,family)
+ m_collect_weight(found,done,all,weight,families,sorted,strictname)
end
- elseif style ~= "" then
- if width ~= "" then
+ elseif style and style ~= "" then
+ if width and width ~= "" then
if trace_names then
logs.report("fonts","resolving stage %s, name '%s', style '%s', width '%s'",stage,name,style,width)
end
- if f and style == f[7] and width == f[8] then
- found[#found+1], done[name] = f, true
- if not all then return end
- end
- for i=1,#sorted do
- local k = sorted[i]
- if not done[k] then
- local v = mapping[k]
- if v[7] == style and v[8] == width and find(v[5],strictname) then
- found[#found+1], done[k] = v, true
- if not all then return end
- end
- end
- end
+ s_collect_style_width(found,done,all,style,width,family)
+ m_collect_style_width(found,done,all,style,width,families,sorted,strictname)
else
if trace_names then
logs.report("fonts","resolving stage %s, name '%s', style '%s'",stage,name,style)
end
- if f and style == f[7] then
- found[#found+1], done[name] = f, true
- if not all then return end
- end
- for i=1,#sorted do
- local k = sorted[i]
- if not done[k] then
- local v = mapping[k]
- if v[7] == style and find(v[5],strictname) then
- found[#found+1], done[k] = v, true
- if not all then return end
- end
- end
- end
+ s_collect_style(found,done,all,style,family)
+ m_collect_style(found,done,all,style,families,sorted,strictname)
end
- elseif width ~= "" then
+ elseif width and width ~= "" then
if trace_names then
logs.report("fonts","resolving stage %s, name '%s', width '%s'",stage,name,width)
end
- if f and width == f[8] then
- found[#found+1], done[name] = f, true
- if not all then return end
- end
- for i=1,#sorted do
- local k = sorted[i]
- if not done[k] then
- local v = mapping[k]
- if v[8] == width and find(v[5],strictname) then
- found[#found+1], done[k] = v, true
- if not all then return end
- end
- end
- end
+ s_collect_width(found,done,all,width,family)
+ m_collect_width(found,done,all,width,families,sorted,strictname)
else
if trace_names then
logs.report("fonts","resolving stage %s, name '%s'",stage,name)
end
- if f then
- found[#found+1], done[name] = f, true
- if not all then return end
- end
- for i=1,#sorted do
- local k = sorted[i]
- if not done[k] then
- local v = mapping[k]
- if find(v[5],strictname) then
- found[#found+1], done[k] = v, true
- if not all then return end
- end
- end
- end
+ s_collect(found,done,all,family)
+ m_collect(found,done,all,families,sorted,strictname)
end
end
function heuristic(name,weight,style,width,all) -- todo: fallbacks
local found, done = { }, { }
- local data = names.data
- local mapping, sorted, fbmapping, fbsorted = data.mapping, data.sorted, data.fallback_mapping, data.fallback_sorted
weight, style = weight or "", style or ""
- name = names.cleanname(name)
- collect(1,mapping,sorted,found,done,name,weight,style,width,all)
- if #found == 0 then
- collect(2,fbmapping,fbsorted,found,done,name,weight,style,width,all)
- end
+ name = cleanname(name)
+ collect(1,found,done,name,weight,style,width,all)
+ -- still needed ?
if #found == 0 and width ~= "" then
- width = "normal"
- collect(3,mapping,sorted,found,done,name,weight,style,width,all)
- if #found == 0 then
- collect(4,fbmapping,fbsorted,found,done,name,weight,style,width,all)
- end
+ width = ""
+ collect(2,found,done,name,weight,style,width,all)
end
if #found == 0 and weight ~= "" then -- not style
- weight = "normal"
- collect(5,mapping,sorted,found,done,name,weight,style,width,all)
- if #found == 0 then
- collect(6,fbmapping,fbsorted,found,done,name,weight,style,width,all)
- end
+ weight = ""
+ collect(3,found,done,name,weight,style,width,all)
end
if #found == 0 and style ~= "" then -- not weight
- style = "normal"
- collect(7,mapping,sorted,found,done,name,weight,style,width,all)
- if #found == 0 then
- collect(8,fbmapping,fbsorted,found,done,name,weight,style,width,all)
- end
+ style = ""
+ collect(4,found,done,name,weight,style,width,all)
end
+ --
local nf = #found
if trace_names then
if nf then
local t = { }
for i=1,nf do
- t[#t+1] = format("'%s'",found[i][2])
+ t[#t+1] = format("'%s'",found[i].fontname)
end
logs.report("fonts","name '%s' resolved to %s instances: %s",name,nf,concat(t," "))
else
@@ -803,63 +1108,48 @@ function heuristic(name,weight,style,width,all) -- todo: fallbacks
end
if all then
return nf > 0 and found
- elseif nf > 0 then
- local f = found[1]
- return f[2], f[3], f[4]
else
- return nil, nil, nil
+ return found[1]
end
end
-local reloaded = false
-
-function names.specification(askedname,weight,style,width)
+function names.specification(askedname,weight,style,width,reload,all)
if askedname and askedname ~= "" and names.enabled then
askedname = lower(askedname) -- or cleanname
- names.load()
- local name, filename, is_sub = heuristic(askedname,weight,style,width)
- if not filename and not reloaded and names.autoreload then
- names.loaded = false
- reloaded = true
- io.flush()
- names.load(true)
- name, filename, is_sub = heuristic(askedname,weight,style,width)
+ names.load(reload)
+ local found = heuristic(askedname,weight,style,width,all)
+ if not found and is_reloaded() then
+ found = heuristic(askedname,weight,style,width,all)
if not filename then
- name, filename, is_sub = found(askedname) -- old method
+ found = foundname(askedname) -- old method
end
end
- return name, filename, is_sub
+ return found
end
end
-function names.collect(askedname,weight,style,width)
+function names.collect(askedname,weight,style,width,reload,all)
if askedname and askedname ~= "" and names.enabled then
askedname = lower(askedname) -- or cleanname
- names.load()
+ names.load(reload)
local list = heuristic(askedname,weight,style,width,true)
- if not list or #list == 0 and not reloaded and names.autoreload then
- names.loaded = false
- reloaded = true
- io.flush()
- names.load(true)
+ if not list or #list == 0 and is_reloaded() then
list = heuristic(askedname,weight,style,width,true)
end
return list
end
end
-function names.resolve(askedname, sub)
- local name, filename, is_sub = names.specification(askedname)
- return filename, (is_sub and name) or sub
-end
-
-function names.collectspec(askedname)
- return names.collect(names.splitspec(askedname))
+function names.collectspec(askedname,reload,all)
+ local name, weight, style, width = names.splitspec(askedname)
+ return names.collect(name,weight,style,width,reload,all)
end
function names.resolvespec(askedname,sub)
- local name, filename, is_sub = names.specification(names.splitspec(askedname))
- return filename, (is_sub and name) or sub
+ local found = names.specification(names.splitspec(askedname))
+ if found then
+ return found.filename, found.subfont and found.rawname
+ end
end
--[[ldx--
@@ -924,3 +1214,89 @@ function names.exists(name)
names.autoreload = fna
return found
end
+
+-- for i=1,fonts.names.lookup(pattern) do
+-- texio.write_nl(fonts.names.getkey("filename",i))
+-- end
+
+local lastlookups, lastpattern = { }, ""
+
+function names.lookup(pattern,name,reload) -- todo: find
+ if lastpattern ~= pattern then
+ names.load(reload)
+ local specifications = names.data.specifications
+ local families = names.data.families
+ local lookups = specifications
+ if name then
+ lookups = families[name]
+ elseif not find(pattern,"=") then
+ lookups = families[pattern]
+ end
+ if trace_names then
+ logs.report("fonts","starting with %s lookups for '%s'",#lookups,pattern)
+ end
+ if lookups then
+ for key, value in gmatch(pattern,"([^=,]+)=([^=,]+)") do
+ local t = { }
+ for i=1,#lookups do
+ local s = lookups[i]
+ if s[key] == value then
+ t[#t+1] = lookups[i]
+ end
+ end
+ if trace_names then
+ logs.report("fonts","%s matches for key '%s' with value '%s'",#t,key,value)
+ end
+ lookups = t
+ end
+ end
+ lastpattern = pattern
+ lastlookups = lookups or { }
+ end
+ return #lastlookups
+end
+
+function names.getlookupkey(key,n)
+ local l = lastlookups[n or 1]
+ return (l and l[key]) or ""
+end
+
+function names.noflookups()
+ return #lastlookups
+end
+
+function names.getlookups(pattern,name,reload)
+ if pattern then
+ names.lookup(pattern,name,reload)
+ end
+ return lastlookups
+end
+
+function table.formatcolumns(result)
+ if result and #result > 0 then
+ local widths = { }
+ local first = result[1]
+ local n = #first
+ for i=1,n do
+ widths[i] = 0
+ end
+ for i=1,#result do
+ local r = result[i]
+ for j=1,n do
+ local w = #r[j]
+ if w > widths[j] then
+ widths[j] = w
+ end
+ end
+ end
+ for i=1,n do
+ widths[i] = "%-" .. widths[i] .. "s"
+ end
+ local template = concat(widths," ")
+ for i=1,#result do
+ local str = format(template,unpack(result[i]))
+ result[i] = string.strip(str)
+ end
+ end
+ return result
+end
diff --git a/tex/context/base/font-tfm.lua b/tex/context/base/font-tfm.lua
index 576829369..2794a947a 100644
--- a/tex/context/base/font-tfm.lua
+++ b/tex/context/base/font-tfm.lua
@@ -533,15 +533,15 @@ local private = fonts.private
end
-- needed for \high cum suis
local tpx = tp.x_height
-if hasmath then
- if not tp[13] then tp[13] = .86*tpx end -- mathsupdisplay
- if not tp[14] then tp[14] = .86*tpx end -- mathsupnormal
- if not tp[15] then tp[15] = .86*tpx end -- mathsupcramped
- if not tp[16] then tp[16] = .48*tpx end -- mathsubnormal
- if not tp[17] then tp[17] = .48*tpx end -- mathsubcombined
- if not tp[22] then tp[22] = 0 end -- mathaxisheight
- if t.MathConstants then t.MathConstants.AccentBaseHeight = nil end -- safeguard
-end
+ if hasmath then
+ if not tp[13] then tp[13] = .86*tpx end -- mathsupdisplay
+ if not tp[14] then tp[14] = .86*tpx end -- mathsupnormal
+ if not tp[15] then tp[15] = .86*tpx end -- mathsupcramped
+ if not tp[16] then tp[16] = .48*tpx end -- mathsubnormal
+ if not tp[17] then tp[17] = .48*tpx end -- mathsubcombined
+ if not tp[22] then tp[22] = 0 end -- mathaxisheight
+ if t.MathConstants then t.MathConstants.AccentBaseHeight = nil end -- safeguard
+ end
t.tounicode = 1
t.cidinfo = tfmtable.cidinfo
-- we have t.name=metricfile and t.fullname=RealName and t.filename=diskfilename
@@ -549,20 +549,21 @@ end
-- can have multiple subfonts
if hasmath then
if trace_defining then
- logs.report("define font","math enabled for: %s %s %s",t.name or "noname",t.fullname or "nofullname",t.filename or "nofilename")
+ logs.report("define font","math enabled for: name '%s', fullname: '%s', filename: '%s'",t.name or "noname",t.fullname or "nofullname",t.filename or "nofilename")
end
else
if trace_defining then
- logs.report("define font","math disabled for: %s %s %s",t.name or "noname",t.fullname or "nofullname",t.filename or "nofilename")
+ logs.report("define font","math disabled for: name '%s', fullname: '%s', filename: '%s'",t.name or "noname",t.fullname or "nofullname",t.filename or "nofilename")
end
t.nomath, t.MathConstants = true, nil
end
- -- fullname is used in the subsetting
if not t.psname then
- t.psname = t.fullname -- else bad luck
+ -- name used in pdf file as well as for selecting subfont in ttc/dfont
+ t.psname = t.fontname or (t.fullname and fonts.names.cleanname(t.fullname))
end
if trace_defining then
- logs.report("define font","used for subsetting: %s ",t.fullname or "nofullname")
+ logs.report("define font","used for accesing subfont: '%s'",t.psname or "nopsname")
+ logs.report("define font","used for subsetting: '%s'",t.fontname or "nofontname")
end
return t, delta
end
diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua
index 0fc40b38b..44447a7ad 100644
--- a/tex/context/base/grph-inc.lua
+++ b/tex/context/base/grph-inc.lua
@@ -667,7 +667,12 @@ function figures.includers.generic(data)
end
if figure then
local n = figures.boxnumber
- tex.box[n] = img.node(figure) -- img.write(figure)
+ tex.box[n] = node.hpack(img.node(figure))
+ -- tex.box[n] = img.node(figure) -- img.write(figure) -- assigning img.node directly no longer valid
+--~ local inode = img.node(figure)
+--~ print(table.serialize(nodes.totable(inode)))
+--~ tex.box[n] = inode
+--~ print(table.serialize(nodes.totable(tex.box[n])))
tex.wd[n], tex.ht[n], tex.dp[n] = figure.width, figure.height, 0 -- new, hm, tricky, we need to do that in tex (yet)
ds.objectnumber = figure.objnum
texsprint(ctxcatcodes,"\\relocateexternalfigure")
diff --git a/tex/context/base/lang-ini.lua b/tex/context/base/lang-ini.lua
index b7b908144..c251ab1a6 100644
--- a/tex/context/base/lang-ini.lua
+++ b/tex/context/base/lang-ini.lua
@@ -280,7 +280,7 @@ end
languages.words = languages.words or {}
languages.words.data = languages.words.data or {}
-languages.words.enable = false
+languages.words.enables = false
languages.words.threshold = 4
languages.words.colors = {
@@ -426,7 +426,7 @@ do
local color = attributes.private('color')
function languages.words.check(head)
- if lw.enable and head.next then
+ if lw.enabled and head.next then
local colors = lw.colors
local alc = attributes.list[color]
return lw.methods[lw.method](head, color, alc[colors.known], alc[colors.unknown])
@@ -435,6 +435,15 @@ do
end
end
+ function languages.words.enable()
+ tasks.enableaction("processors","languages.words.check")
+ languages.words.enabled = true
+ end
+
+ function languages.words.disable()
+ languages.words.enabled = false
+ end
+
end
-- for the moment we hook it into the attribute handler
diff --git a/tex/context/base/lang-ini.mkiv b/tex/context/base/lang-ini.mkiv
index f88281a60..86870d635 100644
--- a/tex/context/base/lang-ini.mkiv
+++ b/tex/context/base/lang-ini.mkiv
@@ -567,8 +567,8 @@
\def\setupspellchecking[#1]% todo colors
{\getparameters[\??wl][#1]%
\doifelse\@@wlstate\v!start
- {\ctxlua{languages.words.enable=true }}
- {\ctxlua{languages.words.enable=false}}}
+ {\ctxlua{languages.words.enable()}}
+ {\ctxlua{languages.words.disable()}}}
\setupspellchecking
[\c!state=\v!stop]
diff --git a/tex/context/base/m-pstric.tex b/tex/context/base/m-pstric.tex
index ac018fe07..f4be08dbd 100644
--- a/tex/context/base/m-pstric.tex
+++ b/tex/context/base/m-pstric.tex
@@ -13,6 +13,9 @@
%M \usemodule[pstric]
+\letvalue{@unused}\plussixteen
+\letvalue{alloc@}\gobblefivearguments
+
\chardef\oldbarcode\the\catcode`\| \catcode`\|=12
\def\loadpstrickscolors#1%
diff --git a/tex/context/base/math-vfu.lua b/tex/context/base/math-vfu.lua
index 0300bb07f..1a8979160 100644
--- a/tex/context/base/math-vfu.lua
+++ b/tex/context/base/math-vfu.lua
@@ -371,7 +371,7 @@ function fonts.vf.math.define(specification,set)
if trace_virtual then
logs.report("math virtual", "unicode point U+%05X has no index %04X in vector %s for font %s",unicode,index,vectorname,fontname)
elseif not already_reported then
- logs.report("math virtual", "the mapping is incomplete for '%s' at %s",name,size)
+ logs.report("math virtual", "the mapping is incomplete for '%s' at %s",name,number.topoints(size))
already_reported = true
end
rv[unicode] = true
@@ -747,6 +747,23 @@ fonts.enc.math["tex-mi"] = {
[0x0003E] = 0x3E, -- >
[0x022C6] = 0x3F, -- star
[0x02202] = 0x40, -- partial
+--
+ [0x0266D] = 0x5B, -- flat
+ [0x0266E] = 0x5C, -- natural
+ [0x0266F] = 0x5D, -- sharp
+ [0x02323] = 0x5E, -- smile
+ [0x02322] = 0x5F, -- frown
+ [0x02113] = 0x60, -- ell
+--
+ [0x1D6A4] = 0x7B, -- imath (TODO: also 0131)
+ [0x1D6A5] = 0x7C, -- jmath (TODO: also 0237)
+ [0x02118] = 0x7D, -- wp
+ [0x020D7] = 0x7E, -- vec (TODO: not sure)
+-- 0x7F, -- (no idea what that could be)
+}
+
+
+fonts.enc.math["tex-it"] = {
-- [0x00041] = 0x41, -- A
[0x1D6E2] = 0x41, -- Alpha
-- [0x00042] = 0x42, -- B
@@ -786,12 +803,6 @@ fonts.enc.math["tex-mi"] = {
-- [0x00059] = 0x59, -- Y
-- [0x0005A] = 0x5A, -- Z
[0x1D6E7] = 0x5A, -- Zeta
- [0x0266D] = 0x5B, -- flat
- [0x0266E] = 0x5C, -- natural
- [0x0266F] = 0x5D, -- sharp
- [0x02323] = 0x5E, -- smile
- [0x02322] = 0x5F, -- frown
- [0x02113] = 0x60, -- ell
-- [0x00061] = 0x61, -- a
-- [0x00062] = 0x62, -- b
-- [0x00063] = 0x63, -- c
@@ -800,7 +811,7 @@ fonts.enc.math["tex-mi"] = {
-- [0x00066] = 0x66, -- f
-- [0x00067] = 0x67, -- g
-- [0x00068] = 0x68, -- h
- [0x0210E] = 0x68, -- plant constant
+ [0x0210E] = 0x68, -- plank constant
-- [0x00069] = 0x69, -- i
-- [0x0006A] = 0x6A, -- j
-- [0x0006B] = 0x6B, -- k
@@ -820,11 +831,6 @@ fonts.enc.math["tex-mi"] = {
-- [0x00078] = 0x78, -- x
-- [0x00079] = 0x79, -- y
-- [0x0007A] = 0x7A, -- z
- [0x1D6A4] = 0x7B, -- imath (TODO: also 0131)
- [0x1D6A5] = 0x7C, -- jmath (TODO: also 0237)
- [0x02118] = 0x7D, -- wp
- [0x020D7] = 0x7E, -- vec (TODO: not sure)
--- 0x7F, -- (no idea what that could be)
}
fonts.enc.math["tex-ss"] = { }
@@ -1314,7 +1320,7 @@ fonts.enc.math["tex-fraktur"] = {
-- now that all other vectors are defined ...
-fonts.vf.math.set_letters(fonts.enc.math, "tex-mi", 0x1D434, 0x1D44E)
+fonts.vf.math.set_letters(fonts.enc.math, "tex-it", 0x1D434, 0x1D44E)
fonts.vf.math.set_letters(fonts.enc.math, "tex-ss", 0x1D5A0, 0x1D5BA)
fonts.vf.math.set_letters(fonts.enc.math, "tex-tt", 0x1D670, 0x1D68A)
fonts.vf.math.set_letters(fonts.enc.math, "tex-bf", 0x1D400, 0x1D41A)
@@ -1342,6 +1348,7 @@ mathematics.make_font ( "lmroman5-math", {
{ name = "lmroman5-regular.otf", features = "virtualmath", main = true },
{ name = "rm-lmr5.tfm", vector = "tex-mr-missing" } ,
{ name = "lmmi5.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmmi5.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "lmsy5.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam5.tfm", vector = "tex-ma" },
@@ -1363,6 +1370,7 @@ mathematics.make_font ( "lmroman6-math", {
{ name = "lmroman6-regular.otf", features = "virtualmath", main = true },
{ name = "rm-lmr6.tfm", vector = "tex-mr-missing" } ,
{ name = "lmmi6.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmmi6.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "lmsy6.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam5.tfm", vector = "tex-ma" },
@@ -1387,6 +1395,7 @@ mathematics.make_font ( "lmroman7-math", {
{ name = "lmroman7-regular.otf", features = "virtualmath", main = true },
{ name = "rm-lmr7.tfm", vector = "tex-mr-missing" } ,
{ name = "lmmi7.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmmi7.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "lmsy7.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam7.tfm", vector = "tex-ma" },
@@ -1409,6 +1418,7 @@ mathematics.make_font ( "lmroman8-math", {
{ name = "lmroman8-regular.otf", features = "virtualmath", main = true },
{ name = "rm-lmr8.tfm", vector = "tex-mr-missing" } ,
{ name = "lmmi8.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmmi8.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "lmsy8.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam7.tfm", vector = "tex-ma" },
@@ -1431,6 +1441,7 @@ mathematics.make_font ( "lmroman9-math", {
{ name = "lmroman9-regular.otf", features = "virtualmath", main = true },
{ name = "rm-lmr9.tfm", vector = "tex-mr-missing" } ,
{ name = "lmmi9.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmmi9.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "lmsy9.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1456,6 +1467,7 @@ mathematics.make_font ( "lmroman10-math", {
{ name = "lmroman10-regular.otf", features = "virtualmath", main = true },
{ name = "rm-lmr10.tfm", vector = "tex-mr-missing" } ,
{ name = "lmmi10.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmmi10.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "lmsy10.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1473,6 +1485,7 @@ mathematics.make_font ( "lmroman10-boldmath", {
{ name = "lmroman10-bold.otf", features = "virtualmath", main = true },
{ name = "rm-lmr10.tfm", vector = "tex-mr-missing" } ,
{ name = "lmmib10.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmmib10.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "lmbsy10.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
-- copied from roman:
@@ -1495,6 +1508,7 @@ mathematics.make_font ( "lmroman12-math", {
{ name = "lmroman12-regular.otf", features = "virtualmath", main = true },
{ name = "rm-lmr12.tfm", vector = "tex-mr-missing" } ,
{ name = "lmmi12.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmmi12.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "lmsy10.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1514,6 +1528,7 @@ mathematics.make_font ( "lmroman17-math", {
{ name = "lmroman17-regular.otf", features = "virtualmath", main = true },
{ name = "rm-lmr12.tfm", vector = "tex-mr-missing" } ,
{ name = "lmmi12.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "lmmi12.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "lmsy10.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "lmex10.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1533,6 +1548,7 @@ mathematics.make_font ( "px-math", {
{ name = "texgyrepagella-regular.otf", features = "virtualmath", main = true },
{ name = "rpxr.tfm", vector = "tex-mr" } ,
{ name = "rpxmi.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "pxmi1.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "pxsy.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "pxex.tfm", vector = "tex-ex", extension = true } ,
{ name = "pxsya.tfm", vector = "tex-ma" },
@@ -1542,6 +1558,7 @@ mathematics.make_font ( "px-math", {
mathematics.make_font ( "tx-math", {
{ name = "texgyretermes-regular.otf", features = "virtualmath", main = true },
{ name = "rtxr.tfm", vector = "tex-mr" } ,
+ { name = "rtxptmri.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "rtxmi.tfm", vector = "tex-mi", skewchar=0x7F },
{ name = "txsy.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "txex.tfm", vector = "tex-ex", extension = true } ,
@@ -1552,6 +1569,7 @@ mathematics.make_font ( "tx-math", {
mathematics.make_font ( "antykwa-math", {
{ name = "file:AntykwaTorunska-Regular", features = "virtualmath", main = true },
{ name = "mi-anttri.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "mi-anttri.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "sy-anttrz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "ex-anttr.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1561,6 +1579,7 @@ mathematics.make_font ( "antykwa-math", {
mathematics.make_font ( "antykwa-light-math", {
{ name = "file:AntykwaTorunskaLight-Regular", features = "virtualmath", main = true },
{ name = "mi-anttli.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "mi-anttli.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "sy-anttlz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "ex-anttl.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1570,6 +1589,7 @@ mathematics.make_font ( "antykwa-light-math", {
mathematics.make_font ( "antykwa-cond-math", {
{ name = "file:AntykwaTorunskaCond-Regular", features = "virtualmath", main = true },
{ name = "mi-anttcri.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "mi-anttcri.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "sy-anttcrz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "ex-anttcr.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1579,6 +1599,7 @@ mathematics.make_font ( "antykwa-cond-math", {
mathematics.make_font ( "antykwa-lightcond-math", {
{ name = "file:AntykwaTorunskaCondLight-Regular", features = "virtualmath", main = true },
{ name = "mi-anttcli.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "mi-anttcli.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "sy-anttclz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "ex-anttcl.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1588,6 +1609,7 @@ mathematics.make_font ( "antykwa-lightcond-math", {
mathematics.make_font ( "iwona-math", {
{ name = "file:Iwona-Regular", features = "virtualmath", main = true },
{ name = "mi-iwonari.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "mi-iwonari.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "sy-iwonarz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "ex-iwonar.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1597,6 +1619,7 @@ mathematics.make_font ( "iwona-math", {
mathematics.make_font ( "iwona-light-math", {
{ name = "file:IwonaLight-Regular", features = "virtualmath", main = true },
{ name = "mi-iwonali.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "mi-iwonali.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "sy-iwonalz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "ex-iwonal.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1606,6 +1629,7 @@ mathematics.make_font ( "iwona-light-math", {
mathematics.make_font ( "iwona-medium-math", {
{ name = "file:IwonaMedium-Regular", features = "virtualmath", main = true },
{ name = "mi-iwonami.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "mi-iwonami.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "sy-iwonamz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "ex-iwonam.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1615,6 +1639,7 @@ mathematics.make_font ( "iwona-medium-math", {
mathematics.make_font ( "iwona-heavy-math", {
{ name = "file:IwonaHeavy-Regular", features = "virtualmath", main = true },
{ name = "mi-iwonahi.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "mi-iwonahi.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "sy-iwonahz.tfm", vector = "tex-sy", skewchar=0x30, parameters = true } ,
{ name = "ex-iwonah.tfm", vector = "tex-ex", extension = true } ,
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1626,6 +1651,7 @@ mathematics.make_font ( "iwona-heavy-math", {
mathematics.make_font ( "mathtimes-math", {
{ name = "file:texgyretermes-regular.otf", features = "virtualmath", main = true },
{ name = "mtmiz.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "mtmiz.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "mtsyn.tfm", vector = "tex-sy", skewchar=0x30, parameters = true },
{ name = "mtex.tfm", vector = "tex-ex", extension = true },
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1635,6 +1661,7 @@ mathematics.make_font ( "mathtimes-math", {
mathematics.make_font ( "lucida-math", {
{ name = "lbr.afm", features = "virtualmath", main = true },
{ name = "hlcrim.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "hlcrim.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "hlcry.tfm", vector = "tex-sy", skewchar=0x30, parameters = true },
{ name = "hlcrv.tfm", vector = "tex-ex", extension = true },
{ name = "hlcra.tfm", vector = "tex-ma" },
@@ -1645,6 +1672,7 @@ mathematics.make_font ( "charter-math", {
{ name = "file:bchr8a", features = "virtualmath", main = true },
-- { name = "md-chr7m.tfm", vector = "tex-mr" },
{ name = "md-chri7m.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "md-chri7m.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "md-chr7y.tfm", vector = "tex-sy", skewchar=0x30, parameters = true },
{ name = "md-chr7v.tfm", vector = "tex-ex", extension = true },
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1655,6 +1683,7 @@ mathematics.make_font ( "garamond-math", {
{ name = "file:ugmr8y", features = "virtualmath", main = true },
-- { name = "md-gmr7m.tfm", vector = "tex-mr" },
{ name = "md-gmri7m.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "md-gmri7m.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "md-gmr7y.tfm", vector = "tex-sy", skewchar=0x30, parameters = true },
{ name = "md-gmr7v.tfm", vector = "tex-ex", extension = true },
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1665,6 +1694,7 @@ mathematics.make_font ( "utopia-math", {
{ name = "file:putr8y", features = "virtualmath", main = true },
-- { name = "md-utr7m.tfm", vector = "tex-mr" },
{ name = "md-utri7m.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "md-utri7m.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "md-utr7y.tfm", vector = "tex-sy", skewchar=0x30, parameters = true },
{ name = "md-utr7v.tfm", vector = "tex-ex", extension = true },
{ name = "msam10.tfm", vector = "tex-ma" },
@@ -1675,6 +1705,7 @@ mathematics.make_font ( "hvmath-math", {
{ name = "file:texgyreheros-regular.otf", features = "virtualmath", main = true },
{ name = "hvrm108r.tfm", vector="tex-mr" },
{ name = "hvmi10.tfm", vector = "tex-mi", skewchar=0x7F },
+ { name = "hvmi10.tfm", vector = "tex-it", skewchar=0x7F },
{ name = "hvsy10.tfm", vector = "tex-sy", skewchar=0x30, parameters = true },
{ name = "hvex10.tfm", vector = "tex-ex", extension = true },
{ name = "hvam10.tfm", vector = "tex-ma" },
diff --git a/tex/context/base/mlib-pps.lua b/tex/context/base/mlib-pps.lua
index 253243500..f0ee1ec29 100644
--- a/tex/context/base/mlib-pps.lua
+++ b/tex/context/base/mlib-pps.lua
@@ -424,7 +424,7 @@ metapost.last_box = metapost.last_box or 1100
metapost.textext_current = metapost.first_box
metapost.multipass = false
-function metapost.free_boxes()
+function metapost.free_boxes() -- todo: mp direct list ipv box
local tb = tex.box
for i = metapost.first_box,metapost.last_box do
local b = tb[i]
diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua
index 02f6ca82d..008e44b6b 100644
--- a/tex/context/base/node-ref.lua
+++ b/tex/context/base/node-ref.lua
@@ -67,6 +67,8 @@ local function dimensions(parent,start,stop)
end
end
+-- is pardir important at all?
+
local function inject_range(head,first,last,reference,make,stack,parent,pardir,txtdir)
local width, height, depth = dimensions(parent,first,last)
if pardir == "TRT" or txtdir == "+TRT" then
diff --git a/tex/context/base/node-res.lua b/tex/context/base/node-res.lua
index f147981ed..49a1297eb 100644
--- a/tex/context/base/node-res.lua
+++ b/tex/context/base/node-res.lua
@@ -60,8 +60,10 @@ local glyph = nodes.register(new_node("glyph",0))
local textdir = nodes.register(new_node("whatsit",7))
local rule = nodes.register(new_node("rule"))
local latelua = nodes.register(new_node("whatsit",35))
---~ local user = nodes.register(new_node("user_defined"))
-local user = nodes.register(new_node(44))
+local user_n = nodes.register(new_node("whatsit",44)) user_n.type = 100
+local user_l = nodes.register(new_node("whatsit",44)) user_l.type = 110
+local user_s = nodes.register(new_node("whatsit",44)) user_s.type = 115
+local user_t = nodes.register(new_node("whatsit",44)) user_t.type = 116
function nodes.glyph(fnt,chr)
local n = copy_node(glyph)
@@ -111,27 +113,41 @@ function nodes.latelua(code)
return n
end
+local cache = { }
+
function nodes.usernumber(num)
- local n = copy_node(user)
- n.type = 100
- if num then n.value = num end
- return n
-end
-function nodes.userstring(str)
- local n = copy_node(user)
- n.type = 115
- if str then n.value = str end
- return n
+ local n = cache[num]
+ if n then
+ return copy_node(n)
+ else
+ local n = copy_node(user_n)
+ if num then n.value = num end
+ return n
+ end
end
+
function nodes.userlist(list)
- local n = copy_node(user)
- n.type = 110
+ local n = copy_node(user_l)
if list then n.value = list end
return n
end
+
+local cache = { } -- we could use the same cache
+
+function nodes.userstring(str)
+ local n = cache[str]
+ if n then
+ return copy_node(n)
+ else
+ local n = copy_node(user_s)
+ n.type = 115
+ if str then n.value = str end
+ return n
+ end
+end
+
function nodes.usertokens(tokens)
- local n = copy_node(user)
- n.type = 116
+ local n = copy_node(user_t)
if tokens then n.value = tokens end
return n
end
diff --git a/tex/context/base/node-rul.lua b/tex/context/base/node-rul.lua
index 60c6e77f3..3f1d572b7 100644
--- a/tex/context/base/node-rul.lua
+++ b/tex/context/base/node-rul.lua
@@ -11,7 +11,6 @@ if not modules then modules = { } end modules ['node-rul'] = {
local trace_ruled = false trackers.register("nodes.ruled", function(v) trace_ruled = v end)
local floor = math.floor
-local topoints = number.topoints
local n_tostring, n_tosequence = nodes.ids_tostring, nodes.tosequence
local a_ruled = attributes.private('ruled')
@@ -19,12 +18,14 @@ local a_color = attributes.private('color')
local a_transparency = attributes.private('transparency')
local a_colorspace = attributes.private('colormodel')
-local glyph = node.id("glyph")
-local disc = node.id("disc")
-local glue = node.id("glue")
-local kern = node.id("kern")
-local hlist = node.id("hlist")
-local vlist = node.id("vlist")
+local glyph = node.id("glyph")
+local disc = node.id("disc")
+local glue = node.id("glue")
+local kern = node.id("kern")
+local hlist = node.id("hlist")
+local vlist = node.id("vlist")
+local rule = node.id("rule")
+local whatsit = node.id("whatsit")
local new_rule = nodes.rule
local new_kern = nodes.kern
@@ -44,6 +45,11 @@ local variables = interfaces.variables
--
-- glyph rule unset whatsit glue margin_kern kern math disc
+local checkdir = true
+
+-- we assume {glyphruns} and no funny extra kerning, ok, maybe we need
+-- a dummy character as start and end; anyway we only collect glyphs
+
local function process_words(attribute,data,flush,head,parent)
local n = head
if n then
@@ -55,7 +61,7 @@ local function process_words(attribute,data,flush,head,parent)
local aa = has_attribute(n,attribute)
if aa then
if aa == a then
- if not f then
+ if not f then -- ?
f = n
end
l = n
@@ -77,6 +83,8 @@ local function process_words(attribute,data,flush,head,parent)
end
elseif f and id == disc then
l = n
+ elseif f and id == rule then
+ l = n
elseif f and id == kern and n.subtype == 0 then
l = n
elseif id == hlist or id == vlist then
@@ -88,6 +96,10 @@ local function process_words(attribute,data,flush,head,parent)
if list then
n.list = process_words(attribute,data,flush,list,n)
end
+ elseif checkdir and id == whatsit and n.subtype == 7 then -- only changes in dir, we assume proper boundaries
+ if f and a then
+ l = n
+ end
elseif f and not continue then
head, done = flush(head,f,l,d,level,parent), true
f, l, a = nil, nil, nil
@@ -160,7 +172,7 @@ local function flush_ruled(head,f,l,d,level,parent) -- not that fast but accepta
insert_after(head,r,k)
end
if trace_ruled then
- logs.report("ruled", "level: %s, width: %s, nodes: %s, text: %s",level,topoints(w),n_tostring(f,l),n_tosequence(f,l,true))
+ logs.report("ruled", "level: %s, width: %s, nodes: %s, text: %s",level,w,n_tostring(f,l),n_tosequence(f,l,true))
end
end
return head
@@ -179,6 +191,8 @@ end
-- tasks.appendaction ("shipouts", "normalizers", "nodes.rules.process")
-- tasks.disableaction("shipouts", "nodes.rules.process") -- only kick in when used
+local trace_shifted = false trackers.register("nodes.shifted", function(v) trace_shifted = v end)
+
local a_shifted = attributes.private('shifted')
nodes.shifts = nodes.shifts or { }
@@ -209,6 +223,9 @@ local function flush_shifted(head,first,last,data,level,parent) -- not that fast
end
local raise = data.dy * dimenfactor(data.unit,fontdata[first.font])
list.shift, list.height, list.depth = raise, height, depth
+ if trace_shifted then
+ logs.report("shifted", "width: %s, nodes: %s, text: %s",width,n_tostring(first,last),n_tosequence(first,last,true))
+ end
return head
end
diff --git a/tex/context/base/node-rul.mkiv b/tex/context/base/node-rul.mkiv
index 40d0014dc..ba2f0aed3 100644
--- a/tex/context/base/node-rul.mkiv
+++ b/tex/context/base/node-rul.mkiv
@@ -11,6 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+% todo: ex and and em traveling with attribute
+
\writestatus{loading}{ConTeXt Core Macros / Bars}
%D The name of this file might change.
@@ -255,13 +257,39 @@
\glet\dodoshifted\dodoshiftedindeed
\dodoshifted}
+% \def\dodoshiftedindeed#1%
+% {\def\currentshift{#1}%
+% \advance\csname\??ra:#1:c\endcsname\plusone
+% \scratchcounter\csname\??ra:#1:c\endcsname
+% \dosetattribute{shifted}{\numexpr1000*\scratchcounter
+% +\csname\??ra#1\ifcsname\??ra#1:\number\scratchcounter\s!parent\endcsname:\number\scratchcounter\fi:a\endcsname}%
+% \setupalign[\shiftparameter\c!align]%
+% \dosetshiftattributes\c!style\c!color}
+
+\def\dostartisolation{\char0 }
+\def\dostopisolation {\char0 }
+\def\doisolator {\char0 }
+
+\def\doisolatedgroupedalign#1#2%
+ {\groupedcommand
+ {\begingroup\dostartisolation\begingroup#1}
+ {#2\endgroup\dostopisolation\endgroup}}
+
+\def\dosetupisolatedalign#1%
+ {\doisolator
+ \setupalign[#1]\relax}
+
\def\dodoshiftedindeed#1%
{\def\currentshift{#1}%
\advance\csname\??ra:#1:c\endcsname\plusone
\scratchcounter\csname\??ra:#1:c\endcsname
\dosetattribute{shifted}{\numexpr1000*\scratchcounter
+\csname\??ra#1\ifcsname\??ra#1:\number\scratchcounter\s!parent\endcsname:\number\scratchcounter\fi:a\endcsname}%
- \dosetshiftattributes\c!style\c!color}
+ \dosetshiftattributes\c!style\c!color
+ \dosetupisolatedalign{\shiftparameter\c!align}}
+
+\def\doshifted#1%
+ {\doisolatedgroupedalign{\dodoshifted{#1}}{}}
\unexpanded\def\startshift[#1]%
{\begingroup
@@ -287,6 +315,7 @@
\c!continue=\v!no,
\c!dy=0,
\c!unit=ex,
+ \c!align=,
\c!style=,
\c!color=]
diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua
index 004aa34fa..f243c9cd0 100644
--- a/tex/context/base/node-tra.lua
+++ b/tex/context/base/node-tra.lua
@@ -310,7 +310,7 @@ function nodes.show_list(head, message)
if message then
texio.write_nl(message)
end
- for n in traverse(head) do
+ for n in traverse_nodes(head) do
texio.write_nl(tostring(n))
end
end
diff --git a/tex/context/base/pack-rul.mkiv b/tex/context/base/pack-rul.mkiv
index 8bae7e754..bd3a127e3 100644
--- a/tex/context/base/pack-rul.mkiv
+++ b/tex/context/base/pack-rul.mkiv
@@ -2286,7 +2286,7 @@
\egroup}
\def\complexvl[#1]%
- {\dovlwdhtdp\linewidth{#1}{#1}}
+ {\dovlwdhtdp{1}{#1}{#1}}
\def\complexhl[#1]%
{\hbox
diff --git a/tex/context/base/spec-fdf.mkii b/tex/context/base/spec-fdf.mkii
index 6f5a83bcb..509ea0596 100644
--- a/tex/context/base/spec-fdf.mkii
+++ b/tex/context/base/spec-fdf.mkii
@@ -191,6 +191,26 @@
\def\appendtoPDFdocumentextgstates#1%
{\xdef\docuPDFextgstates{\docuPDFextgstates\space#1}}
+%D Patterns (for tikz)
+
+\let\docuPDFpatterns\empty
+
+\def\checkPDFpatterns
+ {\ifx\docuPDFpatterns\empty \else
+ \ifnum\realpageno=\lastpage\relax
+ \doPDFdictionaryobject{FDF}{docupatterns}{\docuPDFpatterns}%
+ \fi
+ \doPDFgetobjectreference{FDF}{docupatterns}\PDFobjectreference
+ \doPDFpageresource{/Pattern \PDFobjectreference}%
+ \fi}
+
+\appendtoksonce
+ \checkPDFpatterns
+\to \everyshipout
+
+\def\appendtoPDFdocumentpatterns#1%
+ {\xdef\docuPDFpatterns{\docuPDFpatterns\space#1}}
+
%D Another special mechanism (needed for color separation):
\let\docuPDFcolorspaces\empty
diff --git a/tex/context/base/strc-not.mkiv b/tex/context/base/strc-not.mkiv
index 0d45ee59e..0246767b9 100644
--- a/tex/context/base/strc-not.mkiv
+++ b/tex/context/base/strc-not.mkiv
@@ -251,7 +251,6 @@
% \dochecknote
% \to \everysetupnote
-
\def\setupnote
{\dodoubleempty\dosetupnote}
diff --git a/tex/context/base/tabl-tbl.mkiv b/tex/context/base/tabl-tbl.mkiv
index bfff978ab..6942327fe 100644
--- a/tex/context/base/tabl-tbl.mkiv
+++ b/tex/context/base/tabl-tbl.mkiv
@@ -410,8 +410,8 @@
\def\gettabulatepreskip#1%
{\doifnumberelse{#1}
- {\edef\pretabskip{\the\dimenexpr#1\tabulateunit}\let\next\empty}
- {\edef\pretabskip{\the\dimenexpr.5\tabulateunit}\def\next{#1}}%
+ {\edef\pretabskip{\the\dimexpr#1\tabulateunit}\let\next\empty}
+ {\edef\pretabskip{\the\dimexpr.5\tabulateunit}\def\next{#1}}%
\@EA\settabulatepreamble\next}
\def\gettabulateposskip#1%
@@ -423,8 +423,8 @@
\def\gettabulatepreposskip#1%
{\doifnumberelse{#1}
- {\edef\pretabskip{\the\dimenexpr#1\tabulateunit}\let\next\empty}
- {\edef\pretabskip{\the\dimenexpr.5\tabulateunit}\def\next{#1}}%
+ {\edef\pretabskip{\the\dimexpr#1\tabulateunit}\let\next\empty}
+ {\edef\pretabskip{\the\dimexpr.5\tabulateunit}\def\next{#1}}%
\let\postabskip\pretabskip
\let\gettabulateexit\settabulatepreamble
\@EA\settabulatepreamble\next}
diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua
index dba099451..01bcaec0f 100644
--- a/tex/context/base/task-ini.lua
+++ b/tex/context/base/task-ini.lua
@@ -20,7 +20,8 @@ tasks.appendaction("processors", "characters", "chars.handle_breakpoints")
tasks.appendaction("processors", "characters", "scripts.preprocess")
tasks.appendaction("processors", "words", "kernel.hyphenation")
-tasks.appendaction("processors", "words", "languages.words.check")
+tasks.appendaction("processors", "words", "languages.words.check") -- * disabled
+
tasks.appendaction("processors", "fonts", "nodes.process_characters")
tasks.appendaction("processors", "fonts", "nodes.inject_kerns")
@@ -28,21 +29,18 @@ tasks.appendaction("processors", "fonts", "nodes.protect_glyphs", nil, "no
tasks.appendaction("processors", "fonts", "kernel.ligaturing")
tasks.appendaction("processors", "fonts", "kernel.kerning")
-tasks.appendaction("processors", "lists", "lists.handle_spacing") -- *
-tasks.appendaction("processors", "lists", "lists.handle_kerning") -- *
+tasks.appendaction("processors", "lists", "lists.handle_spacing") -- * disabled
+tasks.appendaction("processors", "lists", "lists.handle_kerning") -- * disabled
tasks.appendaction("shipouts", "normalizers", "nodes.cleanup_page")
tasks.appendaction("shipouts", "normalizers", "nodes.add_references") -- *
tasks.appendaction("shipouts", "normalizers", "nodes.add_destinations") -- *
-tasks.appendaction("shipouts", "normalizers", "nodes.rules.process") -- *
-tasks.appendaction("shipouts", "normalizers", "nodes.shifts.process") -- *
-
-tasks.disableaction("shipouts", "nodes.rules.process") -- * only kick in when used
-tasks.disableaction("shipouts", "nodes.shifts.process") -- * only kick in when used
+tasks.appendaction("shipouts", "normalizers", "nodes.rules.process") -- * disabled
+tasks.appendaction("shipouts", "normalizers", "nodes.shifts.process") -- * disabled
tasks.appendaction("shipouts", "finishers", "shipouts.handle_color")
tasks.appendaction("shipouts", "finishers", "shipouts.handle_transparency")
-tasks.appendaction("shipouts", "finishers", "shipouts.handle_colorintent")
+tasks.appendaction("shipouts", "finishers", "shipouts.handle_colorintent") -- *
tasks.appendaction("shipouts", "finishers", "shipouts.handle_negative") -- *
tasks.appendaction("shipouts", "finishers", "shipouts.handle_effect") -- *
tasks.appendaction("shipouts", "finishers", "shipouts.handle_viewerlayer") -- *
@@ -56,3 +54,11 @@ tasks.appendaction("math", "builders", "noads.mlist_to_hlist")
-- quite experimental
tasks.appendaction("finalizers", "lists", "nodes.repackage_graphicvadjust") -- *
+
+-- speedup: see * -- only kick in when used
+
+tasks.disableaction("processors", "languages.words.check")
+tasks.disableaction("processors", "lists.handle_spacing")
+tasks.disableaction("processors", "lists.handle_kerning")
+tasks.disableaction("shipouts", "nodes.rules.process")
+tasks.disableaction("shipouts", "nodes.shifts.process")
diff --git a/tex/context/base/type-otf.mkiv b/tex/context/base/type-otf.mkiv
index 983e197de..e7844fb0b 100644
--- a/tex/context/base/type-otf.mkiv
+++ b/tex/context/base/type-otf.mkiv
@@ -525,6 +525,24 @@
\loadmapfile[mdput.map]
\stoptypescript
+% asana math
+
+\starttypescript [math] [asana]
+ \definefontsynonym [AsanaMath] [name:asanamath]
+\stoptypescript
+
+\starttypescript [math] [asana] [name]
+ \definefontsynonym [MathRoman] [AsanaMath] [features=math\mathsizesuffix]
+\stoptypescript
+
+\starttypescript[asana]
+ \definetypeface [\typescriptone] [rm] [serif] [palatino] [default]
+ \definetypeface [\typescriptone] [ss] [sans] [modern] [default] [rscale=1.075]
+ \definetypeface [\typescriptone] [tt] [mono] [modern] [default] [rscale=1.075]
+ \definetypeface [\typescriptone] [mm] [math] [\typescriptone] [default]
+ \quittypescriptscanning
+\stoptypescript
+
\stoptypescriptcollection
\endinput
diff --git a/tex/context/base/typo-krn.lua b/tex/context/base/typo-krn.lua
index 5ab0b07ed..87e066531 100644
--- a/tex/context/base/typo-krn.lua
+++ b/tex/context/base/typo-krn.lua
@@ -217,3 +217,8 @@ lists.handle_kerning = nodes.install_attribute_handler {
namespace = kerns,
processor = kerns.process,
}
+
+function kerns.enable()
+ tasks.enableaction("processors","lists.handle_kerning")
+ kerns.enabled = true -- will go
+end
diff --git a/tex/context/base/typo-spa.lua b/tex/context/base/typo-spa.lua
index b6a1fbb5b..56ce36a05 100644
--- a/tex/context/base/typo-spa.lua
+++ b/tex/context/base/typo-spa.lua
@@ -25,7 +25,7 @@ local fontdata = fonts.ids
spacings = spacings or { }
spacings.mapping = spacings.mapping or { }
-spacings.enabled = false
+spacings.enabled = false -- will go
spacings.attribute = attributes.private("spacing")
storage.register("spacings/mapping", spacings.mapping, "spacings.mapping")
@@ -148,3 +148,18 @@ lists.handle_spacing = nodes.install_attribute_handler {
namespace = spacings,
processor = spacings.process,
}
+
+function spacings.enable()
+ tasks.enableaction("processors","lists.handle_spacing")
+ spacings.enabled = true -- will go
+end
+
+--~ local data = {
+--~ name = "spacing",
+--~ namespace = spacings,
+--~ processor = spacings.process,
+--~ }
+--~ nodes.process_attribute = process_attribute
+--~ function lists.handle_spacing(head)
+--~ return process_attribute(head,data)
+--~ end
diff --git a/tex/context/base/typo-spa.mkiv b/tex/context/base/typo-spa.mkiv
index d1b855edd..9ff614be9 100644
--- a/tex/context/base/typo-spa.mkiv
+++ b/tex/context/base/typo-spa.mkiv
@@ -43,7 +43,8 @@
\fi}
\def\setcharacterspacing
- {\ctxlua{spacings.enabled=true}%
+% {\ctxlua{spacings.enabled=true}%
+ {\ctxlua{spacings.enable()}%
\gdef\setcharacterspacing[##1]{\dosetattribute{spacing}{\csname\??ch:##1\endcsname}}%
\setcharacterspacing}
diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua
index 70368ebd9..82fe96610 100644
--- a/tex/generic/context/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/texmf/tex/generic/context/luatex-fonts.lua
--- merge date : 11/13/09 12:51:09
+-- merge date : 11/18/09 21:55:28
do -- begin closure to overcome local limits and interference
@@ -2345,8 +2345,10 @@ local glyph = nodes.register(new_node("glyph",0))
local textdir = nodes.register(new_node("whatsit",7))
local rule = nodes.register(new_node("rule"))
local latelua = nodes.register(new_node("whatsit",35))
---~ local user = nodes.register(new_node("user_defined"))
-local user = nodes.register(new_node(44))
+local user_n = nodes.register(new_node("whatsit",44)) user_n.type = 100
+local user_l = nodes.register(new_node("whatsit",44)) user_l.type = 110
+local user_s = nodes.register(new_node("whatsit",44)) user_s.type = 115
+local user_t = nodes.register(new_node("whatsit",44)) user_t.type = 116
function nodes.glyph(fnt,chr)
local n = copy_node(glyph)
@@ -2396,27 +2398,41 @@ function nodes.latelua(code)
return n
end
+local cache = { }
+
function nodes.usernumber(num)
- local n = copy_node(user)
- n.type = 100
- if num then n.value = num end
- return n
-end
-function nodes.userstring(str)
- local n = copy_node(user)
- n.type = 115
- if str then n.value = str end
- return n
+ local n = cache[num]
+ if n then
+ return copy_node(n)
+ else
+ local n = copy_node(user_n)
+ if num then n.value = num end
+ return n
+ end
end
+
function nodes.userlist(list)
- local n = copy_node(user)
- n.type = 110
+ local n = copy_node(user_l)
if list then n.value = list end
return n
end
+
+local cache = { } -- we could use the same cache
+
+function nodes.userstring(str)
+ local n = cache[str]
+ if n then
+ return copy_node(n)
+ else
+ local n = copy_node(user_s)
+ n.type = 115
+ if str then n.value = str end
+ return n
+ end
+end
+
function nodes.usertokens(tokens)
- local n = copy_node(user)
- n.type = 116
+ local n = copy_node(user_t)
if tokens then n.value = tokens end
return n
end
@@ -3794,15 +3810,15 @@ local private = fonts.private
end
-- needed for \high cum suis
local tpx = tp.x_height
-if hasmath then
- if not tp[13] then tp[13] = .86*tpx end -- mathsupdisplay
- if not tp[14] then tp[14] = .86*tpx end -- mathsupnormal
- if not tp[15] then tp[15] = .86*tpx end -- mathsupcramped
- if not tp[16] then tp[16] = .48*tpx end -- mathsubnormal
- if not tp[17] then tp[17] = .48*tpx end -- mathsubcombined
- if not tp[22] then tp[22] = 0 end -- mathaxisheight
- if t.MathConstants then t.MathConstants.AccentBaseHeight = nil end -- safeguard
-end
+ if hasmath then
+ if not tp[13] then tp[13] = .86*tpx end -- mathsupdisplay
+ if not tp[14] then tp[14] = .86*tpx end -- mathsupnormal
+ if not tp[15] then tp[15] = .86*tpx end -- mathsupcramped
+ if not tp[16] then tp[16] = .48*tpx end -- mathsubnormal
+ if not tp[17] then tp[17] = .48*tpx end -- mathsubcombined
+ if not tp[22] then tp[22] = 0 end -- mathaxisheight
+ if t.MathConstants then t.MathConstants.AccentBaseHeight = nil end -- safeguard
+ end
t.tounicode = 1
t.cidinfo = tfmtable.cidinfo
-- we have t.name=metricfile and t.fullname=RealName and t.filename=diskfilename
@@ -3810,20 +3826,21 @@ end
-- can have multiple subfonts
if hasmath then
if trace_defining then
- logs.report("define font","math enabled for: %s %s %s",t.name or "noname",t.fullname or "nofullname",t.filename or "nofilename")
+ logs.report("define font","math enabled for: name '%s', fullname: '%s', filename: '%s'",t.name or "noname",t.fullname or "nofullname",t.filename or "nofilename")
end
else
if trace_defining then
- logs.report("define font","math disabled for: %s %s %s",t.name or "noname",t.fullname or "nofullname",t.filename or "nofilename")
+ logs.report("define font","math disabled for: name '%s', fullname: '%s', filename: '%s'",t.name or "noname",t.fullname or "nofullname",t.filename or "nofilename")
end
t.nomath, t.MathConstants = true, nil
end
- -- fullname is used in the subsetting
if not t.psname then
- t.psname = t.fullname -- else bad luck
+ -- name used in pdf file as well as for selecting subfont in ttc/dfont
+ t.psname = t.fontname or (t.fullname and fonts.names.cleanname(t.fullname))
end
if trace_defining then
- logs.report("define font","used for subsetting: %s ",t.fullname or "nofullname")
+ logs.report("define font","used for accesing subfont: '%s'",t.psname or "nopsname")
+ logs.report("define font","used for subsetting: '%s'",t.fontname or "nofontname")
end
return t, delta
end
@@ -6705,8 +6722,9 @@ function otf.copy_to_tfm(data,cache_id) -- we can save a copy when we reorder th
tfm.units = metadata.units_per_em or 1000
-- we need a runtime lookup because of running from cdrom or zip, brrr
tfm.filename = resolvers.findbinfile(luatex.filename,"") or luatex.filename
- tfm.fullname = metadata.fontname or metadata.fullname
- tfm.psname = tfm.fullname
+ tfm.fullname = metadata.fullname
+ tfm.fontname = metadata.fontname
+ tfm.psname = tfm.fontname or tfm.fullname
tfm.encodingbytes = 2
tfm.cidinfo = data.cidinfo
tfm.cidinfo.registry = tfm.cidinfo.registry or ""
@@ -6830,7 +6848,8 @@ function tfm.read_from_open_type(specification)
if filename then
tfmtable.encodingbytes = 2
tfmtable.filename = resolvers.findbinfile(filename,"") or filename
- tfmtable.fullname = tfmtable.fullname or otfdata.metadata.fontname or otfdata.metadata.fullname
+ tfmtable.fontname = tfmtable.fontname or otfdata.metadata.fontname
+ tfmtable.fullname = tfmtable.fullname or otfdata.metadata.fullname or tfmtable.fontname
local order = otfdata and otfdata.metadata.order2
if order == 0 then
tfmtable.format = 'opentype'
@@ -6839,7 +6858,7 @@ function tfm.read_from_open_type(specification)
else
tfmtable.format = specification.format
end
- tfmtable.name = tfmtable.filename or tfmtable.fullname
+ tfmtable.name = tfmtable.filename or tfmtable.fullname or tfmtable.fontname
end
fonts.logger.save(tfmtable,file.extname(specification.filename),specification)
end
@@ -7491,7 +7510,7 @@ results in different tables.</p>
-- remark: the 'not implemented yet' variants will be done when we have fonts that use them
-- remark: we need to check what to do with discretionaries
-local concat = table.concat
+local concat, insert, remove = table.concat, table.insert, table.remove
local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip
local type, next, tonumber, tostring = type, next, tonumber, tostring
@@ -7513,6 +7532,7 @@ local trace_details = false trackers.register("otf.details", function
local trace_applied = false trackers.register("otf.applied", function(v) trace_applied = v end)
local trace_steps = false trackers.register("otf.steps", function(v) trace_steps = v end)
local trace_skips = false trackers.register("otf.skips", function(v) trace_skips = v end)
+local trace_directions = false trackers.register("otf.directions", function(v) trace_directions = v end)
trackers.register("otf.verbose_chain", function(v) otf.setcontextchain(v and "verbose") end)
trackers.register("otf.normal_chain", function(v) otf.setcontextchain(v and "normal") end)
@@ -8117,7 +8137,7 @@ function handlers.gpos_cursive(start,kind,lookupname,exitanchors,sequence) -- to
if exit then
local dx, dy, bound = set_cursive(start,nxt,tfmdata.factor,rlmode,exit,entry,characters[startchar],characters[nextchar])
if trace_cursive then
- logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound)
+ logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode)
end
done = true
break
@@ -8769,7 +8789,7 @@ function chainprocs.gpos_cursive(start,stop,kind,chainname,currentcontext,cache,
if exit then
local dx, dy, bound = set_cursive(start,nxt,tfmdata.factor,rlmode,exit,entry,characters[startchar],characters[nextchar])
if trace_cursive then
- logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound)
+ logprocess("%s: moving %s to %s cursive (%s,%s) using anchor %s and bound %s in rlmode %s",pref(kind,lookupname),gref(startchar),gref(nextchar),dx,dy,anchor,bound,rlmode)
end
done = true
break
@@ -9206,6 +9226,9 @@ local resolved = { } -- we only resolve a font,script,language pair once
-- todo: pass all these 'locals' in a table
+-- maybe some day i'll make an alternative that works on 'sub direction runs' which might be
+-- more efficient for arabic but it has quite some consequences
+
function fonts.methods.node.otf.features(head,font,attr)
if trace_steps then
checkstep(head)
@@ -9249,6 +9272,7 @@ function fonts.methods.node.otf.features(head,font,attr)
local ra = rl [attr] if ra == nil then ra = { } rl [attr] = ra end -- attr can be false
-- sequences always > 1 so no need for optimization
for s=1,#sequences do
+ local pardir, txtdir = 0, { }
local success = false
local sequence = sequences[s]
local r = ra[s] -- cache
@@ -9348,7 +9372,7 @@ function fonts.methods.node.otf.features(head,font,attr)
local ns = #subtables
local thecache = featuredata[typ] or { }
start = head -- local ?
- rlmode = 0
+ rlmode = 0 -- to be checked ?
if ns == 1 then
local lookupname = subtables[1]
local lookupcache = thecache[lookupname]
@@ -9390,24 +9414,57 @@ function fonts.methods.node.otf.features(head,font,attr)
-- start = start.next
-- end
elseif id == whatsit then
+--~ if subtype == 7 then
+--~ local dir = start.dir
+--~ if dir == "+TRT" then
+--~ rlmode = -1
+--~ elseif dir == "+TLT" then
+--~ rlmode = 1
+--~ else
+--~ rlmode = 0
+--~ end
+--~ elseif subtype == 6 then
+--~ local dir = start.dir
+--~ if dir == "TRT" then
+--~ rlmode = -1
+--~ elseif dir == "TLT" then
+--~ rlmode = 1
+--~ else
+--~ rlmode = 0
+--~ end
+--~ end
local subtype = start.subtype
if subtype == 7 then
local dir = start.dir
- if dir == "+TRT" then
+ if dir == "+TRT" or dir == "+TLT" then
+ insert(txtdir,dir)
+ elseif dir == "-TRT" or dir == "-TLT" then
+ remove(txtdir)
+ end
+ local d = txtdir[#txtdir]
+ if d == "+TRT" then
rlmode = -1
- elseif dir == "+TLT" then
+ elseif d == "+TLT" then
rlmode = 1
else
- rlmode = 0
+ rlmode = pardir
+ end
+ if trace_directions then
+ logs.report("fonts","directions after textdir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode)
end
elseif subtype == 6 then
local dir = start.dir
if dir == "TRT" then
- rlmode = -1
+ pardir = -1
elseif dir == "TLT" then
- rlmode = 1
+ pardir = 1
else
- rlmode = 0
+ pardir = 0
+ end
+ rlmode = pardir
+ --~ txtdir = { }
+ if trace_directions then
+ logs.report("fonts","directions after pardir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode)
end
end
start = start.next
@@ -9415,7 +9472,6 @@ function fonts.methods.node.otf.features(head,font,attr)
start = start.next
end
end
-
end
else
while start do
@@ -9462,25 +9518,59 @@ function fonts.methods.node.otf.features(head,font,attr)
-- end
elseif id == whatsit then
local subtype = start.subtype
- if subtype == 7 then
- local dir = start.dir
- if dir == "+TRT" then
- rlmode = -1
- elseif dir == "+TLT" then
- rlmode = 1
- else
- rlmode = 0
+--~ if subtype == 7 then
+--~ local dir = start.dir
+--~ if dir == "+TRT" then
+--~ rlmode = -1
+--~ elseif dir == "+TLT" then
+--~ rlmode = 1
+--~ else
+--~ rlmode = 0
+--~ end
+--~ elseif subtype == 6 then
+--~ local dir = start.dir
+--~ if dir == "TRT" then
+--~ rlmode = -1
+--~ elseif dir == "TLT" then
+--~ rlmode = 1
+--~ else
+--~ rlmode = 0
+--~ end
+--~ end
+ local subtype = start.subtype
+ if subtype == 7 then
+ local dir = start.dir
+ if dir == "+TRT" or dir == "+TLT" then
+ insert(txtdir,dir)
+ elseif dir == "-TRT" or dir == "-TLT" then
+ remove(txtdir)
+ end
+ local d = txtdir[#txtdir]
+ if d == "+TRT" then
+ rlmode = -1
+ elseif d == "+TLT" then
+ rlmode = 1
+ else
+ rlmode = pardir
+ end
+ if trace_directions then
+ logs.report("fonts","directions after textdir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode)
+ end
+ elseif subtype == 6 then
+ local dir = start.dir
+ if dir == "TRT" then
+ pardir = -1
+ elseif dir == "TLT" then
+ pardir = 1
+ else
+ pardir = 0
+ end
+ rlmode = pardir
+ --~ txtdir = { }
+ if trace_directions then
+ logs.report("fonts","directions after pardir %s: pardir=%s, txtdir=%s:%s, rlmode=%s",dir,pardir,#txtdir,txtdir[#txtdir] or "unset",rlmode)
end
- elseif subtype == 6 then
- local dir = start.dir
- if dir == "TRT" then
- rlmode = -1
- elseif dir == "TLT" then
- rlmode = 1
- else
- rlmode = 0
end
- end
start = start.next
else
start = start.next
@@ -11521,10 +11611,15 @@ function fonts.logger.save()
end
-- names
+--
+-- Watch out, the version number is the same as the one used in
+-- the mtx-fonts.lua function scripts.fonts.names as we use a
+-- simplified font database in the plain solution and by using
+-- a different number we're less dependent on context.
fonts.names = fonts.names or { }
-fonts.names.version = 1.014
+fonts.names.version = 1.001 -- not the same as in context
fonts.names.basename = "luatex-fonts-names.lua"
fonts.names.new_to_old = { }
fonts.names.old_to_new = { }
@@ -11539,16 +11634,6 @@ function fonts.names.resolve(name,sub)
local foundname = resolvers.find_file(basename,format) or ""
if foundname ~= "" then
data = dofile(foundname)
- if data then
- local d = { }
- for k, v in pairs(data.mapping) do
- local t = v[1]
- if t == "ttf" or t == "otf" or t == "ttc" or t == "dfont" then
- d[k] = v
- end
- end
- data.mapping = d
- end
break
end
end
@@ -11559,9 +11644,12 @@ function fonts.names.resolve(name,sub)
local condensed = string.gsub(string.lower(name),"[^%a%d]","")
local found = data.mapping and data.mapping[condensed]
if found then
- local filename, is_sub = found[3], found[4]
- if is_sub then is_sub = found[2] end
- return filename, is_sub
+ local fontname, filename, subfont = found[1], found[2], found[3]
+ if subfont then
+ return filename, fontname
+ else
+ return filename, false
+ end
else
return name, false -- fallback to filename
end