summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/context/lua/luatools.lua223
-rw-r--r--scripts/context/lua/mtx-update.lua10
-rw-r--r--scripts/context/lua/mtxrun.lua197
-rwxr-xr-xscripts/context/stubs/mswin/context.exebin5633 -> 6144 bytes
-rwxr-xr-xscripts/context/stubs/mswin/luatools.exebin5633 -> 6144 bytes
-rw-r--r--scripts/context/stubs/mswin/luatools.lua223
-rwxr-xr-xscripts/context/stubs/mswin/metatex.exebin5633 -> 6144 bytes
-rw-r--r--scripts/context/stubs/mswin/mtxrun.dllbin7680 -> 8704 bytes
-rwxr-xr-xscripts/context/stubs/mswin/mtxrun.exebin5633 -> 6144 bytes
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua197
-rwxr-xr-xscripts/context/stubs/mswin/texexec.exebin5633 -> 6144 bytes
-rwxr-xr-xscripts/context/stubs/mswin/texmfstart.exebin5633 -> 6144 bytes
-rw-r--r--scripts/context/stubs/source/mtxrun_dll.c347
-rwxr-xr-xscripts/context/stubs/unix/luatools223
-rwxr-xr-xscripts/context/stubs/unix/mtxrun197
-rw-r--r--tex/context/base/char-tex.lua2
-rw-r--r--tex/context/base/cont-new.tex2
-rw-r--r--tex/context/base/context.tex2
-rw-r--r--tex/context/base/data-res.lua11
-rw-r--r--tex/context/base/font-syn.lua2
-rw-r--r--tex/context/base/grph-inc.lua10
-rw-r--r--tex/context/base/l-dir.lua2
-rw-r--r--tex/context/base/l-file.lua4
-rw-r--r--tex/context/base/l-lpeg.lua4
-rw-r--r--tex/context/base/mlib-run.lua2
-rw-r--r--tex/context/base/node-tra.lua19
-rw-r--r--tex/context/base/s-fnt-25.tex7
-rw-r--r--tex/context/base/spec-fdf.mkii12
-rw-r--r--tex/context/base/strc-itm.mkiv113
-rw-r--r--tex/context/base/strc-num.mkiv2
-rw-r--r--tex/context/base/trac-tra.lua4
-rw-r--r--tex/context/interface/cont-cs.xml7
-rw-r--r--tex/context/interface/cont-de.xml7
-rw-r--r--tex/context/interface/cont-en.xml7
-rw-r--r--tex/context/interface/cont-fr.xml7
-rw-r--r--tex/context/interface/cont-it.xml7
-rw-r--r--tex/context/interface/cont-nl.xml7
-rw-r--r--tex/context/interface/cont-pe.xml7
-rw-r--r--tex/context/interface/cont-ro.xml7
-rw-r--r--tex/generic/context/luatex-fonts-merged.lua10
40 files changed, 1342 insertions, 539 deletions
diff --git a/scripts/context/lua/luatools.lua b/scripts/context/lua/luatools.lua
index f9b855f74..1a579eb69 100644
--- a/scripts/context/lua/luatools.lua
+++ b/scripts/context/lua/luatools.lua
@@ -338,6 +338,8 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
lpeg = require("lpeg")
+lpeg.patterns = lpeg.patterns or { } -- so that we can share
+
local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
local match = lpeg.match
@@ -488,11 +490,9 @@ end
--~
--~ 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
-
+lpeg.patterns.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
end -- of closure
@@ -1868,6 +1868,7 @@ elseif os.type == "windows" then
elseif name == "linux" then
function os.resolvers.platform(t,k)
+ -- we sometims have HOSTTYPE set so let's check that first
local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""
if find(architecture,"x86_64") then
platform = "linux-64"
@@ -1881,17 +1882,28 @@ elseif name == "linux" then
return platform
end
-elseif name == "macosx" then -- a rather inconsistent mess
+elseif name == "macosx" then
+
+ --[[
+ Identifying the architecture of OSX is quite a mess and this
+ is the best we can come up with. For some reason $HOSTTYPE is
+ a kind of pseudo environment variable, not known to the current
+ environment. And yes, uname cannot be trusted either, so there
+ is a change that you end up with a 32 bit run on a 64 bit system.
+ Also, some proper 64 bit intel macs are too cheap (low-end) and
+ therefore not permitted to run the 64 bit kernel.
+ ]]--
function os.resolvers.platform(t,k)
- local platform, architecture = "", os.resultof("uname -m") or ""
+ -- local platform, architecture = "", os.getenv("HOSTTYPE") or ""
+ -- if architecture == "" then
+ -- architecture = os.resultof("echo $HOSTTYPE") or ""
+ -- end
+ local platform, architecture = "", os.resultof("echo $HOSTTYPE") or ""
if architecture == "" then
- architecture = os.getenv("HOSTTYPE") or ""
- end
- if architecture == "" then
- architecture = os.resultof("echo $HOSTTYPE") or ""
- end
- if find(architecture,"i386") then
+ -- print("\nI have no clue what kind of OSX you're running so let's assume an 32 bit intel.\n")
+ platform = "osx-intel"
+ elseif find(architecture,"i386") then
platform = "osx-intel"
elseif find(architecture,"x86_64") then
platform = "osx-64"
@@ -1931,6 +1943,21 @@ elseif name == "freebsd" then
return platform
end
+elseif name == "kfreebsd" then
+
+ function os.resolvers.platform(t,k)
+ -- we sometims have HOSTTYPE set so let's check that first
+ local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""
+ if find(architecture,"x86_64") then
+ platform = "kfreebsd-64"
+ else
+ platform = "kfreebsd-i386"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
else
-- platform = "linux"
@@ -1967,6 +1994,21 @@ function os.uuid()
)
end
+local d
+
+function os.timezone(delta)
+ d = d or tonumber(tonumber(os.date("%H")-os.date("!%H")))
+ if delta then
+ if d > 0 then
+ return format("+%02i:00",d)
+ else
+ return format("-%02i:00",-d)
+ end
+ else
+ return 1
+ end
+end
+
end -- of closure
@@ -1985,7 +2027,7 @@ if not modules then modules = { } end modules ['l-file'] = {
file = file or { }
local concat = table.concat
-local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub
+local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char
local lpegmatch = lpeg.match
function file.removesuffix(filename)
@@ -2022,14 +2064,33 @@ end
file.suffix = file.extname
---~ print(file.join("x/","/y"))
---~ print(file.join("http://","/y"))
---~ print(file.join("http://a","/y"))
---~ print(file.join("http:///a","/y"))
---~ print(file.join("//nas-1","/y"))
+--~ function file.join(...)
+--~ local pth = concat({...},"/")
+--~ pth = gsub(pth,"\\","/")
+--~ local a, b = match(pth,"^(.*://)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ a, b = match(pth,"^(//)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ return (gsub(pth,"//+","/"))
+--~ end
+
+local trick_1 = char(1)
+local trick_2 = "^" .. trick_1 .. "/+"
function file.join(...)
- local pth = concat({...},"/")
+ local lst = { ... }
+ local a, b = lst[1], lst[2]
+ if a == "" then
+ lst[1] = trick_1
+ elseif b and find(a,"^/+$") and find(b,"^/") then
+ lst[1] = ""
+ lst[2] = gsub(b,"^/+","")
+ end
+ local pth = concat(lst,"/")
pth = gsub(pth,"\\","/")
local a, b = match(pth,"^(.*://)(.*)$")
if a and b then
@@ -2039,9 +2100,20 @@ function file.join(...)
if a and b then
return a .. gsub(b,"//+","/")
end
+ pth = gsub(pth,trick_2,"")
return (gsub(pth,"//+","/"))
end
+--~ print(file.join("//","/y"))
+--~ print(file.join("/","/y"))
+--~ print(file.join("","/y"))
+--~ print(file.join("/x/","/y"))
+--~ print(file.join("x/","/y"))
+--~ print(file.join("http://","/y"))
+--~ print(file.join("http://a","/y"))
+--~ print(file.join("http:///a","/y"))
+--~ print(file.join("//nas-1","/y"))
+
function file.iswritable(name)
local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,"."))
return a and sub(a.permissions,2,2) == "w"
@@ -2080,16 +2152,22 @@ function file.join_path(tab)
return concat(tab,io.pathseparator) -- can have trailing //
end
+-- we can hash them weakly
+
function file.collapse_path(str)
- str = gsub(str,"/%./","/")
- local n, m = 1, 1
- while n > 0 or m > 0 do
- str, n = gsub(str,"[^/%.]+/%.%.$","")
- str, m = gsub(str,"[^/%.]+/%.%./","")
- end
- str = gsub(str,"([^/])/$","%1")
- str = gsub(str,"^%./","")
- str = gsub(str,"/%.$","")
+ str = gsub(str,"\\","/")
+ if find(str,"/") then
+ str = gsub(str,"^%./",(gsub(lfs.currentdir(),"\\","/")) .. "/") -- ./xx in qualified
+ str = gsub(str,"/%./","/")
+ local n, m = 1, 1
+ while n > 0 or m > 0 do
+ str, n = gsub(str,"[^/%.]+/%.%.$","")
+ str, m = gsub(str,"[^/%.]+/%.%./","")
+ end
+ str = gsub(str,"([^/])/$","%1")
+ -- str = gsub(str,"^%./","") -- ./xx in qualified
+ str = gsub(str,"/%.$","")
+ end
if str == "" then str = "." end
return str
end
@@ -2391,7 +2469,7 @@ function url.hashed(str)
end
function url.hasscheme(str)
- return not url.split(str).nosheme
+ return url.split(str)[1] ~= ""
end
function url.addscheme(str,scheme)
@@ -2788,7 +2866,7 @@ else
--~ print(dir.mkdirs("///a/b/c"))
--~ print(dir.mkdirs("a/bbb//ccc/"))
- function dir.expand_name(str)
+ function dir.expand_name(str) -- will be merged with cleanpath and collapsepath
if not find(str,"^/") then
str = lfs.currentdir() .. "/" .. str
end
@@ -3503,6 +3581,8 @@ local stripper = lpeg.Cs((number + 1)^0)
--~ lpegmatch(stripper,str)
--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample))
+lpeg.patterns.strip_zeros = stripper
+
function aux.strip_zeros(str)
return lpegmatch(stripper,str)
end
@@ -3789,14 +3869,14 @@ end
function setters.enable(t,what)
local e = t.enable
t.enable, t.done = enable, { }
- enable(t,string.simpleesc(what))
+ enable(t,string.simpleesc(tostring(what)))
t.enable, t.done = e, { }
end
function setters.disable(t,what)
local e = t.disable
t.disable, t.done = disable, { }
- disable(t,string.simpleesc(what))
+ disable(t,string.simpleesc(tostring(what)))
t.disable, t.done = e, { }
end
@@ -3847,13 +3927,15 @@ function setters.new(name)
return t
end
-trackers = setters.new("trackers")
-directives = setters.new("directives")
+trackers = setters.new("trackers")
+directives = setters.new("directives")
+experiments = setters.new("experiments")
-- 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 trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end)
+local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end)
local e = directives.enable
local d = directives.disable
@@ -3868,6 +3950,26 @@ function directives.disable(...)
d(...)
end
+local e = experiments.enable
+local d = experiments.disable
+
+function experiments.enable(...)
+ commands.writestatus("experiments","enabling: %s",concat({...}," "))
+ e(...)
+end
+
+function experiments.disable(...)
+ commands.writestatus("experiments","disabling: %s",concat({...}," "))
+ d(...)
+end
+
+-- a useful example
+
+directives.register("system.nostatistics", function(v)
+ statistics.enable = not v
+end)
+
+
end -- of closure
@@ -4181,6 +4283,14 @@ function statistics.hastimer(instance)
return instance and instance.starttime
end
+function statistics.resettiming(instance)
+ if not instance then
+ notimer = { timing = 0, loadtime = 0 }
+ else
+ instance.timing, instance.loadtime = 0, 0
+ end
+end
+
function statistics.starttiming(instance)
if not instance then
notimer = { }
@@ -4240,6 +4350,12 @@ function statistics.elapsedindeed(instance)
return t > statistics.threshold
end
+function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds
+ if statistics.elapsedindeed(instance) then
+ return format("%s seconds %s", statistics.elapsedtime(instance),rest or "")
+ end
+end
+
-- general function
function statistics.register(tag,fnc)
@@ -4318,6 +4434,23 @@ function statistics.timed(action,report)
report("total runtime: %s",statistics.elapsedtime(timer))
end
+-- where, not really the best spot for this:
+
+commands = commands or { }
+
+local timer
+
+function commands.resettimer()
+ statistics.resettiming(timer)
+ statistics.starttiming(timer)
+end
+
+function commands.elapsedtime()
+ statistics.stoptiming(timer)
+ tex.sprint(statistics.elapsedtime(timer))
+end
+
+commands.resettimer()
end -- of closure
@@ -4755,8 +4888,8 @@ suffixes['lua'] = { 'lua', 'luc', 'tma', 'tmc' }
alternatives['map files'] = 'map'
alternatives['enc files'] = 'enc'
-alternatives['cid files'] = 'cid'
-alternatives['fea files'] = 'fea'
+alternatives['cid maps'] = 'cid' -- great, why no cid files
+alternatives['font feature files'] = 'fea' -- and fea files here
alternatives['opentype fonts'] = 'otf'
alternatives['truetype fonts'] = 'ttf'
alternatives['truetype collections'] = 'ttc'
@@ -4899,8 +5032,10 @@ local function check_configuration() -- not yet ok, no time for debugging now
-- bad luck
end
fix("LUAINPUTS" , ".;$TEXINPUTS;$TEXMFSCRIPTS") -- no progname, hm
- fix("FONTFEATURES", ".;$TEXMF/fonts/fea//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
- fix("FONTCIDMAPS" , ".;$TEXMF/fonts/cid//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ -- this will go away some day
+ fix("FONTFEATURES", ".;$TEXMF/fonts/{data,fea}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ fix("FONTCIDMAPS" , ".;$TEXMF/fonts/{data,cid}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ --
fix("LUATEXLIBS" , ".;$TEXMF/luatex/lua//")
end
@@ -5290,7 +5425,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -5319,7 +5454,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -5444,7 +5579,7 @@ local weird = lpeg.P(".")^1 + lpeg.anywhere(lpeg.S("~`!#$%^&*()={}[]:;\"\'||<>,?
--~ local l_forbidden = lpeg.S("~`!#$%^&*()={}[]:;\"\'||\\/<>,?\n\r\t")
--~ local l_confusing = lpeg.P(" ")
---~ local l_character = lpeg.utf8
+--~ local l_character = lpeg.patterns.utf8
--~ local l_dangerous = lpeg.P(".")
--~ local l_normal = (l_character - l_forbidden - l_confusing - l_dangerous) * (l_character - l_forbidden - l_confusing^2)^0 * lpeg.P(-1)
@@ -6184,8 +6319,7 @@ 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 = file.collapse_path(filename)
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -6666,12 +6800,13 @@ end
function table.sequenced(t,sep) -- temp here
local s = { }
for k, v in pairs(t) do -- pairs?
- s[#s+1] = k .. "=" .. v
+ s[#s+1] = k .. "=" .. tostring(v)
end
return concat(s, sep or " | ")
end
function resolvers.methodhandler(what, filename, filetype) -- ...
+ filename = file.collapse_path(filename)
local specification = (type(filename) == "string" and resolvers.splitmethod(filename)) or filename -- no or { }, let it bomb
local scheme = specification.scheme
if resolvers[what][scheme] then
diff --git a/scripts/context/lua/mtx-update.lua b/scripts/context/lua/mtx-update.lua
index 09d3106b6..4f04b2245 100644
--- a/scripts/context/lua/mtx-update.lua
+++ b/scripts/context/lua/mtx-update.lua
@@ -383,7 +383,13 @@ function scripts.update.synchronize()
end
if not force then
logs.report("update", "use --force to really update files")
+ else
+ -- update filename database for pdftex/xetex
+ scripts.update.run("mktexlsr")
+ -- update filename database for luatex
+ scripts.update.run("luatools --generate")
end
+
logs.report("update","done")
end
@@ -408,10 +414,6 @@ function scripts.update.make()
local formats = states.get('formats')
resolvers.load_tree(texroot)
- -- update filename database for pdftex/xetex
- scripts.update.run("mktexlsr")
- -- update filename database for luatex
- scripts.update.run("luatools --generate")
local askedformats = formats
local texformats = table.tohash(scripts.update.texformats)
local mpformats = table.tohash(scripts.update.mpformats)
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 8a2d7a123..ef7eda9b0 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -347,6 +347,8 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
lpeg = require("lpeg")
+lpeg.patterns = lpeg.patterns or { } -- so that we can share
+
local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
local match = lpeg.match
@@ -497,11 +499,9 @@ end
--~
--~ 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
-
+lpeg.patterns.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
end -- of closure
@@ -1952,6 +1952,21 @@ elseif name == "freebsd" then
return platform
end
+elseif name == "kfreebsd" then
+
+ function os.resolvers.platform(t,k)
+ -- we sometims have HOSTTYPE set so let's check that first
+ local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""
+ if find(architecture,"x86_64") then
+ platform = "kfreebsd-64"
+ else
+ platform = "kfreebsd-i386"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
else
-- platform = "linux"
@@ -2021,7 +2036,7 @@ if not modules then modules = { } end modules ['l-file'] = {
file = file or { }
local concat = table.concat
-local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub
+local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char
local lpegmatch = lpeg.match
function file.removesuffix(filename)
@@ -2058,14 +2073,33 @@ end
file.suffix = file.extname
---~ print(file.join("x/","/y"))
---~ print(file.join("http://","/y"))
---~ print(file.join("http://a","/y"))
---~ print(file.join("http:///a","/y"))
---~ print(file.join("//nas-1","/y"))
+--~ function file.join(...)
+--~ local pth = concat({...},"/")
+--~ pth = gsub(pth,"\\","/")
+--~ local a, b = match(pth,"^(.*://)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ a, b = match(pth,"^(//)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ return (gsub(pth,"//+","/"))
+--~ end
+
+local trick_1 = char(1)
+local trick_2 = "^" .. trick_1 .. "/+"
function file.join(...)
- local pth = concat({...},"/")
+ local lst = { ... }
+ local a, b = lst[1], lst[2]
+ if a == "" then
+ lst[1] = trick_1
+ elseif b and find(a,"^/+$") and find(b,"^/") then
+ lst[1] = ""
+ lst[2] = gsub(b,"^/+","")
+ end
+ local pth = concat(lst,"/")
pth = gsub(pth,"\\","/")
local a, b = match(pth,"^(.*://)(.*)$")
if a and b then
@@ -2075,9 +2109,20 @@ function file.join(...)
if a and b then
return a .. gsub(b,"//+","/")
end
+ pth = gsub(pth,trick_2,"")
return (gsub(pth,"//+","/"))
end
+--~ print(file.join("//","/y"))
+--~ print(file.join("/","/y"))
+--~ print(file.join("","/y"))
+--~ print(file.join("/x/","/y"))
+--~ print(file.join("x/","/y"))
+--~ print(file.join("http://","/y"))
+--~ print(file.join("http://a","/y"))
+--~ print(file.join("http:///a","/y"))
+--~ print(file.join("//nas-1","/y"))
+
function file.iswritable(name)
local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,"."))
return a and sub(a.permissions,2,2) == "w"
@@ -2116,16 +2161,22 @@ function file.join_path(tab)
return concat(tab,io.pathseparator) -- can have trailing //
end
+-- we can hash them weakly
+
function file.collapse_path(str)
- str = gsub(str,"/%./","/")
- local n, m = 1, 1
- while n > 0 or m > 0 do
- str, n = gsub(str,"[^/%.]+/%.%.$","")
- str, m = gsub(str,"[^/%.]+/%.%./","")
- end
- str = gsub(str,"([^/])/$","%1")
- str = gsub(str,"^%./","")
- str = gsub(str,"/%.$","")
+ str = gsub(str,"\\","/")
+ if find(str,"/") then
+ str = gsub(str,"^%./",(gsub(lfs.currentdir(),"\\","/")) .. "/") -- ./xx in qualified
+ str = gsub(str,"/%./","/")
+ local n, m = 1, 1
+ while n > 0 or m > 0 do
+ str, n = gsub(str,"[^/%.]+/%.%.$","")
+ str, m = gsub(str,"[^/%.]+/%.%./","")
+ end
+ str = gsub(str,"([^/])/$","%1")
+ -- str = gsub(str,"^%./","") -- ./xx in qualified
+ str = gsub(str,"/%.$","")
+ end
if str == "" then str = "." end
return str
end
@@ -2824,7 +2875,7 @@ else
--~ print(dir.mkdirs("///a/b/c"))
--~ print(dir.mkdirs("a/bbb//ccc/"))
- function dir.expand_name(str)
+ function dir.expand_name(str) -- will be merged with cleanpath and collapsepath
if not find(str,"^/") then
str = lfs.currentdir() .. "/" .. str
end
@@ -3340,6 +3391,8 @@ local stripper = lpeg.Cs((number + 1)^0)
--~ lpegmatch(stripper,str)
--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample))
+lpeg.patterns.strip_zeros = stripper
+
function aux.strip_zeros(str)
return lpegmatch(stripper,str)
end
@@ -3626,14 +3679,14 @@ end
function setters.enable(t,what)
local e = t.enable
t.enable, t.done = enable, { }
- enable(t,string.simpleesc(what))
+ enable(t,string.simpleesc(tostring(what)))
t.enable, t.done = e, { }
end
function setters.disable(t,what)
local e = t.disable
t.disable, t.done = disable, { }
- disable(t,string.simpleesc(what))
+ disable(t,string.simpleesc(tostring(what)))
t.disable, t.done = e, { }
end
@@ -3720,6 +3773,13 @@ function experiments.disable(...)
d(...)
end
+-- a useful example
+
+directives.register("system.nostatistics", function(v)
+ statistics.enable = not v
+end)
+
+
end -- of closure
@@ -3995,9 +4055,9 @@ local function attribute_specification_error(str)
return str
end
-function xml.unknown_dec_entity_format(str) return format("&%s;", str) end
+function xml.unknown_dec_entity_format(str) return (str == "" and "&error;") or format("&%s;",str) end
function xml.unknown_hex_entity_format(str) return format("&#x%s;",str) end
-function xml.unknown_any_entity_format(str) return format("&%s;", str) end
+function xml.unknown_any_entity_format(str) return format("&#x%s;",str) end
local function handle_hex_entity(str)
local h = hcache[str]
@@ -4111,7 +4171,11 @@ local function handle_any_entity(str)
if trace_entities then
logs.report("xml","keeping entity &%s;",str)
end
- a = "&" .. str .. ";"
+ if str == "" then
+ a = "&error;"
+ else
+ a = "&" .. str .. ";"
+ end
end
end
acache[str] = a
@@ -4132,6 +4196,9 @@ local function handle_any_entity(str)
if a then
-- one of the predefined
acache[str] = a
+ elseif str == "" then
+ a = "&error;"
+ acache[str] = a
else
a = "&" .. str .. ";"
acache[str] = a
@@ -4460,7 +4527,7 @@ function xml.checkbom(root) -- can be made faster
local dt, found = root.dt, false
for k=1,#dt do
local v = dt[k]
- if type(v) == "table" and v.special and v.tg == "@pi" and find(v.dt,"xml.*version=") then
+ if type(v) == "table" and v.special and v.tg == "@pi@" and find(v.dt[1],"xml.*version=") then
found = true
break
end
@@ -4842,6 +4909,8 @@ function xml.assign(dt,k,root)
end
end
+-- the following helpers may move
+
--[[ldx--
<p>The next helper assigns a tree (or string). Usage:</p>
<typing>
@@ -4860,6 +4929,22 @@ function xml.tocdata(e,wrapper)
e.dt = { t }
end
+function xml.makestandalone(root)
+ if root.ri then
+ local dt = root.dt
+ for k=1,#dt do
+ local v = dt[k]
+ if type(v) == "table" and v.special and v.tg == "@pi@" then
+ local txt = v.dt[1]
+ if find(txt,"xml.*version=") then
+ v.dt[1] = txt .. " standalone='yes'"
+ break
+ end
+ end
+ end
+ end
+end
+
end -- of closure
@@ -5476,8 +5561,13 @@ local register_initial_child = { kind = "axis", axis = "initial-child"
local register_all_nodes = { kind = "nodes", nodetest = true, nodes = { true, false, false } }
+local skip = { }
+
local function errorrunner_e(str,cnv)
- logs.report("lpath","error in expression: %s => %s",str,cnv)
+ if not skip[str] then
+ logs.report("lpath","error in expression: %s => %s",str,cnv)
+ skip[str] = cnv or str
+ end
return false
end
local function errorrunner_f(str,arg)
@@ -7287,6 +7377,14 @@ function statistics.hastimer(instance)
return instance and instance.starttime
end
+function statistics.resettiming(instance)
+ if not instance then
+ notimer = { timing = 0, loadtime = 0 }
+ else
+ instance.timing, instance.loadtime = 0, 0
+ end
+end
+
function statistics.starttiming(instance)
if not instance then
notimer = { }
@@ -7346,6 +7444,12 @@ function statistics.elapsedindeed(instance)
return t > statistics.threshold
end
+function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds
+ if statistics.elapsedindeed(instance) then
+ return format("%s seconds %s", statistics.elapsedtime(instance),rest or "")
+ end
+end
+
-- general function
function statistics.register(tag,fnc)
@@ -7424,6 +7528,23 @@ function statistics.timed(action,report)
report("total runtime: %s",statistics.elapsedtime(timer))
end
+-- where, not really the best spot for this:
+
+commands = commands or { }
+
+local timer
+
+function commands.resettimer()
+ statistics.resettiming(timer)
+ statistics.starttiming(timer)
+end
+
+function commands.elapsedtime()
+ statistics.stoptiming(timer)
+ tex.sprint(statistics.elapsedtime(timer))
+end
+
+commands.resettimer()
end -- of closure
@@ -7861,8 +7982,8 @@ suffixes['lua'] = { 'lua', 'luc', 'tma', 'tmc' }
alternatives['map files'] = 'map'
alternatives['enc files'] = 'enc'
-alternatives['cid files'] = 'cid'
-alternatives['fea files'] = 'fea'
+alternatives['cid maps'] = 'cid' -- great, why no cid files
+alternatives['font feature files'] = 'fea' -- and fea files here
alternatives['opentype fonts'] = 'otf'
alternatives['truetype fonts'] = 'ttf'
alternatives['truetype collections'] = 'ttc'
@@ -8005,8 +8126,10 @@ local function check_configuration() -- not yet ok, no time for debugging now
-- bad luck
end
fix("LUAINPUTS" , ".;$TEXINPUTS;$TEXMFSCRIPTS") -- no progname, hm
- fix("FONTFEATURES", ".;$TEXMF/fonts/fea//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
- fix("FONTCIDMAPS" , ".;$TEXMF/fonts/cid//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ -- this will go away some day
+ fix("FONTFEATURES", ".;$TEXMF/fonts/{data,fea}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ fix("FONTCIDMAPS" , ".;$TEXMF/fonts/{data,cid}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ --
fix("LUATEXLIBS" , ".;$TEXMF/luatex/lua//")
end
@@ -8396,7 +8519,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -8425,7 +8548,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -8550,7 +8673,7 @@ local weird = lpeg.P(".")^1 + lpeg.anywhere(lpeg.S("~`!#$%^&*()={}[]:;\"\'||<>,?
--~ local l_forbidden = lpeg.S("~`!#$%^&*()={}[]:;\"\'||\\/<>,?\n\r\t")
--~ local l_confusing = lpeg.P(" ")
---~ local l_character = lpeg.utf8
+--~ local l_character = lpeg.patterns.utf8
--~ local l_dangerous = lpeg.P(".")
--~ local l_normal = (l_character - l_forbidden - l_confusing - l_dangerous) * (l_character - l_forbidden - l_confusing^2)^0 * lpeg.P(-1)
@@ -9290,8 +9413,7 @@ 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 = file.collapse_path(filename)
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -9772,12 +9894,13 @@ end
function table.sequenced(t,sep) -- temp here
local s = { }
for k, v in pairs(t) do -- pairs?
- s[#s+1] = k .. "=" .. v
+ s[#s+1] = k .. "=" .. tostring(v)
end
return concat(s, sep or " | ")
end
function resolvers.methodhandler(what, filename, filetype) -- ...
+ filename = file.collapse_path(filename)
local specification = (type(filename) == "string" and resolvers.splitmethod(filename)) or filename -- no or { }, let it bomb
local scheme = specification.scheme
if resolvers[what][scheme] then
diff --git a/scripts/context/stubs/mswin/context.exe b/scripts/context/stubs/mswin/context.exe
index 9a67fc133..2d45f2749 100755
--- a/scripts/context/stubs/mswin/context.exe
+++ b/scripts/context/stubs/mswin/context.exe
Binary files differ
diff --git a/scripts/context/stubs/mswin/luatools.exe b/scripts/context/stubs/mswin/luatools.exe
index 9a67fc133..2d45f2749 100755
--- a/scripts/context/stubs/mswin/luatools.exe
+++ b/scripts/context/stubs/mswin/luatools.exe
Binary files differ
diff --git a/scripts/context/stubs/mswin/luatools.lua b/scripts/context/stubs/mswin/luatools.lua
index f9b855f74..1a579eb69 100644
--- a/scripts/context/stubs/mswin/luatools.lua
+++ b/scripts/context/stubs/mswin/luatools.lua
@@ -338,6 +338,8 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
lpeg = require("lpeg")
+lpeg.patterns = lpeg.patterns or { } -- so that we can share
+
local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
local match = lpeg.match
@@ -488,11 +490,9 @@ end
--~
--~ 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
-
+lpeg.patterns.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
end -- of closure
@@ -1868,6 +1868,7 @@ elseif os.type == "windows" then
elseif name == "linux" then
function os.resolvers.platform(t,k)
+ -- we sometims have HOSTTYPE set so let's check that first
local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""
if find(architecture,"x86_64") then
platform = "linux-64"
@@ -1881,17 +1882,28 @@ elseif name == "linux" then
return platform
end
-elseif name == "macosx" then -- a rather inconsistent mess
+elseif name == "macosx" then
+
+ --[[
+ Identifying the architecture of OSX is quite a mess and this
+ is the best we can come up with. For some reason $HOSTTYPE is
+ a kind of pseudo environment variable, not known to the current
+ environment. And yes, uname cannot be trusted either, so there
+ is a change that you end up with a 32 bit run on a 64 bit system.
+ Also, some proper 64 bit intel macs are too cheap (low-end) and
+ therefore not permitted to run the 64 bit kernel.
+ ]]--
function os.resolvers.platform(t,k)
- local platform, architecture = "", os.resultof("uname -m") or ""
+ -- local platform, architecture = "", os.getenv("HOSTTYPE") or ""
+ -- if architecture == "" then
+ -- architecture = os.resultof("echo $HOSTTYPE") or ""
+ -- end
+ local platform, architecture = "", os.resultof("echo $HOSTTYPE") or ""
if architecture == "" then
- architecture = os.getenv("HOSTTYPE") or ""
- end
- if architecture == "" then
- architecture = os.resultof("echo $HOSTTYPE") or ""
- end
- if find(architecture,"i386") then
+ -- print("\nI have no clue what kind of OSX you're running so let's assume an 32 bit intel.\n")
+ platform = "osx-intel"
+ elseif find(architecture,"i386") then
platform = "osx-intel"
elseif find(architecture,"x86_64") then
platform = "osx-64"
@@ -1931,6 +1943,21 @@ elseif name == "freebsd" then
return platform
end
+elseif name == "kfreebsd" then
+
+ function os.resolvers.platform(t,k)
+ -- we sometims have HOSTTYPE set so let's check that first
+ local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""
+ if find(architecture,"x86_64") then
+ platform = "kfreebsd-64"
+ else
+ platform = "kfreebsd-i386"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
else
-- platform = "linux"
@@ -1967,6 +1994,21 @@ function os.uuid()
)
end
+local d
+
+function os.timezone(delta)
+ d = d or tonumber(tonumber(os.date("%H")-os.date("!%H")))
+ if delta then
+ if d > 0 then
+ return format("+%02i:00",d)
+ else
+ return format("-%02i:00",-d)
+ end
+ else
+ return 1
+ end
+end
+
end -- of closure
@@ -1985,7 +2027,7 @@ if not modules then modules = { } end modules ['l-file'] = {
file = file or { }
local concat = table.concat
-local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub
+local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char
local lpegmatch = lpeg.match
function file.removesuffix(filename)
@@ -2022,14 +2064,33 @@ end
file.suffix = file.extname
---~ print(file.join("x/","/y"))
---~ print(file.join("http://","/y"))
---~ print(file.join("http://a","/y"))
---~ print(file.join("http:///a","/y"))
---~ print(file.join("//nas-1","/y"))
+--~ function file.join(...)
+--~ local pth = concat({...},"/")
+--~ pth = gsub(pth,"\\","/")
+--~ local a, b = match(pth,"^(.*://)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ a, b = match(pth,"^(//)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ return (gsub(pth,"//+","/"))
+--~ end
+
+local trick_1 = char(1)
+local trick_2 = "^" .. trick_1 .. "/+"
function file.join(...)
- local pth = concat({...},"/")
+ local lst = { ... }
+ local a, b = lst[1], lst[2]
+ if a == "" then
+ lst[1] = trick_1
+ elseif b and find(a,"^/+$") and find(b,"^/") then
+ lst[1] = ""
+ lst[2] = gsub(b,"^/+","")
+ end
+ local pth = concat(lst,"/")
pth = gsub(pth,"\\","/")
local a, b = match(pth,"^(.*://)(.*)$")
if a and b then
@@ -2039,9 +2100,20 @@ function file.join(...)
if a and b then
return a .. gsub(b,"//+","/")
end
+ pth = gsub(pth,trick_2,"")
return (gsub(pth,"//+","/"))
end
+--~ print(file.join("//","/y"))
+--~ print(file.join("/","/y"))
+--~ print(file.join("","/y"))
+--~ print(file.join("/x/","/y"))
+--~ print(file.join("x/","/y"))
+--~ print(file.join("http://","/y"))
+--~ print(file.join("http://a","/y"))
+--~ print(file.join("http:///a","/y"))
+--~ print(file.join("//nas-1","/y"))
+
function file.iswritable(name)
local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,"."))
return a and sub(a.permissions,2,2) == "w"
@@ -2080,16 +2152,22 @@ function file.join_path(tab)
return concat(tab,io.pathseparator) -- can have trailing //
end
+-- we can hash them weakly
+
function file.collapse_path(str)
- str = gsub(str,"/%./","/")
- local n, m = 1, 1
- while n > 0 or m > 0 do
- str, n = gsub(str,"[^/%.]+/%.%.$","")
- str, m = gsub(str,"[^/%.]+/%.%./","")
- end
- str = gsub(str,"([^/])/$","%1")
- str = gsub(str,"^%./","")
- str = gsub(str,"/%.$","")
+ str = gsub(str,"\\","/")
+ if find(str,"/") then
+ str = gsub(str,"^%./",(gsub(lfs.currentdir(),"\\","/")) .. "/") -- ./xx in qualified
+ str = gsub(str,"/%./","/")
+ local n, m = 1, 1
+ while n > 0 or m > 0 do
+ str, n = gsub(str,"[^/%.]+/%.%.$","")
+ str, m = gsub(str,"[^/%.]+/%.%./","")
+ end
+ str = gsub(str,"([^/])/$","%1")
+ -- str = gsub(str,"^%./","") -- ./xx in qualified
+ str = gsub(str,"/%.$","")
+ end
if str == "" then str = "." end
return str
end
@@ -2391,7 +2469,7 @@ function url.hashed(str)
end
function url.hasscheme(str)
- return not url.split(str).nosheme
+ return url.split(str)[1] ~= ""
end
function url.addscheme(str,scheme)
@@ -2788,7 +2866,7 @@ else
--~ print(dir.mkdirs("///a/b/c"))
--~ print(dir.mkdirs("a/bbb//ccc/"))
- function dir.expand_name(str)
+ function dir.expand_name(str) -- will be merged with cleanpath and collapsepath
if not find(str,"^/") then
str = lfs.currentdir() .. "/" .. str
end
@@ -3503,6 +3581,8 @@ local stripper = lpeg.Cs((number + 1)^0)
--~ lpegmatch(stripper,str)
--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample))
+lpeg.patterns.strip_zeros = stripper
+
function aux.strip_zeros(str)
return lpegmatch(stripper,str)
end
@@ -3789,14 +3869,14 @@ end
function setters.enable(t,what)
local e = t.enable
t.enable, t.done = enable, { }
- enable(t,string.simpleesc(what))
+ enable(t,string.simpleesc(tostring(what)))
t.enable, t.done = e, { }
end
function setters.disable(t,what)
local e = t.disable
t.disable, t.done = disable, { }
- disable(t,string.simpleesc(what))
+ disable(t,string.simpleesc(tostring(what)))
t.disable, t.done = e, { }
end
@@ -3847,13 +3927,15 @@ function setters.new(name)
return t
end
-trackers = setters.new("trackers")
-directives = setters.new("directives")
+trackers = setters.new("trackers")
+directives = setters.new("directives")
+experiments = setters.new("experiments")
-- 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 trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end)
+local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end)
local e = directives.enable
local d = directives.disable
@@ -3868,6 +3950,26 @@ function directives.disable(...)
d(...)
end
+local e = experiments.enable
+local d = experiments.disable
+
+function experiments.enable(...)
+ commands.writestatus("experiments","enabling: %s",concat({...}," "))
+ e(...)
+end
+
+function experiments.disable(...)
+ commands.writestatus("experiments","disabling: %s",concat({...}," "))
+ d(...)
+end
+
+-- a useful example
+
+directives.register("system.nostatistics", function(v)
+ statistics.enable = not v
+end)
+
+
end -- of closure
@@ -4181,6 +4283,14 @@ function statistics.hastimer(instance)
return instance and instance.starttime
end
+function statistics.resettiming(instance)
+ if not instance then
+ notimer = { timing = 0, loadtime = 0 }
+ else
+ instance.timing, instance.loadtime = 0, 0
+ end
+end
+
function statistics.starttiming(instance)
if not instance then
notimer = { }
@@ -4240,6 +4350,12 @@ function statistics.elapsedindeed(instance)
return t > statistics.threshold
end
+function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds
+ if statistics.elapsedindeed(instance) then
+ return format("%s seconds %s", statistics.elapsedtime(instance),rest or "")
+ end
+end
+
-- general function
function statistics.register(tag,fnc)
@@ -4318,6 +4434,23 @@ function statistics.timed(action,report)
report("total runtime: %s",statistics.elapsedtime(timer))
end
+-- where, not really the best spot for this:
+
+commands = commands or { }
+
+local timer
+
+function commands.resettimer()
+ statistics.resettiming(timer)
+ statistics.starttiming(timer)
+end
+
+function commands.elapsedtime()
+ statistics.stoptiming(timer)
+ tex.sprint(statistics.elapsedtime(timer))
+end
+
+commands.resettimer()
end -- of closure
@@ -4755,8 +4888,8 @@ suffixes['lua'] = { 'lua', 'luc', 'tma', 'tmc' }
alternatives['map files'] = 'map'
alternatives['enc files'] = 'enc'
-alternatives['cid files'] = 'cid'
-alternatives['fea files'] = 'fea'
+alternatives['cid maps'] = 'cid' -- great, why no cid files
+alternatives['font feature files'] = 'fea' -- and fea files here
alternatives['opentype fonts'] = 'otf'
alternatives['truetype fonts'] = 'ttf'
alternatives['truetype collections'] = 'ttc'
@@ -4899,8 +5032,10 @@ local function check_configuration() -- not yet ok, no time for debugging now
-- bad luck
end
fix("LUAINPUTS" , ".;$TEXINPUTS;$TEXMFSCRIPTS") -- no progname, hm
- fix("FONTFEATURES", ".;$TEXMF/fonts/fea//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
- fix("FONTCIDMAPS" , ".;$TEXMF/fonts/cid//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ -- this will go away some day
+ fix("FONTFEATURES", ".;$TEXMF/fonts/{data,fea}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ fix("FONTCIDMAPS" , ".;$TEXMF/fonts/{data,cid}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ --
fix("LUATEXLIBS" , ".;$TEXMF/luatex/lua//")
end
@@ -5290,7 +5425,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -5319,7 +5454,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -5444,7 +5579,7 @@ local weird = lpeg.P(".")^1 + lpeg.anywhere(lpeg.S("~`!#$%^&*()={}[]:;\"\'||<>,?
--~ local l_forbidden = lpeg.S("~`!#$%^&*()={}[]:;\"\'||\\/<>,?\n\r\t")
--~ local l_confusing = lpeg.P(" ")
---~ local l_character = lpeg.utf8
+--~ local l_character = lpeg.patterns.utf8
--~ local l_dangerous = lpeg.P(".")
--~ local l_normal = (l_character - l_forbidden - l_confusing - l_dangerous) * (l_character - l_forbidden - l_confusing^2)^0 * lpeg.P(-1)
@@ -6184,8 +6319,7 @@ 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 = file.collapse_path(filename)
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -6666,12 +6800,13 @@ end
function table.sequenced(t,sep) -- temp here
local s = { }
for k, v in pairs(t) do -- pairs?
- s[#s+1] = k .. "=" .. v
+ s[#s+1] = k .. "=" .. tostring(v)
end
return concat(s, sep or " | ")
end
function resolvers.methodhandler(what, filename, filetype) -- ...
+ filename = file.collapse_path(filename)
local specification = (type(filename) == "string" and resolvers.splitmethod(filename)) or filename -- no or { }, let it bomb
local scheme = specification.scheme
if resolvers[what][scheme] then
diff --git a/scripts/context/stubs/mswin/metatex.exe b/scripts/context/stubs/mswin/metatex.exe
index 9a67fc133..2d45f2749 100755
--- a/scripts/context/stubs/mswin/metatex.exe
+++ b/scripts/context/stubs/mswin/metatex.exe
Binary files differ
diff --git a/scripts/context/stubs/mswin/mtxrun.dll b/scripts/context/stubs/mswin/mtxrun.dll
index 6af687abe..bb7af56ec 100644
--- a/scripts/context/stubs/mswin/mtxrun.dll
+++ b/scripts/context/stubs/mswin/mtxrun.dll
Binary files differ
diff --git a/scripts/context/stubs/mswin/mtxrun.exe b/scripts/context/stubs/mswin/mtxrun.exe
index 9a67fc133..2d45f2749 100755
--- a/scripts/context/stubs/mswin/mtxrun.exe
+++ b/scripts/context/stubs/mswin/mtxrun.exe
Binary files differ
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 8a2d7a123..ef7eda9b0 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -347,6 +347,8 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
lpeg = require("lpeg")
+lpeg.patterns = lpeg.patterns or { } -- so that we can share
+
local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
local match = lpeg.match
@@ -497,11 +499,9 @@ end
--~
--~ 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
-
+lpeg.patterns.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
end -- of closure
@@ -1952,6 +1952,21 @@ elseif name == "freebsd" then
return platform
end
+elseif name == "kfreebsd" then
+
+ function os.resolvers.platform(t,k)
+ -- we sometims have HOSTTYPE set so let's check that first
+ local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""
+ if find(architecture,"x86_64") then
+ platform = "kfreebsd-64"
+ else
+ platform = "kfreebsd-i386"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
else
-- platform = "linux"
@@ -2021,7 +2036,7 @@ if not modules then modules = { } end modules ['l-file'] = {
file = file or { }
local concat = table.concat
-local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub
+local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char
local lpegmatch = lpeg.match
function file.removesuffix(filename)
@@ -2058,14 +2073,33 @@ end
file.suffix = file.extname
---~ print(file.join("x/","/y"))
---~ print(file.join("http://","/y"))
---~ print(file.join("http://a","/y"))
---~ print(file.join("http:///a","/y"))
---~ print(file.join("//nas-1","/y"))
+--~ function file.join(...)
+--~ local pth = concat({...},"/")
+--~ pth = gsub(pth,"\\","/")
+--~ local a, b = match(pth,"^(.*://)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ a, b = match(pth,"^(//)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ return (gsub(pth,"//+","/"))
+--~ end
+
+local trick_1 = char(1)
+local trick_2 = "^" .. trick_1 .. "/+"
function file.join(...)
- local pth = concat({...},"/")
+ local lst = { ... }
+ local a, b = lst[1], lst[2]
+ if a == "" then
+ lst[1] = trick_1
+ elseif b and find(a,"^/+$") and find(b,"^/") then
+ lst[1] = ""
+ lst[2] = gsub(b,"^/+","")
+ end
+ local pth = concat(lst,"/")
pth = gsub(pth,"\\","/")
local a, b = match(pth,"^(.*://)(.*)$")
if a and b then
@@ -2075,9 +2109,20 @@ function file.join(...)
if a and b then
return a .. gsub(b,"//+","/")
end
+ pth = gsub(pth,trick_2,"")
return (gsub(pth,"//+","/"))
end
+--~ print(file.join("//","/y"))
+--~ print(file.join("/","/y"))
+--~ print(file.join("","/y"))
+--~ print(file.join("/x/","/y"))
+--~ print(file.join("x/","/y"))
+--~ print(file.join("http://","/y"))
+--~ print(file.join("http://a","/y"))
+--~ print(file.join("http:///a","/y"))
+--~ print(file.join("//nas-1","/y"))
+
function file.iswritable(name)
local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,"."))
return a and sub(a.permissions,2,2) == "w"
@@ -2116,16 +2161,22 @@ function file.join_path(tab)
return concat(tab,io.pathseparator) -- can have trailing //
end
+-- we can hash them weakly
+
function file.collapse_path(str)
- str = gsub(str,"/%./","/")
- local n, m = 1, 1
- while n > 0 or m > 0 do
- str, n = gsub(str,"[^/%.]+/%.%.$","")
- str, m = gsub(str,"[^/%.]+/%.%./","")
- end
- str = gsub(str,"([^/])/$","%1")
- str = gsub(str,"^%./","")
- str = gsub(str,"/%.$","")
+ str = gsub(str,"\\","/")
+ if find(str,"/") then
+ str = gsub(str,"^%./",(gsub(lfs.currentdir(),"\\","/")) .. "/") -- ./xx in qualified
+ str = gsub(str,"/%./","/")
+ local n, m = 1, 1
+ while n > 0 or m > 0 do
+ str, n = gsub(str,"[^/%.]+/%.%.$","")
+ str, m = gsub(str,"[^/%.]+/%.%./","")
+ end
+ str = gsub(str,"([^/])/$","%1")
+ -- str = gsub(str,"^%./","") -- ./xx in qualified
+ str = gsub(str,"/%.$","")
+ end
if str == "" then str = "." end
return str
end
@@ -2824,7 +2875,7 @@ else
--~ print(dir.mkdirs("///a/b/c"))
--~ print(dir.mkdirs("a/bbb//ccc/"))
- function dir.expand_name(str)
+ function dir.expand_name(str) -- will be merged with cleanpath and collapsepath
if not find(str,"^/") then
str = lfs.currentdir() .. "/" .. str
end
@@ -3340,6 +3391,8 @@ local stripper = lpeg.Cs((number + 1)^0)
--~ lpegmatch(stripper,str)
--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample))
+lpeg.patterns.strip_zeros = stripper
+
function aux.strip_zeros(str)
return lpegmatch(stripper,str)
end
@@ -3626,14 +3679,14 @@ end
function setters.enable(t,what)
local e = t.enable
t.enable, t.done = enable, { }
- enable(t,string.simpleesc(what))
+ enable(t,string.simpleesc(tostring(what)))
t.enable, t.done = e, { }
end
function setters.disable(t,what)
local e = t.disable
t.disable, t.done = disable, { }
- disable(t,string.simpleesc(what))
+ disable(t,string.simpleesc(tostring(what)))
t.disable, t.done = e, { }
end
@@ -3720,6 +3773,13 @@ function experiments.disable(...)
d(...)
end
+-- a useful example
+
+directives.register("system.nostatistics", function(v)
+ statistics.enable = not v
+end)
+
+
end -- of closure
@@ -3995,9 +4055,9 @@ local function attribute_specification_error(str)
return str
end
-function xml.unknown_dec_entity_format(str) return format("&%s;", str) end
+function xml.unknown_dec_entity_format(str) return (str == "" and "&error;") or format("&%s;",str) end
function xml.unknown_hex_entity_format(str) return format("&#x%s;",str) end
-function xml.unknown_any_entity_format(str) return format("&%s;", str) end
+function xml.unknown_any_entity_format(str) return format("&#x%s;",str) end
local function handle_hex_entity(str)
local h = hcache[str]
@@ -4111,7 +4171,11 @@ local function handle_any_entity(str)
if trace_entities then
logs.report("xml","keeping entity &%s;",str)
end
- a = "&" .. str .. ";"
+ if str == "" then
+ a = "&error;"
+ else
+ a = "&" .. str .. ";"
+ end
end
end
acache[str] = a
@@ -4132,6 +4196,9 @@ local function handle_any_entity(str)
if a then
-- one of the predefined
acache[str] = a
+ elseif str == "" then
+ a = "&error;"
+ acache[str] = a
else
a = "&" .. str .. ";"
acache[str] = a
@@ -4460,7 +4527,7 @@ function xml.checkbom(root) -- can be made faster
local dt, found = root.dt, false
for k=1,#dt do
local v = dt[k]
- if type(v) == "table" and v.special and v.tg == "@pi" and find(v.dt,"xml.*version=") then
+ if type(v) == "table" and v.special and v.tg == "@pi@" and find(v.dt[1],"xml.*version=") then
found = true
break
end
@@ -4842,6 +4909,8 @@ function xml.assign(dt,k,root)
end
end
+-- the following helpers may move
+
--[[ldx--
<p>The next helper assigns a tree (or string). Usage:</p>
<typing>
@@ -4860,6 +4929,22 @@ function xml.tocdata(e,wrapper)
e.dt = { t }
end
+function xml.makestandalone(root)
+ if root.ri then
+ local dt = root.dt
+ for k=1,#dt do
+ local v = dt[k]
+ if type(v) == "table" and v.special and v.tg == "@pi@" then
+ local txt = v.dt[1]
+ if find(txt,"xml.*version=") then
+ v.dt[1] = txt .. " standalone='yes'"
+ break
+ end
+ end
+ end
+ end
+end
+
end -- of closure
@@ -5476,8 +5561,13 @@ local register_initial_child = { kind = "axis", axis = "initial-child"
local register_all_nodes = { kind = "nodes", nodetest = true, nodes = { true, false, false } }
+local skip = { }
+
local function errorrunner_e(str,cnv)
- logs.report("lpath","error in expression: %s => %s",str,cnv)
+ if not skip[str] then
+ logs.report("lpath","error in expression: %s => %s",str,cnv)
+ skip[str] = cnv or str
+ end
return false
end
local function errorrunner_f(str,arg)
@@ -7287,6 +7377,14 @@ function statistics.hastimer(instance)
return instance and instance.starttime
end
+function statistics.resettiming(instance)
+ if not instance then
+ notimer = { timing = 0, loadtime = 0 }
+ else
+ instance.timing, instance.loadtime = 0, 0
+ end
+end
+
function statistics.starttiming(instance)
if not instance then
notimer = { }
@@ -7346,6 +7444,12 @@ function statistics.elapsedindeed(instance)
return t > statistics.threshold
end
+function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds
+ if statistics.elapsedindeed(instance) then
+ return format("%s seconds %s", statistics.elapsedtime(instance),rest or "")
+ end
+end
+
-- general function
function statistics.register(tag,fnc)
@@ -7424,6 +7528,23 @@ function statistics.timed(action,report)
report("total runtime: %s",statistics.elapsedtime(timer))
end
+-- where, not really the best spot for this:
+
+commands = commands or { }
+
+local timer
+
+function commands.resettimer()
+ statistics.resettiming(timer)
+ statistics.starttiming(timer)
+end
+
+function commands.elapsedtime()
+ statistics.stoptiming(timer)
+ tex.sprint(statistics.elapsedtime(timer))
+end
+
+commands.resettimer()
end -- of closure
@@ -7861,8 +7982,8 @@ suffixes['lua'] = { 'lua', 'luc', 'tma', 'tmc' }
alternatives['map files'] = 'map'
alternatives['enc files'] = 'enc'
-alternatives['cid files'] = 'cid'
-alternatives['fea files'] = 'fea'
+alternatives['cid maps'] = 'cid' -- great, why no cid files
+alternatives['font feature files'] = 'fea' -- and fea files here
alternatives['opentype fonts'] = 'otf'
alternatives['truetype fonts'] = 'ttf'
alternatives['truetype collections'] = 'ttc'
@@ -8005,8 +8126,10 @@ local function check_configuration() -- not yet ok, no time for debugging now
-- bad luck
end
fix("LUAINPUTS" , ".;$TEXINPUTS;$TEXMFSCRIPTS") -- no progname, hm
- fix("FONTFEATURES", ".;$TEXMF/fonts/fea//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
- fix("FONTCIDMAPS" , ".;$TEXMF/fonts/cid//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ -- this will go away some day
+ fix("FONTFEATURES", ".;$TEXMF/fonts/{data,fea}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ fix("FONTCIDMAPS" , ".;$TEXMF/fonts/{data,cid}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ --
fix("LUATEXLIBS" , ".;$TEXMF/luatex/lua//")
end
@@ -8396,7 +8519,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -8425,7 +8548,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -8550,7 +8673,7 @@ local weird = lpeg.P(".")^1 + lpeg.anywhere(lpeg.S("~`!#$%^&*()={}[]:;\"\'||<>,?
--~ local l_forbidden = lpeg.S("~`!#$%^&*()={}[]:;\"\'||\\/<>,?\n\r\t")
--~ local l_confusing = lpeg.P(" ")
---~ local l_character = lpeg.utf8
+--~ local l_character = lpeg.patterns.utf8
--~ local l_dangerous = lpeg.P(".")
--~ local l_normal = (l_character - l_forbidden - l_confusing - l_dangerous) * (l_character - l_forbidden - l_confusing^2)^0 * lpeg.P(-1)
@@ -9290,8 +9413,7 @@ 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 = file.collapse_path(filename)
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -9772,12 +9894,13 @@ end
function table.sequenced(t,sep) -- temp here
local s = { }
for k, v in pairs(t) do -- pairs?
- s[#s+1] = k .. "=" .. v
+ s[#s+1] = k .. "=" .. tostring(v)
end
return concat(s, sep or " | ")
end
function resolvers.methodhandler(what, filename, filetype) -- ...
+ filename = file.collapse_path(filename)
local specification = (type(filename) == "string" and resolvers.splitmethod(filename)) or filename -- no or { }, let it bomb
local scheme = specification.scheme
if resolvers[what][scheme] then
diff --git a/scripts/context/stubs/mswin/texexec.exe b/scripts/context/stubs/mswin/texexec.exe
index 9a67fc133..2d45f2749 100755
--- a/scripts/context/stubs/mswin/texexec.exe
+++ b/scripts/context/stubs/mswin/texexec.exe
Binary files differ
diff --git a/scripts/context/stubs/mswin/texmfstart.exe b/scripts/context/stubs/mswin/texmfstart.exe
index 9a67fc133..2d45f2749 100755
--- a/scripts/context/stubs/mswin/texmfstart.exe
+++ b/scripts/context/stubs/mswin/texmfstart.exe
Binary files differ
diff --git a/scripts/context/stubs/source/mtxrun_dll.c b/scripts/context/stubs/source/mtxrun_dll.c
index 6cac18c9b..9836c2ac5 100644
--- a/scripts/context/stubs/source/mtxrun_dll.c
+++ b/scripts/context/stubs/source/mtxrun_dll.c
@@ -1,214 +1,207 @@
-/*
+/************************************************************************
-Copyright:
+ Copyright:
-The originally 'runscript' program was written by in 2009 by
-T.M.Trzeciak and is public domain. This derived mtxrun program
-is an adapted version by Hans Hagen.
+ Public Domain
+ Originally written in 2010 by Tomasz M. Trzeciak and Hans Hagen
-Comment:
+ This program is derived from the 'runscript' program originally
+ written in 2009 by T.M. Trzeciak. It has been adapted for use in
+ ConTeXt MkIV.
-In ConTeXt MkIV we have two core scripts: luatools.lua and
-mtxrun.lua where the second one is used to launch other scripts.
-Normally a user will use a call like:
+ Comment:
-mtxrun --script font --reload
+ In ConTeXt MkIV we have two core scripts: luatools.lua and
+ mtxrun.lua where the second one is used to launch other scripts.
+ Normally a user will use a call like:
-Here mtxrun is a lua script. In order to avoid the usage of a cmd
-file on windows this runner will start texlua directly. In TeXlive
-a runner is added for each cmd file but we don't want that overhead
-(and extra files). By using an exe we can call these scripts in
-batch files without the need for using call.
+ mtxrun --script font --reload
-We also don't want to use other runners, like those that use kpse
-to locate the script as this is exactly what mtxrun itself is doing
-already. Therefore the runscript program is adapted to a more direct
-approach suitable for mtxrun.
+ Here mtxrun is a lua script. In order to avoid the usage of a cmd
+ file on windows this runner will start texlua directly. If the
+ shared library luatex.dll is available, texlua will be started in
+ the same process avoiding thus any additional overhead. Otherwise
+ it will be spawned in a new proces.
-Compilation:
+ We also don't want to use other runners, like those that use kpse
+ to locate the script as this is exactly what mtxrun itself is doing
+ already. Therefore the runscript program is adapted to a more direct
+ approach suitable for mtxrun.
-with gcc (size optimized):
+ Compilation:
-gcc -Os -s -shared -o mtxrun.dll mtxrun_dll.c
-gcc -Os -s -o mtxrun.exe mtxrun_exe.c -L./ -lmtxrun
+ with gcc (size optimized):
-with tcc (ver. 0.9.24), extra small size
+ gcc -Os -s -shared -o mtxrun.dll mtxrun_dll.c
+ gcc -Os -s -o mtxrun.exe mtxrun_exe.c
-tcc -shared -o runscript.dll runscript_dll.c
-tcc -o runscript.exe runscript_exe.c runscript.def
+ with tcc (extra small size):
-*/
+ tcc -shared -o mtxrun.dll mtxrun_dll.c
+ tcc -o mtxrun.exe mtxrun_exe.c mtxrun.def
+
+************************************************************************/
-#include <windows.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+//#define STATIC
#define IS_WHITESPACE(c) ((c == ' ') || (c == '\t'))
#define MAX_CMD 32768
-//~ #define DRYRUN
+#define DIE(...) { \
+ fprintf( stderr, "mtxrun: " ); \
+ fprintf( stderr, __VA_ARGS__ ); \
+ return 1; \
+}
-static char dirname [MAX_PATH];
-static char basename[MAX_PATH];
+char texlua_name[] = "texlua"; // just a bare name, luatex strips the rest anyway
+static char cmdline[MAX_CMD];
+static char dirpath[MAX_PATH];
static char progname[MAX_PATH];
-static char cmdline [MAX_CMD];
-
-__declspec(dllexport) int dllrunscript( int argc, char *argv[] ) {
-
- int i;
-
- static char path[MAX_PATH];
-
- // get file name of this executable and split it into parts
-
- DWORD nchars = GetModuleFileNameA(NULL, path, MAX_PATH);
- if ( !nchars || (nchars == MAX_PATH) ) {
- fprintf(stderr, "mtxrun: unable to determine a valid own name\n");
- return -1;
- }
-
- // file extension part
-
- i = strlen(path);
-
- while ( i && (path[i] != '.') && (path[i] != '\\') ) i--;
-
- strcpy(basename, path);
-
- if ( basename[i] == '.' ) basename[i] = '\0'; //remove file extension
-
- // file name part
-
- while ( i && (path[i] != '\\') ) i--;
-
- if ( path[i] != '\\' ) {
- fprintf(stderr, "mtxrun: the runner has no directory part in its name: %s\n", path);
- return -1;
- }
-
- strcpy(dirname, path);
- dirname[i+1] = '\0'; //remove file name, leave trailing backslash
- strcpy(progname, &basename[i+1]);
-
- // find program to execute
-
- if ( (strlen(basename)+100 >= MAX_PATH) ) {
- fprintf(stderr, "mtxrun: the runners path is too long: %s\n", path);
- return -1;
- }
-
- // check .lua
-
- strcpy(path, dirname);
- strcat(path, "mtxrun.lua");
-
- if ( GetFileAttributesA(path) != INVALID_FILE_ATTRIBUTES ) {
- goto PROGRAM_FOUND;
- } else {
- fprintf(stderr, "mtxrun: the mtxrun.lua file is not in the same path\n");
- return -1;
- }
-
-PROGRAM_FOUND:
-
- strcpy(cmdline,"texlua.exe ");
-
- if ( ( strcmp(progname,"mtxrun") == 0 ) || ( strcmp(progname,"luatools") == 0 ) ) {
- strcat(cmdline, dirname);
- strcat(cmdline,progname);
- strcat(cmdline, ".lua");
- } else if ( ( strcmp(progname,"texmfstart") == 0 ) ) {
- strcat(cmdline, dirname);
- strcat(cmdline,"mtxrun.lua");
- } else {
- strcat(cmdline, dirname);
- strcat(cmdline, "mtxrun.lua --script ");
- strcat(cmdline,progname);
- }
-
- // get the command line for this process
-
- char *argstr;
- argstr = GetCommandLineA();
- if ( argstr == NULL ) {
- fprintf(stderr, "mtxrun: fetching the command line string fails\n");
- return -1;
+static char scriptpath[MAX_PATH];
+HMODULE dllluatex = NULL;
+typedef int ( *mainlikeproc )( int, char ** );
+
+#ifdef STATIC
+int main( int argc, char *argv[] )
+#else
+__declspec(dllexport) int dllrunscript( int argc, char *argv[] )
+#endif
+{
+ char *s, *argstr, **lua_argv;
+ int k, quoted, lua_argc;
+ int passprogname = 0;
+
+ // directory of this module/executable
+
+ HMODULE module_handle = GetModuleHandle( "mtxrun.dll" );
+ // if ( module_handle == NULL ) exe path will be used, which is OK too
+ k = (int) GetModuleFileName( module_handle, dirpath, MAX_PATH );
+ if ( !k || ( k == MAX_PATH ) )
+ DIE( "unable to determine a valid module name\n" );
+ s = strrchr(dirpath, '\\');
+ if ( s == NULL ) DIE( "no directory part in module path: %s\n", dirpath );
+ *(++s) = '\0'; //remove file name, leave trailing backslash
+
+ // program name
+
+ k = strlen(argv[0]);
+ while ( k && (argv[0][k] != '/') && (argv[0][k] != '\\') ) k--;
+ strcpy(progname, &argv[0][k]);
+ s = progname;
+ if ( s = strrchr(s, '.') ) *s = '\0'; // remove file extension part
+
+ // script path
+
+ strcpy( scriptpath, dirpath );
+ k = strlen(progname);
+ if ( k < 6 ) k = 6; // in case the program name is shorter than "mtxrun"
+ if ( strlen(dirpath) + k + 4 >= MAX_PATH )
+ DIE( "path too long: %s%s\n", dirpath, progname );
+ if ( ( strcmpi(progname,"mtxrun") == 0 ) || ( strcmpi(progname,"luatools") == 0 ) ) {
+ strcat( scriptpath, progname );
+ strcat( scriptpath, ".lua" );
+ } else {
+ strcat( scriptpath, "mtxrun.lua" );
+ if ( strcmpi(progname,"texmfstart") != 0 ) passprogname = 1;
+ }
+ if ( GetFileAttributes(scriptpath) == INVALID_FILE_ATTRIBUTES )
+ DIE( "file not found: %s\n", scriptpath );
+
+ // link with luatex.dll if available
+
+ if ( dllluatex = LoadLibrary("luatex.dll") )
+ {
+ mainlikeproc dllluatexmain = (mainlikeproc) GetProcAddress( dllluatex, "dllluatexmain" );
+ if ( dllluatexmain == NULL )
+ DIE( "unable to locate dllluatexmain procedure in luatex.dll" );
+
+ // set up argument list for texlua script
+
+ lua_argv = (char **)malloc( (argc + 4) * sizeof(char *) );
+ if ( lua_argv == NULL ) DIE( "out of memory\n" );
+ lua_argv[lua_argc=0] = texlua_name;
+ lua_argv[++lua_argc] = scriptpath; // script to execute
+ if (passprogname) {
+ lua_argv[++lua_argc] = "--script";
+ lua_argv[++lua_argc] = progname;
}
+ for ( k = 1; k < argc; k++ ) lua_argv[++lua_argc] = argv[k];
+ lua_argv[++lua_argc] = NULL;
- // skip over argv[0] (it can contain embedded double quotes if launched from cmd.exe!)
+ // call texlua interpreter
+ // dllluatexmain never returns, but we pretend that it does
- int argstrlen = strlen(argstr);
- int quoted = 0;
- for ( i = 0; ( i < argstrlen) && ( !IS_WHITESPACE(argstr[i]) || quoted ); i++ )
+ k = dllluatexmain( lua_argc, lua_argv );
+ if (lua_argv) free( lua_argv );
+ return k;
+ }
- if (argstr[i] == '"') quoted = !quoted;
+ // we are still here, so no luatex.dll; spawn texlua.exe instead
- // while ( IS_WHITESPACE(argstr[i]) ) i++; // arguments leading whitespace
+ strcpy( cmdline, "\"" );
+// strcat( cmdline, dirpath );
+ strcat( cmdline, "texlua.exe\" \"" );
+ strcat( cmdline, scriptpath );
+ strcat( cmdline, "\"" );
+ if (passprogname) {
+ strcat( cmdline, " --script " );
+ strcat( cmdline, progname );
+ }
- argstr = &argstr[i];
+ argstr = GetCommandLine(); // get the command line of this process
+ if ( argstr == NULL ) DIE( "unable to retrieve the command line string\n" );
- if ( strlen(cmdline) + strlen(argstr) >= MAX_CMD ) {
- fprintf(stderr, "mtxrun: the command line string is too long:\n%s%s\n", cmdline, argstr);
- return -1;
- }
+ // skip over argv[0] in the argument string
+ // (it can contain embedded double quotes if launched from cmd.exe!)
- // pass through all the arguments
+ for ( quoted = 0; (*argstr) && ( !IS_WHITESPACE(*argstr) || quoted ); argstr++ )
+ if (*argstr == '"') quoted = !quoted;
- strcat(cmdline, argstr);
+ // pass through all the arguments
-#ifdef DRYRUN
- printf("progname : %s\n", progname);
- printf("dirname : %s\n", dirname);
- printf("arguments : %s\n", &argstr[-i]);
- for (i = 0; i < argc; i++) {
- printf("argv[%d] : %s\n", i, argv[i]);
- }
- printf("commandline : %s\n", cmdline);
- return;
-#endif
+ if ( strlen(cmdline) + strlen(argstr) >= MAX_CMD )
+ DIE( "command line string too long:\n%s%s\n", cmdline, argstr );
+ strcat( cmdline, argstr );
- // create child process
+ // create child process
- STARTUPINFOA si; // ANSI variant
- PROCESS_INFORMATION pi;
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;// | STARTF_USESHOWWINDOW;
-
//si.dwFlags = STARTF_USESHOWWINDOW;
//si.wShowWindow = SW_HIDE ; // can be used to hide console window (requires STARTF_USESHOWWINDOW flag)
-
- si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
- si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
- si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
-
- ZeroMemory( &pi, sizeof(pi) );
- if( !CreateProcessA(
- NULL, // module name (uses command line if NULL)
- cmdline, // command line
- NULL, // process security attributes
- NULL, // thread security attributes
- TRUE, // handle inheritance
- 0, // creation flags, e.g. CREATE_NEW_CONSOLE, CREATE_NO_WINDOW, DETACHED_PROCESS
- NULL, // pointer to environment block (uses parent if NULL)
- NULL, // starting directory (uses parent if NULL)
- &si, // STARTUPINFO structure
- &pi ) // PROCESS_INFORMATION structure
- ) {
- fprintf(stderr, "mtxrun: unable to create a process for: %s\n", cmdline);
- return -1;
- }
- CloseHandle( pi.hThread ); // thread handle is not needed
- DWORD ret = 0;
- if ( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_OBJECT_0 ) {
- if ( !GetExitCodeProcess( pi.hProcess, &ret) ) {
- fprintf(stderr, "mtxrun: unable to fetch the exit code for process: %s\n", cmdline);
- return -1;
- }
- } else {
- fprintf(stderr, "mtxrun: the script has been terminated unexpectedly: %s\n", cmdline);
- return -1;
- }
- CloseHandle( pi.hProcess );
-
- return ret;
+ si.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
+ si.hStdOutput = GetStdHandle( STD_OUTPUT_HANDLE );
+ si.hStdError = GetStdHandle( STD_ERROR_HANDLE );
+ ZeroMemory( &pi, sizeof(pi) );
+
+ if( !CreateProcess(
+ NULL, // module name (uses command line if NULL)
+ cmdline, // command line
+ NULL, // process security atrributes
+ NULL, // thread security atrributes
+ TRUE, // handle inheritance
+ 0, // creation flags, e.g. CREATE_NEW_CONSOLE, CREATE_NO_WINDOW, DETACHED_PROCESS
+ NULL, // pointer to environment block (uses parent if NULL)
+ NULL, // starting directory (uses parent if NULL)
+ &si, // STARTUPINFO structure
+ &pi ) // PROCESS_INFORMATION structure
+ ) DIE( "command execution failed: %s\n", cmdline );
+
+ DWORD ret = 0;
+ CloseHandle( pi.hThread ); // thread handle is not needed
+ if ( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_OBJECT_0 ) {
+ if ( !GetExitCodeProcess( pi.hProcess, &ret) )
+ DIE( "unable to retrieve process exit code: %s\n", cmdline );
+ } else DIE( "failed to wait for process termination: %s\n", cmdline );
+ CloseHandle( pi.hProcess );
+
+ // propagate exit code from the child process
+
+ return ret;
}
diff --git a/scripts/context/stubs/unix/luatools b/scripts/context/stubs/unix/luatools
index f9b855f74..1a579eb69 100755
--- a/scripts/context/stubs/unix/luatools
+++ b/scripts/context/stubs/unix/luatools
@@ -338,6 +338,8 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
lpeg = require("lpeg")
+lpeg.patterns = lpeg.patterns or { } -- so that we can share
+
local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
local match = lpeg.match
@@ -488,11 +490,9 @@ end
--~
--~ 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
-
+lpeg.patterns.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
end -- of closure
@@ -1868,6 +1868,7 @@ elseif os.type == "windows" then
elseif name == "linux" then
function os.resolvers.platform(t,k)
+ -- we sometims have HOSTTYPE set so let's check that first
local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""
if find(architecture,"x86_64") then
platform = "linux-64"
@@ -1881,17 +1882,28 @@ elseif name == "linux" then
return platform
end
-elseif name == "macosx" then -- a rather inconsistent mess
+elseif name == "macosx" then
+
+ --[[
+ Identifying the architecture of OSX is quite a mess and this
+ is the best we can come up with. For some reason $HOSTTYPE is
+ a kind of pseudo environment variable, not known to the current
+ environment. And yes, uname cannot be trusted either, so there
+ is a change that you end up with a 32 bit run on a 64 bit system.
+ Also, some proper 64 bit intel macs are too cheap (low-end) and
+ therefore not permitted to run the 64 bit kernel.
+ ]]--
function os.resolvers.platform(t,k)
- local platform, architecture = "", os.resultof("uname -m") or ""
+ -- local platform, architecture = "", os.getenv("HOSTTYPE") or ""
+ -- if architecture == "" then
+ -- architecture = os.resultof("echo $HOSTTYPE") or ""
+ -- end
+ local platform, architecture = "", os.resultof("echo $HOSTTYPE") or ""
if architecture == "" then
- architecture = os.getenv("HOSTTYPE") or ""
- end
- if architecture == "" then
- architecture = os.resultof("echo $HOSTTYPE") or ""
- end
- if find(architecture,"i386") then
+ -- print("\nI have no clue what kind of OSX you're running so let's assume an 32 bit intel.\n")
+ platform = "osx-intel"
+ elseif find(architecture,"i386") then
platform = "osx-intel"
elseif find(architecture,"x86_64") then
platform = "osx-64"
@@ -1931,6 +1943,21 @@ elseif name == "freebsd" then
return platform
end
+elseif name == "kfreebsd" then
+
+ function os.resolvers.platform(t,k)
+ -- we sometims have HOSTTYPE set so let's check that first
+ local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""
+ if find(architecture,"x86_64") then
+ platform = "kfreebsd-64"
+ else
+ platform = "kfreebsd-i386"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
else
-- platform = "linux"
@@ -1967,6 +1994,21 @@ function os.uuid()
)
end
+local d
+
+function os.timezone(delta)
+ d = d or tonumber(tonumber(os.date("%H")-os.date("!%H")))
+ if delta then
+ if d > 0 then
+ return format("+%02i:00",d)
+ else
+ return format("-%02i:00",-d)
+ end
+ else
+ return 1
+ end
+end
+
end -- of closure
@@ -1985,7 +2027,7 @@ if not modules then modules = { } end modules ['l-file'] = {
file = file or { }
local concat = table.concat
-local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub
+local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char
local lpegmatch = lpeg.match
function file.removesuffix(filename)
@@ -2022,14 +2064,33 @@ end
file.suffix = file.extname
---~ print(file.join("x/","/y"))
---~ print(file.join("http://","/y"))
---~ print(file.join("http://a","/y"))
---~ print(file.join("http:///a","/y"))
---~ print(file.join("//nas-1","/y"))
+--~ function file.join(...)
+--~ local pth = concat({...},"/")
+--~ pth = gsub(pth,"\\","/")
+--~ local a, b = match(pth,"^(.*://)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ a, b = match(pth,"^(//)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ return (gsub(pth,"//+","/"))
+--~ end
+
+local trick_1 = char(1)
+local trick_2 = "^" .. trick_1 .. "/+"
function file.join(...)
- local pth = concat({...},"/")
+ local lst = { ... }
+ local a, b = lst[1], lst[2]
+ if a == "" then
+ lst[1] = trick_1
+ elseif b and find(a,"^/+$") and find(b,"^/") then
+ lst[1] = ""
+ lst[2] = gsub(b,"^/+","")
+ end
+ local pth = concat(lst,"/")
pth = gsub(pth,"\\","/")
local a, b = match(pth,"^(.*://)(.*)$")
if a and b then
@@ -2039,9 +2100,20 @@ function file.join(...)
if a and b then
return a .. gsub(b,"//+","/")
end
+ pth = gsub(pth,trick_2,"")
return (gsub(pth,"//+","/"))
end
+--~ print(file.join("//","/y"))
+--~ print(file.join("/","/y"))
+--~ print(file.join("","/y"))
+--~ print(file.join("/x/","/y"))
+--~ print(file.join("x/","/y"))
+--~ print(file.join("http://","/y"))
+--~ print(file.join("http://a","/y"))
+--~ print(file.join("http:///a","/y"))
+--~ print(file.join("//nas-1","/y"))
+
function file.iswritable(name)
local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,"."))
return a and sub(a.permissions,2,2) == "w"
@@ -2080,16 +2152,22 @@ function file.join_path(tab)
return concat(tab,io.pathseparator) -- can have trailing //
end
+-- we can hash them weakly
+
function file.collapse_path(str)
- str = gsub(str,"/%./","/")
- local n, m = 1, 1
- while n > 0 or m > 0 do
- str, n = gsub(str,"[^/%.]+/%.%.$","")
- str, m = gsub(str,"[^/%.]+/%.%./","")
- end
- str = gsub(str,"([^/])/$","%1")
- str = gsub(str,"^%./","")
- str = gsub(str,"/%.$","")
+ str = gsub(str,"\\","/")
+ if find(str,"/") then
+ str = gsub(str,"^%./",(gsub(lfs.currentdir(),"\\","/")) .. "/") -- ./xx in qualified
+ str = gsub(str,"/%./","/")
+ local n, m = 1, 1
+ while n > 0 or m > 0 do
+ str, n = gsub(str,"[^/%.]+/%.%.$","")
+ str, m = gsub(str,"[^/%.]+/%.%./","")
+ end
+ str = gsub(str,"([^/])/$","%1")
+ -- str = gsub(str,"^%./","") -- ./xx in qualified
+ str = gsub(str,"/%.$","")
+ end
if str == "" then str = "." end
return str
end
@@ -2391,7 +2469,7 @@ function url.hashed(str)
end
function url.hasscheme(str)
- return not url.split(str).nosheme
+ return url.split(str)[1] ~= ""
end
function url.addscheme(str,scheme)
@@ -2788,7 +2866,7 @@ else
--~ print(dir.mkdirs("///a/b/c"))
--~ print(dir.mkdirs("a/bbb//ccc/"))
- function dir.expand_name(str)
+ function dir.expand_name(str) -- will be merged with cleanpath and collapsepath
if not find(str,"^/") then
str = lfs.currentdir() .. "/" .. str
end
@@ -3503,6 +3581,8 @@ local stripper = lpeg.Cs((number + 1)^0)
--~ lpegmatch(stripper,str)
--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample))
+lpeg.patterns.strip_zeros = stripper
+
function aux.strip_zeros(str)
return lpegmatch(stripper,str)
end
@@ -3789,14 +3869,14 @@ end
function setters.enable(t,what)
local e = t.enable
t.enable, t.done = enable, { }
- enable(t,string.simpleesc(what))
+ enable(t,string.simpleesc(tostring(what)))
t.enable, t.done = e, { }
end
function setters.disable(t,what)
local e = t.disable
t.disable, t.done = disable, { }
- disable(t,string.simpleesc(what))
+ disable(t,string.simpleesc(tostring(what)))
t.disable, t.done = e, { }
end
@@ -3847,13 +3927,15 @@ function setters.new(name)
return t
end
-trackers = setters.new("trackers")
-directives = setters.new("directives")
+trackers = setters.new("trackers")
+directives = setters.new("directives")
+experiments = setters.new("experiments")
-- 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 trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end)
+local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end)
local e = directives.enable
local d = directives.disable
@@ -3868,6 +3950,26 @@ function directives.disable(...)
d(...)
end
+local e = experiments.enable
+local d = experiments.disable
+
+function experiments.enable(...)
+ commands.writestatus("experiments","enabling: %s",concat({...}," "))
+ e(...)
+end
+
+function experiments.disable(...)
+ commands.writestatus("experiments","disabling: %s",concat({...}," "))
+ d(...)
+end
+
+-- a useful example
+
+directives.register("system.nostatistics", function(v)
+ statistics.enable = not v
+end)
+
+
end -- of closure
@@ -4181,6 +4283,14 @@ function statistics.hastimer(instance)
return instance and instance.starttime
end
+function statistics.resettiming(instance)
+ if not instance then
+ notimer = { timing = 0, loadtime = 0 }
+ else
+ instance.timing, instance.loadtime = 0, 0
+ end
+end
+
function statistics.starttiming(instance)
if not instance then
notimer = { }
@@ -4240,6 +4350,12 @@ function statistics.elapsedindeed(instance)
return t > statistics.threshold
end
+function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds
+ if statistics.elapsedindeed(instance) then
+ return format("%s seconds %s", statistics.elapsedtime(instance),rest or "")
+ end
+end
+
-- general function
function statistics.register(tag,fnc)
@@ -4318,6 +4434,23 @@ function statistics.timed(action,report)
report("total runtime: %s",statistics.elapsedtime(timer))
end
+-- where, not really the best spot for this:
+
+commands = commands or { }
+
+local timer
+
+function commands.resettimer()
+ statistics.resettiming(timer)
+ statistics.starttiming(timer)
+end
+
+function commands.elapsedtime()
+ statistics.stoptiming(timer)
+ tex.sprint(statistics.elapsedtime(timer))
+end
+
+commands.resettimer()
end -- of closure
@@ -4755,8 +4888,8 @@ suffixes['lua'] = { 'lua', 'luc', 'tma', 'tmc' }
alternatives['map files'] = 'map'
alternatives['enc files'] = 'enc'
-alternatives['cid files'] = 'cid'
-alternatives['fea files'] = 'fea'
+alternatives['cid maps'] = 'cid' -- great, why no cid files
+alternatives['font feature files'] = 'fea' -- and fea files here
alternatives['opentype fonts'] = 'otf'
alternatives['truetype fonts'] = 'ttf'
alternatives['truetype collections'] = 'ttc'
@@ -4899,8 +5032,10 @@ local function check_configuration() -- not yet ok, no time for debugging now
-- bad luck
end
fix("LUAINPUTS" , ".;$TEXINPUTS;$TEXMFSCRIPTS") -- no progname, hm
- fix("FONTFEATURES", ".;$TEXMF/fonts/fea//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
- fix("FONTCIDMAPS" , ".;$TEXMF/fonts/cid//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ -- this will go away some day
+ fix("FONTFEATURES", ".;$TEXMF/fonts/{data,fea}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ fix("FONTCIDMAPS" , ".;$TEXMF/fonts/{data,cid}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ --
fix("LUATEXLIBS" , ".;$TEXMF/luatex/lua//")
end
@@ -5290,7 +5425,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -5319,7 +5454,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -5444,7 +5579,7 @@ local weird = lpeg.P(".")^1 + lpeg.anywhere(lpeg.S("~`!#$%^&*()={}[]:;\"\'||<>,?
--~ local l_forbidden = lpeg.S("~`!#$%^&*()={}[]:;\"\'||\\/<>,?\n\r\t")
--~ local l_confusing = lpeg.P(" ")
---~ local l_character = lpeg.utf8
+--~ local l_character = lpeg.patterns.utf8
--~ local l_dangerous = lpeg.P(".")
--~ local l_normal = (l_character - l_forbidden - l_confusing - l_dangerous) * (l_character - l_forbidden - l_confusing^2)^0 * lpeg.P(-1)
@@ -6184,8 +6319,7 @@ 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 = file.collapse_path(filename)
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -6666,12 +6800,13 @@ end
function table.sequenced(t,sep) -- temp here
local s = { }
for k, v in pairs(t) do -- pairs?
- s[#s+1] = k .. "=" .. v
+ s[#s+1] = k .. "=" .. tostring(v)
end
return concat(s, sep or " | ")
end
function resolvers.methodhandler(what, filename, filetype) -- ...
+ filename = file.collapse_path(filename)
local specification = (type(filename) == "string" and resolvers.splitmethod(filename)) or filename -- no or { }, let it bomb
local scheme = specification.scheme
if resolvers[what][scheme] then
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 8a2d7a123..ef7eda9b0 100755
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -347,6 +347,8 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
lpeg = require("lpeg")
+lpeg.patterns = lpeg.patterns or { } -- so that we can share
+
local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
local match = lpeg.match
@@ -497,11 +499,9 @@ end
--~
--~ 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
-
+lpeg.patterns.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
end -- of closure
@@ -1952,6 +1952,21 @@ elseif name == "freebsd" then
return platform
end
+elseif name == "kfreebsd" then
+
+ function os.resolvers.platform(t,k)
+ -- we sometims have HOSTTYPE set so let's check that first
+ local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""
+ if find(architecture,"x86_64") then
+ platform = "kfreebsd-64"
+ else
+ platform = "kfreebsd-i386"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
else
-- platform = "linux"
@@ -2021,7 +2036,7 @@ if not modules then modules = { } end modules ['l-file'] = {
file = file or { }
local concat = table.concat
-local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub
+local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char
local lpegmatch = lpeg.match
function file.removesuffix(filename)
@@ -2058,14 +2073,33 @@ end
file.suffix = file.extname
---~ print(file.join("x/","/y"))
---~ print(file.join("http://","/y"))
---~ print(file.join("http://a","/y"))
---~ print(file.join("http:///a","/y"))
---~ print(file.join("//nas-1","/y"))
+--~ function file.join(...)
+--~ local pth = concat({...},"/")
+--~ pth = gsub(pth,"\\","/")
+--~ local a, b = match(pth,"^(.*://)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ a, b = match(pth,"^(//)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ return (gsub(pth,"//+","/"))
+--~ end
+
+local trick_1 = char(1)
+local trick_2 = "^" .. trick_1 .. "/+"
function file.join(...)
- local pth = concat({...},"/")
+ local lst = { ... }
+ local a, b = lst[1], lst[2]
+ if a == "" then
+ lst[1] = trick_1
+ elseif b and find(a,"^/+$") and find(b,"^/") then
+ lst[1] = ""
+ lst[2] = gsub(b,"^/+","")
+ end
+ local pth = concat(lst,"/")
pth = gsub(pth,"\\","/")
local a, b = match(pth,"^(.*://)(.*)$")
if a and b then
@@ -2075,9 +2109,20 @@ function file.join(...)
if a and b then
return a .. gsub(b,"//+","/")
end
+ pth = gsub(pth,trick_2,"")
return (gsub(pth,"//+","/"))
end
+--~ print(file.join("//","/y"))
+--~ print(file.join("/","/y"))
+--~ print(file.join("","/y"))
+--~ print(file.join("/x/","/y"))
+--~ print(file.join("x/","/y"))
+--~ print(file.join("http://","/y"))
+--~ print(file.join("http://a","/y"))
+--~ print(file.join("http:///a","/y"))
+--~ print(file.join("//nas-1","/y"))
+
function file.iswritable(name)
local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,"."))
return a and sub(a.permissions,2,2) == "w"
@@ -2116,16 +2161,22 @@ function file.join_path(tab)
return concat(tab,io.pathseparator) -- can have trailing //
end
+-- we can hash them weakly
+
function file.collapse_path(str)
- str = gsub(str,"/%./","/")
- local n, m = 1, 1
- while n > 0 or m > 0 do
- str, n = gsub(str,"[^/%.]+/%.%.$","")
- str, m = gsub(str,"[^/%.]+/%.%./","")
- end
- str = gsub(str,"([^/])/$","%1")
- str = gsub(str,"^%./","")
- str = gsub(str,"/%.$","")
+ str = gsub(str,"\\","/")
+ if find(str,"/") then
+ str = gsub(str,"^%./",(gsub(lfs.currentdir(),"\\","/")) .. "/") -- ./xx in qualified
+ str = gsub(str,"/%./","/")
+ local n, m = 1, 1
+ while n > 0 or m > 0 do
+ str, n = gsub(str,"[^/%.]+/%.%.$","")
+ str, m = gsub(str,"[^/%.]+/%.%./","")
+ end
+ str = gsub(str,"([^/])/$","%1")
+ -- str = gsub(str,"^%./","") -- ./xx in qualified
+ str = gsub(str,"/%.$","")
+ end
if str == "" then str = "." end
return str
end
@@ -2824,7 +2875,7 @@ else
--~ print(dir.mkdirs("///a/b/c"))
--~ print(dir.mkdirs("a/bbb//ccc/"))
- function dir.expand_name(str)
+ function dir.expand_name(str) -- will be merged with cleanpath and collapsepath
if not find(str,"^/") then
str = lfs.currentdir() .. "/" .. str
end
@@ -3340,6 +3391,8 @@ local stripper = lpeg.Cs((number + 1)^0)
--~ lpegmatch(stripper,str)
--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample))
+lpeg.patterns.strip_zeros = stripper
+
function aux.strip_zeros(str)
return lpegmatch(stripper,str)
end
@@ -3626,14 +3679,14 @@ end
function setters.enable(t,what)
local e = t.enable
t.enable, t.done = enable, { }
- enable(t,string.simpleesc(what))
+ enable(t,string.simpleesc(tostring(what)))
t.enable, t.done = e, { }
end
function setters.disable(t,what)
local e = t.disable
t.disable, t.done = disable, { }
- disable(t,string.simpleesc(what))
+ disable(t,string.simpleesc(tostring(what)))
t.disable, t.done = e, { }
end
@@ -3720,6 +3773,13 @@ function experiments.disable(...)
d(...)
end
+-- a useful example
+
+directives.register("system.nostatistics", function(v)
+ statistics.enable = not v
+end)
+
+
end -- of closure
@@ -3995,9 +4055,9 @@ local function attribute_specification_error(str)
return str
end
-function xml.unknown_dec_entity_format(str) return format("&%s;", str) end
+function xml.unknown_dec_entity_format(str) return (str == "" and "&error;") or format("&%s;",str) end
function xml.unknown_hex_entity_format(str) return format("&#x%s;",str) end
-function xml.unknown_any_entity_format(str) return format("&%s;", str) end
+function xml.unknown_any_entity_format(str) return format("&#x%s;",str) end
local function handle_hex_entity(str)
local h = hcache[str]
@@ -4111,7 +4171,11 @@ local function handle_any_entity(str)
if trace_entities then
logs.report("xml","keeping entity &%s;",str)
end
- a = "&" .. str .. ";"
+ if str == "" then
+ a = "&error;"
+ else
+ a = "&" .. str .. ";"
+ end
end
end
acache[str] = a
@@ -4132,6 +4196,9 @@ local function handle_any_entity(str)
if a then
-- one of the predefined
acache[str] = a
+ elseif str == "" then
+ a = "&error;"
+ acache[str] = a
else
a = "&" .. str .. ";"
acache[str] = a
@@ -4460,7 +4527,7 @@ function xml.checkbom(root) -- can be made faster
local dt, found = root.dt, false
for k=1,#dt do
local v = dt[k]
- if type(v) == "table" and v.special and v.tg == "@pi" and find(v.dt,"xml.*version=") then
+ if type(v) == "table" and v.special and v.tg == "@pi@" and find(v.dt[1],"xml.*version=") then
found = true
break
end
@@ -4842,6 +4909,8 @@ function xml.assign(dt,k,root)
end
end
+-- the following helpers may move
+
--[[ldx--
<p>The next helper assigns a tree (or string). Usage:</p>
<typing>
@@ -4860,6 +4929,22 @@ function xml.tocdata(e,wrapper)
e.dt = { t }
end
+function xml.makestandalone(root)
+ if root.ri then
+ local dt = root.dt
+ for k=1,#dt do
+ local v = dt[k]
+ if type(v) == "table" and v.special and v.tg == "@pi@" then
+ local txt = v.dt[1]
+ if find(txt,"xml.*version=") then
+ v.dt[1] = txt .. " standalone='yes'"
+ break
+ end
+ end
+ end
+ end
+end
+
end -- of closure
@@ -5476,8 +5561,13 @@ local register_initial_child = { kind = "axis", axis = "initial-child"
local register_all_nodes = { kind = "nodes", nodetest = true, nodes = { true, false, false } }
+local skip = { }
+
local function errorrunner_e(str,cnv)
- logs.report("lpath","error in expression: %s => %s",str,cnv)
+ if not skip[str] then
+ logs.report("lpath","error in expression: %s => %s",str,cnv)
+ skip[str] = cnv or str
+ end
return false
end
local function errorrunner_f(str,arg)
@@ -7287,6 +7377,14 @@ function statistics.hastimer(instance)
return instance and instance.starttime
end
+function statistics.resettiming(instance)
+ if not instance then
+ notimer = { timing = 0, loadtime = 0 }
+ else
+ instance.timing, instance.loadtime = 0, 0
+ end
+end
+
function statistics.starttiming(instance)
if not instance then
notimer = { }
@@ -7346,6 +7444,12 @@ function statistics.elapsedindeed(instance)
return t > statistics.threshold
end
+function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds
+ if statistics.elapsedindeed(instance) then
+ return format("%s seconds %s", statistics.elapsedtime(instance),rest or "")
+ end
+end
+
-- general function
function statistics.register(tag,fnc)
@@ -7424,6 +7528,23 @@ function statistics.timed(action,report)
report("total runtime: %s",statistics.elapsedtime(timer))
end
+-- where, not really the best spot for this:
+
+commands = commands or { }
+
+local timer
+
+function commands.resettimer()
+ statistics.resettiming(timer)
+ statistics.starttiming(timer)
+end
+
+function commands.elapsedtime()
+ statistics.stoptiming(timer)
+ tex.sprint(statistics.elapsedtime(timer))
+end
+
+commands.resettimer()
end -- of closure
@@ -7861,8 +7982,8 @@ suffixes['lua'] = { 'lua', 'luc', 'tma', 'tmc' }
alternatives['map files'] = 'map'
alternatives['enc files'] = 'enc'
-alternatives['cid files'] = 'cid'
-alternatives['fea files'] = 'fea'
+alternatives['cid maps'] = 'cid' -- great, why no cid files
+alternatives['font feature files'] = 'fea' -- and fea files here
alternatives['opentype fonts'] = 'otf'
alternatives['truetype fonts'] = 'ttf'
alternatives['truetype collections'] = 'ttc'
@@ -8005,8 +8126,10 @@ local function check_configuration() -- not yet ok, no time for debugging now
-- bad luck
end
fix("LUAINPUTS" , ".;$TEXINPUTS;$TEXMFSCRIPTS") -- no progname, hm
- fix("FONTFEATURES", ".;$TEXMF/fonts/fea//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
- fix("FONTCIDMAPS" , ".;$TEXMF/fonts/cid//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ -- this will go away some day
+ fix("FONTFEATURES", ".;$TEXMF/fonts/{data,fea}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ fix("FONTCIDMAPS" , ".;$TEXMF/fonts/{data,cid}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ --
fix("LUATEXLIBS" , ".;$TEXMF/luatex/lua//")
end
@@ -8396,7 +8519,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -8425,7 +8548,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -8550,7 +8673,7 @@ local weird = lpeg.P(".")^1 + lpeg.anywhere(lpeg.S("~`!#$%^&*()={}[]:;\"\'||<>,?
--~ local l_forbidden = lpeg.S("~`!#$%^&*()={}[]:;\"\'||\\/<>,?\n\r\t")
--~ local l_confusing = lpeg.P(" ")
---~ local l_character = lpeg.utf8
+--~ local l_character = lpeg.patterns.utf8
--~ local l_dangerous = lpeg.P(".")
--~ local l_normal = (l_character - l_forbidden - l_confusing - l_dangerous) * (l_character - l_forbidden - l_confusing^2)^0 * lpeg.P(-1)
@@ -9290,8 +9413,7 @@ 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 = file.collapse_path(filename)
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -9772,12 +9894,13 @@ end
function table.sequenced(t,sep) -- temp here
local s = { }
for k, v in pairs(t) do -- pairs?
- s[#s+1] = k .. "=" .. v
+ s[#s+1] = k .. "=" .. tostring(v)
end
return concat(s, sep or " | ")
end
function resolvers.methodhandler(what, filename, filetype) -- ...
+ filename = file.collapse_path(filename)
local specification = (type(filename) == "string" and resolvers.splitmethod(filename)) or filename -- no or { }, let it bomb
local scheme = specification.scheme
if resolvers[what][scheme] then
diff --git a/tex/context/base/char-tex.lua b/tex/context/base/char-tex.lua
index f3af91f79..3e726703a 100644
--- a/tex/context/base/char-tex.lua
+++ b/tex/context/base/char-tex.lua
@@ -58,7 +58,7 @@ local function remap_commands(c)
end
local P, C, R, S, Cs, Cc = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cs, lpeg.Cc
-local U, lpegmatch = lpeg.utf8, lpeg.match
+local U, lpegmatch = lpeg.patterns.utf8, lpeg.match
local accents = (P('\\') * C(S(accents)) * (P("{") * C(U) * P("}" * Cc(true)) + C(U) * Cc(false))) / remap_accents
local commands = (P('\\') * C(R("az","AZ")^1)) / remap_commands
diff --git a/tex/context/base/cont-new.tex b/tex/context/base/cont-new.tex
index aada1b888..a80de62a0 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{2010.03.02 12:34}
+\newcontextversion{2010.03.09 10:39}
%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 6a89f4cfe..328f3f683 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{2010.03.02 12:34}
+\edef\contextversion{2010.03.09 10:39}
%D For those who want to use this:
diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua
index 40cd3eb1a..47c29fda9 100644
--- a/tex/context/base/data-res.lua
+++ b/tex/context/base/data-res.lua
@@ -645,7 +645,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -674,7 +674,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -799,7 +799,7 @@ local weird = lpeg.P(".")^1 + lpeg.anywhere(lpeg.S("~`!#$%^&*()={}[]:;\"\'||<>,?
--~ local l_forbidden = lpeg.S("~`!#$%^&*()={}[]:;\"\'||\\/<>,?\n\r\t")
--~ local l_confusing = lpeg.P(" ")
---~ local l_character = lpeg.utf8
+--~ local l_character = lpeg.patterns.utf8
--~ local l_dangerous = lpeg.P(".")
--~ local l_normal = (l_character - l_forbidden - l_confusing - l_dangerous) * (l_character - l_forbidden - l_confusing^2)^0 * lpeg.P(-1)
@@ -1539,8 +1539,7 @@ 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 = file.collapse_path(filename)
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -2021,7 +2020,7 @@ end
function table.sequenced(t,sep) -- temp here
local s = { }
for k, v in pairs(t) do -- pairs?
- s[#s+1] = k .. "=" .. v
+ s[#s+1] = k .. "=" .. tostring(v)
end
return concat(s, sep or " | ")
end
diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua
index 4b892ed8c..1d9bc64f5 100644
--- a/tex/context/base/font-syn.lua
+++ b/tex/context/base/font-syn.lua
@@ -671,7 +671,7 @@ local function analysefiles()
end
end
if not trace_warnings then
- logs.report("fontnames", "warnings are disables (tracker 'fonts.warnings')")
+ logs.report("fontnames", "warnings are disabled (tracker 'fonts.warnings')")
end
traverse("tree", function(suffix) -- TEXTREE only
resolvers.with_files(".*%." .. suffix .. "$", function(method,root,path,name)
diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua
index 7f786248e..574bece89 100644
--- a/tex/context/base/grph-inc.lua
+++ b/tex/context/base/grph-inc.lua
@@ -377,8 +377,8 @@ local function register(askedname,specification)
end
local newname = file.join(newpath,newbase)
dir.makedirs(newpath)
- oldname = dir.expand_name(oldname)
- newname = dir.expand_name(newname)
+ oldname = file.collapse_path(oldname)
+ newname = file.collapse_path(newname)
local oldtime = lfs.attributes(oldname,'modification') or 0
local newtime = lfs.attributes(newname,'modification') or 0
if oldtime > newtime then
@@ -428,7 +428,7 @@ local function register(askedname,specification)
return specification
end
-local resolve_too = true
+local resolve_too = true -- urls
local function locate(request) -- name, format, cache
local askedname = resolvers.clean_path(request.name)
@@ -544,7 +544,7 @@ local function locate(request) -- name, format, cache
for _, format in ipairs(figures.order) do
local list = figures.formats[format].list or { format }
for _, suffix in ipairs(list) do
---~ local name = file.replacesuffix(askedbase,suffix)
+ -- local name = file.replacesuffix(askedbase,suffix)
local name = file.replacesuffix(askedname,suffix)
for _, path in ipairs(figures.paths) do
local check = path .. "/" .. name
@@ -553,7 +553,7 @@ local function locate(request) -- name, format, cache
if trace_figures then
commands.writestatus("figures","warning: skipping path %s",path)
end
- elseif figures.exists(check,format,resolve_too) then
+ elseif figures.exists(check,format,true) then
return register(askedname, {
askedname = askedname,
fullname = check,
diff --git a/tex/context/base/l-dir.lua b/tex/context/base/l-dir.lua
index 3760db2c1..369895c43 100644
--- a/tex/context/base/l-dir.lua
+++ b/tex/context/base/l-dir.lua
@@ -323,7 +323,7 @@ else
--~ print(dir.mkdirs("///a/b/c"))
--~ print(dir.mkdirs("a/bbb//ccc/"))
- function dir.expand_name(str)
+ function dir.expand_name(str) -- will be merged with cleanpath and collapsepath
if not find(str,"^/") then
str = lfs.currentdir() .. "/" .. str
end
diff --git a/tex/context/base/l-file.lua b/tex/context/base/l-file.lua
index 2064fcdd1..0b2c96d8f 100644
--- a/tex/context/base/l-file.lua
+++ b/tex/context/base/l-file.lua
@@ -139,7 +139,9 @@ end
-- we can hash them weakly
function file.collapse_path(str)
+ str = gsub(str,"\\","/")
if find(str,"/") then
+ str = gsub(str,"^%./",(gsub(lfs.currentdir(),"\\","/")) .. "/") -- ./xx in qualified
str = gsub(str,"/%./","/")
local n, m = 1, 1
while n > 0 or m > 0 do
@@ -147,7 +149,7 @@ function file.collapse_path(str)
str, m = gsub(str,"[^/%.]+/%.%./","")
end
str = gsub(str,"([^/])/$","%1")
- str = gsub(str,"^%./","")
+ -- str = gsub(str,"^%./","") -- ./xx in qualified
str = gsub(str,"/%.$","")
end
if str == "" then str = "." end
diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua
index e7b319874..227b193da 100644
--- a/tex/context/base/l-lpeg.lua
+++ b/tex/context/base/l-lpeg.lua
@@ -160,8 +160,6 @@ end
--~
--~ 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
-
+lpeg.patterns.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
diff --git a/tex/context/base/mlib-run.lua b/tex/context/base/mlib-run.lua
index 73ce51c89..212b7b7f3 100644
--- a/tex/context/base/mlib-run.lua
+++ b/tex/context/base/mlib-run.lua
@@ -58,7 +58,7 @@ metapost.finder = finder
metapost.parameters = {
hash_size = 100000,
- main_memory = 2500000,
+ main_memory = 4000000,
max_in_open = 50,
param_size = 100000,
}
diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua
index 3534e9719..39ff32209 100644
--- a/tex/context/base/node-tra.lua
+++ b/tex/context/base/node-tra.lua
@@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['node-tra'] = {
--[[ldx--
<p>This is rather experimental. We need more control and some of this
-might become a runtime module instead.</p>
+might become a runtime module instead. This module will be cleaned up!</p>
--ldx]]--
local utf = unicode.utf8
@@ -445,3 +445,20 @@ end
--~ \stopluacode
nodes.show_simple_list = function(h,depth) show_simple_list(h,depth,0) end
+
+function nodes.list_to_utf(h,joiner)
+ local joiner = (joiner ==true and utfchar(0x200C)) or joiner -- zwnj
+ local w = { }
+ while h do
+ if h.id == glyph then -- always true
+ w[#w+1] = utfchar(h.char)
+ if joiner then
+ w[#w+1] = joiner
+ end
+ else
+ w[#w+1] = "[-]"
+ end
+ h = h.next
+ end
+ return concat(w)
+end
diff --git a/tex/context/base/s-fnt-25.tex b/tex/context/base/s-fnt-25.tex
index a71aaa330..a8b398716 100644
--- a/tex/context/base/s-fnt-25.tex
+++ b/tex/context/base/s-fnt-25.tex
@@ -44,7 +44,7 @@
\blank}
\def\mathfontlistentryhexdectit#1#2#3%
- {#1: \ruledhbox{\char#2}\enspace#3\par
+ {#1: \char#2\enspace\ruledhbox{\char#2}\enspace#3\par
\advance\leftskip 1em\relax}
\def\mathfontlistentrywdhtdpic#1#2#3#4%
@@ -90,7 +90,8 @@ function document.showmathfont(id,slot)
names[k] = (name and file.basename(name)) or v.id
end
end
- print(table.serialize(names))
+ local round = math.round
+-- print(table.serialize(names))
for _, s in next, sorted do
local char = characters[s]
if char then
@@ -98,7 +99,7 @@ function document.showmathfont(id,slot)
local cnext, cvert_variants, choriz_variants = char.next, char.vert_variants, char.horiz_variants
report("\\startmathfontlistentry")
report("\\mathfontlistentryhexdectit{U+%05X}{%s}{%s}",s,s,string.lower(info.description or "no description, private to font"))
- report("\\mathfontlistentrywdhtdpic{%s}{%s}{%s}{%s}",char.width or 0,char.height or 0,char.depth or 0,char.italic or 0)
+ report("\\mathfontlistentrywdhtdpic{%s}{%s}{%s}{%s}",round(char.width or 0),round(char.height or 0),round(char.depth or 0),round(char.italic or 0))
if virtual then
local commands = char.commands
if commands then
diff --git a/tex/context/base/spec-fdf.mkii b/tex/context/base/spec-fdf.mkii
index 5d180b38c..4bf4115c6 100644
--- a/tex/context/base/spec-fdf.mkii
+++ b/tex/context/base/spec-fdf.mkii
@@ -321,7 +321,17 @@
\addPDFdocumentinfo
\to \everyfirstshipout
-\def\PDFversion{1.\the\pdfminorversion}
+\ifx\pdfminorversion\undefined
+ \ifx\pdfoptionpdfminorversion\undefined
+ \newcount\pdfminorversion
+ \else
+ \let\pdfminorversion\pdfoptionpdfminorversion
+ \fi
+\fi
+
+\pdfminorversion=5
+
+\def\PDFversion{1.\number\pdfminorversion}
\appendtoksonce
\def\PDFversion{1.\the\pdfminorversion}%
diff --git a/tex/context/base/strc-itm.mkiv b/tex/context/base/strc-itm.mkiv
index 423508930..6f3f5bb77 100644
--- a/tex/context/base/strc-itm.mkiv
+++ b/tex/context/base/strc-itm.mkiv
@@ -985,83 +985,6 @@
\fi
\fi\fi}
-% \def\dodolapitem
-% {% todo: align+marge binnen de hbox
-% \llap{\hbox to \itemgrouplistwidth{\ifconditional\sublistitem\llap{+\enspace}\fi
-% \symalignleft
-% \box\itemgroupitembox\hfil
-% \hskip\getitemparameter\currentitemlevel\c!distance% T h
-% }}}
-
-% \def\dolistitem % evt aantal items opslaan per niveau, scheelt zoeken
-% {\ifconditional\textlistitem
-% % begin of item
-% \else
-% \par
-% \fi
-% \advance\noflistelements\plusone
-% \optimizelistitemsbreak
-% \noindent
-% \setbox\itemgroupitembox\hbox
-% {\ifconditional\headlistitem
-% \ifconditional\symbollistitem
-% \dosetitemattributes\currentitemlevel\c!symstyle\c!symcolor{\symsymbol}%
-% \else
-% \dosetitemattributes\currentitemlevel\c!headstyle\c!headcolor{\listitem}%
-% \fi
-% \else
-% \ifconditional\symbollistitem
-% \dosetitemattributes\currentitemlevel\c!symstyle\c!symcolor{\symsymbol}%
-% \else
-% \dosetitemattributes\currentitemlevel\c!style\c!color{\listitem}%
-% \fi
-% \fi}%
-% \ifconditional\fittinglistitems
-% \ifdim\wd\itemgroupitembox>\getitemparameter\currentitemlevel\c!maxwidth sp\relax
-% \xsetitemparameter\currentitemlevel\c!maxwidth{\number\wd\itemgroupitembox}%
-% \fi
-% \ifdim\currentitemmaxwidth>\zeropoint
-% \setbox\itemgroupitembox\simplealignedbox{\getitemparameter\currentitemlevel\c!itemalign}{\currentitemmaxwidth}{\box\itemgroupitembox}%
-% \fi
-% \fi
-% \doifsomething\doitemdestination
-% {\setbox\itemgroupitembox\hbox{\directgotobox{\box\itemgroupitembox}[\doitemdestination]}}%
-% \globallet\doitemdestination\empty
-% \itemgroupaskedwidth\getitemparameter\currentitemlevel\c!width\relax
-% % new, prevents loops when symbol is (not yet found) graphic
-% \ht\itemgroupitembox\strutheight
-% \dp\itemgroupitembox\strutdepth
-% % so that content differs per run (esp mp graphics afterwards)
-% \checkforrepeatedlistitem
-% \ifdim\itemgroupaskedwidth<\zeropoint\relax
-% \llap{\ifconditional\sublistitem\llap{+\enspace}\fi\box\itemgroupitembox\hskip\leftmargindistance}%
-% \else
-% \ifdim\itemgroupaskedwidth=\zeropoint\relax
-% \calculatelistwidth1%
-% \else
-% \calculatelistwidth\currentitemlevel
-% \fi
-% \ifconditional\textlistitem
-% \hbox{\ifconditional\sublistitem+\enspace\fi\box\itemgroupitembox\hskip\interwordspace}\nobreak
-% \else\ifconditional\inlinelistitem
-% \hbox to \itemgrouplistwidth{\ifconditional\sublistitem\llap{+\enspace}\fi\box\itemgroupitembox\hss}% was: \hfill
-% \else\ifconditional\txtlistitem
-% \dodotxtitem
-% \else
-% \dodolapitem
-% \fi\fi\fi
-% \fi
-% \forceunexpanded % needed for m conversion (\os) / i need to look into this
-% \setevalue{\@@currentitemsymbol\currentitemlevel}%
-% {\getvalue{\@@localitemsymbol\currentitemlevel}}% still problems with \uchar ?
-% %{\noexpand\getvalue{\@@localitemsymbol\currentitemlevel}}% no, spoils subrefs
-% \resetunexpanded
-% \setfalse\headlistitem
-% \setfalse\sublistitem
-% \setfalse\symbollistitem
-% \EveryPar{\ignorespaces}% needed ?
-% \ignorespaces}
-
\def\dodosubitem
{\ifconditional\sublistitem\llap{+\enspace}\fi}
@@ -1074,7 +997,7 @@
\hfil
\hskip\getitemparameter\currentitemlevel\c!distance}}}
-\def\dolistitem % evt aantal items opslaan per niveau, scheelt zoeken
+\unprotected\def\dolistitem % evt aantal items opslaan per niveau, scheelt zoeken
{\ifconditional\textlistitem
% begin of item
\else
@@ -1082,7 +1005,8 @@
\fi
\advance\noflistelements\plusone
\optimizelistitemsbreak
- \noindent
+ %\noindent %% WS: don't apply \noindent when the user sets 'first' in the indenting key
+ \checkindentation\ifindentfirstparagraph\indent\else\noindent\fi
\setbox\itemgroupitembox\hbox
{\ifconditional\headlistitem
\ifconditional\symbollistitem
@@ -1204,7 +1128,7 @@
\chardef\autoitemgroupspacing=2 % 0 = voor/na, 1=tussen als geen voor 2=(prev)tussen=old/normal
-\def\complexdoitemgroupitem[#1]%
+\unprotected\def\complexdoitemgroupitem[#1]%
{\def\currentitemreference{#1}%
\ifconditional\textlistitem
% begin of item
@@ -1239,7 +1163,11 @@
\fi
\else
\ifconditional\textlistitem % was bugged: \inlinelistitem
- \removeunwantedspaces\hskip\emwidth\!!plus\interwordstretch\!!minus\interwordshrink\relax % new per 2006/10/20
+ \ifhmode
+ % WS: make the distance between items customizable, think about better default values -> see itemize-1.tex
+ \normalexpanded{\doassigntextitemdistance{\getitemparameter\currentitemlevel\c!textdistance}}% HH: moved out and made configurable (sort of)
+ \removeunwantedspaces\hskip\textitemdistance\relax
+ \fi
\else
\iteminbetweencommand
\fi
@@ -1262,6 +1190,28 @@
\hskip\itemsignal % new, concat
\getitemparameter\currentitemlevel\c!command} % \defaultitemcommand
+% \startitemize[text][space=medium]
+% \item one \item two \item three
+% \stopitemize
+
+\setvalue{\??op:\??op:\c!textdistance:\v!none}%
+ {\let\textitemdistance\zeropoint}
+
+\def\doassigngiventextitemdistance#1%
+ {\assignvalue
+ {#1}%
+ \textitemdistance
+ {.5\interwordspace\!!plus.5\emwidth}%
+ {\interwordspace \!!plus \emwidth}%
+ {\emwidth \!!plus \interwordstretch\!!minus\interwordshrink}}
+
+\unexpanded\def\doassigntextitemdistance#1%
+ {\ifcsname\??op:\??op:\c!textdistance:#1\endcsname
+ \csname\??op:\??op:\c!textdistance:#1\endcsname
+ \else
+ \doassigngiventextitemdistance{#1}%
+ \fi}
+
\def\defaultitemcommand
{\EveryPar{\ignorespaces}% needed ?
\ignorespaces}
@@ -1369,6 +1319,7 @@
\c!start=1,
\c!criterium=\v!all, % permits 0 and negative numbers
%\c!option=,
+ \c!textdistance=\v!big,
\c!command=\defaultitemcommand,
\c!symbol=\currentitemlevel]
diff --git a/tex/context/base/strc-num.mkiv b/tex/context/base/strc-num.mkiv
index 42f59c9e7..c5bad7224 100644
--- a/tex/context/base/strc-num.mkiv
+++ b/tex/context/base/strc-num.mkiv
@@ -203,7 +203,7 @@
\ctxlua{structure.counters.add("\@@thestructurecounter{#1}",1,1)}}
\def\doincrementsubstructurecounter[#1][#2]%
- {\docheckstructurecounterbypage{#1}
+ {\docheckstructurecounterbypage{#1}%
\ctxlua{structure.counters.add("\@@thestructurecounter{#1}",#2,1)}}
\def\convertedstructurecounter
diff --git a/tex/context/base/trac-tra.lua b/tex/context/base/trac-tra.lua
index 4c578fcee..5d15d5ad8 100644
--- a/tex/context/base/trac-tra.lua
+++ b/tex/context/base/trac-tra.lua
@@ -236,14 +236,14 @@ end
function setters.enable(t,what)
local e = t.enable
t.enable, t.done = enable, { }
- enable(t,string.simpleesc(what))
+ enable(t,string.simpleesc(tostring(what)))
t.enable, t.done = e, { }
end
function setters.disable(t,what)
local e = t.disable
t.disable, t.done = disable, { }
- disable(t,string.simpleesc(what))
+ disable(t,string.simpleesc(tostring(what)))
t.disable, t.done = e, { }
end
diff --git a/tex/context/interface/cont-cs.xml b/tex/context/interface/cont-cs.xml
index 106f50197..079606e99 100644
--- a/tex/context/interface/cont-cs.xml
+++ b/tex/context/interface/cont-cs.xml
@@ -6235,6 +6235,13 @@
<cd:parameter name="odsadpristi">
<cd:resolve name="indentnext"/>
</cd:parameter>
+ <cd:parameter name="textdistance">
+ <!-- maybe resolve here too -->
+ <cd:constant type="zadny"/>
+ <cd:constant type="velke"/>
+ <cd:constant type="stredni"/>
+ <cd:constant type="male"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
diff --git a/tex/context/interface/cont-de.xml b/tex/context/interface/cont-de.xml
index f2ce1cfe5..bb011ddbc 100644
--- a/tex/context/interface/cont-de.xml
+++ b/tex/context/interface/cont-de.xml
@@ -6235,6 +6235,13 @@
<cd:parameter name="ziehefolgendeein">
<cd:resolve name="indentnext"/>
</cd:parameter>
+ <cd:parameter name="textdistance">
+ <!-- maybe resolve here too -->
+ <cd:constant type="kein"/>
+ <cd:constant type="gross"/>
+ <cd:constant type="mittel"/>
+ <cd:constant type="klein"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
diff --git a/tex/context/interface/cont-en.xml b/tex/context/interface/cont-en.xml
index 9d2319722..4c6ef7c7d 100644
--- a/tex/context/interface/cont-en.xml
+++ b/tex/context/interface/cont-en.xml
@@ -6235,6 +6235,13 @@
<cd:parameter name="indentnext">
<cd:resolve name="indentnext"/>
</cd:parameter>
+ <cd:parameter name="textdistance">
+ <!-- maybe resolve here too -->
+ <cd:constant type="none"/>
+ <cd:constant type="big"/>
+ <cd:constant type="medium"/>
+ <cd:constant type="small"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
diff --git a/tex/context/interface/cont-fr.xml b/tex/context/interface/cont-fr.xml
index 2e38c3667..b07e97936 100644
--- a/tex/context/interface/cont-fr.xml
+++ b/tex/context/interface/cont-fr.xml
@@ -6235,6 +6235,13 @@
<cd:parameter name="indentesuivant">
<cd:resolve name="indentnext"/>
</cd:parameter>
+ <cd:parameter name="distancetexte">
+ <!-- maybe resolve here too -->
+ <cd:constant type="rien"/>
+ <cd:constant type="grand"/>
+ <cd:constant type="moyen"/>
+ <cd:constant type="petit"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
diff --git a/tex/context/interface/cont-it.xml b/tex/context/interface/cont-it.xml
index 94e61e619..fa86d2159 100644
--- a/tex/context/interface/cont-it.xml
+++ b/tex/context/interface/cont-it.xml
@@ -6235,6 +6235,13 @@
<cd:parameter name="rientrasuccessivo">
<cd:resolve name="indentnext"/>
</cd:parameter>
+ <cd:parameter name="distanzatesto">
+ <!-- maybe resolve here too -->
+ <cd:constant type="nessuno"/>
+ <cd:constant type="grande"/>
+ <cd:constant type="medio"/>
+ <cd:constant type="piccolo"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
diff --git a/tex/context/interface/cont-nl.xml b/tex/context/interface/cont-nl.xml
index a337bbb6e..a4bd85c61 100644
--- a/tex/context/interface/cont-nl.xml
+++ b/tex/context/interface/cont-nl.xml
@@ -6235,6 +6235,13 @@
<cd:parameter name="springvolgendein">
<cd:resolve name="indentnext"/>
</cd:parameter>
+ <cd:parameter name="tekstafstand">
+ <!-- maybe resolve here too -->
+ <cd:constant type="geen"/>
+ <cd:constant type="groot"/>
+ <cd:constant type="middel"/>
+ <cd:constant type="klein"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
diff --git a/tex/context/interface/cont-pe.xml b/tex/context/interface/cont-pe.xml
index 9bcda97f7..cf6a91683 100644
--- a/tex/context/interface/cont-pe.xml
+++ b/tex/context/interface/cont-pe.xml
@@ -6235,6 +6235,13 @@
<cd:parameter name="متن‌تورفته">
<cd:resolve name="indentnext"/>
</cd:parameter>
+ <cd:parameter name="فاصله‌متن">
+ <!-- maybe resolve here too -->
+ <cd:constant type="هیچکدام"/>
+ <cd:constant type="بزرگ"/>
+ <cd:constant type="متوسط"/>
+ <cd:constant type="کوچک"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
diff --git a/tex/context/interface/cont-ro.xml b/tex/context/interface/cont-ro.xml
index 0e83841d3..44d72a866 100644
--- a/tex/context/interface/cont-ro.xml
+++ b/tex/context/interface/cont-ro.xml
@@ -6235,6 +6235,13 @@
<cd:parameter name="aliniaturmator">
<cd:resolve name="indentnext"/>
</cd:parameter>
+ <cd:parameter name="textdistance">
+ <!-- maybe resolve here too -->
+ <cd:constant type="niciunul"/>
+ <cd:constant type="mare"/>
+ <cd:constant type="mediu"/>
+ <cd:constant type="mic"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
diff --git a/tex/generic/context/luatex-fonts-merged.lua b/tex/generic/context/luatex-fonts-merged.lua
index 77600a7bd..3d4bf05e8 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 : 03/02/10 12:39:47
+-- merge date : 03/09/10 10:46:16
do -- begin closure to overcome local limits and interference
@@ -456,11 +456,9 @@ end
--~
--~ 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
-
+lpeg.patterns.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
end -- closure
@@ -1577,7 +1575,9 @@ end
-- we can hash them weakly
function file.collapse_path(str)
+ str = gsub(str,"\\","/")
if find(str,"/") then
+ str = gsub(str,"^%./",(gsub(lfs.currentdir(),"\\","/")) .. "/") -- ./xx in qualified
str = gsub(str,"/%./","/")
local n, m = 1, 1
while n > 0 or m > 0 do
@@ -1585,7 +1585,7 @@ function file.collapse_path(str)
str, m = gsub(str,"[^/%.]+/%.%./","")
end
str = gsub(str,"([^/])/$","%1")
- str = gsub(str,"^%./","")
+ -- str = gsub(str,"^%./","") -- ./xx in qualified
str = gsub(str,"/%.$","")
end
if str == "" then str = "." end