summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2019-01-19 13:13:21 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2019-01-19 13:13:21 +0100
commit3861c9ef2ffeffe824f05a255534d61800e27e7a (patch)
tree023d3e32dd6d7ef55f3eed41e23e012c32b07894
parent823bd4a7d8ff32c05807b02e650ecbd60b43e95d (diff)
downloadcontext-3861c9ef2ffeffe824f05a255534d61800e27e7a.tar.gz
2019-01-19 12:15:00
-rw-r--r--context/data/scite/context/scite-context.properties46
-rw-r--r--doc/context/documents/general/manuals/luatex.pdfbin1518696 -> 1518264 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-cs.pdfbin857587 -> 857591 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-de.pdfbin858090 -> 858086 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-en.pdfbin864658 -> 864657 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-fr.pdfbin856250 -> 856253 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-it.pdfbin861434 -> 861435 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-cs.pdfbin348075 -> 348077 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-de.pdfbin432578 -> 432573 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-en.pdfbin345874 -> 345878 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-fr.pdfbin348779 -> 348779 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-it.pdfbin347186 -> 347187 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-nl.pdfbin346590 -> 346588 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-ro.pdfbin509893 -> 509894 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-nl.pdfbin851293 -> 851293 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-ro.pdfbin855450 -> 855453 bytes
-rw-r--r--scripts/context/lua/mtx-context.lua9
-rw-r--r--scripts/context/lua/mtxrun.lua35378
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua35378
-rw-r--r--scripts/context/stubs/unix/mtxrun35378
-rw-r--r--scripts/context/stubs/win64/mtxrun.lua35378
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/back-ini.lua2
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/core-uti.lua17
-rw-r--r--tex/context/base/mkiv/font-ots.lua2
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin26060 -> 26052 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin269299 -> 268471 bytes
-rw-r--r--tex/context/base/mkiv/trac-inf.lua13
-rw-r--r--tex/context/base/mkiv/util-mrg.lua1
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin864658 -> 864657 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60769 -> 60773 bytes
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua59628
35 files changed, 100641 insertions, 100597 deletions
diff --git a/context/data/scite/context/scite-context.properties b/context/data/scite/context/scite-context.properties
index e6ee79050..f3555c1fb 100644
--- a/context/data/scite/context/scite-context.properties
+++ b/context/data/scite/context/scite-context.properties
@@ -165,7 +165,7 @@ command.help.$(file.patterns.context)=mtxrun --gethelp --url="http://localhost:8
command.help.$(file.patterns.example)=
command.help.$(file.patterns.metafun)=
-command.help.subsystem.$(file.patterns.context)=1
+#~ command.help.subsystem.$(file.patterns.context)=1
# Commands: tools menu extensions
@@ -195,10 +195,10 @@ command.compile.$(file.patterns.metafun)=$(name.context.run) $(name.flag.pdfopen
command.compile.$(file.patterns.example)=$(name.context.run) --forcexml $(FileNameExt)
command.compile.*.fo=$(name.context.run) $(name.flag.pdfopen) --forcexml --use=foxet $(FileNameExt)
-command.compile.subsystem.$(file.patterns.context)=1
-command.compile.subsystem.$(file.patterns.metafun)=1
-command.compile.subsystem.$(file.patterns.example)=1
-command.compile.subsystem.*.fo=1
+#~ command.compile.subsystem.$(file.patterns.context)=1
+#~ command.compile.subsystem.$(file.patterns.metafun)=1
+#~ command.compile.subsystem.$(file.patterns.example)=1
+#~ command.compile.subsystem.*.fo=1
if PLAT_WIN
command.go.$(file.patterns.context)=$(FileName).pdf
@@ -239,13 +239,13 @@ command.1.$(file.patterns.metafun)=$(name.context.run) $(FileNameExt) --metapost
command.1.$(file.patterns.example)=$(name.context.run) $(FileNameExt) --xml
command.1.$(file.patterns.lua)=$(name.context.mtxrunjit) --script "$(FileNameExt)"
-command.1.subsystem.$(file.patterns.context)=1
-command.1.subsystem.$(file.patterns.metafun)=1
-command.1.subsystem.$(file.patterns.example)=1
-command.1.subsystem.$(file.patterns.lua)=1
+#~ command.1.subsystem.$(file.patterns.context)=1
+#~ command.1.subsystem.$(file.patterns.metafun)=1
+#~ command.1.subsystem.$(file.patterns.example)=1
+#~ command.1.subsystem.$(file.patterns.lua)=1
command.name.29.*=Run with jit
-command.subsystem.29.*=1
+#~ command.subsystem.29.*=1
command.29.$(file.patterns.context)=$(name.context.runjit) $(FileNameExt)
command.29.$(file.patterns.metafun)=$(name.context.runjit) $(FileNameExt) --metapost
command.29.$(file.patterns.example)=$(name.context.runjit) $(FileNameExt) --xml
@@ -322,11 +322,11 @@ command.7.$(file.patterns.metafun)=$(name.context.run) --extra=listing --pretty
command.7.$(file.patterns.example)=$(name.context.run) --extra=listing --pretty --result=$(FileName) $(FileNameExt)
command.7.$(file.patterns.lua)=$(name.context.run) --extra=listing --pretty --result=$(FileName) $(FileNameExt)
-command.7.subsystem=1
-command.7.subsystem.$(file.patterns.context)=1
-command.7.subsystem.$(file.patterns.metafun)=1
-command.7.subsystem.$(file.patterns.example)=1
-command.7.subsystem.$(file.patterns.lua)=1
+#~ command.7.subsystem=1
+#~ command.7.subsystem.$(file.patterns.context)=1
+#~ command.7.subsystem.$(file.patterns.metafun)=1
+#~ command.7.subsystem.$(file.patterns.example)=1
+#~ command.7.subsystem.$(file.patterns.lua)=1
# 10: arranging
@@ -336,9 +336,9 @@ command.name.10.$(file.patterns.example)=Process and Arrange
command.10.$(file.patterns.context)=$(name.context.run) --arrange $(FileNameExt)
command.10.$(file.patterns.metafun)=$(name.context.run) --mptex $(FileNameExt)
command.10.$(file.patterns.example)=$(name.context.run) --arrange --xml $(FileNameExt)
-command.10.subsystem.$(file.patterns.context)=1
-command.10.subsystem.$(file.patterns.metafun)=1
-command.10.subsystem.$(file.patterns.example)=1
+#~ command.10.subsystem.$(file.patterns.context)=1
+#~ command.10.subsystem.$(file.patterns.metafun)=1
+#~ command.10.subsystem.$(file.patterns.example)=1
# 11: make
@@ -348,21 +348,21 @@ command.name.11.$(file.patterns.example)=Generate Formats
command.11.$(file.patterns.context)=$(name.context.run) --make --all --pdftex
command.11.$(file.patterns.metafun)=$(name.context.run) --make --all
command.11.$(file.patterns.example)=$(name.context.run) --make --all
-command.11.subsystem.$(file.patterns.context)=1
-command.11.subsystem.$(file.patterns.metafun)=1
-command.11.subsystem.$(file.patterns.example)=1
+#~ command.11.subsystem.$(file.patterns.context)=1
+#~ command.11.subsystem.$(file.patterns.metafun)=1
+#~ command.11.subsystem.$(file.patterns.example)=1
# 12: make
command.name.12.$(file.patterns.context)=Generate Formats (luaTeX)
command.12.$(file.patterns.context)=$(name.context.run) --make --all --luatex
-command.12.subsystem.$(file.patterns.context)=1
+#~ command.12.subsystem.$(file.patterns.context)=1
# 13: make
command.name.13.$(file.patterns.context)=Generate Formats (XeTeX)
command.13.$(file.patterns.context)=$(name.context.run) --make --all --xetex
-command.13.subsystem.$(file.patterns.context)=1
+#~ command.13.subsystem.$(file.patterns.context)=1
# 15: example
diff --git a/doc/context/documents/general/manuals/luatex.pdf b/doc/context/documents/general/manuals/luatex.pdf
index 64579ea5d..d932219bc 100644
--- a/doc/context/documents/general/manuals/luatex.pdf
+++ b/doc/context/documents/general/manuals/luatex.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf
index 71d8eb54d..b688f4abb 100644
--- a/doc/context/documents/general/qrcs/setup-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-de.pdf b/doc/context/documents/general/qrcs/setup-de.pdf
index cad5b8d43..1c74b7d71 100644
--- a/doc/context/documents/general/qrcs/setup-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-en.pdf b/doc/context/documents/general/qrcs/setup-en.pdf
index 1809a7c91..cb329ec26 100644
--- a/doc/context/documents/general/qrcs/setup-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-fr.pdf b/doc/context/documents/general/qrcs/setup-fr.pdf
index 2cbd3c68b..d6173a031 100644
--- a/doc/context/documents/general/qrcs/setup-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-it.pdf b/doc/context/documents/general/qrcs/setup-it.pdf
index 6a8a1c586..095b721af 100644
--- a/doc/context/documents/general/qrcs/setup-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
index 7f08d5350..0f1defdaa 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-de.pdf b/doc/context/documents/general/qrcs/setup-mapping-de.pdf
index a861f8bd0..fde12fde3 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-en.pdf b/doc/context/documents/general/qrcs/setup-mapping-en.pdf
index f9960640a..ced9c2d3a 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
index eb6995b3a..9b3d9dea8 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-it.pdf b/doc/context/documents/general/qrcs/setup-mapping-it.pdf
index e54ce4ba9..4cee880bf 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
index 7acf48429..ff726bbeb 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
index c9632d1f2..9f123d2b0 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf
index 2ab474370..1f65ee8fc 100644
--- a/doc/context/documents/general/qrcs/setup-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-ro.pdf b/doc/context/documents/general/qrcs/setup-ro.pdf
index 672199d15..6a64f7685 100644
--- a/doc/context/documents/general/qrcs/setup-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-ro.pdf
Binary files differ
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua
index 04226df4c..ae2ff1c6a 100644
--- a/scripts/context/lua/mtx-context.lua
+++ b/scripts/context/lua/mtx-context.lua
@@ -433,6 +433,7 @@ end
local pdfview -- delayed
local function pdf_open(name,method)
+ statistics.starttiming("pdfview")
pdfview = pdfview or dofile(resolvers.findfile("l-pdfview.lua","tex"))
pdfview.setmethod(method)
report(pdfview.status())
@@ -441,9 +442,13 @@ local function pdf_open(name,method)
pdfname = name .. ".pdf" -- agressive
end
pdfview.open(pdfname)
+ statistics.stoptiming("pdfview")
+ -- report("pdfview overhead after opening: %0.3f seconds",statistics.elapsedtime("pdfview"))
+ report("pdfview overhead: %0.3f seconds",statistics.elapsedtime("pdfview"))
end
local function pdf_close(name,method)
+ statistics.starttiming("pdfview")
pdfview = pdfview or dofile(resolvers.findfile("l-pdfview.lua","tex"))
pdfview.setmethod(method)
local pdfname = filenewsuffix(name,"pdf")
@@ -452,6 +457,8 @@ local function pdf_close(name,method)
end
pdfname = name .. ".pdf" -- agressive
pdfview.close(pdfname)
+ statistics.stoptiming("pdfview")
+ -- report("pdfview overhead after closing: %0.3f seconds",statistics.elapsedtime("pdfview"))
end
-- result file handling
@@ -1584,7 +1591,7 @@ end
-- updating (often one will use mtx-update instead)
function scripts.context.timed(action)
- statistics.timed(action)
+ statistics.timed(action,true)
end
local zipname = "cont-tmf.zip"
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 2763cbc04..168f204c7 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -63,14 +63,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lua"] = package.loaded["l-lua"] or true
--- original size: 6266, stripped down to: 3009
+-- original size: 6266, stripped down to: 2875
if not modules then modules={} end modules ['l-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,tonumber=next,type,tonumber
LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
@@ -78,111 +78,111 @@ LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
LUAVERSION=LUAMAJORVERSION+LUAMINORVERSION/10
if LUAVERSION<5.2 and jit then
- MINORVERSION=2
- LUAVERSION=5.2
+ MINORVERSION=2
+ LUAVERSION=5.2
end
_LUAVERSION=LUAVERSION
if not lpeg then
- lpeg=require("lpeg")
+ lpeg=require("lpeg")
end
if loadstring then
- local loadnormal=load
- function load(first,...)
- if type(first)=="string" then
- return loadstring(first,...)
- else
- return loadnormal(first,...)
- end
+ local loadnormal=load
+ function load(first,...)
+ if type(first)=="string" then
+ return loadstring(first,...)
+ else
+ return loadnormal(first,...)
end
+ end
else
- loadstring=load
+ loadstring=load
end
if not ipairs then
- local function iterate(a,i)
- i=i+1
- local v=a[i]
- if v~=nil then
- return i,v
- end
- end
- function ipairs(a)
- return iterate,a,0
+ local function iterate(a,i)
+ i=i+1
+ local v=a[i]
+ if v~=nil then
+ return i,v
end
+ end
+ function ipairs(a)
+ return iterate,a,0
+ end
end
if not pairs then
- function pairs(t)
- return next,t
- end
+ function pairs(t)
+ return next,t
+ end
end
if not table.unpack then
- table.unpack=_G.unpack
+ table.unpack=_G.unpack
elseif not unpack then
- _G.unpack=table.unpack
+ _G.unpack=table.unpack
end
if not package.loaders then
- package.loaders=package.searchers
+ package.loaders=package.searchers
end
local print,select,tostring=print,select,tostring
local inspectors={}
function setinspector(kind,inspector)
- inspectors[kind]=inspector
+ inspectors[kind]=inspector
end
function inspect(...)
- for s=1,select("#",...) do
- local value=select(s,...)
- if value==nil then
- print("nil")
- else
- local done=false
- local kind=type(value)
- local inspector=inspectors[kind]
- if inspector then
- done=inspector(value)
- if done then
- break
- end
- end
- for kind,inspector in next,inspectors do
- done=inspector(value)
- if done then
- break
- end
- end
- if not done then
- print(tostring(value))
- end
+ for s=1,select("#",...) do
+ local value=select(s,...)
+ if value==nil then
+ print("nil")
+ else
+ local done=false
+ local kind=type(value)
+ local inspector=inspectors[kind]
+ if inspector then
+ done=inspector(value)
+ if done then
+ break
+ end
+ end
+ for kind,inspector in next,inspectors do
+ done=inspector(value)
+ if done then
+ break
end
+ end
+ if not done then
+ print(tostring(value))
+ end
end
+ end
end
local dummy=function() end
function optionalrequire(...)
- local ok,result=xpcall(require,dummy,...)
- if ok then
- return result
- end
+ local ok,result=xpcall(require,dummy,...)
+ if ok then
+ return result
+ end
end
if lua then
- lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
+ lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
end
local flush=io.flush
if flush then
- local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
- local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
- local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
- local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
+ local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
+ local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
+ local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
+ local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
end
FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
if not FFISUPPORTED then
- local okay;okay,ffi=pcall(require,"ffi")
- FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
+ local okay;okay,ffi=pcall(require,"ffi")
+ FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
end
if not FFISUPPORTED then
- ffi=nil
+ ffi=nil
elseif not ffi.number then
- ffi.number=tonumber
+ ffi.number=tonumber
end
if not bit32 then
- bit32=require("l-bit32")
+ bit32=require("l-bit32")
end
@@ -192,14 +192,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-macro"] = package.loaded["l-macro"] or true
--- original size: 10131, stripped down to: 6337
+-- original size: 10131, stripped down to: 5991
if not modules then modules={} end modules ['l-macros']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local S,P,R,V,C,Cs,Cc,Ct,Carg=lpeg.S,lpeg.P,lpeg.R,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg
local lpegmatch=lpeg.match
@@ -229,214 +229,214 @@ local definitions={}
local resolve
local subparser
local report_lua=function(...)
- if logs and logs.reporter then
- report_lua=logs.reporter("system","lua")
- report_lua(...)
- else
- print(format(...))
- end
+ if logs and logs.reporter then
+ report_lua=logs.reporter("system","lua")
+ report_lua(...)
+ else
+ print(format(...))
+ end
end
local safeguard=P("local")*whitespace^1*name*(whitespace+P("="))
resolve=safeguard+C(C(name)*(arguments^-1))/function(raw,s,a)
- local d=definitions[s]
- if d then
- if a then
- local n=#a
- local p=patterns[s][n]
- if p then
- local d=d[n]
- for i=1,n do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return lpegmatch(p,d,1,a) or d
- else
- return raw
- end
- else
- return d[0] or raw
- end
- elseif a then
- for i=1,#a do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
+ local d=definitions[s]
+ if d then
+ if a then
+ local n=#a
+ local p=patterns[s][n]
+ if p then
+ local d=d[n]
+ for i=1,n do
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
end
- return s.."("..concat(a,",")..")"
- else
+ return lpegmatch(p,d,1,a) or d
+ else
return raw
+ end
+ else
+ return d[0] or raw
end
+ elseif a then
+ for i=1,#a do
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
+ end
+ return s.."("..concat(a,",")..")"
+ else
+ return raw
+ end
end
subparser=Cs((resolve+P(1))^1)
local enddefine=P("#enddefine")/""
local beginregister=(C(name)*(arguments+Cc(false))*C((1-enddefine)^1)*enddefine)/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
+ definitions[k]=d
+ end
+ d[n]=lpegmatch(subparser,v) or v
+ return ""
end
local register=(Cs(name)*(arguments+Cc(false))*spaces^0*Cs(body))/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
+ definitions[k]=d
+ end
+ d[n]=lpegmatch(subparser,v) or v
+ return ""
end
local unregister=(C(name)*spaces^0*(arguments+Cc(false)))/function(k,a)
- local n=0
- if a then
- n=#a
- local p=patterns[k]
- if p then
- p[n]=false
- end
- end
- local d=definitions[k]
- if d then
- d[n]=false
+ local n=0
+ if a then
+ n=#a
+ local p=patterns[k]
+ if p then
+ p[n]=false
end
- return ""
+ end
+ local d=definitions[k]
+ if d then
+ d[n]=false
+ end
+ return ""
end
local begindefine=(P("begindefine")*spaces^0/"")*beginregister
-local define=(P("define" )*spaces^0/"")*register
-local undefine=(P("undefine" )*spaces^0/"")*unregister
+local define=(P("define" )*spaces^0/"")*register
+local undefine=(P("undefine" )*spaces^0/"")*unregister
local parser=Cs((((P("#")/"")*(define+begindefine+undefine)*(newline^0/"") )+resolve+P(1) )^0 )
function macros.reset()
- definitions={}
- patterns={}
+ definitions={}
+ patterns={}
end
function macros.showdefinitions()
- for name,list in table.sortedhash(definitions) do
- local arguments=list.a
- if arguments then
- arguments="("..concat(arguments,",")..")"
- else
- arguments=""
- end
- print("macro: "..name..arguments)
- for i=0,#list do
- local l=list[i]
- if l then
- print(" "..l)
- end
- end
+ for name,list in table.sortedhash(definitions) do
+ local arguments=list.a
+ if arguments then
+ arguments="("..concat(arguments,",")..")"
+ else
+ arguments=""
+ end
+ print("macro: "..name..arguments)
+ for i=0,#list do
+ local l=list[i]
+ if l then
+ print(" "..l)
+ end
end
+ end
end
function macros.resolvestring(str)
- return lpegmatch(parser,str) or str
+ return lpegmatch(parser,str) or str
end
function macros.resolving()
- return next(patterns)
+ return next(patterns)
end
local function reload(path,name,data)
- local only=match(name,".-([^/]+)%.lua")
+ local only=match(name,".-([^/]+)%.lua")
+ if only and only~="" then
+ local name=path.."/"..only
+ local f=io.open(name,"wb")
+ f:write(data)
+ f:close()
+ local f=loadfile(name)
+ os.remove(name)
+ return f
+ end
+end
+local function reload(path,name,data)
+ if path and path~="" then
+ local only=string.match(name,".-([^/]+)%.lua")
if only and only~="" then
- local name=path.."/"..only
- local f=io.open(name,"wb")
+ local name=path.."/"..only.."-macro.lua"
+ local f=io.open(name,"wb")
+ if f then
f:write(data)
f:close()
- local f=loadfile(name)
+ local l=loadfile(name)
os.remove(name)
- return f
- end
-end
-local function reload(path,name,data)
- if path and path~="" then
- local only=string.match(name,".-([^/]+)%.lua")
- if only and only~="" then
- local name=path.."/"..only.."-macro.lua"
- local f=io.open(name,"wb")
- if f then
- f:write(data)
- f:close()
- local l=loadfile(name)
- os.remove(name)
- return l
- end
- end
+ return l
+ end
end
- return load(data,name)
+ end
+ return load(data,name)
end
local function loaded(name,trace,detail)
- local f=io.open(name,"rb")
- if not f then
- return false,format("file '%s' not found",name)
- end
- local c=f:read("*a")
- if not c then
- return false,format("file '%s' is invalid",name)
- end
- f:close()
- local n=lpegmatch(parser,c)
- if trace then
- if #n~=#c then
- report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
- if detail then
- report_lua()
- report_lua(n)
- report_lua()
- end
- elseif detail then
- report_lua("no macros expanded in '%s'",name)
- end
+ local f=io.open(name,"rb")
+ if not f then
+ return false,format("file '%s' not found",name)
+ end
+ local c=f:read("*a")
+ if not c then
+ return false,format("file '%s' is invalid",name)
+ end
+ f:close()
+ local n=lpegmatch(parser,c)
+ if trace then
+ if #n~=#c then
+ report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
+ if detail then
+ report_lua()
+ report_lua(n)
+ report_lua()
+ end
+ elseif detail then
+ report_lua("no macros expanded in '%s'",name)
end
- return reload(lfs and lfs.currentdir(),name,n)
+ end
+ return reload(lfs and lfs.currentdir(),name,n)
end
macros.loaded=loaded
function required(name,trace)
- local filename=file.addsuffix(name,"lua")
- local fullname=resolvers and resolvers.find_file(filename) or filename
- if not fullname or fullname=="" then
- return false
- end
- local codeblob=package.loaded[fullname]
- if codeblob then
- return codeblob
- end
- local code,message=loaded(fullname,macros,trace,trace)
- if type(code)=="function" then
- code=code()
- else
- report_lua("error when loading '%s'",fullname)
- return false,message
- end
- if code==nil then
- code=false
- end
- package.loaded[fullname]=code
- return code
+ local filename=file.addsuffix(name,"lua")
+ local fullname=resolvers and resolvers.find_file(filename) or filename
+ if not fullname or fullname=="" then
+ return false
+ end
+ local codeblob=package.loaded[fullname]
+ if codeblob then
+ return codeblob
+ end
+ local code,message=loaded(fullname,macros,trace,trace)
+ if type(code)=="function" then
+ code=code()
+ else
+ report_lua("error when loading '%s'",fullname)
+ return false,message
+ end
+ if code==nil then
+ code=false
+ end
+ package.loaded[fullname]=code
+ return code
end
macros.required=required
@@ -447,14 +447,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true
--- original size: 9747, stripped down to: 6739
+-- original size: 9747, stripped down to: 6313
if not modules then modules={} end modules ['l-sandbox']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local global=_G
local next=next
@@ -480,234 +480,234 @@ local trace=false
local logger=false
local blocked={}
local function report(...)
- tprint("sandbox ! "..format(...))
+ tprint("sandbox ! "..format(...))
end
sandbox.report=report
function sandbox.setreporter(r)
- report=r
- sandbox.report=r
+ report=r
+ sandbox.report=r
end
function sandbox.settrace(v)
- trace=v
+ trace=v
end
function sandbox.setlogger(l)
- logger=type(l)=="function" and l or false
+ logger=type(l)=="function" and l or false
end
local function register(func,overload,comment)
- if type(func)=="function" then
- if type(overload)=="string" then
- comment=overload
- overload=nil
- end
- local function f(...)
- if sandboxed then
- local overload=overloads[f]
- if overload then
- if logger then
- local result={ overload(func,...) }
- logger {
- comment=comments[f] or tostring(f),
- arguments={... },
- result=result[1] and true or false,
- }
- return unpack(result)
- else
- return overload(func,...)
- end
- else
- end
- else
- return func(...)
- end
- end
- if comment then
- comments[f]=comment
- if trace then
- report("registering function: %s",comment)
- end
+ if type(func)=="function" then
+ if type(overload)=="string" then
+ comment=overload
+ overload=nil
+ end
+ local function f(...)
+ if sandboxed then
+ local overload=overloads[f]
+ if overload then
+ if logger then
+ local result={ overload(func,...) }
+ logger {
+ comment=comments[f] or tostring(f),
+ arguments={... },
+ result=result[1] and true or false,
+ }
+ return unpack(result)
+ else
+ return overload(func,...)
+ end
+ else
end
- overloads[f]=overload or false
- originals[f]=func
- return f
+ else
+ return func(...)
+ end
end
+ if comment then
+ comments[f]=comment
+ if trace then
+ report("registering function: %s",comment)
+ end
+ end
+ overloads[f]=overload or false
+ originals[f]=func
+ return f
+ end
end
local function redefine(func,comment)
- if type(func)=="function" then
- skiploads[func]=comment or comments[func] or "unknown"
- if overloads[func]==false then
- overloads[func]=nil
- end
+ if type(func)=="function" then
+ skiploads[func]=comment or comments[func] or "unknown"
+ if overloads[func]==false then
+ overloads[func]=nil
end
+ end
end
sandbox.register=register
sandbox.redefine=redefine
function sandbox.original(func)
- return originals and originals[func] or func
+ return originals and originals[func] or func
end
function sandbox.overload(func,overload,comment)
- comment=comment or comments[func] or "?"
- if type(func)~="function" then
- if trace then
- report("overloading unknown function: %s",comment)
- end
- elseif type(overload)~="function" then
- if trace then
- report("overloading function with bad overload: %s",comment)
- end
- elseif overloads[func]==nil then
- if trace then
- report("function is not registered: %s",comment)
- end
- elseif skiploads[func] then
- if trace then
- report("function is not skipped: %s",comment)
- end
- else
- if trace then
- report("overloading function: %s",comment)
- end
- overloads[func]=overload
+ comment=comment or comments[func] or "?"
+ if type(func)~="function" then
+ if trace then
+ report("overloading unknown function: %s",comment)
+ end
+ elseif type(overload)~="function" then
+ if trace then
+ report("overloading function with bad overload: %s",comment)
+ end
+ elseif overloads[func]==nil then
+ if trace then
+ report("function is not registered: %s",comment)
+ end
+ elseif skiploads[func] then
+ if trace then
+ report("function is not skipped: %s",comment)
+ end
+ else
+ if trace then
+ report("overloading function: %s",comment)
end
- return func
+ overloads[func]=overload
+ end
+ return func
end
local function whatever(specification,what,target)
- if type(specification)~="table" then
- report("%s needs a specification",what)
- elseif type(specification.category)~="string" or type(specification.action)~="function" then
- report("%s needs a category and action",what)
- elseif not sandboxed then
- target[#target+1]=specification
- elseif trace then
- report("already enabled, discarding %s",what)
- end
+ if type(specification)~="table" then
+ report("%s needs a specification",what)
+ elseif type(specification.category)~="string" or type(specification.action)~="function" then
+ report("%s needs a category and action",what)
+ elseif not sandboxed then
+ target[#target+1]=specification
+ elseif trace then
+ report("already enabled, discarding %s",what)
+ end
end
function sandbox.initializer(specification)
- whatever(specification,"initializer",initializers)
+ whatever(specification,"initializer",initializers)
end
function sandbox.finalizer(specification)
- whatever(specification,"finalizer",finalizers)
+ whatever(specification,"finalizer",finalizers)
end
function require(name)
- local n=gsub(name,"^.*[\\/]","")
- local n=gsub(n,"[%.].*$","")
- local b=blocked[n]
- if b==false then
- return nil
- elseif b then
- if trace then
- report("using blocked: %s",n)
- end
- return b
- else
- if trace then
- report("requiring: %s",name)
- end
- return requiem(name)
+ local n=gsub(name,"^.*[\\/]","")
+ local n=gsub(n,"[%.].*$","")
+ local b=blocked[n]
+ if b==false then
+ return nil
+ elseif b then
+ if trace then
+ report("using blocked: %s",n)
end
-end
-function blockrequire(name,lib)
+ return b
+ else
if trace then
- report("preventing reload of: %s",name)
+ report("requiring: %s",name)
end
- blocked[name]=lib or _G[name] or false
+ return requiem(name)
+ end
+end
+function blockrequire(name,lib)
+ if trace then
+ report("preventing reload of: %s",name)
+ end
+ blocked[name]=lib or _G[name] or false
end
function sandbox.enable()
- if not sandboxed then
- debug={
- traceback=debug.traceback,
- }
- for i=1,#initializers do
- initializers[i].action()
- end
- for i=1,#finalizers do
- finalizers[i].action()
- end
- local nnot=0
- local nyes=0
- local cnot={}
- local cyes={}
- local skip={}
- for k,v in next,overloads do
- local c=comments[k]
- if v then
- if c then
- cyes[#cyes+1]=c
- else
- nyes=nyes+1
- end
- else
- if c then
- cnot[#cnot+1]=c
- else
- nnot=nnot+1
- end
- end
- end
- for k,v in next,skiploads do
- skip[#skip+1]=v
- end
- if #cyes>0 then
- sort(cyes)
- report("overloaded known: %s",concat(cyes," | "))
- end
- if nyes>0 then
- report("overloaded unknown: %s",nyes)
- end
- if #cnot>0 then
- sort(cnot)
- report("not overloaded known: %s",concat(cnot," | "))
- end
- if nnot>0 then
- report("not overloaded unknown: %s",nnot)
+ if not sandboxed then
+ debug={
+ traceback=debug.traceback,
+ }
+ for i=1,#initializers do
+ initializers[i].action()
+ end
+ for i=1,#finalizers do
+ finalizers[i].action()
+ end
+ local nnot=0
+ local nyes=0
+ local cnot={}
+ local cyes={}
+ local skip={}
+ for k,v in next,overloads do
+ local c=comments[k]
+ if v then
+ if c then
+ cyes[#cyes+1]=c
+ else
+ nyes=nyes+1
end
- if #skip>0 then
- sort(skip)
- report("not overloaded redefined: %s",concat(skip," | "))
+ else
+ if c then
+ cnot[#cnot+1]=c
+ else
+ nnot=nnot+1
end
- initializers=nil
- finalizers=nil
- originals=nil
- sandboxed=true
+ end
+ end
+ for k,v in next,skiploads do
+ skip[#skip+1]=v
+ end
+ if #cyes>0 then
+ sort(cyes)
+ report("overloaded known: %s",concat(cyes," | "))
+ end
+ if nyes>0 then
+ report("overloaded unknown: %s",nyes)
+ end
+ if #cnot>0 then
+ sort(cnot)
+ report("not overloaded known: %s",concat(cnot," | "))
+ end
+ if nnot>0 then
+ report("not overloaded unknown: %s",nnot)
end
+ if #skip>0 then
+ sort(skip)
+ report("not overloaded redefined: %s",concat(skip," | "))
+ end
+ initializers=nil
+ finalizers=nil
+ originals=nil
+ sandboxed=true
+ end
end
blockrequire("lfs",lfs)
blockrequire("io",io)
blockrequire("os",os)
blockrequire("ffi",ffi)
local function supported(library)
- local l=_G[library]
- return l
+ local l=_G[library]
+ return l
end
loadfile=register(loadfile,"loadfile")
if supported("io") then
- io.open=register(io.open,"io.open")
- io.popen=register(io.popen,"io.popen")
- io.lines=register(io.lines,"io.lines")
- io.output=register(io.output,"io.output")
- io.input=register(io.input,"io.input")
+ io.open=register(io.open,"io.open")
+ io.popen=register(io.popen,"io.popen")
+ io.lines=register(io.lines,"io.lines")
+ io.output=register(io.output,"io.output")
+ io.input=register(io.input,"io.input")
end
if supported("os") then
- os.execute=register(os.execute,"os.execute")
- os.spawn=register(os.spawn,"os.spawn")
- os.exec=register(os.exec,"os.exec")
- os.rename=register(os.rename,"os.rename")
- os.remove=register(os.remove,"os.remove")
+ os.execute=register(os.execute,"os.execute")
+ os.spawn=register(os.spawn,"os.spawn")
+ os.exec=register(os.exec,"os.exec")
+ os.rename=register(os.rename,"os.rename")
+ os.remove=register(os.remove,"os.remove")
end
if supported("lfs") then
- lfs.chdir=register(lfs.chdir,"lfs.chdir")
- lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
- lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
- lfs.isfile=register(lfs.isfile,"lfs.isfile")
- lfs.isdir=register(lfs.isdir,"lfs.isdir")
- lfs.attributes=register(lfs.attributes,"lfs.attributes")
- lfs.dir=register(lfs.dir,"lfs.dir")
- lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
- lfs.touch=register(lfs.touch,"lfs.touch")
- lfs.link=register(lfs.link,"lfs.link")
- lfs.setmode=register(lfs.setmode,"lfs.setmode")
- lfs.readlink=register(lfs.readlink,"lfs.readlink")
- lfs.shortname=register(lfs.shortname,"lfs.shortname")
- lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
+ lfs.chdir=register(lfs.chdir,"lfs.chdir")
+ lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
+ lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
+ lfs.isfile=register(lfs.isfile,"lfs.isfile")
+ lfs.isdir=register(lfs.isdir,"lfs.isdir")
+ lfs.attributes=register(lfs.attributes,"lfs.attributes")
+ lfs.dir=register(lfs.dir,"lfs.dir")
+ lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
+ lfs.touch=register(lfs.touch,"lfs.touch")
+ lfs.link=register(lfs.link,"lfs.link")
+ lfs.setmode=register(lfs.setmode,"lfs.setmode")
+ lfs.readlink=register(lfs.readlink,"lfs.readlink")
+ lfs.shortname=register(lfs.shortname,"lfs.shortname")
+ lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
end
@@ -717,14 +717,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-package"] = package.loaded["l-package"] or true
--- original size: 11605, stripped down to: 8663
+-- original size: 11605, stripped down to: 8299
if not modules then modules={} end modules ['l-package']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type=type
local gsub,format,find=string.gsub,string.format,string.find
@@ -732,40 +732,40 @@ local insert,remove=table.insert,table.remove
local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
local package=package
local searchers=package.searchers or package.loaders
-local filejoin=file and file.join or function(path,name) return path.."/"..name end
-local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
-local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
+local filejoin=file and file.join or function(path,name) return path.."/"..name end
+local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
+local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
local function cleanpath(path)
- return path
+ return path
end
local pattern=Cs((((1-S("\\/"))^0*(S("\\/")^1/"/"))^0*(P(".")^1/"/"+P(1))^1)*-1)
local function lualibfile(name)
- return lpegmatch(pattern,name) or name
+ return lpegmatch(pattern,name) or name
end
local offset=luarocks and 1 or 0
local helpers=package.helpers or {
- cleanpath=cleanpath,
- lualibfile=lualibfile,
- trace=false,
- report=function(...) print(format(...)) end,
- builtin={
- ["preload table"]=searchers[1+offset],
- ["path specification"]=searchers[2+offset],
- ["cpath specification"]=searchers[3+offset],
- ["all in one fallback"]=searchers[4+offset],
- },
- methods={},
- sequence={
- "already loaded",
- "preload table",
- "qualified path",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
- }
+ cleanpath=cleanpath,
+ lualibfile=lualibfile,
+ trace=false,
+ report=function(...) print(format(...)) end,
+ builtin={
+ ["preload table"]=searchers[1+offset],
+ ["path specification"]=searchers[2+offset],
+ ["cpath specification"]=searchers[3+offset],
+ ["all in one fallback"]=searchers[4+offset],
+ },
+ methods={},
+ sequence={
+ "already loaded",
+ "preload table",
+ "qualified path",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
+ }
}
package.helpers=helpers
local methods=helpers.methods
@@ -781,255 +781,255 @@ local nofextralib=-1
local nofpathlua=-1
local nofpathlib=-1
local function listpaths(what,paths)
- local nofpaths=#paths
- if nofpaths>0 then
- for i=1,nofpaths do
- helpers.report("using %s path %i: %s",what,i,paths[i])
- end
- else
- helpers.report("no %s paths defined",what)
+ local nofpaths=#paths
+ if nofpaths>0 then
+ for i=1,nofpaths do
+ helpers.report("using %s path %i: %s",what,i,paths[i])
end
- return nofpaths
+ else
+ helpers.report("no %s paths defined",what)
+ end
+ return nofpaths
end
local function getextraluapaths()
- if helpers.trace and #extraluapaths~=nofextralua then
- nofextralua=listpaths("extra lua",extraluapaths)
- end
- return extraluapaths
+ if helpers.trace and #extraluapaths~=nofextralua then
+ nofextralua=listpaths("extra lua",extraluapaths)
+ end
+ return extraluapaths
end
local function getextralibpaths()
- if helpers.trace and #extralibpaths~=nofextralib then
- nofextralib=listpaths("extra lib",extralibpaths)
- end
- return extralibpaths
+ if helpers.trace and #extralibpaths~=nofextralib then
+ nofextralib=listpaths("extra lib",extralibpaths)
+ end
+ return extralibpaths
end
local function getluapaths()
- local luapath=package.path or ""
- if oldluapath~=luapath then
- luapaths=file.splitpath(luapath,";")
- oldluapath=luapath
- nofpathlua=-1
- end
- if helpers.trace and #luapaths~=nofpathlua then
- nofpathlua=listpaths("builtin lua",luapaths)
- end
- return luapaths
+ local luapath=package.path or ""
+ if oldluapath~=luapath then
+ luapaths=file.splitpath(luapath,";")
+ oldluapath=luapath
+ nofpathlua=-1
+ end
+ if helpers.trace and #luapaths~=nofpathlua then
+ nofpathlua=listpaths("builtin lua",luapaths)
+ end
+ return luapaths
end
local function getlibpaths()
- local libpath=package.cpath or ""
- if oldlibpath~=libpath then
- libpaths=file.splitpath(libpath,";")
- oldlibpath=libpath
- nofpathlib=-1
- end
- if helpers.trace and #libpaths~=nofpathlib then
- nofpathlib=listpaths("builtin lib",libpaths)
- end
- return libpaths
+ local libpath=package.cpath or ""
+ if oldlibpath~=libpath then
+ libpaths=file.splitpath(libpath,";")
+ oldlibpath=libpath
+ nofpathlib=-1
+ end
+ if helpers.trace and #libpaths~=nofpathlib then
+ nofpathlib=listpaths("builtin lib",libpaths)
+ end
+ return libpaths
end
package.luapaths=getluapaths
package.libpaths=getlibpaths
package.extraluapaths=getextraluapaths
package.extralibpaths=getextralibpaths
local hashes={
- lua={},
- lib={},
+ lua={},
+ lib={},
}
local function registerpath(tag,what,target,...)
- local pathlist={... }
- local cleanpath=helpers.cleanpath
- local trace=helpers.trace
- local report=helpers.report
- local hash=hashes[what]
- local function add(path)
- local path=cleanpath(path)
- if not hash[path] then
- target[#target+1]=path
- hash[path]=true
- if trace then
- report("registered %s path %s: %s",tag,#target,path)
- end
- else
- if trace then
- report("duplicate %s path: %s",tag,path)
- end
- end
+ local pathlist={... }
+ local cleanpath=helpers.cleanpath
+ local trace=helpers.trace
+ local report=helpers.report
+ local hash=hashes[what]
+ local function add(path)
+ local path=cleanpath(path)
+ if not hash[path] then
+ target[#target+1]=path
+ hash[path]=true
+ if trace then
+ report("registered %s path %s: %s",tag,#target,path)
+ end
+ else
+ if trace then
+ report("duplicate %s path: %s",tag,path)
+ end
end
- for p=1,#pathlist do
- local path=pathlist[p]
- if type(path)=="table" then
- for i=1,#path do
- add(path[i])
- end
- else
- add(path)
- end
+ end
+ for p=1,#pathlist do
+ local path=pathlist[p]
+ if type(path)=="table" then
+ for i=1,#path do
+ add(path[i])
+ end
+ else
+ add(path)
end
+ end
end
local function pushpath(tag,what,target,path)
- local path=helpers.cleanpath(path)
- insert(target,1,path)
- if helpers.trace then
- helpers.report("pushing %s path in front: %s",tag,path)
- end
+ local path=helpers.cleanpath(path)
+ insert(target,1,path)
+ if helpers.trace then
+ helpers.report("pushing %s path in front: %s",tag,path)
+ end
end
local function poppath(tag,what,target)
- local path=remove(target,1)
- if helpers.trace then
- if path then
- helpers.report("popping %s path from front: %s",tag,path)
- else
- helpers.report("no %s path to pop",tag)
- end
+ local path=remove(target,1)
+ if helpers.trace then
+ if path then
+ helpers.report("popping %s path from front: %s",tag,path)
+ else
+ helpers.report("no %s path to pop",tag)
end
+ end
end
helpers.registerpath=registerpath
function package.extraluapath(...)
- registerpath("extra lua","lua",extraluapaths,...)
+ registerpath("extra lua","lua",extraluapaths,...)
end
function package.pushluapath(path)
- pushpath("extra lua","lua",extraluapaths,path)
+ pushpath("extra lua","lua",extraluapaths,path)
end
function package.popluapath()
- poppath("extra lua","lua",extraluapaths)
+ poppath("extra lua","lua",extraluapaths)
end
function package.extralibpath(...)
- registerpath("extra lib","lib",extralibpaths,...)
+ registerpath("extra lib","lib",extralibpaths,...)
end
function package.pushlibpath(path)
- pushpath("extra lib","lib",extralibpaths,path)
+ pushpath("extra lib","lib",extralibpaths,path)
end
function package.poplibpath()
- poppath("extra lib","lua",extralibpaths)
+ poppath("extra lib","lua",extralibpaths)
end
local function loadedaslib(resolved,rawname)
- local base=gsub(rawname,"%.","_")
- local init="luaopen_"..gsub(base,"%.","_")
- if helpers.trace then
- helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
- end
- return package.loadlib(resolved,init)
+ local base=gsub(rawname,"%.","_")
+ local init="luaopen_"..gsub(base,"%.","_")
+ if helpers.trace then
+ helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+ end
+ return package.loadlib(resolved,init)
end
helpers.loadedaslib=loadedaslib
local function loadedbypath(name,rawname,paths,islib,what)
- local trace=helpers.trace
- for p=1,#paths do
- local path=paths[p]
- local resolved=filejoin(path,name)
- if trace then
- helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
- end
- if isreadable(resolved) then
- if trace then
- helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ for p=1,#paths do
+ local path=paths[p]
+ local resolved=filejoin(path,name)
+ if trace then
+ helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
+ end
+ if isreadable(resolved) then
+ if trace then
+ helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
end
+ end
end
helpers.loadedbypath=loadedbypath
local function loadedbyname(name,rawname)
- if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
- local trace=helpers.trace
- if trace then
- helpers.report("qualified name, identifying '%s'",what,name)
- end
- if isreadable(name) then
- if trace then
- helpers.report("qualified name, '%s' found",what,name)
- end
- return loadfile(name)
- end
+ if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
+ local trace=helpers.trace
+ if trace then
+ helpers.report("qualified name, identifying '%s'",what,name)
end
+ if isreadable(name) then
+ if trace then
+ helpers.report("qualified name, '%s' found",what,name)
+ end
+ return loadfile(name)
+ end
+ end
end
helpers.loadedbyname=loadedbyname
methods["already loaded"]=function(name)
- return package.loaded[name]
+ return package.loaded[name]
end
methods["preload table"]=function(name)
- return builtin["preload table"](name)
+ return builtin["preload table"](name)
end
methods["qualified path"]=function(name)
- return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
+ return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
end
methods["lua extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
+ return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
end
methods["lib extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
+ return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
end
methods["path specification"]=function(name)
- getluapaths()
- return builtin["path specification"](name)
+ getluapaths()
+ return builtin["path specification"](name)
end
methods["cpath specification"]=function(name)
- getlibpaths()
- return builtin["cpath specification"](name)
+ getlibpaths()
+ return builtin["cpath specification"](name)
end
methods["all in one fallback"]=function(name)
- return builtin["all in one fallback"](name)
+ return builtin["all in one fallback"](name)
end
methods["not loaded"]=function(name)
- if helpers.trace then
- helpers.report("unable to locate '%s'",name or "?")
- end
- return nil
+ if helpers.trace then
+ helpers.report("unable to locate '%s'",name or "?")
+ end
+ return nil
end
local level=0
local used={}
helpers.traceused=false
function helpers.loaded(name)
- local sequence=helpers.sequence
- level=level+1
- for i=1,#sequence do
- local method=sequence[i]
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
- end
- local result,rest=methods[method](name)
- if type(result)=="function" then
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
- end
- if helpers.traceused then
- used[#used+1]={ level=level,name=name }
- end
- level=level-1
- return result,rest
- end
+ local sequence=helpers.sequence
+ level=level+1
+ for i=1,#sequence do
+ local method=sequence[i]
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
end
- level=level-1
- return nil
+ local result,rest=methods[method](name)
+ if type(result)=="function" then
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
+ end
+ if helpers.traceused then
+ used[#used+1]={ level=level,name=name }
+ end
+ level=level-1
+ return result,rest
+ end
+ end
+ level=level-1
+ return nil
end
function helpers.showused()
- local n=#used
- if n>0 then
- helpers.report("%s libraries loaded:",n)
- helpers.report()
- for i=1,n do
- local u=used[i]
- helpers.report("%i %a",u.level,u.name)
- end
- helpers.report()
- end
+ local n=#used
+ if n>0 then
+ helpers.report("%s libraries loaded:",n)
+ helpers.report()
+ for i=1,n do
+ local u=used[i]
+ helpers.report("%i %a",u.level,u.name)
+ end
+ helpers.report()
+ end
end
function helpers.unload(name)
- if helpers.trace then
- if package.loaded[name] then
- helpers.report("unloading, name '%s', %s",name,"done")
- else
- helpers.report("unloading, name '%s', %s",name,"not loaded")
- end
+ if helpers.trace then
+ if package.loaded[name] then
+ helpers.report("unloading, name '%s', %s",name,"done")
+ else
+ helpers.report("unloading, name '%s', %s",name,"not loaded")
end
- package.loaded[name]=nil
+ end
+ package.loaded[name]=nil
end
table.insert(searchers,1,helpers.loaded)
if context then
- package.path=""
+ package.path=""
end
@@ -1039,14 +1039,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
--- original size: 38434, stripped down to: 20344
+-- original size: 38434, stripped down to: 19310
if not modules then modules={} end modules ['l-lpeg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
lpeg=require("lpeg")
local lpeg=lpeg
@@ -1057,7 +1057,7 @@ local floor=math.floor
local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt
local lpegtype,lpegmatch,lpegprint=lpeg.type,lpeg.match,lpeg.print
if setinspector then
- setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
+ setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
end
lpeg.patterns=lpeg.patterns or {}
local patterns=lpeg.patterns
@@ -1080,7 +1080,7 @@ local underscore=P("_")
local hexdigit=digit+lowercase+uppercase
local hexdigits=hexdigit^1
local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
-local newline=P("\r")*(P("\n")+P(true))+P("\n")
+local newline=P("\r")*(P("\n")+P(true))+P("\n")
local escaped=P("\\")*anything
local squote=P("'")
local dquote=P('"')
@@ -1089,9 +1089,9 @@ local period=P(".")
local comma=P(",")
local utfbom_32_be=P('\000\000\254\255')
local utfbom_32_le=P('\255\254\000\000')
-local utfbom_16_be=P('\254\255')
-local utfbom_16_le=P('\255\254')
-local utfbom_8=P('\239\187\191')
+local utfbom_16_be=P('\254\255')
+local utfbom_16_le=P('\255\254')
+local utfbom_8=P('\239\187\191')
local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8
local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8")
local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")
@@ -1123,7 +1123,7 @@ patterns.utf8character=utf8character
patterns.validutf8=validutf8char
patterns.validutf8char=validutf8char
local eol=S("\n\r")
-local spacer=S(" \t\f\v")
+local spacer=S(" \t\f\v")
local whitespace=eol+spacer
local nonspacer=1-spacer
local nonwhitespace=1-whitespace
@@ -1132,7 +1132,7 @@ patterns.spacer=spacer
patterns.whitespace=whitespace
patterns.nonspacer=nonspacer
patterns.nonwhitespace=nonwhitespace
-local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
+local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0)
local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0)
@@ -1209,82 +1209,82 @@ patterns.somecontent=(anything-newline-space)^1
patterns.beginline=#(1-newline)
patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0))
function anywhere(pattern)
- return (1-P(pattern))^0*P(pattern)
+ return (1-P(pattern))^0*P(pattern)
end
lpeg.anywhere=anywhere
function lpeg.instringchecker(p)
- p=anywhere(p)
- return function(str)
- return lpegmatch(p,str) and true or false
- end
+ p=anywhere(p)
+ return function(str)
+ return lpegmatch(p,str) and true or false
+ end
end
function lpeg.splitter(pattern,action)
- if action then
- return (((1-P(pattern))^1)/action+1)^0
- else
- return (Cs((1-P(pattern))^1)+1)^0
- end
+ if action then
+ return (((1-P(pattern))^1)/action+1)^0
+ else
+ return (Cs((1-P(pattern))^1)+1)^0
+ end
end
function lpeg.tsplitter(pattern,action)
- if action then
- return Ct((((1-P(pattern))^1)/action+1)^0)
- else
- return Ct((Cs((1-P(pattern))^1)+1)^0)
- end
+ if action then
+ return Ct((((1-P(pattern))^1)/action+1)^0)
+ else
+ return Ct((Cs((1-P(pattern))^1)+1)^0)
+ end
end
local splitters_s,splitters_m,splitters_t={},{},{}
local function splitat(separator,single)
- local splitter=(single and splitters_s[separator]) or splitters_m[separator]
- if not splitter then
- separator=P(separator)
- local other=C((1-separator)^0)
- if single then
- local any=anything
- splitter=other*(separator*C(any^0)+"")
- splitters_s[separator]=splitter
- else
- splitter=other*(separator*other)^0
- splitters_m[separator]=splitter
- end
+ local splitter=(single and splitters_s[separator]) or splitters_m[separator]
+ if not splitter then
+ separator=P(separator)
+ local other=C((1-separator)^0)
+ if single then
+ local any=anything
+ splitter=other*(separator*C(any^0)+"")
+ splitters_s[separator]=splitter
+ else
+ splitter=other*(separator*other)^0
+ splitters_m[separator]=splitter
end
- return splitter
+ end
+ return splitter
end
local function tsplitat(separator)
- local splitter=splitters_t[separator]
- if not splitter then
- splitter=Ct(splitat(separator))
- splitters_t[separator]=splitter
- end
- return splitter
+ local splitter=splitters_t[separator]
+ if not splitter then
+ splitter=Ct(splitat(separator))
+ splitters_t[separator]=splitter
+ end
+ return splitter
end
lpeg.splitat=splitat
lpeg.tsplitat=tsplitat
function string.splitup(str,separator)
- if not separator then
- separator=","
- end
- return lpegmatch(splitters_m[separator] or splitat(separator),str)
+ if not separator then
+ separator=","
+ end
+ return lpegmatch(splitters_m[separator] or splitat(separator),str)
end
local cache={}
function lpeg.split(separator,str)
+ local c=cache[separator]
+ if not c then
+ c=tsplitat(separator)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+function string.split(str,separator)
+ if separator then
local c=cache[separator]
if not c then
- c=tsplitat(separator)
- cache[separator]=c
+ c=tsplitat(separator)
+ cache[separator]=c
end
return lpegmatch(c,str)
-end
-function string.split(str,separator)
- if separator then
- local c=cache[separator]
- if not c then
- c=tsplitat(separator)
- cache[separator]=c
- end
- return lpegmatch(c,str)
- else
- return { str }
- end
+ else
+ return { str }
+ end
end
local spacing=patterns.spacer^0*newline
local empty=spacing*Cc("")
@@ -1294,463 +1294,463 @@ patterns.textline=content
local linesplitter=tsplitat(newline)
patterns.linesplitter=linesplitter
function string.splitlines(str)
- return lpegmatch(linesplitter,str)
+ return lpegmatch(linesplitter,str)
end
local cache={}
function lpeg.checkedsplit(separator,str)
- local c=cache[separator]
- if not c then
- separator=P(separator)
- local other=C((1-separator)^1)
- c=Ct(separator^0*other*(separator^1*other)^0)
- cache[separator]=c
- end
- return lpegmatch(c,str)
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
end
function string.checkedsplit(str,separator)
- local c=cache[separator]
- if not c then
- separator=P(separator)
- local other=C((1-separator)^1)
- c=Ct(separator^0*other*(separator^1*other)^0)
- cache[separator]=c
- end
- return lpegmatch(c,str)
-end
-local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
-local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
+local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
local function f4(s) local c1,c2,c3,c4=byte(s,1,4) return ((c1*64+c2)*64+c3)*64+c4-63447168 end
local utf8byte=patterns.utf8one/byte+patterns.utf8two/f2+patterns.utf8three/f3+patterns.utf8four/f4
patterns.utf8byte=utf8byte
local cache={}
function lpeg.stripper(str)
- if type(str)=="string" then
- local s=cache[str]
- if not s then
- s=Cs(((S(str)^1)/""+1)^0)
- cache[str]=s
- end
- return s
- else
- return Cs(((str^1)/""+1)^0)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs(((S(str)^1)/""+1)^0)
+ cache[str]=s
end
+ return s
+ else
+ return Cs(((str^1)/""+1)^0)
+ end
end
local cache={}
function lpeg.keeper(str)
- if type(str)=="string" then
- local s=cache[str]
- if not s then
- s=Cs((((1-S(str))^1)/""+1)^0)
- cache[str]=s
- end
- return s
- else
- return Cs((((1-str)^1)/""+1)^0)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs((((1-S(str))^1)/""+1)^0)
+ cache[str]=s
end
+ return s
+ else
+ return Cs((((1-str)^1)/""+1)^0)
+ end
end
function lpeg.frontstripper(str)
- return (P(str)+P(true))*Cs(anything^0)
+ return (P(str)+P(true))*Cs(anything^0)
end
function lpeg.endstripper(str)
- return Cs((1-P(str)*endofstring)^0)
+ return Cs((1-P(str)*endofstring)^0)
end
function lpeg.replacer(one,two,makefunction,isutf)
- local pattern
- local u=isutf and utf8char or 1
- if type(one)=="table" then
- local no=#one
- local p=P(false)
- if no==0 then
- for k,v in next,one do
- p=p+P(k)/v
- end
- pattern=Cs((p+u)^0)
- elseif no==1 then
- local o=one[1]
- one,two=P(o[1]),o[2]
- pattern=Cs((one/two+u)^0)
- else
- for i=1,no do
- local o=one[i]
- p=p+P(o[1])/o[2]
- end
- pattern=Cs((p+u)^0)
- end
- else
- pattern=Cs((P(one)/(two or "")+u)^0)
+ local pattern
+ local u=isutf and utf8char or 1
+ if type(one)=="table" then
+ local no=#one
+ local p=P(false)
+ if no==0 then
+ for k,v in next,one do
+ p=p+P(k)/v
+ end
+ pattern=Cs((p+u)^0)
+ elseif no==1 then
+ local o=one[1]
+ one,two=P(o[1]),o[2]
+ pattern=Cs((one/two+u)^0)
+ else
+ for i=1,no do
+ local o=one[i]
+ p=p+P(o[1])/o[2]
+ end
+ pattern=Cs((p+u)^0)
end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ else
+ pattern=Cs((P(one)/(two or "")+u)^0)
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
end
+ else
+ return pattern
+ end
end
function lpeg.finder(lst,makefunction,isutf)
- local pattern
- if type(lst)=="table" then
- pattern=P(false)
- if #lst==0 then
- for k,v in next,lst do
- pattern=pattern+P(k)
- end
- else
- for i=1,#lst do
- pattern=pattern+P(lst[i])
- end
- end
- else
- pattern=P(lst)
- end
- if isutf then
- pattern=((utf8char or 1)-pattern)^0*pattern
+ local pattern
+ if type(lst)=="table" then
+ pattern=P(false)
+ if #lst==0 then
+ for k,v in next,lst do
+ pattern=pattern+P(k)
+ end
else
- pattern=(1-pattern)^0*pattern
+ for i=1,#lst do
+ pattern=pattern+P(lst[i])
+ end
end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ else
+ pattern=P(lst)
+ end
+ if isutf then
+ pattern=((utf8char or 1)-pattern)^0*pattern
+ else
+ pattern=(1-pattern)^0*pattern
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
end
+ else
+ return pattern
+ end
end
local splitters_f,splitters_s={},{}
function lpeg.firstofsplit(separator)
- local splitter=splitters_f[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)
- splitters_f[separator]=splitter
- end
- return splitter
+ local splitter=splitters_f[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)
+ splitters_f[separator]=splitter
+ end
+ return splitter
end
function lpeg.secondofsplit(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=(1-pattern)^0*pattern*C(anything^0)
- splitters_s[separator]=splitter
- end
- return splitter
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=(1-pattern)^0*pattern*C(anything^0)
+ splitters_s[separator]=splitter
+ end
+ return splitter
end
local splitters_s,splitters_p={},{}
function lpeg.beforesuffix(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)*pattern*endofstring
- splitters_s[separator]=splitter
- end
- return splitter
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)*pattern*endofstring
+ splitters_s[separator]=splitter
+ end
+ return splitter
end
function lpeg.afterprefix(separator)
- local splitter=splitters_p[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=pattern*C(anything^0)
- splitters_p[separator]=splitter
- end
- return splitter
+ local splitter=splitters_p[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=pattern*C(anything^0)
+ splitters_p[separator]=splitter
+ end
+ return splitter
end
function lpeg.balancer(left,right)
- left,right=P(left),P(right)
- return P { left*((1-left-right)+V(1))^0*right }
+ left,right=P(left),P(right)
+ return P { left*((1-left-right)+V(1))^0*right }
end
function lpeg.counter(pattern,action)
- local n=0
- local pattern=(P(pattern)/function() n=n+1 end+anything)^0
- if action then
- return function(str) n=0;lpegmatch(pattern,str);action(n) end
- else
- return function(str) n=0;lpegmatch(pattern,str);return n end
- end
+ local n=0
+ local pattern=(P(pattern)/function() n=n+1 end+anything)^0
+ if action then
+ return function(str) n=0;lpegmatch(pattern,str);action(n) end
+ else
+ return function(str) n=0;lpegmatch(pattern,str);return n end
+ end
end
function lpeg.is_lpeg(p)
- return p and lpegtype(p)=="pattern"
+ return p and lpegtype(p)=="pattern"
end
function lpeg.oneof(list,...)
- if type(list)~="table" then
- list={ list,... }
- end
- local p=P(list[1])
- for l=2,#list do
- p=p+P(list[l])
- end
- return p
+ if type(list)~="table" then
+ list={ list,... }
+ end
+ local p=P(list[1])
+ for l=2,#list do
+ p=p+P(list[l])
+ end
+ return p
end
local sort=table.sort
local function copyindexed(old)
- local new={}
- for i=1,#old do
- new[i]=old
- end
- return new
+ local new={}
+ for i=1,#old do
+ new[i]=old
+ end
+ return new
end
local function sortedkeys(tab)
- local keys,s={},0
- for key,_ in next,tab do
- s=s+1
- keys[s]=key
- end
- sort(keys)
- return keys
+ local keys,s={},0
+ for key,_ in next,tab do
+ s=s+1
+ keys[s]=key
+ end
+ sort(keys)
+ return keys
end
function lpeg.append(list,pp,delayed,checked)
- local p=pp
- if #list>0 then
- local keys=copyindexed(list)
- sort(keys)
- for i=#keys,1,-1 do
- local k=keys[i]
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- elseif delayed then
- local keys=sortedkeys(list)
+ local p=pp
+ if #list>0 then
+ local keys=copyindexed(list)
+ sort(keys)
+ for i=#keys,1,-1 do
+ local k=keys[i]
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
+ end
+ elseif delayed then
+ local keys=sortedkeys(list)
+ if p then
+ for i=1,#keys,1 do
+ local k=keys[i]
+ local v=list[k]
+ p=P(k)/list+p
+ end
+ else
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
if p then
- for i=1,#keys,1 do
- local k=keys[i]
- local v=list[k]
- p=P(k)/list+p
- end
+ p=P(k)+p
else
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- if p then
- p=p/list
- end
+ p=P(k)
end
- elseif checked then
- local keys=sortedkeys(list)
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- if k==v then
- p=P(k)+p
- else
- p=P(k)/v+p
- end
- else
- if k==v then
- p=P(k)
- else
- p=P(k)/v
- end
- end
+ end
+ if p then
+ p=p/list
+ end
+ end
+ elseif checked then
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ if k==v then
+ p=P(k)+p
+ else
+ p=P(k)/v+p
end
- else
- local keys=sortedkeys(list)
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- p=P(k)/v+p
- else
- p=P(k)/v
- end
+ else
+ if k==v then
+ p=P(k)
+ else
+ p=P(k)/v
end
+ end
end
- return p
+ else
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ p=P(k)/v+p
+ else
+ p=P(k)/v
+ end
+ end
+ end
+ return p
end
local p_false=P(false)
local p_true=P(true)
local lower=utf and utf.lower or string.lower
local upper=utf and utf.upper or string.upper
function lpeg.setutfcasers(l,u)
- lower=l or lower
- upper=u or upper
+ lower=l or lower
+ upper=u or upper
end
local function make1(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
- local k=keys[i]
- if k~="" then
- local v=t[k]
- if v==true then
- p=p+P(k)*p_true
- elseif v==false then
- else
- p=p+P(k)*make1(v,v[""])
- end
- end
- end
- if rest then
- p=p+p_true
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+P(k)*p_true
+ elseif v==false then
+ else
+ p=p+P(k)*make1(v,v[""])
+ end
end
- return p
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
end
local function make2(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
- local k=keys[i]
- if k~="" then
- local v=t[k]
- if v==true then
- p=p+(P(lower(k))+P(upper(k)))*p_true
- elseif v==false then
- else
- p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
- end
- end
- end
- if rest then
- p=p+p_true
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+(P(lower(k))+P(upper(k)))*p_true
+ elseif v==false then
+ else
+ p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
+ end
end
- return p
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
end
local function utfchartabletopattern(list,insensitive)
- local tree={}
- local n=#list
- if n==0 then
- for s in next,list do
- local t=tree
- local p,pk
- for c in gmatch(s,".") do
- if t==true then
- t={ [c]=true,[""]=true }
- p[pk]=t
- p=t
- t=false
- elseif t==false then
- t={ [c]=false }
- p[pk]=t
- p=t
- t=false
- else
- local tc=t[c]
- if not tc then
- tc=false
- t[c]=false
- end
- p=t
- t=tc
- end
- pk=c
- end
- if t==false then
- p[pk]=true
- elseif t==true then
- else
- t[""]=true
- end
+ local tree={}
+ local n=#list
+ if n==0 then
+ for s in next,list do
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
end
- else
- for i=1,n do
- local s=list[i]
- local t=tree
- local p,pk
- for c in gmatch(s,".") do
- if t==true then
- t={ [c]=true,[""]=true }
- p[pk]=t
- p=t
- t=false
- elseif t==false then
- t={ [c]=false }
- p[pk]=t
- p=t
- t=false
- else
- local tc=t[c]
- if not tc then
- tc=false
- t[c]=false
- end
- p=t
- t=tc
- end
- pk=c
- end
- if t==false then
- p[pk]=true
- elseif t==true then
- else
- t[""]=true
- end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
+ end
+ else
+ for i=1,n do
+ local s=list[i]
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
end
- return (insensitive and make2 or make1)(tree)
+ end
+ return (insensitive and make2 or make1)(tree)
end
lpeg.utfchartabletopattern=utfchartabletopattern
function lpeg.utfreplacer(list,insensitive)
- local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
- return function(str)
- return lpegmatch(pattern,str) or str
- end
+ local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
+ return function(str)
+ return lpegmatch(pattern,str) or str
+ end
end
patterns.containseol=lpeg.finder(eol)
local function nextstep(n,step,result)
- local m=n%step
- local d=floor(n/step)
- if d>0 then
- local v=V(tostring(step))
- local s=result.start
- for i=1,d do
- if s then
- s=v*s
- else
- s=v
- end
- end
- result.start=s
- end
- if step>1 and result.start then
- local v=V(tostring(step/2))
- result[tostring(step)]=v*v
- end
- if step>0 then
- return nextstep(m,step/2,result)
- else
- return result
+ local m=n%step
+ local d=floor(n/step)
+ if d>0 then
+ local v=V(tostring(step))
+ local s=result.start
+ for i=1,d do
+ if s then
+ s=v*s
+ else
+ s=v
+ end
end
+ result.start=s
+ end
+ if step>1 and result.start then
+ local v=V(tostring(step/2))
+ result[tostring(step)]=v*v
+ end
+ if step>0 then
+ return nextstep(m,step/2,result)
+ else
+ return result
+ end
end
function lpeg.times(pattern,n)
- return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
+ return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
end
do
- local trailingzeros=zero^0*-digit
- local stripper=Cs((
- digits*(
- period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
- )+1
- )^0)
- lpeg.patterns.stripzeros=stripper
- local nonzero=digit-zero
- local trailingzeros=zero^1*endofstring
- local stripper=Cs((1-period)^0*(
- period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
- ))
- lpeg.patterns.stripzero=stripper
+ local trailingzeros=zero^0*-digit
+ local stripper=Cs((
+ digits*(
+ period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
+ )+1
+ )^0)
+ lpeg.patterns.stripzeros=stripper
+ local nonzero=digit-zero
+ local trailingzeros=zero^1*endofstring
+ local stripper=Cs((1-period)^0*(
+ period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
+ ))
+ lpeg.patterns.stripzero=stripper
end
local byte_to_HEX={}
local byte_to_hex={}
local byte_to_dec={}
local hex_to_byte={}
for i=0,255 do
- local H=format("%02X",i)
- local h=format("%02x",i)
- local d=format("%03i",i)
- local c=char(i)
- byte_to_HEX[c]=H
- byte_to_hex[c]=h
- byte_to_dec[c]=d
- hex_to_byte[h]=c
- hex_to_byte[H]=c
+ local H=format("%02X",i)
+ local h=format("%02x",i)
+ local d=format("%03i",i)
+ local c=char(i)
+ byte_to_HEX[c]=H
+ byte_to_hex[c]=h
+ byte_to_dec[c]=d
+ hex_to_byte[h]=c
+ hex_to_byte[H]=c
end
local hextobyte=P(2)/hex_to_byte
local bytetoHEX=P(1)/byte_to_HEX
@@ -1769,47 +1769,47 @@ patterns.bytestoHEX=bytestoHEX
patterns.bytestohex=bytestohex
patterns.bytestodec=bytestodec
function string.toHEX(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestoHEX,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestoHEX,s)
+ end
end
function string.tohex(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestohex,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestohex,s)
+ end
end
function string.todec(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestodec,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestodec,s)
+ end
end
function string.tobytes(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(hextobytes,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(hextobytes,s)
+ end
end
local patterns={}
local function containsws(what)
- local p=patterns[what]
- if not p then
- local p1=P(what)*(whitespace+endofstring)*Cc(true)
- local p2=whitespace*P(p1)
- p=P(p1)+P(1-p2)^0*p2+Cc(false)
- patterns[what]=p
- end
- return p
+ local p=patterns[what]
+ if not p then
+ local p1=P(what)*(whitespace+endofstring)*Cc(true)
+ local p2=whitespace*P(p1)
+ p=P(p1)+P(1-p2)^0*p2+Cc(false)
+ patterns[what]=p
+ end
+ return p
end
lpeg.containsws=containsws
function string.containsws(str,what)
- return lpegmatch(patterns[what] or containsws(what),str)
+ return lpegmatch(patterns[what] or containsws(what),str)
end
@@ -1819,14 +1819,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-function"] = package.loaded["l-function"] or true
--- original size: 361, stripped down to: 322
+-- original size: 361, stripped down to: 317
if not modules then modules={} end modules ['l-functions']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
functions=functions or {}
function functions.dummy() end
@@ -1838,14 +1838,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-string"] = package.loaded["l-string"] or true
--- original size: 6461, stripped down to: 3341
+-- original size: 6461, stripped down to: 3255
if not modules then modules={} end modules ['l-string']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local string=string
local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower
@@ -1853,25 +1853,25 @@ local lpegmatch,patterns=lpeg.match,lpeg.patterns
local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs
local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote
function string.unquoted(str)
- return lpegmatch(unquoted,str) or str
+ return lpegmatch(unquoted,str) or str
end
function string.quoted(str)
- return format("%q",str)
+ return format("%q",str)
end
function string.count(str,pattern)
- local n=0
- for _ in gmatch(str,pattern) do
- n=n+1
- end
- return n
+ local n=0
+ for _ in gmatch(str,pattern) do
+ n=n+1
+ end
+ return n
end
function string.limit(str,n,sentinel)
- if #str>n then
- sentinel=sentinel or "..."
- return sub(str,1,(n-#sentinel))..sentinel
- else
- return str
- end
+ if #str>n then
+ sentinel=sentinel or "..."
+ return sub(str,1,(n-#sentinel))..sentinel
+ else
+ return str
+ end
end
local stripper=patterns.stripper
local fullstripper=patterns.fullstripper
@@ -1879,81 +1879,81 @@ local collapser=patterns.collapser
local nospacer=patterns.nospacer
local longtostring=patterns.longtostring
function string.strip(str)
- return str and lpegmatch(stripper,str) or ""
+ return str and lpegmatch(stripper,str) or ""
end
function string.fullstrip(str)
- return str and lpegmatch(fullstripper,str) or ""
+ return str and lpegmatch(fullstripper,str) or ""
end
function string.collapsespaces(str)
- return str and lpegmatch(collapser,str) or ""
+ return str and lpegmatch(collapser,str) or ""
end
function string.nospaces(str)
- return str and lpegmatch(nospacer,str) or ""
+ return str and lpegmatch(nospacer,str) or ""
end
function string.longtostring(str)
- return str and lpegmatch(longtostring,str) or ""
+ return str and lpegmatch(longtostring,str) or ""
end
local pattern=P(" ")^0*P(-1)
function string.is_empty(str)
- if not str or str=="" then
- return true
- else
- return lpegmatch(pattern,str) and true or false
- end
+ if not str or str=="" then
+ return true
+ else
+ return lpegmatch(pattern,str) and true or false
+ end
end
local anything=patterns.anything
local allescapes=Cc("%")*S(".-+%?()[]*")
-local someescapes=Cc("%")*S(".-+%()[]")
-local matchescapes=Cc(".")*S("*?")
+local someescapes=Cc("%")*S(".-+%()[]")
+local matchescapes=Cc(".")*S("*?")
local pattern_a=Cs ((allescapes+anything )^0 )
local pattern_b=Cs ((someescapes+matchescapes+anything )^0 )
local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") )
function string.escapedpattern(str,simple)
- return lpegmatch(simple and pattern_b or pattern_a,str)
+ return lpegmatch(simple and pattern_b or pattern_a,str)
end
function string.topattern(str,lowercase,strict)
- if str=="" or type(str)~="string" then
- return ".*"
- elseif strict then
- str=lpegmatch(pattern_c,str)
- else
- str=lpegmatch(pattern_b,str)
- end
- if lowercase then
- return lower(str)
- else
- return str
- end
+ if str=="" or type(str)~="string" then
+ return ".*"
+ elseif strict then
+ str=lpegmatch(pattern_c,str)
+ else
+ str=lpegmatch(pattern_b,str)
+ end
+ if lowercase then
+ return lower(str)
+ else
+ return str
+ end
end
function string.valid(str,default)
- return (type(str)=="string" and str~="" and str) or default or nil
+ return (type(str)=="string" and str~="" and str) or default or nil
end
string.itself=function(s) return s end
local pattern_c=Ct(C(1)^0)
local pattern_b=Ct((C(1)/byte)^0)
function string.totable(str,bytes)
- return lpegmatch(bytes and pattern_b or pattern_c,str)
+ return lpegmatch(bytes and pattern_b or pattern_c,str)
end
local replacer=lpeg.replacer("@","%%")
function string.tformat(fmt,...)
- return format(lpegmatch(replacer,fmt),...)
+ return format(lpegmatch(replacer,fmt),...)
end
string.quote=string.quoted
string.unquote=string.unquoted
if not string.bytetable then
- local limit=5000
- function string.bytetable(str)
- local n=#str
- if n>limit then
- local t={ byte(str,1,limit) }
- for i=limit+1,n do
- t[i]=byte(str,i)
- end
- return t
- else
- return { byte(str,1,n) }
- end
+ local limit=5000
+ function string.bytetable(str)
+ local n=#str
+ if n>limit then
+ local t={ byte(str,1,limit) }
+ for i=limit+1,n do
+ t[i]=byte(str,i)
+ end
+ return t
+ else
+ return { byte(str,1,n) }
end
+ end
end
@@ -1963,14 +1963,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 40960, stripped down to: 24090
+-- original size: 40960, stripped down to: 21348
if not modules then modules={} end modules ['l-table']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber,select=type,next,tostring,tonumber,select
local table,string=table,string
@@ -1981,147 +1981,147 @@ local lpegmatch,patterns=lpeg.match,lpeg.patterns
local floor=math.floor
local stripper=patterns.stripper
function table.getn(t)
- return t and #t
+ return t and #t
end
function table.strip(tab)
- local lst,l={},0
- for i=1,#tab do
- local s=lpegmatch(stripper,tab[i]) or ""
- if s=="" then
- else
- l=l+1
- lst[l]=s
- end
+ local lst,l={},0
+ for i=1,#tab do
+ local s=lpegmatch(stripper,tab[i]) or ""
+ if s=="" then
+ else
+ l=l+1
+ lst[l]=s
end
- return lst
+ end
+ return lst
end
function table.keys(t)
- if t then
- local keys,k={},0
- for key in next,t do
- k=k+1
- keys[k]=key
- end
- return keys
- else
- return {}
+ if t then
+ local keys,k={},0
+ for key in next,t do
+ k=k+1
+ keys[k]=key
end
+ return keys
+ else
+ return {}
+ end
end
local function compare(a,b)
- local ta=type(a)
- if ta=="number" then
- local tb=type(b)
- if ta==tb then
- return a<b
- elseif tb=="string" then
- return tostring(a)<b
- end
- elseif ta=="string" then
- local tb=type(b)
- if ta==tb then
- return a<b
- else
- return a<tostring(b)
- end
+ local ta=type(a)
+ if ta=="number" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ elseif tb=="string" then
+ return tostring(a)<b
+ end
+ elseif ta=="string" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ else
+ return a<tostring(b)
end
- return tostring(a)<tostring(b)
+ end
+ return tostring(a)<tostring(b)
end
local function sortedkeys(tab)
- if tab then
- local srt,category,s={},0,0
- for key in next,tab do
- s=s+1
- srt[s]=key
- if category==3 then
- elseif category==1 then
- if type(key)~="string" then
- category=3
- end
- elseif category==2 then
- if type(key)~="number" then
- category=3
- end
- else
- local tkey=type(key)
- if tkey=="string" then
- category=1
- elseif tkey=="number" then
- category=2
- else
- category=3
- end
- end
- end
- if s<2 then
- elseif category==3 then
- sort(srt,compare)
+ if tab then
+ local srt,category,s={},0,0
+ for key in next,tab do
+ s=s+1
+ srt[s]=key
+ if category==3 then
+ elseif category==1 then
+ if type(key)~="string" then
+ category=3
+ end
+ elseif category==2 then
+ if type(key)~="number" then
+ category=3
+ end
+ else
+ local tkey=type(key)
+ if tkey=="string" then
+ category=1
+ elseif tkey=="number" then
+ category=2
else
- sort(srt)
+ category=3
end
- return srt
+ end
+ end
+ if s<2 then
+ elseif category==3 then
+ sort(srt,compare)
else
- return {}
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="string" then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if type(key)=="string" then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedindexonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="number" then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if type(key)=="number" then
+ s=s+1
+ srt[s]=key
+ end
end
+ if s>1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashkeys(tab,cmp)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if key then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt,cmp)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if key then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt,cmp)
end
+ return srt
+ else
+ return {}
+ end
end
function table.allkeys(t)
- local keys={}
- for k,v in next,t do
- for k in next,v do
- keys[k]=true
- end
+ local keys={}
+ for k,v in next,t do
+ for k in next,v do
+ keys[k]=true
end
- return sortedkeys(keys)
+ end
+ return sortedkeys(keys)
end
table.sortedkeys=sortedkeys
table.sortedhashonly=sortedhashonly
@@ -2129,927 +2129,927 @@ table.sortedindexonly=sortedindexonly
table.sortedhashkeys=sortedhashkeys
local function nothing() end
local function sortedhash(t,cmp)
- if t then
- local s
- if cmp then
- s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
- else
- s=sortedkeys(t)
- end
- local m=#s
- if m==1 then
- return next,t
- elseif m>0 then
- local n=0
- return function()
- if n<m then
- n=n+1
- local k=s[n]
- return k,t[k]
- end
- end
+ if t then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local m=#s
+ if m==1 then
+ return next,t
+ elseif m>0 then
+ local n=0
+ return function()
+ if n<m then
+ n=n+1
+ local k=s[n]
+ return k,t[k]
end
+ end
end
- return nothing
+ end
+ return nothing
end
table.sortedhash=sortedhash
table.sortedpairs=sortedhash
function table.append(t,list)
- local n=#t
- for i=1,#list do
- n=n+1
- t[n]=list[i]
- end
- return t
+ local n=#t
+ for i=1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ return t
end
function table.prepend(t,list)
- local nl=#list
- local nt=nl+#t
- for i=#t,1,-1 do
- t[nt]=t[i]
- nt=nt-1
- end
- for i=1,#list do
- t[i]=list[i]
- end
- return t
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+ t[nt]=t[i]
+ nt=nt-1
+ end
+ for i=1,#list do
+ t[i]=list[i]
+ end
+ return t
end
function table.merge(t,...)
- t=t or {}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ t=t or {}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.merged(...)
- local t={}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ local t={}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.imerge(t,...)
- local nt=#t
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- nt=nt+1
- t[nt]=nst[j]
- end
+ local nt=#t
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ nt=nt+1
+ t[nt]=nst[j]
end
- return t
+ end
+ return t
end
function table.imerged(...)
- local tmp,ntmp={},0
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- ntmp=ntmp+1
- tmp[ntmp]=nst[j]
- end
+ local tmp,ntmp={},0
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ ntmp=ntmp+1
+ tmp[ntmp]=nst[j]
end
- return tmp
+ end
+ return tmp
end
local function fastcopy(old,metatabletoo)
- if old then
- local new={}
- for k,v in next,old do
- if type(v)=="table" then
- new[k]=fastcopy(v,metatabletoo)
- else
- new[k]=v
- end
- end
- if metatabletoo then
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ if type(v)=="table" then
+ new[k]=fastcopy(v,metatabletoo)
+ else
+ new[k]=v
+ end
end
+ if metatabletoo then
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ end
+ return new
+ else
+ return {}
+ end
end
local function copy(t,tables)
- tables=tables or {}
- local tcopy={}
- if not tables[t] then
- tables[t]=tcopy
- end
- for i,v in next,t do
- if type(i)=="table" then
- if tables[i] then
- i=tables[i]
- else
- i=copy(i,tables)
- end
- end
- if type(v)~="table" then
- tcopy[i]=v
- elseif tables[v] then
- tcopy[i]=tables[v]
- else
- tcopy[i]=copy(v,tables)
- end
+ tables=tables or {}
+ local tcopy={}
+ if not tables[t] then
+ tables[t]=tcopy
+ end
+ for i,v in next,t do
+ if type(i)=="table" then
+ if tables[i] then
+ i=tables[i]
+ else
+ i=copy(i,tables)
+ end
end
- local mt=getmetatable(t)
- if mt then
- setmetatable(tcopy,mt)
+ if type(v)~="table" then
+ tcopy[i]=v
+ elseif tables[v] then
+ tcopy[i]=tables[v]
+ else
+ tcopy[i]=copy(v,tables)
end
- return tcopy
+ end
+ local mt=getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
end
table.fastcopy=fastcopy
table.copy=copy
function table.derive(parent)
- local child={}
- if parent then
- setmetatable(child,{ __index=parent })
- end
- return child
+ local child={}
+ if parent then
+ setmetatable(child,{ __index=parent })
+ end
+ return child
end
function table.tohash(t,value)
- local h={}
- if t then
- if value==nil then value=true end
- for _,v in next,t do
- h[v]=value
- end
+ local h={}
+ if t then
+ if value==nil then value=true end
+ for _,v in next,t do
+ h[v]=value
end
- return h
+ end
+ return h
end
function table.fromhash(t)
- local hsh,h={},0
- for k,v in next,t do
- if v then
- h=h+1
- hsh[h]=k
- end
+ local hsh,h={},0
+ for k,v in next,t do
+ if v then
+ h=h+1
+ hsh[h]=k
end
- return hsh
+ end
+ return hsh
end
local noquotes,hexify,handle,compact,inline,functions,metacheck
local reserved=table.tohash {
- 'and','break','do','else','elseif','end','false','for','function','if',
- 'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
}
local function is_simple_table(t,hexify)
- local nt=#t
- if nt>0 then
- local n=0
- for _,v in next,t do
- n=n+1
- if type(v)=="table" then
- return nil
- end
+ local nt=#t
+ if nt>0 then
+ local n=0
+ for _,v in next,t do
+ n=n+1
+ if type(v)=="table" then
+ return nil
+ end
+ end
+ local haszero=rawget(t,0)
+ if n==nt then
+ local tt={}
+ for i=1,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i]=format("0x%X",v)
+ else
+ tt[i]=v
+ end
+ elseif tv=="string" then
+ tt[i]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i]=v and "true" or "false"
+ else
+ return nil
end
- local haszero=rawget(t,0)
- if n==nt then
- local tt={}
- for i=1,nt do
- local v=t[i]
- local tv=type(v)
- if tv=="number" then
- if hexify then
- tt[i]=format("0x%X",v)
- else
- tt[i]=v
- end
- elseif tv=="string" then
- tt[i]=format("%q",v)
- elseif tv=="boolean" then
- tt[i]=v and "true" or "false"
- else
- return nil
- end
- end
- return tt
- elseif haszero and (n==nt+1) then
- local tt={}
- for i=0,nt do
- local v=t[i]
- local tv=type(v)
- if tv=="number" then
- if hexify then
- tt[i+1]=format("0x%X",v)
- else
- tt[i+1]=v
- end
- elseif tv=="string" then
- tt[i+1]=format("%q",v)
- elseif tv=="boolean" then
- tt[i+1]=v and "true" or "false"
- else
- return nil
- end
- end
- tt[1]="[0] = "..tt[1]
- return tt
+ end
+ return tt
+ elseif haszero and (n==nt+1) then
+ local tt={}
+ for i=0,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i+1]=format("0x%X",v)
+ else
+ tt[i+1]=v
+ end
+ elseif tv=="string" then
+ tt[i+1]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i+1]=v and "true" or "false"
+ else
+ return nil
end
+ end
+ tt[1]="[0] = "..tt[1]
+ return tt
end
- return nil
+ end
+ return nil
end
table.is_simple_table=is_simple_table
local propername=patterns.propername
local function dummy() end
local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- depth=depth.." "
- if indexed then
- handle(format("%s{",depth))
+ if level>0 then
+ depth=depth.." "
+ if indexed then
+ handle(format("%s{",depth))
+ else
+ local tn=type(name)
+ if tn=="number" then
+ if hexify then
+ handle(format("%s[0x%X]={",depth,name))
else
- local tn=type(name)
- if tn=="number" then
- if hexify then
- handle(format("%s[0x%X]={",depth,name))
- else
- handle(format("%s[%s]={",depth,name))
- end
- elseif tn=="string" then
- if noquotes and not reserved[name] and lpegmatch(propername,name) then
- handle(format("%s%s={",depth,name))
- else
- handle(format("%s[%q]={",depth,name))
- end
- elseif tn=="boolean" then
- handle(format("%s[%s]={",depth,name and "true" or "false"))
- else
- handle(format("%s{",depth))
- end
+ handle(format("%s[%s]={",depth,name))
end
+ elseif tn=="string" then
+ if noquotes and not reserved[name] and lpegmatch(propername,name) then
+ handle(format("%s%s={",depth,name))
+ else
+ handle(format("%s[%q]={",depth,name))
+ end
+ elseif tn=="boolean" then
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
+ else
+ handle(format("%s{",depth))
+ end
end
- if root and next(root)~=nil then
- local first,last=nil,0
- if compact then
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
- end
- if last>0 then
- first=1
- end
+ end
+ if root and next(root)~=nil then
+ local first,last=nil,0
+ if compact then
+ last=#root
+ for k=1,last do
+ if rawget(root,k)==nil then
+ last=k-1
+ break
end
- local sk=sortedkeys(root)
- for i=1,#sk do
- local k=sk[i]
- local v=root[k]
- local tv=type(v)
- local tk=type(k)
- if compact and first and tk=="number" and k>=first and k<=last then
- if tv=="number" then
- if hexify then
- handle(format("%s 0x%X,",depth,v))
- else
- handle(format("%s %s,",depth,v))
- end
- elseif tv=="string" then
- handle(format("%s %q,",depth,v))
- elseif tv=="table" then
- if next(v)==nil then
- handle(format("%s {},",depth))
- elseif inline then
- local st=is_simple_table(v,hexify)
- if st then
- handle(format("%s { %s },",depth,concat(st,", ")))
- else
- do_serialize(v,k,depth,level+1,true)
- end
- else
- do_serialize(v,k,depth,level+1,true)
- end
- elseif tv=="boolean" then
- handle(format("%s %s,",depth,v and "true" or "false"))
- elseif tv=="function" then
- if functions then
- handle(format('%s load(%q),',depth,dump(v)))
- else
- handle(format('%s "function",',depth))
- end
- else
- handle(format("%s %q,",depth,tostring(v)))
- end
- elseif k=="__p__" then
- if false then
- handle(format("%s __p__=nil,",depth))
- end
- elseif tv=="number" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=0x%X,",depth,k,v))
- else
- handle(format("%s [%s]=%s,",depth,k,v))
- end
- elseif tk=="boolean" then
- if hexify then
- handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
- else
- handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
- end
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- if hexify then
- handle(format("%s %s=0x%X,",depth,k,v))
- else
- handle(format("%s %s=%s,",depth,k,v))
- end
- else
- if hexify then
- handle(format("%s [%q]=0x%X,",depth,k,v))
- else
- handle(format("%s [%q]=%s,",depth,k,v))
- end
- end
- elseif tv=="string" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%q,",depth,k,v))
- else
- handle(format("%s [%s]=%q,",depth,k,v))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%q,",depth,k,v))
- else
- handle(format("%s [%q]=%q,",depth,k,v))
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]={},",depth,k))
- else
- handle(format("%s [%s]={},",depth,k))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]={},",depth,k and "true" or "false"))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s={},",depth,k))
- else
- handle(format("%s [%q]={},",depth,k))
- end
- elseif inline then
- local st=is_simple_table(v,hexify)
- if st then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
- else
- handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
- else
- handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
- end
- else
- do_serialize(v,k,depth,level+1)
- end
- else
- do_serialize(v,k,depth,level+1)
- end
- elseif tv=="boolean" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
- else
- handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
- else
- handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
- end
- elseif tv=="function" then
- if functions then
- local getinfo=debug and debug.getinfo
- if getinfo then
- local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=load(%q),",depth,k,f))
- else
- handle(format("%s [%s]=load(%q),",depth,k,f))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=load(%q),",depth,k,f))
- else
- handle(format("%s [%q]=load(%q),",depth,k,f))
- end
- end
- end
+ end
+ if last>0 then
+ first=1
+ end
+ end
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if compact and first and tk=="number" and k>=first and k<=last then
+ if tv=="number" then
+ if hexify then
+ handle(format("%s 0x%X,",depth,v))
+ else
+ handle(format("%s %s,",depth,v))
+ end
+ elseif tv=="string" then
+ handle(format("%s %q,",depth,v))
+ elseif tv=="table" then
+ if next(v)==nil then
+ handle(format("%s {},",depth))
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ handle(format("%s { %s },",depth,concat(st,", ")))
else
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
- else
- handle(format("%s [%s]=%q,",depth,k,tostring(v)))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%q,",depth,k,tostring(v)))
- else
- handle(format("%s [%q]=%q,",depth,k,tostring(v)))
- end
+ do_serialize(v,k,depth,level+1,true)
end
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ elseif tv=="boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv=="function" then
+ if functions then
+ handle(format('%s load(%q),',depth,dump(v)))
+ else
+ handle(format('%s "function",',depth))
+ end
+ else
+ handle(format("%s %q,",depth,tostring(v)))
end
- end
- if level>0 then
- handle(format("%s},",depth))
- end
-end
-local function serialize(_handle,root,name,specification)
- local tname=type(name)
- if type(specification)=="table" then
- noquotes=specification.noquotes
- hexify=specification.hexify
- handle=_handle or specification.handle or print
- functions=specification.functions
- compact=specification.compact
- inline=specification.inline and compact
- metacheck=specification.metacheck
- if functions==nil then
- functions=true
- end
- if compact==nil then
- compact=true
- end
- if inline==nil then
- inline=compact
- end
- if metacheck==nil then
- metacheck=true
+ elseif k=="__p__" then
+ if false then
+ handle(format("%s __p__=nil,",depth))
end
- else
- noquotes=false
- hexify=false
- handle=_handle or print
- compact=true
- inline=true
- functions=true
- metacheck=true
- end
- if tname=="string" then
- if name=="return" then
- handle("return {")
+ elseif tv=="number" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ if hexify then
+ handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ else
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
+ end
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ if hexify then
+ handle(format("%s %s=0x%X,",depth,k,v))
+ else
+ handle(format("%s %s=%s,",depth,k,v))
+ end
else
- handle(name.."={")
+ if hexify then
+ handle(format("%s [%q]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v))
+ end
end
- elseif tname=="number" then
- if hexify then
- handle(format("[0x%X]={",name))
+ elseif tv=="string" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,v))
+ else
+ handle(format("%s [%s]=%q,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,v))
else
- handle("["..name.."]={")
+ handle(format("%s [%q]=%q,",depth,k,v))
end
- elseif tname=="boolean" then
- if name then
- handle("return {")
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={},",depth,k))
+ else
+ handle(format("%s [%s]={},",depth,k))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={},",depth,k))
+ else
+ handle(format("%s [%q]={},",depth,k))
+ end
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
else
- handle("{")
+ do_serialize(v,k,depth,level+1)
end
- else
- handle("t={")
- end
- if root then
- if metacheck and getmetatable(root) then
- local dummy=root._w_h_a_t_e_v_e_r_
- root._w_h_a_t_e_v_e_r_=nil
+ elseif tv=="boolean" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
end
- if next(root)~=nil then
- do_serialize(root,name,"",0)
+ elseif tv=="function" then
+ if functions then
+ local getinfo=debug and debug.getinfo
+ if getinfo then
+ local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%s]=load(%q),",depth,k,f))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%q]=load(%q),",depth,k,f))
+ end
+ end
+ end
+ else
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
end
+ end
end
- handle("}")
+ end
+ if level>0 then
+ handle(format("%s},",depth))
+ end
end
-function table.serialize(root,name,specification)
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
+local function serialize(_handle,root,name,specification)
+ local tname=type(name)
+ if type(specification)=="table" then
+ noquotes=specification.noquotes
+ hexify=specification.hexify
+ handle=_handle or specification.handle or print
+ functions=specification.functions
+ compact=specification.compact
+ inline=specification.inline and compact
+ metacheck=specification.metacheck
+ if functions==nil then
+ functions=true
+ end
+ if compact==nil then
+ compact=true
+ end
+ if inline==nil then
+ inline=compact
+ end
+ if metacheck==nil then
+ metacheck=true
+ end
+ else
+ noquotes=false
+ hexify=false
+ handle=_handle or print
+ compact=true
+ inline=true
+ functions=true
+ metacheck=true
+ end
+ if tname=="string" then
+ if name=="return" then
+ handle("return {")
+ else
+ handle(name.."={")
+ end
+ elseif tname=="number" then
+ if hexify then
+ handle(format("[0x%X]={",name))
+ else
+ handle("["..name.."]={")
+ end
+ elseif tname=="boolean" then
+ if name then
+ handle("return {")
+ else
+ handle("{")
+ end
+ else
+ handle("t={")
+ end
+ if root then
+ if metacheck and getmetatable(root) then
+ local dummy=root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_=nil
+ end
+ if next(root)~=nil then
+ do_serialize(root,name,"",0)
end
- serialize(flush,root,name,specification)
- return concat(t,"\n")
+ end
+ handle("}")
+end
+function table.serialize(root,name,specification)
+ local t,n={},0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ end
+ serialize(flush,root,name,specification)
+ return concat(t,"\n")
end
table.tohandle=serialize
local maxtab=2*1024
function table.tofile(filename,root,name,specification)
- local f=io.open(filename,'w')
- if f then
- if maxtab>1 then
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
- if n>maxtab then
- f:write(concat(t,"\n"),"\n")
- t,n={},0
- end
- end
- serialize(flush,root,name,specification)
- f:write(concat(t,"\n"),"\n")
- else
- local function flush(s)
- f:write(s,"\n")
- end
- serialize(flush,root,name,specification)
+ local f=io.open(filename,'w')
+ if f then
+ if maxtab>1 then
+ local t,n={},0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ if n>maxtab then
+ f:write(concat(t,"\n"),"\n")
+ t,n={},0
end
- f:close()
- io.flush()
+ end
+ serialize(flush,root,name,specification)
+ f:write(concat(t,"\n"),"\n")
+ else
+ local function flush(s)
+ f:write(s,"\n")
+ end
+ serialize(flush,root,name,specification)
end
+ f:close()
+ io.flush()
+ end
end
local function flattened(t,f,depth)
- if f==nil then
- f={}
- depth=0xFFFF
- elseif tonumber(f) then
- depth=f
- f={}
- elseif not depth then
- depth=0xFFFF
- end
- for k,v in next,t do
- if type(k)~="number" then
- if depth>0 and type(v)=="table" then
- flattened(v,f,depth-1)
- else
- f[#f+1]=v
- end
- end
+ if f==nil then
+ f={}
+ depth=0xFFFF
+ elseif tonumber(f) then
+ depth=f
+ f={}
+ elseif not depth then
+ depth=0xFFFF
+ end
+ for k,v in next,t do
+ if type(k)~="number" then
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
+ end
end
- for k=1,#t do
- local v=t[k]
- if depth>0 and type(v)=="table" then
- flattened(v,f,depth-1)
- else
- f[#f+1]=v
- end
+ end
+ for k=1,#t do
+ local v=t[k]
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
end
- return f
+ end
+ return f
end
table.flattened=flattened
local function collapsed(t,f,h)
- if f==nil then
- f={}
- h={}
- end
- for k=1,#t do
- local v=t[k]
- if type(v)=="table" then
- collapsed(v,f,h)
- elseif not h[v] then
- f[#f+1]=v
- h[v]=true
- end
+ if f==nil then
+ f={}
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsed(v,f,h)
+ elseif not h[v] then
+ f[#f+1]=v
+ h[v]=true
end
- return f
+ end
+ return f
end
local function collapsedhash(t,h)
- if h==nil then
- h={}
- end
- for k=1,#t do
- local v=t[k]
- if type(v)=="table" then
- collapsedhash(v,h)
- else
- h[v]=true
- end
+ if h==nil then
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsedhash(v,h)
+ else
+ h[v]=true
end
- return h
+ end
+ return h
end
-table.collapsed=collapsed
+table.collapsed=collapsed
table.collapsedhash=collapsedhash
local function unnest(t,f)
- if not f then
- f={}
- end
- for i=1,#t do
- local v=t[i]
- if type(v)=="table" then
- if type(v[1])=="table" then
- unnest(v,f)
- else
- f[#f+1]=v
- end
- else
- f[#f+1]=v
- end
+ if not f then
+ f={}
+ end
+ for i=1,#t do
+ local v=t[i]
+ if type(v)=="table" then
+ if type(v[1])=="table" then
+ unnest(v,f)
+ else
+ f[#f+1]=v
+ end
+ else
+ f[#f+1]=v
end
- return f
+ end
+ return f
end
function table.unnest(t)
- return unnest(t)
+ return unnest(t)
end
local function are_equal(a,b,n,m)
- if a==b then
- return true
- elseif a and b and #a==#b then
- n=n or 1
- m=m or #a
- for i=n,m do
- local ai,bi=a[i],b[i]
- if ai==bi then
- elseif type(ai)=="table" and type(bi)=="table" then
- if not are_equal(ai,bi) then
- return false
- end
- else
- return false
- end
- end
- return true
- else
+ if a==b then
+ return true
+ elseif a and b and #a==#b then
+ n=n or 1
+ m=m or #a
+ for i=n,m do
+ local ai,bi=a[i],b[i]
+ if ai==bi then
+ elseif type(ai)=="table" and type(bi)=="table" then
+ if not are_equal(ai,bi) then
+ return false
+ end
+ else
return false
+ end
end
+ return true
+ else
+ return false
+ end
end
local function identical(a,b)
- if a~=b then
- for ka,va in next,a do
- local vb=b[ka]
- if va==vb then
- elseif type(va)=="table" and type(vb)=="table" then
- if not identical(va,vb) then
- return false
- end
- else
- return false
- end
- end
+ if a~=b then
+ for ka,va in next,a do
+ local vb=b[ka]
+ if va==vb then
+ elseif type(va)=="table" and type(vb)=="table" then
+ if not identical(va,vb) then
+ return false
+ end
+ else
+ return false
+ end
end
- return true
+ end
+ return true
end
table.identical=identical
table.are_equal=are_equal
local function sparse(old,nest,keeptables)
- local new={}
- for k,v in next,old do
- if not (v=="" or v==false) then
- if nest and type(v)=="table" then
- v=sparse(v,nest)
- if keeptables or next(v)~=nil then
- new[k]=v
- end
- else
- new[k]=v
- end
- end
+ local new={}
+ for k,v in next,old do
+ if not (v=="" or v==false) then
+ if nest and type(v)=="table" then
+ v=sparse(v,nest)
+ if keeptables or next(v)~=nil then
+ new[k]=v
+ end
+ else
+ new[k]=v
+ end
end
- return new
+ end
+ return new
end
table.sparse=sparse
function table.compact(t)
- return sparse(t,true,true)
+ return sparse(t,true,true)
end
function table.contains(t,v)
- if t then
- for i=1,#t do
- if t[i]==v then
- return i
- end
- end
+ if t then
+ for i=1,#t do
+ if t[i]==v then
+ return i
+ end
end
- return false
+ end
+ return false
end
function table.count(t)
- local n=0
- for k,v in next,t do
- n=n+1
- end
- return n
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ end
+ return n
end
function table.swapped(t,s)
- local n={}
- if s then
- for k,v in next,s do
- n[k]=v
- end
+ local n={}
+ if s then
+ for k,v in next,s do
+ n[k]=v
end
- for k,v in next,t do
- n[v]=k
- end
- return n
+ end
+ for k,v in next,t do
+ n[v]=k
+ end
+ return n
end
function table.hashed(t)
- for i=1,#t do
- t[t[i]]=i
- end
- return t
+ for i=1,#t do
+ t[t[i]]=i
+ end
+ return t
end
function table.mirrored(t)
- local n={}
- for k,v in next,t do
- n[v]=k
- n[k]=v
- end
- return n
+ local n={}
+ for k,v in next,t do
+ n[v]=k
+ n[k]=v
+ end
+ return n
end
function table.reversed(t)
- if t then
- local tt,tn={},#t
- if tn>0 then
- local ttn=0
- for i=tn,1,-1 do
- ttn=ttn+1
- tt[ttn]=t[i]
- end
- end
- return tt
+ if t then
+ local tt,tn={},#t
+ if tn>0 then
+ local ttn=0
+ for i=tn,1,-1 do
+ ttn=ttn+1
+ tt[ttn]=t[i]
+ end
end
+ return tt
+ end
end
function table.reverse(t)
- if t then
- local n=#t
- local m=n+1
- for i=1,floor(n/2) do
- local j=m-i
- t[i],t[j]=t[j],t[i]
- end
- return t
+ if t then
+ local n=#t
+ local m=n+1
+ for i=1,floor(n/2) do
+ local j=m-i
+ t[i],t[j]=t[j],t[i]
end
+ return t
+ end
end
local function sequenced(t,sep,simple)
- if not t then
- return ""
- elseif type(t)=="string" then
- return t
+ if not t then
+ return ""
+ elseif type(t)=="string" then
+ return t
+ end
+ local n=#t
+ local s={}
+ if n>0 then
+ for i=1,n do
+ local v=t[i]
+ if type(v)=="table" then
+ s[i]="{"..sequenced(v,sep,simple).."}"
+ else
+ s[i]=tostring(t[i])
+ end
end
- local n=#t
- local s={}
- if n>0 then
- for i=1,n do
- local v=t[i]
- if type(v)=="table" then
- s[i]="{"..sequenced(v,sep,simple).."}"
- else
- s[i]=tostring(t[i])
- end
+ else
+ n=0
+ for k,v in sortedhash(t) do
+ if simple then
+ if v==true then
+ n=n+1
+ s[n]=k
+ elseif v and v~="" then
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
+ end
end
- else
- n=0
- for k,v in sortedhash(t) do
- if simple then
- if v==true then
- n=n+1
- s[n]=k
- elseif v and v~="" then
- n=n+1
- if type(v)=="table" then
- s[n]=k.."={"..sequenced(v,sep,simple).."}"
- else
- s[n]=k.."="..tostring(v)
- end
- end
- else
- n=n+1
- if type(v)=="table" then
- s[n]=k.."={"..sequenced(v,sep,simple).."}"
- else
- s[n]=k.."="..tostring(v)
- end
- end
+ else
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
end
+ end
end
- return concat(s,sep or " | ")
+ end
+ return concat(s,sep or " | ")
end
table.sequenced=sequenced
function table.print(t,...)
- if type(t)~="table" then
- print(tostring(t))
- else
- serialize(print,t,...)
- end
+ if type(t)~="table" then
+ print(tostring(t))
+ else
+ serialize(print,t,...)
+ end
end
if setinspector then
- setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
+ setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
end
function table.sub(t,i,j)
- return { unpack(t,i,j) }
+ return { unpack(t,i,j) }
end
function table.is_empty(t)
- return not t or next(t)==nil
+ return not t or next(t)==nil
end
function table.has_one_entry(t)
- return t and next(t,next(t))==nil
+ return t and next(t,next(t))==nil
end
function table.loweredkeys(t)
- local l={}
- for k,v in next,t do
- l[lower(k)]=v
- end
- return l
+ local l={}
+ for k,v in next,t do
+ l[lower(k)]=v
+ end
+ return l
end
function table.unique(old)
- local hash={}
- local new={}
- local n=0
- for i=1,#old do
- local oi=old[i]
- if not hash[oi] then
- n=n+1
- new[n]=oi
- hash[oi]=true
- end
- end
- return new
+ local hash={}
+ local new={}
+ local n=0
+ for i=1,#old do
+ local oi=old[i]
+ if not hash[oi] then
+ n=n+1
+ new[n]=oi
+ hash[oi]=true
+ end
+ end
+ return new
end
function table.sorted(t,...)
- sort(t,...)
- return t
+ sort(t,...)
+ return t
end
function table.values(t,s)
- if t then
- local values,keys,v={},{},0
- for key,value in next,t do
- if not keys[value] then
- v=v+1
- values[v]=value
- keys[k]=key
- end
- end
- if s then
- sort(values)
- end
- return values
- else
- return {}
+ if t then
+ local values,keys,v={},{},0
+ for key,value in next,t do
+ if not keys[value] then
+ v=v+1
+ values[v]=value
+ keys[k]=key
+ end
end
+ if s then
+ sort(values)
+ end
+ return values
+ else
+ return {}
+ end
end
function table.filtered(t,pattern,sort,cmp)
- if t and type(pattern)=="string" then
- if sort then
- local s
- if cmp then
- s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
- else
- s=sortedkeys(t)
- end
- local n=0
- local m=#s
- local function kv(s)
- while n<m do
- n=n+1
- local k=s[n]
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return kv,s
- else
- local n=next(t)
- local function iterator()
- while n~=nil do
- local k=n
- n=next(t,k)
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return iterator,t
+ if t and type(pattern)=="string" then
+ if sort then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local n=0
+ local m=#s
+ local function kv(s)
+ while n<m do
+ n=n+1
+ local k=s[n]
+ if find(k,pattern) then
+ return k,t[k]
+ end
end
- else
- return nothing
+ end
+ return kv,s
+ else
+ local n=next(t)
+ local function iterator()
+ while n~=nil do
+ local k=n
+ n=next(t,k)
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return iterator,t
end
+ else
+ return nothing
+ end
end
if not table.move then
- function table.move(a1,f,e,t,a2)
- if a2 and a1~=a2 then
- for i=f,e do
- a2[t]=a1[i]
- t=t+1
- end
- return a2
- else
- t=t+e-f
- for i=e,f,-1 do
- a1[t]=a1[i]
- t=t-1
- end
- return a1
- end
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1~=a2 then
+ for i=f,e do
+ a2[t]=a1[i]
+ t=t+1
+ end
+ return a2
+ else
+ t=t+e-f
+ for i=e,f,-1 do
+ a1[t]=a1[i]
+ t=t-1
+ end
+ return a1
end
+ end
end
@@ -3059,14 +3059,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-io"] = package.loaded["l-io"] or true
--- original size: 11823, stripped down to: 6945
+-- original size: 11823, stripped down to: 6325
if not modules then modules={} end modules ['l-io']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local io=io
local open,flush,write,read=io.open,io.flush,io.write,io.read
@@ -3074,334 +3074,334 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
local concat=table.concat
local type=type
if string.find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator="\\",";"
+ io.fileseparator,io.pathseparator="\\",";"
else
- io.fileseparator,io.pathseparator="/",":"
+ io.fileseparator,io.pathseparator="/",":"
end
local large=0x01000000
local medium=0x00100000
local small=0x00020000
local function readall(f)
- local size=f:seek("end")
- if size>0 then
- f:seek("set",0)
- return f:read(size)
- else
- return ""
- end
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ return f:read(size)
+ else
+ return ""
+ end
end
io.readall=readall
function io.loaddata(filename,textmode)
- local f=open(filename,(textmode and 'r') or 'rb')
- if f then
- local size=f:seek("end")
- local data=nil
- if size>0 then
- f:seek("set",0)
- data=f:read(size)
- end
- f:close()
- return data
+ local f=open(filename,(textmode and 'r') or 'rb')
+ if f then
+ local size=f:seek("end")
+ local data=nil
+ if size>0 then
+ f:seek("set",0)
+ data=f:read(size)
end
+ f:close()
+ return data
+ end
end
function io.copydata(source,target,action)
- local f=open(source,"rb")
- if f then
- local g=open(target,"wb")
- if g then
- local size=f:seek("end")
- if size>0 then
- f:seek("set",0)
- local data=f:read(size)
- if action then
- data=action(data)
- end
- if data then
- g:write(data)
- end
- end
- g:close()
+ local f=open(source,"rb")
+ if f then
+ local g=open(target,"wb")
+ if g then
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ local data=f:read(size)
+ if action then
+ data=action(data)
end
- f:close()
- flush()
+ if data then
+ g:write(data)
+ end
+ end
+ g:close()
end
+ f:close()
+ flush()
+ end
end
function io.savedata(filename,data,joiner)
- local f=open(filename,"wb")
- if f then
- if type(data)=="table" then
- f:write(concat(data,joiner or ""))
- elseif type(data)=="function" then
- data(f)
- else
- f:write(data or "")
- end
- f:close()
- flush()
- return true
+ local f=open(filename,"wb")
+ if f then
+ if type(data)=="table" then
+ f:write(concat(data,joiner or ""))
+ elseif type(data)=="function" then
+ data(f)
else
- return false
+ f:write(data or "")
end
+ f:close()
+ flush()
+ return true
+ else
+ return false
+ end
end
if fio and fio.readline then
- local readline=fio.readline
- function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=readline(f)
- if line then
- lines[i]=line
- else
- break
- end
- end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
+ local readline=fio.readline
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=readline(f)
+ if line then
+ lines[i]=line
else
- local line=readline(f)
- f:close()
- if line and #line>0 then
- return line
- end
+ break
end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=readline(f)
+ f:close()
+ if line and #line>0 then
+ return line
+ end
end
+ end
else
- function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=f:read("*lines")
- if line then
- lines[i]=line
- else
- break
- end
- end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=f:read("*lines")
+ if line then
+ lines[i]=line
else
- local line=f:read("*line") or ""
- f:close()
- if #line>0 then
- return line
- end
+ break
end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=f:read("*line") or ""
+ f:close()
+ if #line>0 then
+ return line
+ end
end
+ end
end
function io.loadchunk(filename,n)
- local f=open(filename,'rb')
- if f then
- local data=f:read(n or 1024)
- f:close()
- if #data>0 then
- return data
- end
+ local f=open(filename,'rb')
+ if f then
+ local data=f:read(n or 1024)
+ f:close()
+ if #data>0 then
+ return data
end
+ end
end
function io.exists(filename)
- local f=open(filename)
- if f==nil then
- return false
- else
- f:close()
- return true
- end
+ local f=open(filename)
+ if f==nil then
+ return false
+ else
+ f:close()
+ return true
+ end
end
function io.size(filename)
- local f=open(filename)
- if f==nil then
- return 0
- else
- local s=f:seek("end")
- f:close()
- return s
- end
+ local f=open(filename)
+ if f==nil then
+ return 0
+ else
+ local s=f:seek("end")
+ f:close()
+ return s
+ end
end
local function noflines(f)
- if type(f)=="string" then
- local f=open(filename)
- if f then
- local n=f and noflines(f) or 0
- f:close()
- return n
- else
- return 0
- end
+ if type(f)=="string" then
+ local f=open(filename)
+ if f then
+ local n=f and noflines(f) or 0
+ f:close()
+ return n
else
- local n=0
- for _ in f:lines() do
- n=n+1
- end
- f:seek('set',0)
- return n
+ return 0
+ end
+ else
+ local n=0
+ for _ in f:lines() do
+ n=n+1
end
+ f:seek('set',0)
+ return n
+ end
end
io.noflines=noflines
local nextchar={
- [ 4]=function(f)
- return f:read(1,1,1,1)
- end,
- [ 2]=function(f)
- return f:read(1,1)
- end,
- [ 1]=function(f)
- return f:read(1)
- end,
- [-2]=function(f)
- local a,b=f:read(1,1)
- return b,a
- end,
- [-4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- return d,c,b,a
- end
+ [ 4]=function(f)
+ return f:read(1,1,1,1)
+ end,
+ [ 2]=function(f)
+ return f:read(1,1)
+ end,
+ [ 1]=function(f)
+ return f:read(1)
+ end,
+ [-2]=function(f)
+ local a,b=f:read(1,1)
+ return b,a
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ return d,c,b,a
+ end
}
function io.characters(f,n)
- if f then
- return nextchar[n or 1],f
- end
+ if f then
+ return nextchar[n or 1],f
+ end
end
local nextbyte={
- [4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- if d then
- return byte(a),byte(b),byte(c),byte(d)
- end
- end,
- [3]=function(f)
- local a,b,c=f:read(1,1,1)
- if b then
- return byte(a),byte(b),byte(c)
- end
- end,
- [2]=function(f)
- local a,b=f:read(1,1)
- if b then
- return byte(a),byte(b)
- end
- end,
- [1]=function (f)
- local a=f:read(1)
- if a then
- return byte(a)
- end
- end,
- [-2]=function (f)
- local a,b=f:read(1,1)
- if b then
- return byte(b),byte(a)
- end
- end,
- [-3]=function(f)
- local a,b,c=f:read(1,1,1)
- if b then
- return byte(c),byte(b),byte(a)
- end
- end,
- [-4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- if d then
- return byte(d),byte(c),byte(b),byte(a)
- end
+ [4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(a),byte(b),byte(c),byte(d)
+ end
+ end,
+ [3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(a),byte(b),byte(c)
+ end
+ end,
+ [2]=function(f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(a),byte(b)
+ end
+ end,
+ [1]=function (f)
+ local a=f:read(1)
+ if a then
+ return byte(a)
+ end
+ end,
+ [-2]=function (f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(b),byte(a)
+ end
+ end,
+ [-3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(c),byte(b),byte(a)
+ end
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(d),byte(c),byte(b),byte(a)
end
+ end
}
function io.bytes(f,n)
- if f then
- return nextbyte[n or 1],f
- else
- return nil,nil
- end
+ if f then
+ return nextbyte[n or 1],f
+ else
+ return nil,nil
+ end
end
function io.ask(question,default,options)
- while true do
- write(question)
- if options then
- write(format(" [%s]",concat(options,"|")))
- end
- if default then
- write(format(" [%s]",default))
- end
- write(format(" "))
- flush()
- local answer=read()
- answer=gsub(answer,"^%s*(.*)%s*$","%1")
- if answer=="" and default then
- return default
- elseif not options then
- return answer
- else
- for k=1,#options do
- if options[k]==answer then
- return answer
- end
- end
- local pattern="^"..answer
- for k=1,#options do
- local v=options[k]
- if find(v,pattern) then
- return v
- end
- end
+ while true do
+ write(question)
+ if options then
+ write(format(" [%s]",concat(options,"|")))
+ end
+ if default then
+ write(format(" [%s]",default))
+ end
+ write(format(" "))
+ flush()
+ local answer=read()
+ answer=gsub(answer,"^%s*(.*)%s*$","%1")
+ if answer=="" and default then
+ return default
+ elseif not options then
+ return answer
+ else
+ for k=1,#options do
+ if options[k]==answer then
+ return answer
end
+ end
+ local pattern="^"..answer
+ for k=1,#options do
+ local v=options[k]
+ if find(v,pattern) then
+ return v
+ end
+ end
end
+ end
end
local function readnumber(f,n,m)
- if m then
- f:seek("set",n)
- n=m
- end
- if n==1 then
- return byte(f:read(1))
- elseif n==2 then
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
- elseif n==3 then
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
- elseif n==4 then
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==8 then
- local a,b=readnumber(f,4),readnumber(f,4)
- return 0x100*a+b
- elseif n==12 then
- local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
- return 0x10000*a+0x100*b+c
- elseif n==-2 then
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
- elseif n==-3 then
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
- elseif n==-4 then
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==-8 then
- local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
- return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
- else
- return 0
- end
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ if n==1 then
+ return byte(f:read(1))
+ elseif n==2 then
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==3 then
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==4 then
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==8 then
+ local a,b=readnumber(f,4),readnumber(f,4)
+ return 0x100*a+b
+ elseif n==12 then
+ local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
+ return 0x10000*a+0x100*b+c
+ elseif n==-2 then
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==-3 then
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==-4 then
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==-8 then
+ local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
+ return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+ else
+ return 0
+ end
end
io.readnumber=readnumber
function io.readstring(f,n,m)
- if m then
- f:seek("set",n)
- n=m
- end
- local str=gsub(f:read(n),"\000","")
- return str
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ local str=gsub(f:read(n),"\000","")
+ return str
end
@@ -3411,14 +3411,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-number"] = package.loaded["l-number"] or true
--- original size: 5720, stripped down to: 2392
+-- original size: 5720, stripped down to: 2176
if not modules then modules={} end modules ['l-number']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tostring,tonumber=tostring,tonumber
local format,floor,match,rep=string.format,math.floor,string.match,string.rep
@@ -3428,107 +3428,107 @@ local floor=math.floor
number=number or {}
local number=number
if bit32 then
- local bextract=bit32.extract
- local t={
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- }
- function number.tobitstring(b,m,w)
- if not w then
- w=32
- end
- local n=w
- for i=0,w-1 do
- local v=bextract(b,i)
- local k=w-i
- if v==1 then
- n=k
- t[k]="1"
- else
- t[k]="0"
- end
- end
- if w then
- return concat(t,"",1,w)
- elseif m then
- m=33-m*8
- if m<1 then
- m=1
- end
- return concat(t,"",1,m)
- elseif n<8 then
- return concat(t)
- elseif n<16 then
- return concat(t,"",9)
- elseif n<24 then
- return concat(t,"",17)
- else
- return concat(t,"",25)
- end
+ local bextract=bit32.extract
+ local t={
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ }
+ function number.tobitstring(b,m,w)
+ if not w then
+ w=32
+ end
+ local n=w
+ for i=0,w-1 do
+ local v=bextract(b,i)
+ local k=w-i
+ if v==1 then
+ n=k
+ t[k]="1"
+ else
+ t[k]="0"
+ end
+ end
+ if w then
+ return concat(t,"",1,w)
+ elseif m then
+ m=33-m*8
+ if m<1 then
+ m=1
+ end
+ return concat(t,"",1,m)
+ elseif n<8 then
+ return concat(t)
+ elseif n<16 then
+ return concat(t,"",9)
+ elseif n<24 then
+ return concat(t,"",17)
+ else
+ return concat(t,"",25)
end
+ end
else
- function number.tobitstring(n,m)
- if n>0 then
- local t={}
- while n>0 do
- insert(t,1,n%2>0 and 1 or 0)
- n=floor(n/2)
- end
- local nn=8-#t%8
- if nn>0 and nn<8 then
- for i=1,nn do
- insert(t,1,0)
- end
- end
- if m then
- m=m*8-#t
- if m>0 then
- insert(t,1,rep("0",m))
- end
- end
- return concat(t)
- elseif m then
- rep("00000000",m)
- else
- return "00000000"
+ function number.tobitstring(n,m)
+ if n>0 then
+ local t={}
+ while n>0 do
+ insert(t,1,n%2>0 and 1 or 0)
+ n=floor(n/2)
+ end
+ local nn=8-#t%8
+ if nn>0 and nn<8 then
+ for i=1,nn do
+ insert(t,1,0)
+ end
+ end
+ if m then
+ m=m*8-#t
+ if m>0 then
+ insert(t,1,rep("0",m))
end
+ end
+ return concat(t)
+ elseif m then
+ rep("00000000",m)
+ else
+ return "00000000"
end
+ end
end
function number.valid(str,default)
- return tonumber(str) or default or nil
+ return tonumber(str) or default or nil
end
function number.toevenhex(n)
- local s=format("%X",n)
- if #s%2==0 then
- return s
- else
- return "0"..s
- end
+ local s=format("%X",n)
+ if #s%2==0 then
+ return s
+ else
+ return "0"..s
+ end
end
function number.bytetodecimal(b)
- local d=floor(b*100/255+0.5)
- if d>100 then
- return 100
- elseif d<-100 then
- return -100
- else
- return d
- end
+ local d=floor(b*100/255+0.5)
+ if d>100 then
+ return 100
+ elseif d<-100 then
+ return -100
+ else
+ return d
+ end
end
function number.decimaltobyte(d)
- local b=floor(d*255/100+0.5)
- if b>255 then
- return 255
- elseif b<-255 then
- return -255
- else
- return b
- end
+ local b=floor(d*255/100+0.5)
+ if b>255 then
+ return 255
+ elseif b<-255 then
+ return -255
+ else
+ return b
+ end
end
function number.idiv(i,d)
- return floor(i/d)
+ return floor(i/d)
end
@@ -3538,14 +3538,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-set"] = package.loaded["l-set"] or true
--- original size: 1923, stripped down to: 1133
+-- original size: 1923, stripped down to: 1044
if not modules then modules={} end modules ['l-set']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
set=set or {}
local nums={}
@@ -3554,54 +3554,54 @@ local concat=table.concat
local next,type=next,type
set.create=table.tohash
function set.tonumber(t)
- if next(t) then
- local s=""
- for k,v in next,t do
- if v then
- s=s.." "..k
- end
- end
- local n=nums[s]
- if not n then
- n=#tabs+1
- tabs[n]=t
- nums[s]=n
- end
- return n
- else
- return 0
+ if next(t) then
+ local s=""
+ for k,v in next,t do
+ if v then
+ s=s.." "..k
+ end
+ end
+ local n=nums[s]
+ if not n then
+ n=#tabs+1
+ tabs[n]=t
+ nums[s]=n
end
+ return n
+ else
+ return 0
+ end
end
function set.totable(n)
- if n==0 then
- return {}
- else
- return tabs[n] or {}
- end
+ if n==0 then
+ return {}
+ else
+ return tabs[n] or {}
+ end
end
function set.tolist(n)
- if n==0 or not tabs[n] then
- return ""
- else
- local t,n={},0
- for k,v in next,tabs[n] do
- if v then
- n=n+1
- t[n]=k
- end
- end
- return concat(t," ")
+ if n==0 or not tabs[n] then
+ return ""
+ else
+ local t,n={},0
+ for k,v in next,tabs[n] do
+ if v then
+ n=n+1
+ t[n]=k
+ end
end
+ return concat(t," ")
+ end
end
function set.contains(n,s)
- if type(n)=="table" then
- return n[s]
- elseif n==0 then
- return false
- else
- local t=tabs[n]
- return t and t[s]
- end
+ if type(n)=="table" then
+ return n[s]
+ elseif n==0 then
+ return false
+ else
+ local t=tabs[n]
+ return t and t[s]
+ end
end
@@ -3611,14 +3611,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-os"] = package.loaded["l-os"] or true
--- original size: 19347, stripped down to: 11016
+-- original size: 19347, stripped down to: 10258
if not modules then modules={} end modules ['l-os']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local os=os
local date,time=os.date,os.time
@@ -3627,433 +3627,433 @@ local concat=table.concat
local random,ceil,randomseed=math.random,math.ceil,math.randomseed
local rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring=rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring
do
- local selfdir=os.selfdir
- if selfdir=="" then
- selfdir=nil
+ local selfdir=os.selfdir
+ if selfdir=="" then
+ selfdir=nil
+ end
+ if not selfdir then
+ if arg then
+ for i=1,#arg do
+ local a=arg[i]
+ if find(a,"^%-%-[c:]*texmfbinpath=") then
+ selfdir=gsub(a,"^.-=","")
+ break
+ end
+ end
end
if not selfdir then
- if arg then
- for i=1,#arg do
- local a=arg[i]
- if find(a,"^%-%-[c:]*texmfbinpath=") then
- selfdir=gsub(a,"^.-=","")
- break
- end
+ selfdir=os.selfbin or "luatex"
+ if find(selfdir,"[/\\]") then
+ selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
+ elseif os.getenv then
+ local path=os.getenv("PATH")
+ local name=gsub(selfdir,"^.*[/\\][^/\\]","")
+ local patt="[^:]+"
+ if os.type=="windows" then
+ patt="[^;]+"
+ name=name..".exe"
+ end
+ local isfile
+ if lfs then
+ local attributes=lfs.attributes
+ isfile=function(name)
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
+ end
+ else
+ local open=io.open
+ isfile=function(name)
+ local f=open(name)
+ if f then
+ f:close()
+ return true
end
+ end
end
- if not selfdir then
- selfdir=os.selfbin or "luatex"
- if find(selfdir,"[/\\]") then
- selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
- elseif os.getenv then
- local path=os.getenv("PATH")
- local name=gsub(selfdir,"^.*[/\\][^/\\]","")
- local patt="[^:]+"
- if os.type=="windows" then
- patt="[^;]+"
- name=name..".exe"
- end
- local isfile
- if lfs then
- local attributes=lfs.attributes
- isfile=function(name)
- local a=attributes(name,"mode")
- return a=="file" or a=="link" or nil
- end
- else
- local open=io.open
- isfile=function(name)
- local f=open(name)
- if f then
- f:close()
- return true
- end
- end
- end
- for p in gmatch(path,patt) do
- if isfile(p.."/"..name) then
- selfdir=p
- break
- end
- end
- end
+ for p in gmatch(path,patt) do
+ if isfile(p.."/"..name) then
+ selfdir=p
+ break
+ end
end
- os.selfdir=selfdir or "."
+ end
end
+ os.selfdir=selfdir or "."
+ end
end
math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
randomseed(math.initialseed)
if not os.__getenv__ then
- os.__getenv__=os.getenv
- os.__setenv__=os.setenv
- if os.env then
- local osgetenv=os.getenv
- local ossetenv=os.setenv
- local osenv=os.env local _=osenv.PATH
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- if type(v)=="table" then
- v=concat(v,";")
- end
- ossetenv(K,v)
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
- end
- else
- local ossetenv=os.setenv
- local osgetenv=os.getenv
- local osenv={}
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
- end
- local function __index(t,k)
- return os.getenv(k)
- end
- local function __newindex(t,k,v)
- os.setenv(k,v)
- end
- os.env={}
- setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ os.__getenv__=os.getenv
+ os.__setenv__=os.setenv
+ if os.env then
+ local osgetenv=os.getenv
+ local ossetenv=os.setenv
+ local osenv=os.env local _=osenv.PATH
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ if type(v)=="table" then
+ v=concat(v,";")
+ end
+ ossetenv(K,v)
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ else
+ local ossetenv=os.setenv
+ local osgetenv=os.getenv
+ local osenv={}
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ local function __index(t,k)
+ return os.getenv(k)
+ end
+ local function __newindex(t,k,v)
+ os.setenv(k,v)
+ end
+ os.env={}
+ setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
end
local execute=os.execute
local iopopen=io.popen
local function resultof(command)
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- else
- return ""
- end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ else
+ return ""
+ end
end
os.resultof=resultof
function os.pipeto(command)
- return iopopen(command,"w")
+ return iopopen(command,"w")
end
if not io.fileseparator then
- if find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
- else
- io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
- end
+ if find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
+ else
+ io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
+ end
end
os.type=os.type or (io.pathseparator==";" and "windows") or "unix"
-os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
+os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
if os.type=="windows" then
- os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
else
- os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
end
local launchers={
- windows="start %s",
- macosx="open %s",
- unix="xdg-open %s &> /dev/null &",
+ windows="start %s",
+ macosx="open %s",
+ unix="xdg-open %s &> /dev/null &",
}
function os.launch(str)
- execute(format(launchers[os.name] or launchers.unix,str))
+ execute(format(launchers[os.name] or launchers.unix,str))
end
if not os.times then
- function os.times()
- return {
- utime=os.gettimeofday(),
- stime=0,
- cutime=0,
- cstime=0,
- }
- end
+ function os.times()
+ return {
+ utime=os.gettimeofday(),
+ stime=0,
+ cutime=0,
+ cstime=0,
+ }
+ end
end
local gettimeofday=os.gettimeofday or os.clock
os.gettimeofday=gettimeofday
local startuptime=gettimeofday()
function os.runtime()
- return gettimeofday()-startuptime
+ return gettimeofday()-startuptime
end
local resolvers=os.resolvers or {}
os.resolvers=resolvers
setmetatable(os,{ __index=function(t,k)
- local r=resolvers[k]
- return r and r(t,k) or nil
+ local r=resolvers[k]
+ return r and r(t,k) or nil
end })
local name,platform=os.name or "linux",os.getenv("MTX_PLATFORM") or ""
if platform~="" then
- os.platform=platform
+ os.platform=platform
elseif os.type=="windows" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
- local platform=""
- if find(architecture,"AMD64",1,true) then
- platform="win64"
- else
- platform="mswin"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
+ local platform=""
+ if find(architecture,"AMD64",1,true) then
+ platform="win64"
+ else
+ platform="mswin"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="linux" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- local platform=os.getenv("MTX_PLATFORM") or ""
- local musl=find(os.selfdir or "","linuxmusl")
- if platform~="" then
- elseif find(architecture,"x86_64",1,true) then
- platform=musl and "linuxmusl" or "linux-64"
- elseif find(architecture,"ppc",1,true) then
- platform="linux-ppc"
- else
- platform=musl and "linuxmusl" or "linux"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=os.getenv("MTX_PLATFORM") or ""
+ local musl=find(os.selfdir or "","linuxmusl")
+ if platform~="" then
+ elseif find(architecture,"x86_64",1,true) then
+ platform=musl and "linuxmusl" or "linux-64"
+ elseif find(architecture,"ppc",1,true) then
+ platform="linux-ppc"
+ else
+ platform=musl and "linuxmusl" or "linux"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="macosx" then
- function resolvers.platform(t,k)
- local architecture=resultof("echo $HOSTTYPE") or ""
- local platform=""
- if architecture=="" then
- platform="osx-intel"
- elseif find(architecture,"i386",1,true) then
- platform="osx-intel"
- elseif find(architecture,"x86_64",1,true) then
- platform="osx-64"
- else
- platform="osx-ppc"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local architecture=resultof("echo $HOSTTYPE") or ""
+ local platform=""
+ if architecture=="" then
+ platform="osx-intel"
+ elseif find(architecture,"i386",1,true) then
+ platform="osx-intel"
+ elseif find(architecture,"x86_64",1,true) then
+ platform="osx-64"
+ else
+ platform="osx-ppc"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="sunos" then
- function resolvers.platform(t,k)
- local architecture=resultof("uname -m") or ""
- local platform=""
- if find(architecture,"sparc",1,true) then
- platform="solaris-sparc"
- else
- platform="solaris-intel"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"sparc",1,true) then
+ platform="solaris-sparc"
+ else
+ platform="solaris-intel"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="freebsd" then
- function resolvers.platform(t,k)
- local architecture=resultof("uname -m") or ""
- local platform=""
- if find(architecture,"amd64",1,true) then
- platform="freebsd-amd64"
- else
- platform="freebsd"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"amd64",1,true) then
+ platform="freebsd-amd64"
+ else
+ platform="freebsd"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="kfreebsd" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- local platform=""
- if find(architecture,"x86_64",1,true) then
- platform="kfreebsd-amd64"
- else
- platform="kfreebsd-i386"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"x86_64",1,true) then
+ platform="kfreebsd-amd64"
+ else
+ platform="kfreebsd-i386"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
else
- function resolvers.platform(t,k)
- local platform="linux"
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local platform="linux"
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
end
os.newline=name=="windows" and "\013\010" or "\010"
function resolvers.bits(t,k)
- local bits=find(os.platform,"64",1,true) and 64 or 32
- os.bits=bits
- return bits
+ local bits=find(os.platform,"64",1,true) and 64 or 32
+ os.bits=bits
+ return bits
end
local t={ 8,9,"a","b" }
function os.uuid()
- return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
- random(0xFFFF),random(0xFFFF),
- random(0x0FFF),
- t[ceil(random(4))] or 8,random(0x0FFF),
- random(0xFFFF),
- random(0xFFFF),random(0xFFFF),random(0xFFFF)
- )
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
end
local d
function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
- if delta then
- if d>0 then
- return format("+%02i:00",d)
- else
- return format("-%02i:00",-d)
- end
+ d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ if delta then
+ if d>0 then
+ return format("+%02i:00",d)
else
- return 1
+ return format("-%02i:00",-d)
end
+ else
+ return 1
+ end
end
local timeformat=format("%%s%s",os.timezone(true))
local dateformat="!%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.fulltime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=format(timeformat,date(dateformat))
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=format(timeformat,date(dateformat))
+ end
+ return lastdate
end
local dateformat="%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.localtime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=date(dateformat,t)
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=date(dateformat,t)
+ end
+ return lastdate
end
function os.converttime(t,default)
- local t=tonumber(t)
- if t and t>0 then
- return date(dateformat,t)
- else
- return default or "-"
- end
+ local t=tonumber(t)
+ if t and t>0 then
+ return date(dateformat,t)
+ else
+ return default or "-"
+ end
end
local memory={}
local function which(filename)
- local fullname=memory[filename]
- if fullname==nil then
- local suffix=file.suffix(filename)
- local suffixes=suffix=="" and os.binsuffixes or { suffix }
- for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
- local df=file.join(directory,filename)
- for i=1,#suffixes do
- local dfs=file.addsuffix(df,suffixes[i])
- if io.exists(dfs) then
- fullname=dfs
- break
- end
- end
- end
- if not fullname then
- fullname=false
+ local fullname=memory[filename]
+ if fullname==nil then
+ local suffix=file.suffix(filename)
+ local suffixes=suffix=="" and os.binsuffixes or { suffix }
+ for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local df=file.join(directory,filename)
+ for i=1,#suffixes do
+ local dfs=file.addsuffix(df,suffixes[i])
+ if io.exists(dfs) then
+ fullname=dfs
+ break
end
- memory[filename]=fullname
+ end
end
- return fullname
+ if not fullname then
+ fullname=false
+ end
+ memory[filename]=fullname
+ end
+ return fullname
end
os.which=which
os.where=which
function os.today()
- return date("!*t")
+ return date("!*t")
end
function os.now()
- return date("!%Y-%m-%d %H:%M:%S")
+ return date("!%Y-%m-%d %H:%M:%S")
end
if not os.sleep then
- local socket=socket
- function os.sleep(n)
- if not socket then
- socket=require("socket")
- end
- socket.sleep(n)
+ local socket=socket
+ function os.sleep(n)
+ if not socket then
+ socket=require("socket")
end
+ socket.sleep(n)
+ end
end
local function isleapyear(year)
- return (year%4==0) and (year%100~=0 or year%400==0)
+ return (year%4==0) and (year%100~=0 or year%400==0)
end
os.isleapyear=isleapyear
local days={ 31,28,31,30,31,30,31,31,30,31,30,31 }
local function nofdays(year,month)
- if not month then
- return isleapyear(year) and 365 or 364
- else
- return month==2 and isleapyear(year) and 29 or days[month]
- end
+ if not month then
+ return isleapyear(year) and 365 or 364
+ else
+ return month==2 and isleapyear(year) and 29 or days[month]
+ end
end
os.nofdays=nofdays
function os.weekday(day,month,year)
- return date("%w",time { year=year,month=month,day=day })+1
+ return date("%w",time { year=year,month=month,day=day })+1
end
function os.validdate(year,month,day)
- if month<1 then
- month=1
- elseif month>12 then
- month=12
- end
- if day<1 then
- day=1
- else
- local max=nofdays(year,month)
- if day>max then
- day=max
- end
- end
- return year,month,day
+ if month<1 then
+ month=1
+ elseif month>12 then
+ month=12
+ end
+ if day<1 then
+ day=1
+ else
+ local max=nofdays(year,month)
+ if day>max then
+ day=max
+ end
+ end
+ return year,month,day
end
local osexit=os.exit
local exitcode=nil
function os.setexitcode(code)
- exitcode=code
+ exitcode=code
end
function os.exit(c)
- if exitcode~=nil then
- return osexit(exitcode)
- end
- if c~=nil then
- return osexit(c)
- end
- return osexit()
+ if exitcode~=nil then
+ return osexit(exitcode)
+ end
+ if c~=nil then
+ return osexit(c)
+ end
+ return osexit()
end
@@ -4063,19 +4063,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-file"] = package.loaded["l-file"] or true
--- original size: 21804, stripped down to: 10461
+-- original size: 21804, stripped down to: 9980
if not modules then modules={} end modules ['l-file']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
file=file or {}
local file=file
if not lfs then
- lfs=optionalrequire("lfs")
+ lfs=optionalrequire("lfs")
end
local insert,concat=table.insert,table.concat
local match,find,gmatch=string.match,string.find,string.gmatch
@@ -4085,20 +4085,20 @@ local checkedsplit=string.checkedsplit
local P,R,S,C,Cs,Cp,Cc,Ct=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cp,lpeg.Cc,lpeg.Ct
local attributes=lfs.attributes
function lfs.isdir(name)
- return attributes(name,"mode")=="directory"
+ return attributes(name,"mode")=="directory"
end
function lfs.isfile(name)
- local a=attributes(name,"mode")
- return a=="file" or a=="link" or nil
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
end
function lfs.isfound(name)
- local a=attributes(name,"mode")
- return (a=="file" or a=="link") and name or nil
+ local a=attributes(name,"mode")
+ return (a=="file" or a=="link") and name or nil
end
if sandbox then
- sandbox.redefine(lfs.isfile,"lfs.isfile")
- sandbox.redefine(lfs.isdir,"lfs.isdir")
- sandbox.redefine(lfs.isfound,"lfs.isfound")
+ sandbox.redefine(lfs.isfile,"lfs.isfile")
+ sandbox.redefine(lfs.isdir,"lfs.isdir")
+ sandbox.redefine(lfs.isfound,"lfs.isfound")
end
local colon=P(":")
local period=P(".")
@@ -4112,27 +4112,27 @@ local name=noperiod^1
local suffix=period/""*(1-period-slashes)^1*-1
local pattern=C((1-(slashes^1*noslashes^1*-1))^1)*P(1)
local function pathpart(name,default)
- return name and lpegmatch(pattern,name) or default or ""
+ return name and lpegmatch(pattern,name) or default or ""
end
local pattern=(noslashes^0*slashes)^1*C(noslashes^1)*-1
local function basename(name)
- return name and lpegmatch(pattern,name) or name
+ return name and lpegmatch(pattern,name) or name
end
local pattern=(noslashes^0*slashes^1)^0*Cs((1-suffix)^1)*suffix^0
local function nameonly(name)
- return name and lpegmatch(pattern,name) or name
+ return name and lpegmatch(pattern,name) or name
end
local pattern=(noslashes^0*slashes)^0*(noperiod^1*period)^1*C(noperiod^1)*-1
local function suffixonly(name)
- return name and lpegmatch(pattern,name) or ""
+ return name and lpegmatch(pattern,name) or ""
end
local pattern=(noslashes^0*slashes)^0*noperiod^1*((period*C(noperiod^1))^1)*-1+Cc("")
local function suffixesonly(name)
- if name then
- return lpegmatch(pattern,name)
- else
- return ""
- end
+ if name then
+ return lpegmatch(pattern,name)
+ else
+ return ""
+ end
end
file.pathpart=pathpart
file.basename=basename
@@ -4141,7 +4141,7 @@ file.suffixonly=suffixonly
file.suffix=suffixonly
file.suffixesonly=suffixesonly
file.suffixes=suffixesonly
-file.dirname=pathpart
+file.dirname=pathpart
file.extname=suffixonly
local drive=C(R("az","AZ"))*colon
local path=C((noslashes^0*slashes)^0)
@@ -4157,142 +4157,142 @@ local pattern_b=path*base*suffix
local pattern_c=C(drive*path)*C(base*suffix)
local pattern_d=path*rest
function file.splitname(str,splitdrive)
- if not str then
- elseif splitdrive then
- return lpegmatch(pattern_a,str)
- else
- return lpegmatch(pattern_b,str)
- end
+ if not str then
+ elseif splitdrive then
+ return lpegmatch(pattern_a,str)
+ else
+ return lpegmatch(pattern_b,str)
+ end
end
function file.splitbase(str)
- if str then
- return lpegmatch(pattern_d,str)
- else
- return "",str
- end
+ if str then
+ return lpegmatch(pattern_d,str)
+ else
+ return "",str
+ end
end
function file.nametotable(str,splitdrive)
- if str then
- local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
- if splitdrive then
- return {
- path=path,
- drive=drive,
- subpath=subpath,
- name=name,
- base=base,
- suffix=suffix,
- }
- else
- return {
- path=path,
- name=name,
- base=base,
- suffix=suffix,
- }
- end
+ if str then
+ local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
+ if splitdrive then
+ return {
+ path=path,
+ drive=drive,
+ subpath=subpath,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
+ else
+ return {
+ path=path,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
end
+ end
end
local pattern=Cs(((period*(1-period-slashes)^1*-1)/""+1)^1)
function file.removesuffix(name)
- return name and lpegmatch(pattern,name)
+ return name and lpegmatch(pattern,name)
end
local suffix=period/""*(1-period-slashes)^1*-1
local pattern=Cs((noslashes^0*slashes^1)^0*((1-suffix)^1))*Cs(suffix)
function file.addsuffix(filename,suffix,criterium)
- if not filename or not suffix or suffix=="" then
- return filename
- elseif criterium==true then
- return filename.."."..suffix
- elseif not criterium then
- local n,s=lpegmatch(pattern,filename)
- if not s or s=="" then
- return filename.."."..suffix
- else
+ if not filename or not suffix or suffix=="" then
+ return filename
+ elseif criterium==true then
+ return filename.."."..suffix
+ elseif not criterium then
+ local n,s=lpegmatch(pattern,filename)
+ if not s or s=="" then
+ return filename.."."..suffix
+ else
+ return filename
+ end
+ else
+ local n,s=lpegmatch(pattern,filename)
+ if s and s~="" then
+ local t=type(criterium)
+ if t=="table" then
+ for i=1,#criterium do
+ if s==criterium[i] then
return filename
+ end
end
- else
- local n,s=lpegmatch(pattern,filename)
- if s and s~="" then
- local t=type(criterium)
- if t=="table" then
- for i=1,#criterium do
- if s==criterium[i] then
- return filename
- end
- end
- elseif t=="string" then
- if s==criterium then
- return filename
- end
- end
+ elseif t=="string" then
+ if s==criterium then
+ return filename
end
- return (n or filename).."."..suffix
+ end
end
+ return (n or filename).."."..suffix
+ end
end
local suffix=period*(1-period-slashes)^1*-1
local pattern=Cs((1-suffix)^0)
function file.replacesuffix(name,suffix)
- if name and suffix and suffix~="" then
- return lpegmatch(pattern,name).."."..suffix
- else
- return name
- end
+ if name and suffix and suffix~="" then
+ return lpegmatch(pattern,name).."."..suffix
+ else
+ return name
+ end
end
local reslasher=lpeg.replacer(P("\\"),"/")
function file.reslash(str)
- return str and lpegmatch(reslasher,str)
+ return str and lpegmatch(reslasher,str)
end
function file.is_writable(name)
- if not name then
- elseif lfs.isdir(name) then
- name=name.."/m_t_x_t_e_s_t.tmp"
- local f=io.open(name,"wb")
- if f then
- f:close()
- os.remove(name)
- return true
- end
- elseif lfs.isfile(name) then
- local f=io.open(name,"ab")
- if f then
- f:close()
- return true
- end
- else
- local f=io.open(name,"ab")
- if f then
- f:close()
- os.remove(name)
- return true
- end
+ if not name then
+ elseif lfs.isdir(name) then
+ name=name.."/m_t_x_t_e_s_t.tmp"
+ local f=io.open(name,"wb")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
end
- return false
+ elseif lfs.isfile(name) then
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ return true
+ end
+ else
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ end
+ return false
end
local readable=P("r")*Cc(true)
function file.is_readable(name)
- if name then
- local a=attributes(name)
- return a and lpegmatch(readable,a.permissions) or false
- else
- return false
- end
+ if name then
+ local a=attributes(name)
+ return a and lpegmatch(readable,a.permissions) or false
+ else
+ return false
+ end
end
file.isreadable=file.is_readable
file.iswritable=file.is_writable
function file.size(name)
- if name then
- local a=attributes(name)
- return a and a.size or 0
- else
- return 0
- end
+ if name then
+ local a=attributes(name)
+ return a and a.size or 0
+ else
+ return 0
+ end
end
function file.splitpath(str,separator)
- return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
+ return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
end
function file.joinpath(tab,separator)
- return tab and concat(tab,separator or io.pathseparator)
+ return tab and concat(tab,separator or io.pathseparator)
end
local someslash=S("\\/")
local stripper=Cs(P(fwslash)^0/""*reslasher)
@@ -4302,30 +4302,30 @@ local hasroot=fwslash^1
local reslasher=lpeg.replacer(S("\\/"),"/")
local deslasher=lpeg.replacer(S("\\/")^1,"/")
function file.join(one,two,three,...)
- if not two then
- return one=="" and one or lpegmatch(reslasher,one)
- end
- if one=="" then
- return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
- end
- if lpegmatch(isnetwork,one) then
- local one=lpegmatch(reslasher,one)
- local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
- if lpegmatch(hasroot,two) then
- return one..two
- else
- return one.."/"..two
- end
- elseif lpegmatch(isroot,one) then
- local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
- if lpegmatch(hasroot,two) then
- return two
- else
- return "/"..two
- end
- else
- return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
- end
+ if not two then
+ return one=="" and one or lpegmatch(reslasher,one)
+ end
+ if one=="" then
+ return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
+ end
+ if lpegmatch(isnetwork,one) then
+ local one=lpegmatch(reslasher,one)
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return one..two
+ else
+ return one.."/"..two
+ end
+ elseif lpegmatch(isroot,one) then
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return two
+ else
+ return "/"..two
+ end
+ else
+ return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+ end
end
local drivespec=R("az","AZ")^1*colon
local anchors=fwslash+drivespec
@@ -4335,56 +4335,56 @@ local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//")
local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
local absolute=fwslash
function file.collapsepath(str,anchor)
- if not str then
- return
- end
- if anchor==true and not lpegmatch(anchors,str) then
- str=getcurrentdir().."/"..str
- end
- if str=="" or str=="." then
- return "."
- elseif lpegmatch(untouched,str) then
- return lpegmatch(reslasher,str)
- end
- local starter,oldelements=lpegmatch(splitstarter,str)
- local newelements={}
- local i=#oldelements
- while i>0 do
- local element=oldelements[i]
- if element=='.' then
- elseif element=='..' then
- local n=i-1
- while n>0 do
- local element=oldelements[n]
- if element~='..' and element~='.' then
- oldelements[n]='.'
- break
- else
- n=n-1
- end
- end
- if n<1 then
- insert(newelements,1,'..')
- end
- elseif element~="" then
- insert(newelements,1,element)
- end
- i=i-1
- end
- if #newelements==0 then
- return starter or "."
- elseif starter then
- return starter..concat(newelements,'/')
- elseif lpegmatch(absolute,str) then
- return "/"..concat(newelements,'/')
- else
- newelements=concat(newelements,'/')
- if anchor=="." and find(str,"^%./") then
- return "./"..newelements
+ if not str then
+ return
+ end
+ if anchor==true and not lpegmatch(anchors,str) then
+ str=getcurrentdir().."/"..str
+ end
+ if str=="" or str=="." then
+ return "."
+ elseif lpegmatch(untouched,str) then
+ return lpegmatch(reslasher,str)
+ end
+ local starter,oldelements=lpegmatch(splitstarter,str)
+ local newelements={}
+ local i=#oldelements
+ while i>0 do
+ local element=oldelements[i]
+ if element=='.' then
+ elseif element=='..' then
+ local n=i-1
+ while n>0 do
+ local element=oldelements[n]
+ if element~='..' and element~='.' then
+ oldelements[n]='.'
+ break
else
- return newelements
+ n=n-1
end
- end
+ end
+ if n<1 then
+ insert(newelements,1,'..')
+ end
+ elseif element~="" then
+ insert(newelements,1,element)
+ end
+ i=i-1
+ end
+ if #newelements==0 then
+ return starter or "."
+ elseif starter then
+ return starter..concat(newelements,'/')
+ elseif lpegmatch(absolute,str) then
+ return "/"..concat(newelements,'/')
+ else
+ newelements=concat(newelements,'/')
+ if anchor=="." and find(str,"^%./") then
+ return "./"..newelements
+ else
+ return newelements
+ end
+ end
end
local validchars=R("az","09","AZ","--","..")
local pattern_a=lpeg.replacer(1-validchars)
@@ -4392,26 +4392,26 @@ local pattern_a=Cs((validchars+P(1)/"-")^1)
local whatever=P("-")^0/""
local pattern_b=Cs(whatever*(1-whatever*-1)^1)
function file.robustname(str,strict)
- if str then
- str=lpegmatch(pattern_a,str) or str
- if strict then
- return lpegmatch(pattern_b,str) or str
- else
- return str
- end
+ if str then
+ str=lpegmatch(pattern_a,str) or str
+ if strict then
+ return lpegmatch(pattern_b,str) or str
+ else
+ return str
end
+ end
end
local loaddata=io.loaddata
local savedata=io.savedata
file.readdata=loaddata
file.savedata=savedata
function file.copy(oldname,newname)
- if oldname and newname then
- local data=loaddata(oldname)
- if data and data~="" then
- savedata(newname,data)
- end
+ if oldname and newname then
+ local data=loaddata(oldname)
+ if data and data~="" then
+ savedata(newname,data)
end
+ end
end
local letter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -4420,44 +4420,44 @@ local rootbased=fwslash+letter*colon
lpeg.patterns.qualified=qualified
lpeg.patterns.rootbased=rootbased
function file.is_qualified_path(filename)
- return filename and lpegmatch(qualified,filename)~=nil
+ return filename and lpegmatch(qualified,filename)~=nil
end
function file.is_rootbased_path(filename)
- return filename and lpegmatch(rootbased,filename)~=nil
+ return filename and lpegmatch(rootbased,filename)~=nil
end
function file.strip(name,dir)
- if name then
- local b,a=match(name,"^(.-)"..dir.."(.*)$")
- return a~="" and a or name
- end
+ if name then
+ local b,a=match(name,"^(.-)"..dir.."(.*)$")
+ return a~="" and a or name
+ end
end
function lfs.mkdirs(path)
- local full=""
- for sub in gmatch(path,"(/*[^\\/]+)") do
- full=full..sub
- lfs.mkdir(full)
- end
+ local full=""
+ for sub in gmatch(path,"(/*[^\\/]+)") do
+ full=full..sub
+ lfs.mkdir(full)
+ end
end
function file.withinbase(path)
- local l=0
- if not find(path,"^/") then
- path="/"..path
- end
- for dir in gmatch(path,"/([^/]+)") do
- if dir==".." then
- l=l-1
- elseif dir~="." then
- l=l+1
- end
- if l<0 then
- return false
- end
- end
- return true
+ local l=0
+ if not find(path,"^/") then
+ path="/"..path
+ end
+ for dir in gmatch(path,"/([^/]+)") do
+ if dir==".." then
+ l=l-1
+ elseif dir~="." then
+ l=l+1
+ end
+ if l<0 then
+ return false
+ end
+ end
+ return true
end
local symlinkattributes=lfs.symlinkattributes
function lfs.readlink(name)
- return symlinkattributes(name,"target") or nil
+ return symlinkattributes(name,"target") or nil
end
@@ -4467,51 +4467,51 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-gzip"] = package.loaded["l-gzip"] or true
--- original size: 1211, stripped down to: 1002
+-- original size: 1211, stripped down to: 951
if not modules then modules={} end modules ['l-gzip']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not gzip then
- return
+ return
end
local suffix,suffixes=file.suffix,file.suffixes
function gzip.load(filename)
- local f=io.open(filename,"rb")
- if not f then
- elseif suffix(filename)=="gz" then
- f:close()
- local g=gzip.open(filename,"rb")
- if g then
- local str=g:read("*all")
- g:close()
- return str
- end
- else
- local str=f:read("*all")
- f:close()
- return str
- end
+ local f=io.open(filename,"rb")
+ if not f then
+ elseif suffix(filename)=="gz" then
+ f:close()
+ local g=gzip.open(filename,"rb")
+ if g then
+ local str=g:read("*all")
+ g:close()
+ return str
+ end
+ else
+ local str=f:read("*all")
+ f:close()
+ return str
+ end
end
function gzip.save(filename,data)
- if suffix(filename)~="gz" then
- filename=filename..".gz"
- end
- local f=io.open(filename,"wb")
- if f then
- local s=zlib.compress(data or "",9,nil,15+16)
- f:write(s)
- f:close()
- return #s
- end
+ if suffix(filename)~="gz" then
+ filename=filename..".gz"
+ end
+ local f=io.open(filename,"wb")
+ if f then
+ local s=zlib.compress(data or "",9,nil,15+16)
+ f:write(s)
+ f:close()
+ return #s
+ end
end
function gzip.suffix(filename)
- local suffix,extra=suffixes(filename)
- local gzipped=extra=="gz"
- return suffix,gzipped
+ local suffix,extra=suffixes(filename)
+ local gzipped=extra=="gz"
+ return suffix,gzipped
end
@@ -4521,87 +4521,87 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-md5"] = package.loaded["l-md5"] or true
--- original size: 3309, stripped down to: 2314
+-- original size: 3309, stripped down to: 2218
if not modules then modules={} end modules ['l-md5']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not md5 then
- md5=optionalrequire("md5")
+ md5=optionalrequire("md5")
end
if not md5 then
- md5={
- sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
- sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
- }
+ md5={
+ sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
+ sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
+ }
end
local md5,file=md5,file
local gsub=string.gsub
do
- local patterns=lpeg and lpeg.patterns
- if patterns then
- local bytestoHEX=patterns.bytestoHEX
- local bytestohex=patterns.bytestohex
- local bytestodec=patterns.bytestodec
- local lpegmatch=lpeg.match
- local md5sum=md5.sum
- if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
- if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
- if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
- md5.sumhexa=md5.hex
- md5.sumHEXA=md5.HEX
- end
+ local patterns=lpeg and lpeg.patterns
+ if patterns then
+ local bytestoHEX=patterns.bytestoHEX
+ local bytestohex=patterns.bytestohex
+ local bytestodec=patterns.bytestodec
+ local lpegmatch=lpeg.match
+ local md5sum=md5.sum
+ if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
+ if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
+ if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
+ md5.sumhexa=md5.hex
+ md5.sumHEXA=md5.HEX
+ end
end
function file.needsupdating(oldname,newname,threshold)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime then
- local newtime=lfs.attributes(newname,"modification")
- if not newtime then
- return true
- elseif newtime>=oldtime then
- return false
- elseif oldtime-newtime<(threshold or 1) then
- return false
- else
- return true
- end
- else
- return false
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime then
+ local newtime=lfs.attributes(newname,"modification")
+ if not newtime then
+ return true
+ elseif newtime>=oldtime then
+ return false
+ elseif oldtime-newtime<(threshold or 1) then
+ return false
+ else
+ return true
+ end
+ else
+ return false
+ end
end
file.needs_updating=file.needsupdating
function file.syncmtimes(oldname,newname)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime and lfs.isfile(newname) then
- lfs.touch(newname,oldtime,oldtime)
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime and lfs.isfile(newname) then
+ lfs.touch(newname,oldtime,oldtime)
+ end
end
function file.checksum(name)
- if md5 then
- local data=io.loaddata(name)
- if data then
- return md5.HEX(data)
- end
+ if md5 then
+ local data=io.loaddata(name)
+ if data then
+ return md5.HEX(data)
end
- return nil
+ end
+ return nil
end
function file.loadchecksum(name)
- if md5 then
- local data=io.loaddata(name..".md5")
- return data and (gsub(data,"%s",""))
- end
- return nil
+ if md5 then
+ local data=io.loaddata(name..".md5")
+ return data and (gsub(data,"%s",""))
+ end
+ return nil
end
function file.savechecksum(name,checksum)
- if not checksum then checksum=file.checksum(name) end
- if checksum then
- io.savedata(name..".md5",checksum)
- return checksum
- end
- return nil
+ if not checksum then checksum=file.checksum(name) end
+ if checksum then
+ io.savedata(name..".md5",checksum)
+ return checksum
+ end
+ return nil
end
@@ -4611,29 +4611,29 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-sha"] = package.loaded["l-sha"] or true
--- original size: 1085, stripped down to: 987
+-- original size: 1085, stripped down to: 969
if not modules then modules={} end modules ['l-sha']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if sha2 then
- local lpegmatch=lpeg.match
- local lpegpatterns=lpeg.patterns
- local bytestohex=lpegpatterns.bytestohex
- local bytestoHEX=lpegpatterns.bytestoHEX
- local digest256=sha2.digest256
- local digest384=sha2.digest384
- local digest512=sha2.digest512
- sha2.hash256=function(str) return lpegmatch(bytestohex,digest256(str)) end
- sha2.hash384=function(str) return lpegmatch(bytestohex,digest384(str)) end
- sha2.hash512=function(str) return lpegmatch(bytestohex,digest512(str)) end
- sha2.HASH256=function(str) return lpegmatch(bytestoHEX,digest256(str)) end
- sha2.HASH384=function(str) return lpegmatch(bytestoHEX,digest384(str)) end
- sha2.HASH512=function(str) return lpegmatch(bytestoHEX,digest512(str)) end
+ local lpegmatch=lpeg.match
+ local lpegpatterns=lpeg.patterns
+ local bytestohex=lpegpatterns.bytestohex
+ local bytestoHEX=lpegpatterns.bytestoHEX
+ local digest256=sha2.digest256
+ local digest384=sha2.digest384
+ local digest512=sha2.digest512
+ sha2.hash256=function(str) return lpegmatch(bytestohex,digest256(str)) end
+ sha2.hash384=function(str) return lpegmatch(bytestohex,digest384(str)) end
+ sha2.hash512=function(str) return lpegmatch(bytestohex,digest512(str)) end
+ sha2.HASH256=function(str) return lpegmatch(bytestoHEX,digest256(str)) end
+ sha2.HASH384=function(str) return lpegmatch(bytestoHEX,digest384(str)) end
+ sha2.HASH512=function(str) return lpegmatch(bytestoHEX,digest512(str)) end
end
@@ -4643,14 +4643,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-url"] = package.loaded["l-url"] or true
--- original size: 14755, stripped down to: 7236
+-- original size: 14755, stripped down to: 6981
if not modules then modules={} end modules ['l-url']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local char,format,byte=string.char,string.format,string.byte
local concat=table.concat
@@ -4663,14 +4663,14 @@ local url=url
local unescapes={}
local escapes={}
setmetatable(unescapes,{ __index=function(t,k)
- local v=char(tonumber(k,16))
- t[k]=v
- return v
+ local v=char(tonumber(k,16))
+ t[k]=v
+ return v
end })
setmetatable(escapes,{ __index=function(t,k)
- local v=format("%%%02X",byte(k))
- t[k]=v
- return v
+ local v=format("%%%02X",byte(k))
+ t[k]=v
+ return v
end })
local colon=P(":")
local qmark=P("?")
@@ -4689,21 +4689,21 @@ local escaped=(plus/" ")+escapedchar
local noslash=P("/")/""
local plustospace=P("+")/" "
local decoder=Cs((
- plustospace+escapedchar+P("\r\n")/"\n"+P(1)
- )^0 )
+ plustospace+escapedchar+P("\r\n")/"\n"+P(1)
+ )^0 )
local encoder=Cs((
- R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
- )^0 )
+ R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
+ )^0 )
lpegpatterns.urldecoder=decoder
lpegpatterns.urlencoder=encoder
-function url.decode (str) return str and lpegmatch(decoder,str) or str end
-function url.encode (str) return str and lpegmatch(encoder,str) or str end
+function url.decode (str) return str and lpegmatch(decoder,str) or str end
+function url.encode (str) return str and lpegmatch(encoder,str) or str end
function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2)
local authoritystr=Cs((escaped+(1- slash-qmark-hash))^0)
-local pathstr=Cs((escaped+(1- qmark-hash))^0)
-local querystr=Cs(((1- hash))^0)
-local fragmentstr=Cs((escaped+(1- endofstring))^0)
+local pathstr=Cs((escaped+(1- qmark-hash))^0)
+local querystr=Cs(((1- hash))^0)
+local fragmentstr=Cs((escaped+(1- endofstring))^0)
local scheme=schemestr*colon+nothing
local authority=slash*slash*authoritystr+nothing
local path=slash*pathstr+nothing
@@ -4721,19 +4721,19 @@ lpegpatterns.urlescaper=escaper
lpegpatterns.urlunescaper=unescaper
lpegpatterns.urlgetcleaner=getcleaner
function url.unescapeget(str)
- return lpegmatch(getcleaner,str)
+ return lpegmatch(getcleaner,str)
end
local function split(str)
- return (type(str)=="string" and lpegmatch(parser,str)) or str
+ return (type(str)=="string" and lpegmatch(parser,str)) or str
end
local isscheme=schemestr*colon*slash*slash
local function hasscheme(str)
- if str then
- local scheme=lpegmatch(isscheme,str)
- return scheme~="" and scheme or false
- else
- return false
- end
+ if str then
+ local scheme=lpegmatch(isscheme,str)
+ return scheme~="" and scheme or false
+ else
+ return false
+ end
end
local rootletter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -4743,161 +4743,161 @@ local barswapper=replacer("|",":")
local backslashswapper=replacer("\\","/")
local equal=P("=")
local amp=P("&")
-local key=Cs(((plustospace+escapedchar+1)-equal )^0)
+local key=Cs(((plustospace+escapedchar+1)-equal )^0)
local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0)
local splitquery=Cf (Ct("")*P { "sequence",
- sequence=V("pair")*(amp*V("pair"))^0,
- pair=Cg(key*equal*value),
+ sequence=V("pair")*(amp*V("pair"))^0,
+ pair=Cg(key*equal*value),
},rawset)
local userpart=(1-atsign-colon)^1
local serverpart=(1-colon)^1
local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil))
local function hashed(str)
- if not str or str=="" then
- return {
- scheme="invalid",
- original=str,
- }
- end
- local detailed=split(str)
- local rawscheme=""
- local rawquery=""
- local somescheme=false
- local somequery=false
- if detailed then
- rawscheme=detailed[1]
- rawquery=detailed[4]
- somescheme=rawscheme~=""
- somequery=rawquery~=""
- end
- if not somescheme and not somequery then
- return {
- scheme="file",
- authority="",
- path=str,
- query="",
- fragment="",
- original=str,
- noscheme=true,
- filename=str,
- }
- end
- local authority=detailed[2]
- local path=detailed[3]
- local filename
- local username
- local password
- local host
- local port
- if authority~="" then
- username,password,host,port=lpegmatch(splitauthority,authority)
- end
- if authority=="" then
- filename=path
- elseif path=="" then
- filename=""
- else
- filename=authority.."/"..path
- end
+ if not str or str=="" then
return {
- scheme=rawscheme,
- authority=authority,
- path=path,
- query=lpegmatch(unescaper,rawquery),
- queries=lpegmatch(splitquery,rawquery),
- fragment=detailed[5],
- original=str,
- noscheme=false,
- filename=filename,
- host=host,
- port=port,
+ scheme="invalid",
+ original=str,
+ }
+ end
+ local detailed=split(str)
+ local rawscheme=""
+ local rawquery=""
+ local somescheme=false
+ local somequery=false
+ if detailed then
+ rawscheme=detailed[1]
+ rawquery=detailed[4]
+ somescheme=rawscheme~=""
+ somequery=rawquery~=""
+ end
+ if not somescheme and not somequery then
+ return {
+ scheme="file",
+ authority="",
+ path=str,
+ query="",
+ fragment="",
+ original=str,
+ noscheme=true,
+ filename=str,
}
+ end
+ local authority=detailed[2]
+ local path=detailed[3]
+ local filename
+ local username
+ local password
+ local host
+ local port
+ if authority~="" then
+ username,password,host,port=lpegmatch(splitauthority,authority)
+ end
+ if authority=="" then
+ filename=path
+ elseif path=="" then
+ filename=""
+ else
+ filename=authority.."/"..path
+ end
+ return {
+ scheme=rawscheme,
+ authority=authority,
+ path=path,
+ query=lpegmatch(unescaper,rawquery),
+ queries=lpegmatch(splitquery,rawquery),
+ fragment=detailed[5],
+ original=str,
+ noscheme=false,
+ filename=filename,
+ host=host,
+ port=port,
+ }
end
url.split=split
url.hasscheme=hasscheme
url.hashed=hashed
function url.addscheme(str,scheme)
- if hasscheme(str) then
- return str
- elseif not scheme then
- return "file:///"..str
- else
- return scheme..":///"..str
- end
+ if hasscheme(str) then
+ return str
+ elseif not scheme then
+ return "file:///"..str
+ else
+ return scheme..":///"..str
+ end
end
function url.construct(hash)
- local result,r={},0
- local scheme=hash.scheme
- local authority=hash.authority
- local path=hash.path
- local queries=hash.queries
- local fragment=hash.fragment
- if scheme and scheme~="" then
- r=r+1;result[r]=lpegmatch(escaper,scheme)
- r=r+1;result[r]="://"
- end
- if authority and authority~="" then
- r=r+1;result[r]=lpegmatch(escaper,authority)
- end
- if path and path~="" then
- r=r+1;result[r]="/"
- r=r+1;result[r]=lpegmatch(escaper,path)
- end
- if queries then
- local done=false
- for k,v in sortedhash(queries) do
- r=r+1;result[r]=done and "&" or "?"
- r=r+1;result[r]=lpegmatch(escaper,k)
- r=r+1;result[r]="="
- r=r+1;result[r]=lpegmatch(escaper,v)
- done=true
- end
- end
- if fragment and fragment~="" then
- r=r+1;result[r]="#"
- r=r+1;result[r]=lpegmatch(escaper,fragment)
- end
- return concat(result)
+ local result,r={},0
+ local scheme=hash.scheme
+ local authority=hash.authority
+ local path=hash.path
+ local queries=hash.queries
+ local fragment=hash.fragment
+ if scheme and scheme~="" then
+ r=r+1;result[r]=lpegmatch(escaper,scheme)
+ r=r+1;result[r]="://"
+ end
+ if authority and authority~="" then
+ r=r+1;result[r]=lpegmatch(escaper,authority)
+ end
+ if path and path~="" then
+ r=r+1;result[r]="/"
+ r=r+1;result[r]=lpegmatch(escaper,path)
+ end
+ if queries then
+ local done=false
+ for k,v in sortedhash(queries) do
+ r=r+1;result[r]=done and "&" or "?"
+ r=r+1;result[r]=lpegmatch(escaper,k)
+ r=r+1;result[r]="="
+ r=r+1;result[r]=lpegmatch(escaper,v)
+ done=true
+ end
+ end
+ if fragment and fragment~="" then
+ r=r+1;result[r]="#"
+ r=r+1;result[r]=lpegmatch(escaper,fragment)
+ end
+ return concat(result)
end
local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0)
function url.filename(filename)
- local spec=hashed(filename)
- local path=spec.path
- return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
+ local spec=hashed(filename)
+ local path=spec.path
+ return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
end
local function escapestring(str)
- return lpegmatch(escaper,str)
+ return lpegmatch(escaper,str)
end
url.escape=escapestring
function url.query(str)
- if type(str)=="string" then
- return lpegmatch(splitquery,str) or ""
- else
- return str
- end
+ if type(str)=="string" then
+ return lpegmatch(splitquery,str) or ""
+ else
+ return str
+ end
end
function url.toquery(data)
- local td=type(data)
- if td=="string" then
- return #str and escape(data) or nil
- elseif td=="table" then
- if next(data) then
- local t={}
- for k,v in next,data do
- t[#t+1]=format("%s=%s",k,escapestring(v))
- end
- return concat(t,"&")
- end
- else
+ local td=type(data)
+ if td=="string" then
+ return #str and escape(data) or nil
+ elseif td=="table" then
+ if next(data) then
+ local t={}
+ for k,v in next,data do
+ t[#t+1]=format("%s=%s",k,escapestring(v))
+ end
+ return concat(t,"&")
end
+ else
+ end
end
local pattern=Cs(noslash^0*(1-noslash*P(-1))^0)
function url.barepath(path)
- if not path or path=="" then
- return ""
- else
- return lpegmatch(pattern,path)
- end
+ if not path or path=="" then
+ return ""
+ else
+ return lpegmatch(pattern,path)
+ end
end
@@ -4907,14 +4907,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-dir"] = package.loaded["l-dir"] or true
--- original size: 18002, stripped down to: 11863
+-- original size: 18002, stripped down to: 10681
if not modules then modules={} end modules ['l-dir']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,select=type,select
local find,gmatch,match,gsub,sub=string.find,string.gmatch,string.match,string.gsub,string.sub
@@ -4926,478 +4926,478 @@ local dir=dir
local lfs=lfs
local attributes=lfs.attributes
local walkdir=lfs.dir
-local isdir=lfs.isdir
+local isdir=lfs.isdir
local isfile=lfs.isfile
local currentdir=lfs.currentdir
local chdir=lfs.chdir
local mkdir=lfs.mkdir
local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true)
if onwindows then
- local tricky=S("/\\")*P(-1)
- isdir=function(name)
- if lpegmatch(tricky,name) then
- return attributes(name,"mode")=="directory"
- else
- return attributes(name.."/.","mode")=="directory"
- end
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ local tricky=S("/\\")*P(-1)
+ isdir=function(name)
+ if lpegmatch(tricky,name) then
+ return attributes(name,"mode")=="directory"
+ else
+ return attributes(name.."/.","mode")=="directory"
+ end
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
else
- isdir=function(name)
- return attributes(name,"mode")=="directory"
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ isdir=function(name)
+ return attributes(name,"mode")=="directory"
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
end
function dir.current()
- return (gsub(currentdir(),"\\","/"))
+ return (gsub(currentdir(),"\\","/"))
end
local function glob_pattern_function(path,patt,recurse,action)
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- local nofdirs=0
- for name in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- action(full)
- end
- elseif recurse and mode=="directory" then
- if dirs then
- nofdirs=nofdirs+1
- dirs[nofdirs]=full
- else
- nofdirs=1
- dirs={ full }
- end
- end
- end
- end
- if dirs then
- for i=1,nofdirs do
- glob_pattern_function(dirs[i],patt,recurse,action)
- end
- end
- end
-end
-local function glob_pattern_table(path,patt,recurse,result)
- if not result then
- result={}
- end
+ if isdir(path) then
local usedpath
if path=="/" then
- usedpath="/."
+ usedpath="/."
elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
+ usedpath=path.."/."
+ path=path.."/"
else
- usedpath=path
+ usedpath=path
end
local dirs
local nofdirs=0
- local noffiles=#result
- for name,a in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- noffiles=noffiles+1
- result[noffiles]=full
- end
- elseif recurse and mode=="directory" then
- if dirs then
- nofdirs=nofdirs+1
- dirs[nofdirs]=full
- else
- nofdirs=1
- dirs={ full }
- end
- end
+ for name in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ action(full)
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
end
+ end
end
if dirs then
- for i=1,nofdirs do
- glob_pattern_table(dirs[i],patt,recurse,result)
- end
+ for i=1,nofdirs do
+ glob_pattern_function(dirs[i],patt,recurse,action)
+ end
end
- return result
+ end
end
-local function globpattern(path,patt,recurse,method)
- local kind=type(method)
- if patt and sub(patt,1,-3)==path then
- patt=false
+local function glob_pattern_table(path,patt,recurse,result)
+ if not result then
+ result={}
+ end
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ local noffiles=#result
+ for name,a in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ noffiles=noffiles+1
+ result[noffiles]=full
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
+ end
end
- local okay=isdir(path)
- if kind=="function" then
- return okay and glob_pattern_function(path,patt,recurse,method) or {}
- elseif kind=="table" then
- return okay and glob_pattern_table(path,patt,recurse,method) or method
- else
- return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_table(dirs[i],patt,recurse,result)
end
+ end
+ return result
+end
+local function globpattern(path,patt,recurse,method)
+ local kind=type(method)
+ if patt and sub(patt,1,-3)==path then
+ patt=false
+ end
+ local okay=isdir(path)
+ if kind=="function" then
+ return okay and glob_pattern_function(path,patt,recurse,method) or {}
+ elseif kind=="table" then
+ return okay and glob_pattern_table(path,patt,recurse,method) or method
+ else
+ return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
end
dir.globpattern=globpattern
local function collectpattern(path,patt,recurse,result)
- local ok,scanner
- result=result or {}
- if path=="/" then
- ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
- else
- ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
- end
- if ok and type(scanner)=="function" then
- if not find(path,"/$") then
- path=path..'/'
- end
- for name in scanner,first do
- if name=="." then
- elseif name==".." then
- else
- local full=path..name
- local attr=attributes(full)
- local mode=attr.mode
- if mode=='file' then
- if find(full,patt) then
- result[name]=attr
- end
- elseif recurse and mode=="directory" then
- attr.list=collectpattern(full,patt,recurse)
- result[name]=attr
- end
- end
+ local ok,scanner
+ result=result or {}
+ if path=="/" then
+ ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
+ else
+ ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
+ end
+ if ok and type(scanner)=="function" then
+ if not find(path,"/$") then
+ path=path..'/'
+ end
+ for name in scanner,first do
+ if name=="." then
+ elseif name==".." then
+ else
+ local full=path..name
+ local attr=attributes(full)
+ local mode=attr.mode
+ if mode=='file' then
+ if find(full,patt) then
+ result[name]=attr
+ end
+ elseif recurse and mode=="directory" then
+ attr.list=collectpattern(full,patt,recurse)
+ result[name]=attr
end
+ end
end
- return result
+ end
+ return result
end
dir.collectpattern=collectpattern
local separator,pattern
if onwindows then
- local slash=S("/\\")/"/"
- pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
- }
+ local slash=S("/\\")/"/"
+ pattern={
+ [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
+ [3]=Cs(P(1)^0)
+ }
else
- pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
- }
+ pattern={
+ [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ [2]=C(((1-S("*?/"))^0*P("/"))^0),
+ [3]=C(P(1)^0)
+ }
end
local filter=Cs ((
- P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
+ P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
)^0 )
local function glob(str,t)
- if type(t)=="function" then
- if type(str)=="table" then
- for s=1,#str do
- glob(str[s],t)
- end
- elseif isfile(str) then
- t(str)
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- globpattern(start,result,recurse,t)
- end
- end
+ if type(t)=="function" then
+ if type(str)=="table" then
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ elseif isfile(str) then
+ t(str)
+ else
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ globpattern(start,result,recurse,t)
+ end
+ end
+ else
+ if type(str)=="table" then
+ local t=t or {}
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ return t
+ elseif isfile(str) then
+ if t then
+ t[#t+1]=str
+ return t
+ else
+ return { str }
+ end
else
- if type(str)=="table" then
- local t=t or {}
- for s=1,#str do
- glob(str[s],t)
- end
- return t
- elseif isfile(str) then
- if t then
- t[#t+1]=str
- return t
- else
- return { str }
- end
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- return globpattern(start,result,recurse,t)
- else
- return {}
- end
- end
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ return globpattern(start,result,recurse,t)
+ else
+ return {}
+ end
end
+ end
end
dir.glob=glob
local function globfiles(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if recurse then
- globfiles(path.."/"..name,recurse,func,files)
- end
- elseif mode=="file" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if recurse then
+ globfiles(path.."/"..name,recurse,func,files)
+ end
+ elseif mode=="file" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
end
+ end
end
- return files
+ end
+ return files
end
dir.globfiles=globfiles
local function globdirs(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- if recurse then
- globdirs(path.."/"..name,recurse,func,files)
- end
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
+ if recurse then
+ globdirs(path.."/"..name,recurse,func,files)
+ end
end
+ end
end
- return files
+ end
+ return files
end
dir.globdirs=globdirs
function dir.ls(pattern)
- return concat(glob(pattern),"\n")
+ return concat(glob(pattern),"\n")
end
local make_indeed=true
if onwindows then
- function dir.mkdirs(...)
- local n=select("#",...)
- local str
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s=="" then
+ elseif str=="" then
+ str=s
else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s=="" then
- elseif str=="" then
- str=s
- else
- str=str.."/"..s
- end
- end
+ str=str.."/"..s
end
- local pth=""
- local drive=false
- local first,middle,last=match(str,"^(//)(//*)(.*)$")
- if first then
+ end
+ end
+ local pth=""
+ local drive=false
+ local first,middle,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ else
+ first,last=match(str,"^(//)/*(.-)$")
+ if first then
+ middle,last=match(str,"([^/]+)/+(.-)$")
+ if middle then
+ pth="//"..middle
else
- first,last=match(str,"^(//)/*(.-)$")
- if first then
- middle,last=match(str,"([^/]+)/+(.-)$")
- if middle then
- pth="//"..middle
- else
- pth="//"..last
- last=""
- end
- else
- first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
- if first then
- pth,drive=first..middle,true
- else
- middle,last=match(str,"^(/*)(.-)$")
- if not middle then
- last=str
- end
- end
- end
+ pth="//"..last
+ last=""
end
- for s in gmatch(last,"[^/]+") do
- if pth=="" then
- pth=s
- elseif drive then
- pth,drive=pth..s,false
- else
- pth=pth.."/"..s
- end
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
+ else
+ first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
+ if first then
+ pth,drive=first..middle,true
+ else
+ middle,last=match(str,"^(/*)(.-)$")
+ if not middle then
+ last=str
+ end
end
- return pth,(isdir(pth)==true)
+ end
end
+ for s in gmatch(last,"[^/]+") do
+ if pth=="" then
+ pth=s
+ elseif drive then
+ pth,drive=pth..s,false
+ else
+ pth=pth.."/"..s
+ end
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ return pth,(isdir(pth)==true)
+ end
else
- function dir.mkdirs(...)
- local n=select("#",...)
- local str,pth
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
- else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s and s~="" then
- if str~="" then
- str=str.."/"..s
- else
- str=s
- end
- end
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str,pth
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s and s~="" then
+ if str~="" then
+ str=str.."/"..s
+ else
+ str=s
+ end
end
- str=gsub(str,"/+","/")
- if find(str,"^/") then
- pth="/"
- for s in gmatch(str,"[^/]+") do
- local first=(pth=="/")
- if first then
- pth=pth..s
- else
- pth=pth.."/"..s
- end
- if make_indeed and not first and not isdir(pth) then
- mkdir(pth)
- end
- end
+ end
+ end
+ str=gsub(str,"/+","/")
+ if find(str,"^/") then
+ pth="/"
+ for s in gmatch(str,"[^/]+") do
+ local first=(pth=="/")
+ if first then
+ pth=pth..s
else
- pth="."
- for s in gmatch(str,"[^/]+") do
- pth=pth.."/"..s
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
- end
+ pth=pth.."/"..s
+ end
+ if make_indeed and not first and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ else
+ pth="."
+ for s in gmatch(str,"[^/]+") do
+ pth=pth.."/"..s
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
end
- return pth,(isdir(pth)==true)
+ end
end
+ return pth,(isdir(pth)==true)
+ end
end
dir.makedirs=dir.mkdirs
do
- local chdir=sandbox and sandbox.original(chdir) or chdir
- if onwindows then
- local xcurrentdir=dir.current
- function dir.expandname(str)
- local first,nothing,last=match(str,"^(//)(//*)(.*)$")
- if first then
- first=xcurrentdir().."/"
- end
- if not first then
- first,last=match(str,"^(//)/*(.*)$")
- end
- if not first then
- first,last=match(str,"^([a-zA-Z]:)(.*)$")
- if first and not find(last,"^/") then
- local d=currentdir()
- if chdir(first) then
- first=xcurrentdir()
- end
- chdir(d)
- end
- end
- if not first then
- first,last=xcurrentdir(),str
- end
- last=gsub(last,"//","/")
- last=gsub(last,"/%./","/")
- last=gsub(last,"^/*","")
- first=gsub(first,"/*$","")
- if last=="" or last=="." then
- return first
- else
- return first.."/"..last
- end
- end
- else
- function dir.expandname(str)
- if not find(str,"^/") then
- str=currentdir().."/"..str
- end
- str=gsub(str,"//","/")
- str=gsub(str,"/%./","/")
- str=gsub(str,"(.)/%.$","%1")
- return str
+ local chdir=sandbox and sandbox.original(chdir) or chdir
+ if onwindows then
+ local xcurrentdir=dir.current
+ function dir.expandname(str)
+ local first,nothing,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ first=xcurrentdir().."/"
+ end
+ if not first then
+ first,last=match(str,"^(//)/*(.*)$")
+ end
+ if not first then
+ first,last=match(str,"^([a-zA-Z]:)(.*)$")
+ if first and not find(last,"^/") then
+ local d=currentdir()
+ if chdir(first) then
+ first=xcurrentdir()
+ end
+ chdir(d)
end
+ end
+ if not first then
+ first,last=xcurrentdir(),str
+ end
+ last=gsub(last,"//","/")
+ last=gsub(last,"/%./","/")
+ last=gsub(last,"^/*","")
+ first=gsub(first,"/*$","")
+ if last=="" or last=="." then
+ return first
+ else
+ return first.."/"..last
+ end
+ end
+ else
+ function dir.expandname(str)
+ if not find(str,"^/") then
+ str=currentdir().."/"..str
+ end
+ str=gsub(str,"//","/")
+ str=gsub(str,"/%./","/")
+ str=gsub(str,"(.)/%.$","%1")
+ return str
end
+ end
end
file.expandname=dir.expandname
local stack={}
function dir.push(newdir)
- local curdir=currentdir()
- insert(stack,curdir)
- if newdir and newdir~="" then
- chdir(newdir)
- return newdir
- else
- return curdir
- end
+ local curdir=currentdir()
+ insert(stack,curdir)
+ if newdir and newdir~="" then
+ chdir(newdir)
+ return newdir
+ else
+ return curdir
+ end
end
function dir.pop()
- local d=remove(stack)
- if d then
- chdir(d)
- end
- return d
+ local d=remove(stack)
+ if d then
+ chdir(d)
+ end
+ return d
end
local function found(...)
- for i=1,select("#",...) do
- local path=select(i,...)
- local kind=type(path)
- if kind=="string" then
- if isdir(path) then
- return path
- end
- elseif kind=="table" then
- local path=found(unpack(path))
- if path then
- return path
- end
- end
+ for i=1,select("#",...) do
+ local path=select(i,...)
+ local kind=type(path)
+ if kind=="string" then
+ if isdir(path) then
+ return path
+ end
+ elseif kind=="table" then
+ local path=found(unpack(path))
+ if path then
+ return path
+ end
end
+ end
end
dir.found=found
@@ -5408,69 +5408,69 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-boolean"] = package.loaded["l-boolean"] or true
--- original size: 1850, stripped down to: 1568
+-- original size: 1850, stripped down to: 1498
if not modules then modules={} end modules ['l-boolean']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber=type,tonumber
boolean=boolean or {}
local boolean=boolean
function boolean.tonumber(b)
- if b then return 1 else return 0 end
+ if b then return 1 else return 0 end
end
function toboolean(str,tolerant)
- if str==nil then
- return false
- elseif str==false then
- return false
- elseif str==true then
- return true
- elseif str=="true" then
- return true
- elseif str=="false" then
- return false
- elseif not tolerant then
- return false
- elseif str==0 then
- return false
- elseif (tonumber(str) or 0)>0 then
- return true
- else
- return str=="yes" or str=="on" or str=="t"
- end
+ if str==nil then
+ return false
+ elseif str==false then
+ return false
+ elseif str==true then
+ return true
+ elseif str=="true" then
+ return true
+ elseif str=="false" then
+ return false
+ elseif not tolerant then
+ return false
+ elseif str==0 then
+ return false
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
end
string.toboolean=toboolean
function string.booleanstring(str)
- if str=="0" then
- return false
- elseif str=="1" then
- return true
- elseif str=="" then
- return false
- elseif str=="false" then
- return false
- elseif str=="true" then
- return true
- elseif (tonumber(str) or 0)>0 then
- return true
- else
- return str=="yes" or str=="on" or str=="t"
- end
+ if str=="0" then
+ return false
+ elseif str=="1" then
+ return true
+ elseif str=="" then
+ return false
+ elseif str=="false" then
+ return false
+ elseif str=="true" then
+ return true
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
end
function string.is_boolean(str,default,strict)
- if type(str)=="string" then
- if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
- return true
- elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
- return false
- end
+ if type(str)=="string" then
+ if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
+ return true
+ elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
+ return false
end
- return default
+ end
+ return default
end
@@ -5480,22 +5480,22 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 41047, stripped down to: 18594
+-- original size: 41047, stripped down to: 17171
if not modules then modules={} end modules ['l-unicode']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utf=utf or {}
unicode=nil
if not string.utfcharacters then
- local gmatch=string.gmatch
- function string.characters(str)
- return gmatch(str,".[\128-\191]*")
- end
+ local gmatch=string.gmatch
+ function string.characters(str)
+ return gmatch(str,".[\128-\191]*")
+ end
end
utf.characters=string.utfcharacters
local type=type
@@ -5518,304 +5518,304 @@ local p_utfbom=patterns.utfbom
local p_newline=patterns.newline
local p_whitespace=patterns.whitespace
if not utf.char then
- utf.char=string.utfcharacter or (utf8 and utf8.char)
- if not utf.char then
- local char=string.char
- if bit32 then
- local rshift=bit32.rshift
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+rshift(n,6),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+rshift(n,12),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+rshift(n,18),
- 0x80+(rshift(n,12)%0x40),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
+ utf.char=string.utfcharacter or (utf8 and utf8.char)
+ if not utf.char then
+ local char=string.char
+ if bit32 then
+ local rshift=bit32.rshift
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+rshift(n,6),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+rshift(n,12),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+rshift(n,18),
+ 0x80+(rshift(n,12)%0x40),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
else
- local floor=math.floor
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+floor(n/0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+floor(n/0x1000),
- 0x80+(floor(n/0x40)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+floor(n/0x40000),
- 0x80+(floor(n/0x1000)%0x40),
- 0x80+(floor(n/0x40)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
+ return ""
+ end
+ end
+ else
+ local floor=math.floor
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+floor(n/0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+floor(n/0x1000),
+ 0x80+(floor(n/0x40)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+floor(n/0x40000),
+ 0x80+(floor(n/0x1000)%0x40),
+ 0x80+(floor(n/0x40)%0x40),
+ 0x80+(n%0x40)
+ )
+ else
+ return ""
end
+ end
end
+ end
end
if not utf.byte then
- utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
- if not utf.byte then
- function utf.byte(c)
- return lpegmatch(p_utf8byte,c)
- end
+ utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
+ if not utf.byte then
+ function utf.byte(c)
+ return lpegmatch(p_utf8byte,c)
end
+ end
end
local utfchar,utfbyte=utf.char,utf.byte
function utf.filetype(data)
- return data and lpegmatch(p_utftype,data) or "unknown"
+ return data and lpegmatch(p_utftype,data) or "unknown"
end
local toentities=Cs (
- (
- patterns.utf8one+(
- patterns.utf8two+patterns.utf8three+patterns.utf8four
- )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
- )^0
+ (
+ patterns.utf8one+(
+ patterns.utf8two+patterns.utf8three+patterns.utf8four
+ )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
+ )^0
)
patterns.toentities=toentities
function utf.toentities(str)
- return lpegmatch(toentities,str)
+ return lpegmatch(toentities,str)
end
local one=P(1)
local two=C(1)*C(1)
local four=C(R(utfchar(0xD8),utfchar(0xFF)))*C(1)*C(1)*C(1)
local pattern=P("\254\255")*Cs((
- four/function(a,b,c,d)
- local ab=0xFF*byte(a)+byte(b)
- local cd=0xFF*byte(c)+byte(d)
- return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
- end+two/function(a,b)
- return utfchar(byte(a)*256+byte(b))
- end+one
- )^1 )+P("\255\254")*Cs((
- four/function(b,a,d,c)
- local ab=0xFF*byte(a)+byte(b)
- local cd=0xFF*byte(c)+byte(d)
- return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
- end+two/function(b,a)
- return utfchar(byte(a)*256+byte(b))
- end+one
- )^1 )
+ four/function(a,b,c,d)
+ local ab=0xFF*byte(a)+byte(b)
+ local cd=0xFF*byte(c)+byte(d)
+ return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+ end+two/function(a,b)
+ return utfchar(byte(a)*256+byte(b))
+ end+one
+ )^1 )+P("\255\254")*Cs((
+ four/function(b,a,d,c)
+ local ab=0xFF*byte(a)+byte(b)
+ local cd=0xFF*byte(c)+byte(d)
+ return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+ end+two/function(b,a)
+ return utfchar(byte(a)*256+byte(b))
+ end+one
+ )^1 )
function string.toutf(s)
- return lpegmatch(pattern,s) or s
+ return lpegmatch(pattern,s) or s
end
local validatedutf=Cs (
- (
- patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
- )^0
+ (
+ patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
+ )^0
)
patterns.validatedutf=validatedutf
function utf.is_valid(str)
- return type(str)=="string" and lpegmatch(validatedutf,str) or false
+ return type(str)=="string" and lpegmatch(validatedutf,str) or false
end
if not utf.len then
- utf.len=string.utflength or (utf8 and utf8.len)
- if not utf.len then
- local n,f=0,1
- local utfcharcounter=patterns.utfbom^-1*Cmt (
- Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
- function(_,t,d)
- n=n+(t-f)/d
- f=t
- return true
- end
- )^0
- function utf.len(str)
- n,f=0,1
- lpegmatch(utfcharcounter,str or "")
- return n
- end
+ utf.len=string.utflength or (utf8 and utf8.len)
+ if not utf.len then
+ local n,f=0,1
+ local utfcharcounter=patterns.utfbom^-1*Cmt (
+ Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
+ function(_,t,d)
+ n=n+(t-f)/d
+ f=t
+ return true
+ end
+ )^0
+ function utf.len(str)
+ n,f=0,1
+ lpegmatch(utfcharcounter,str or "")
+ return n
end
+ end
end
utf.length=utf.len
if not utf.sub then
- local utflength=utf.length
- local b,e,n,first,last=0,0,0,0,0
- local function slide_zero(s,p)
- n=n+1
- if n>=last then
- e=p-1
- else
- return p
- end
+ local utflength=utf.length
+ local b,e,n,first,last=0,0,0,0,0
+ local function slide_zero(s,p)
+ n=n+1
+ if n>=last then
+ e=p-1
+ else
+ return p
end
- local function slide_one(s,p)
- n=n+1
- if n==first then
- b=p
- end
- if n>=last then
- e=p-1
- else
- return p
- end
+ end
+ local function slide_one(s,p)
+ n=n+1
+ if n==first then
+ b=p
end
- local function slide_two(s,p)
- n=n+1
- if n==first then
- b=p
- else
- return true
- end
+ if n>=last then
+ e=p-1
+ else
+ return p
end
- local pattern_zero=Cmt(p_utf8character,slide_zero)^0
- local pattern_one=Cmt(p_utf8character,slide_one )^0
- local pattern_two=Cmt(p_utf8character,slide_two )^0
- local pattern_first=C(p_utf8character)
- function utf.sub(str,start,stop)
- if not start then
- return str
- end
- if start==0 then
- start=1
- end
- if not stop then
- if start<0 then
- local l=utflength(str)
- start=l+start
- else
- start=start-1
- end
- b,n,first=0,0,start
- lpegmatch(pattern_two,str)
- if n>=first then
- return sub(str,b)
- else
- return ""
- end
- end
- if start<0 or stop<0 then
- local l=utf.length(str)
- if start<0 then
- start=l+start
- if start<=0 then
- start=1
- else
- start=start+1
- end
- end
- if stop<0 then
- stop=l+stop
- if stop==0 then
- stop=1
- else
- stop=stop+1
- end
- end
+ end
+ local function slide_two(s,p)
+ n=n+1
+ if n==first then
+ b=p
+ else
+ return true
+ end
+ end
+ local pattern_zero=Cmt(p_utf8character,slide_zero)^0
+ local pattern_one=Cmt(p_utf8character,slide_one )^0
+ local pattern_two=Cmt(p_utf8character,slide_two )^0
+ local pattern_first=C(p_utf8character)
+ function utf.sub(str,start,stop)
+ if not start then
+ return str
+ end
+ if start==0 then
+ start=1
+ end
+ if not stop then
+ if start<0 then
+ local l=utflength(str)
+ start=l+start
+ else
+ start=start-1
+ end
+ b,n,first=0,0,start
+ lpegmatch(pattern_two,str)
+ if n>=first then
+ return sub(str,b)
+ else
+ return ""
+ end
+ end
+ if start<0 or stop<0 then
+ local l=utf.length(str)
+ if start<0 then
+ start=l+start
+ if start<=0 then
+ start=1
+ else
+ start=start+1
end
- if start==1 and stop==1 then
- return lpegmatch(pattern_first,str) or ""
- elseif start>stop then
- return ""
- elseif start>1 then
- b,e,n,first,last=0,0,0,start-1,stop
- lpegmatch(pattern_one,str)
- if n>=first and e==0 then
- e=#str
- end
- return sub(str,b,e)
+ end
+ if stop<0 then
+ stop=l+stop
+ if stop==0 then
+ stop=1
else
- b,e,n,last=1,0,0,stop
- lpegmatch(pattern_zero,str)
- if e==0 then
- e=#str
- end
- return sub(str,b,e)
+ stop=stop+1
end
+ end
end
+ if start==1 and stop==1 then
+ return lpegmatch(pattern_first,str) or ""
+ elseif start>stop then
+ return ""
+ elseif start>1 then
+ b,e,n,first,last=0,0,0,start-1,stop
+ lpegmatch(pattern_one,str)
+ if n>=first and e==0 then
+ e=#str
+ end
+ return sub(str,b,e)
+ else
+ b,e,n,last=1,0,0,stop
+ lpegmatch(pattern_zero,str)
+ if e==0 then
+ e=#str
+ end
+ return sub(str,b,e)
+ end
+ end
end
function utf.remapper(mapping,option,action)
- local variant=type(mapping)
- if variant=="table" then
- action=action or mapping
- if option=="dynamic" then
- local pattern=false
- table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
- return function(str)
- if not str or str=="" then
- return ""
- else
- if not pattern then
- pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
- end
- return lpegmatch(pattern,str)
- end
- end
- elseif option=="pattern" then
- return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ local variant=type(mapping)
+ if variant=="table" then
+ action=action or mapping
+ if option=="dynamic" then
+ local pattern=false
+ table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
+ return function(str)
+ if not str or str=="" then
+ return ""
else
- local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
- return function(str)
- if not str or str=="" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end,pattern
+ if not pattern then
+ pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ end
+ return lpegmatch(pattern,str)
end
- elseif variant=="function" then
- if option=="pattern" then
- return Cs((p_utf8character/mapping+p_utf8character)^0)
+ end
+ elseif option=="pattern" then
+ return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ else
+ local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
else
- local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
- return function(str)
- if not str or str=="" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end,pattern
+ return lpegmatch(pattern,str)
end
+ end,pattern
+ end
+ elseif variant=="function" then
+ if option=="pattern" then
+ return Cs((p_utf8character/mapping+p_utf8character)^0)
else
- return function(str)
- return str or ""
+ local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
end
+ end,pattern
end
-end
-function utf.replacer(t)
- local r=replacer(t,false,false,true)
+ else
return function(str)
- return lpegmatch(r,str)
+ return str or ""
end
+ end
+end
+function utf.replacer(t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ return lpegmatch(r,str)
+ end
end
function utf.subtituter(t)
- local f=finder (t)
- local r=replacer(t,false,false,true)
- return function(str)
- local i=lpegmatch(f,str)
- if not i then
- return str
- elseif i>#str then
- return str
- else
- return lpegmatch(r,str)
- end
+ local f=finder (t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ local i=lpegmatch(f,str)
+ if not i then
+ return str
+ elseif i>#str then
+ return str
+ else
+ return lpegmatch(r,str)
end
+ end
end
local utflinesplitter=p_utfbom^-1*lpeg.tsplitat(p_newline)
local utfcharsplitter_ows=p_utfbom^-1*Ct(C(p_utf8character)^0)
@@ -5823,25 +5823,25 @@ local utfcharsplitter_iws=p_utfbom^-1*Ct((p_whitespace^1+C(p_utf8character))^0)
local utfcharsplitter_raw=Ct(C(p_utf8character)^0)
patterns.utflinesplitter=utflinesplitter
function utf.splitlines(str)
- return lpegmatch(utflinesplitter,str or "")
+ return lpegmatch(utflinesplitter,str or "")
end
function utf.split(str,ignorewhitespace)
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
+ if ignorewhitespace then
+ return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+ return lpegmatch(utfcharsplitter_ows,str or "")
+ end
end
function utf.totable(str)
- return lpegmatch(utfcharsplitter_raw,str)
+ return lpegmatch(utfcharsplitter_raw,str)
end
function utf.magic(f)
- local str=f:read(4) or ""
- local off=lpegmatch(p_utfoffset,str)
- if off<4 then
- f:seek('set',off)
- end
- return lpegmatch(p_utftype,str)
+ local str=f:read(4) or ""
+ local off=lpegmatch(p_utfoffset,str)
+ if off<4 then
+ f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
end
local utf16_to_utf8_be,utf16_to_utf8_le
local utf32_to_utf8_be,utf32_to_utf8_le
@@ -5855,36 +5855,36 @@ local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_n
local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
local more=0
local p_utf16_to_utf8_be=C(1)*C(1)/function(left,right)
- local now=256*byte(left)+byte(right)
- if more>0 then
- now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ return ""
+ else
+ return utfchar(now)
+ end
end
local p_utf16_to_utf8_le=C(1)*C(1)/function(right,left)
- local now=256*byte(left)+byte(right)
- if more>0 then
- now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ return ""
+ else
+ return utfchar(now)
+ end
end
local p_utf32_to_utf8_be=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
- return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
+ return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
end
local p_utf32_to_utf8_le=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
- return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
+ return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
end
p_utf16_to_utf8_be=P(true)/function() more=0 end*utf_16_be_getbom*Cs(p_utf16_to_utf8_be^0)
p_utf16_to_utf8_le=P(true)/function() more=0 end*utf_16_le_getbom*Cs(p_utf16_to_utf8_le^0)
@@ -5895,88 +5895,88 @@ patterns.utf16_to_utf8_le=p_utf16_to_utf8_le
patterns.utf32_to_utf8_be=p_utf32_to_utf8_be
patterns.utf32_to_utf8_le=p_utf32_to_utf8_le
utf16_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_be,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+ return s
+ end
end
local utf16_to_utf8_be_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_16_be_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf16_to_utf8_be,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_16_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf16_to_utf8_be,s)
end
- return t
+ end
+ return t
end
utf16_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+ return s
+ end
end
local utf16_to_utf8_le_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_16_le_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf16_to_utf8_le,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_16_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf16_to_utf8_le,s)
end
- return t
+ end
+ return t
end
utf32_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_be,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+ return s
+ end
end
local utf32_to_utf8_be_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_32_be_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf32_to_utf8_be,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_32_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf32_to_utf8_be,s)
end
- return t
+ end
+ return t
end
utf32_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+ return s
+ end
end
local utf32_to_utf8_le_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_32_le_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf32_to_utf8_le,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_32_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf32_to_utf8_le,s)
end
- return t
+ end
+ return t
end
utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
@@ -5987,225 +5987,225 @@ utf.utf16_to_utf8_be=utf16_to_utf8_be
utf.utf32_to_utf8_le=utf32_to_utf8_le
utf.utf32_to_utf8_be=utf32_to_utf8_be
function utf.utf8_to_utf8_t(t)
- return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
+ return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
end
function utf.utf16_to_utf8_t(t,endian)
- return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
+ return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
end
function utf.utf32_to_utf8_t(t,endian)
- return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
+ return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
end
local function little(b)
- if b<0x10000 then
- return char(b%256,rshift(b,8))
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
- end
+ if b<0x10000 then
+ return char(b%256,rshift(b,8))
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
end
local function big(b)
- if b<0x10000 then
- return char(rshift(b,8),b%256)
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
- end
+ if b<0x10000 then
+ return char(rshift(b,8),b%256)
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
end
local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
local function utf8_to_utf16_be(str,nobom)
- if nobom then
- return lpegmatch(b_remap,str)
- else
- return char(254,255)..lpegmatch(b_remap,str)
- end
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
end
local function utf8_to_utf16_le(str,nobom)
- if nobom then
- return lpegmatch(l_remap,str)
- else
- return char(255,254)..lpegmatch(l_remap,str)
- end
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
end
utf.utf8_to_utf16_be=utf8_to_utf16_be
utf.utf8_to_utf16_le=utf8_to_utf16_le
function utf.utf8_to_utf16(str,littleendian,nobom)
- if littleendian then
- return utf8_to_utf16_le(str,nobom)
- else
- return utf8_to_utf16_be(str,nobom)
- end
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
end
local pattern=Cs (
- (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
+ (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
)
function utf.tocodes(str,separator)
- return lpegmatch(pattern,str,1,separator or " ")
+ return lpegmatch(pattern,str,1,separator or " ")
end
function utf.ustring(s)
- return format("U+%05X",type(s)=="number" and s or utfbyte(s))
+ return format("U+%05X",type(s)=="number" and s or utfbyte(s))
end
function utf.xstring(s)
- return format("0x%05X",type(s)=="number" and s or utfbyte(s))
+ return format("0x%05X",type(s)=="number" and s or utfbyte(s))
end
function utf.toeight(str)
- if not str or str=="" then
- return nil
- end
- local utftype=lpegmatch(p_utfstricttype,str)
- if utftype=="utf-8" then
- return sub(str,4)
- elseif utftype=="utf-16-be" then
- return utf16_to_utf8_be(str)
- elseif utftype=="utf-16-le" then
- return utf16_to_utf8_le(str)
- else
- return str
- end
+ if not str or str=="" then
+ return nil
+ end
+ local utftype=lpegmatch(p_utfstricttype,str)
+ if utftype=="utf-8" then
+ return sub(str,4)
+ elseif utftype=="utf-16-be" then
+ return utf16_to_utf8_be(str)
+ elseif utftype=="utf-16-le" then
+ return utf16_to_utf8_le(str)
+ else
+ return str
+ end
end
do
- local p_nany=p_utf8character/""
- local cache={}
- function utf.count(str,what)
- if type(what)=="string" then
- local p=cache[what]
- if not p then
- p=Cs((P(what)/" "+p_nany)^0)
- cache[p]=p
- end
- return #lpegmatch(p,str)
- else
- return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
- end
+ local p_nany=p_utf8character/""
+ local cache={}
+ function utf.count(str,what)
+ if type(what)=="string" then
+ local p=cache[what]
+ if not p then
+ p=Cs((P(what)/" "+p_nany)^0)
+ cache[p]=p
+ end
+ return #lpegmatch(p,str)
+ else
+ return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
end
+ end
end
if not string.utfvalues then
- local find=string.find
- local dummy=function()
- end
- function string.utfvalues(str)
- local n=#str
- if n==0 then
- return dummy
- elseif n==1 then
- return function() return utfbyte(str) end
- else
- local p=1
- return function()
- local b,e=find(str,".[\128-\191]*",p)
- if b then
- p=e+1
- return utfbyte(sub(str,b,e))
- end
- end
- end
+ local find=string.find
+ local dummy=function()
+ end
+ function string.utfvalues(str)
+ local n=#str
+ if n==0 then
+ return dummy
+ elseif n==1 then
+ return function() return utfbyte(str) end
+ else
+ local p=1
+ return function()
+ local b,e=find(str,".[\128-\191]*",p)
+ if b then
+ p=e+1
+ return utfbyte(sub(str,b,e))
+ end
+ end
end
+ end
end
utf.values=string.utfvalues
function utf.chrlen(u)
- return
- (u<0x80 and 1) or
- (u<0xE0 and 2) or
- (u<0xF0 and 3) or
- (u<0xF8 and 4) or
- (u<0xFC and 5) or
- (u<0xFE and 6) or 0
+ return
+ (u<0x80 and 1) or
+ (u<0xE0 and 2) or
+ (u<0xF0 and 3) or
+ (u<0xF8 and 4) or
+ (u<0xFC and 5) or
+ (u<0xFE and 6) or 0
end
if bit32 then
- local extract=bit32.extract
- local char=string.char
- function utf.toutf32string(n)
- if n<=0xFF then
- return
- char(n).."\000\000\000"
- elseif n<=0xFFFF then
- return
- char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
- elseif n<=0xFFFFFF then
- return
- char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
- else
- return
- char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
- end
- end
+ local extract=bit32.extract
+ local char=string.char
+ function utf.toutf32string(n)
+ if n<=0xFF then
+ return
+ char(n).."\000\000\000"
+ elseif n<=0xFFFF then
+ return
+ char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
+ elseif n<=0xFFFFFF then
+ return
+ char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
+ else
+ return
+ char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
+ end
+ end
end
local len=utf.len
local rep=rep
function string.utfpadd(s,n)
- if n and n~=0 then
- local l=len(s)
- if n>0 then
- local d=n-l
- if d>0 then
- return rep(c or " ",d)..s
- end
- else
- local d=- n-l
- if d>0 then
- return s..rep(c or " ",d)
- end
- end
+ if n and n~=0 then
+ local l=len(s)
+ if n>0 then
+ local d=n-l
+ if d>0 then
+ return rep(c or " ",d)..s
+ end
+ else
+ local d=- n-l
+ if d>0 then
+ return s..rep(c or " ",d)
+ end
end
- return s
+ end
+ return s
end
do
- local utfcharacters=utf.characters or string.utfcharacters
- local utfchar=utf.char or string.utfcharacter
- lpeg.UP=P
- if utfcharacters then
- function lpeg.US(str)
- local p=P(false)
- for uc in utfcharacters(str) do
- p=p+P(uc)
- end
- return p
- end
- else
- function lpeg.US(str)
- local p=P(false)
- local f=function(uc)
- p=p+P(uc)
- end
- lpegmatch((p_utf8char/f)^0,str)
- return p
- end
+ local utfcharacters=utf.characters or string.utfcharacters
+ local utfchar=utf.char or string.utfcharacter
+ lpeg.UP=P
+ if utfcharacters then
+ function lpeg.US(str)
+ local p=P(false)
+ for uc in utfcharacters(str) do
+ p=p+P(uc)
+ end
+ return p
end
- local range=p_utf8byte*p_utf8byte+Cc(false)
- function lpeg.UR(str,more)
- local first,last
- if type(str)=="number" then
- first=str
- last=more or first
- else
- first,last=lpegmatch(range,str)
- if not last then
- return P(str)
- end
- end
- if first==last then
- return P(str)
- end
- if not utfchar then
- utfchar=utf.char
- end
- if utfchar and (last-first<8) then
- local p=P(false)
- for i=first,last do
- p=p+P(utfchar(i))
- end
- return p
- else
- local f=function(b)
- return b>=first and b<=last
- end
- return p_utf8byte/f
- end
+ else
+ function lpeg.US(str)
+ local p=P(false)
+ local f=function(uc)
+ p=p+P(uc)
+ end
+ lpegmatch((p_utf8char/f)^0,str)
+ return p
+ end
+ end
+ local range=p_utf8byte*p_utf8byte+Cc(false)
+ function lpeg.UR(str,more)
+ local first,last
+ if type(str)=="number" then
+ first=str
+ last=more or first
+ else
+ first,last=lpegmatch(range,str)
+ if not last then
+ return P(str)
+ end
+ end
+ if first==last then
+ return P(str)
+ end
+ if not utfchar then
+ utfchar=utf.char
+ end
+ if utfchar and (last-first<8) then
+ local p=P(false)
+ for i=first,last do
+ p=p+P(utfchar(i))
+ end
+ return p
+ else
+ local f=function(b)
+ return b>=first and b<=last
+ end
+ return p_utf8byte/f
end
+ end
end
@@ -6215,93 +6215,93 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-math"] = package.loaded["l-math"] or true
--- original size: 2555, stripped down to: 1900
+-- original size: 2555, stripped down to: 1831
if not modules then modules={} end modules ['l-math']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not math.ceiling then
- math.ceiling=math.ceil
+ math.ceiling=math.ceil
end
if not math.round then
- local floor=math.floor
- function math.round(x) return floor(x+0.5) end
+ local floor=math.floor
+ function math.round(x) return floor(x+0.5) end
end
if not math.div then
- local floor=math.floor
- function math.div(n,m) return floor(n/m) end
+ local floor=math.floor
+ function math.div(n,m) return floor(n/m) end
end
if not math.mod then
- function math.mod(n,m) return n%m end
+ function math.mod(n,m) return n%m end
end
if not math.sind then
- local sin,cos,tan=math.sin,math.cos,math.tan
- local pipi=2*math.pi/360
- function math.sind(d) return sin(d*pipi) end
- function math.cosd(d) return cos(d*pipi) end
- function math.tand(d) return tan(d*pipi) end
+ local sin,cos,tan=math.sin,math.cos,math.tan
+ local pipi=2*math.pi/360
+ function math.sind(d) return sin(d*pipi) end
+ function math.cosd(d) return cos(d*pipi) end
+ function math.tand(d) return tan(d*pipi) end
end
if not math.odd then
- function math.odd (n) return n%2~=0 end
- function math.even(n) return n%2==0 end
+ function math.odd (n) return n%2~=0 end
+ function math.even(n) return n%2==0 end
end
if not math.cosh then
- local exp=math.exp
- function math.cosh(x)
- local xx=exp(x)
- return (xx+1/xx)/2
- end
- function math.sinh(x)
- local xx=exp(x)
- return (xx-1/xx)/2
- end
- function math.tanh(x)
- local xx=exp(x)
- return (xx-1/xx)/(xx+1/xx)
- end
+ local exp=math.exp
+ function math.cosh(x)
+ local xx=exp(x)
+ return (xx+1/xx)/2
+ end
+ function math.sinh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/2
+ end
+ function math.tanh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/(xx+1/xx)
+ end
end
if not math.pow then
- function math.pow(x,y)
- return x^y
- end
+ function math.pow(x,y)
+ return x^y
+ end
end
if not math.atan2 then
- math.atan2=math.atan
+ math.atan2=math.atan
end
if not math.ldexp then
- function math.ldexp(x,e)
- return x*2.0^e
- end
+ function math.ldexp(x,e)
+ return x*2.0^e
+ end
end
if not math.log10 then
- local log=math.log
- function math.log10(x)
- return log(x,10)
- end
+ local log=math.log
+ function math.log10(x)
+ return log(x,10)
+ end
end
if not math.type then
- function math.type()
- return "float"
- end
+ function math.type()
+ return "float"
+ end
end
if not math.tointeger then
- math.mininteger=-0x4FFFFFFFFFFF
- math.maxinteger=0x4FFFFFFFFFFF
- local floor=math.floor
- function math.tointeger(n)
- local f=floor(n)
- return f==n and f or nil
- end
+ math.mininteger=-0x4FFFFFFFFFFF
+ math.maxinteger=0x4FFFFFFFFFFF
+ local floor=math.floor
+ function math.tointeger(n)
+ local f=floor(n)
+ return f==n and f or nil
+ end
end
if not math.ult then
- local floor=math.floor
- function math.tointeger(m,n)
- return floor(m)<floor(n)
- end
+ local floor=math.floor
+ function math.tointeger(m,n)
+ return floor(m)<floor(n)
+ end
end
@@ -6311,14 +6311,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 43481, stripped down to: 23845
+-- original size: 43481, stripped down to: 23049
if not modules then modules={} end modules ['util-str']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.strings=utilities.strings or {}
@@ -6334,17 +6334,17 @@ local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
local loadstripped=nil
local oldfashioned=LUAVERSION<5.2
if oldfashioned then
- loadstripped=function(str,shortcuts)
- return load(str)
- end
+ loadstripped=function(str,shortcuts)
+ return load(str)
+ end
else
- loadstripped=function(str,shortcuts)
- if shortcuts then
- return load(dump(load(str),true),nil,nil,shortcuts)
- else
- return load(dump(load(str),true))
- end
+ loadstripped=function(str,shortcuts)
+ if shortcuts then
+ return load(dump(load(str),true),nil,nil,shortcuts)
+ else
+ return load(dump(load(str),true))
end
+ end
end
if not number then number={} end
local stripzero=patterns.stripzero
@@ -6362,32 +6362,32 @@ local period=patterns.period
local ptf=1/65536
local bpf=(7200/7227)/65536
local function points(n)
- if n==0 then
- return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
- return "0pt"
- end
- n=n*ptf
- if n%1==0 then
- return format("%ipt",n)
- end
- return lpegmatch(stripzeros,format("%.5fpt",n))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*ptf
+ if n%1==0 then
+ return format("%ipt",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fpt",n))
end
local function basepoints(n)
- if n==0 then
- return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
- return "0pt"
- end
- n=n*bpf
- if n%1==0 then
- return format("%ibp",n)
- end
- return lpegmatch(stripzeros,format("%.5fbp",n))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*bpf
+ if n%1==0 then
+ return format("%ibp",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fbp",n))
end
number.points=points
number.basepoints=basepoints
@@ -6399,65 +6399,65 @@ local trailing=(anyrubish^1*endofstring)/""
local redundant=rubish^3/"\n"
local pattern=Cs(leading*(trailing+redundant+stripped+anything)^0)
function strings.collapsecrlf(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local repeaters={}
function strings.newrepeater(str,offset)
- offset=offset or 0
- local s=repeaters[str]
- if not s then
- s={}
- repeaters[str]=s
- end
- local t=s[offset]
- if t then
- return t
- end
- t={}
- setmetatable(t,{ __index=function(t,k)
- if not k then
- return ""
- end
- local n=k+offset
- local s=n>0 and rep(str,n) or ""
- t[k]=s
- return s
- end })
- s[offset]=t
+ offset=offset or 0
+ local s=repeaters[str]
+ if not s then
+ s={}
+ repeaters[str]=s
+ end
+ local t=s[offset]
+ if t then
return t
+ end
+ t={}
+ setmetatable(t,{ __index=function(t,k)
+ if not k then
+ return ""
+ end
+ local n=k+offset
+ local s=n>0 and rep(str,n) or ""
+ t[k]=s
+ return s
+ end })
+ s[offset]=t
+ return t
end
local extra,tab,start=0,0,4,0
local nspaces=strings.newrepeater(" ")
string.nspaces=nspaces
local pattern=Carg(1)/function(t)
- extra,tab,start=0,t or 7,1
- end*Cs((
+ extra,tab,start=0,t or 7,1
+ end*Cs((
Cp()*patterns.tab/function(position)
- local current=(position-start+1)+extra
- local spaces=tab-(current-1)%tab
- if spaces>0 then
- extra=extra+spaces-1
- return nspaces[spaces]
- else
- return ""
- end
+ local current=(position-start+1)+extra
+ local spaces=tab-(current-1)%tab
+ if spaces>0 then
+ extra=extra+spaces-1
+ return nspaces[spaces]
+ else
+ return ""
+ end
end+newline*Cp()/function(position)
- extra,start=0,position
+ extra,start=0,position
end+anything
- )^1)
+ )^1)
function strings.tabtospace(str,tab)
- return lpegmatch(pattern,str,1,tab or 7)
+ return lpegmatch(pattern,str,1,tab or 7)
end
function string.utfpadding(s,n)
- if not n or n==0 then
- return ""
- end
- local l=utflen(s)
- if n>0 then
- return nspaces[n-l]
- else
- return nspaces[-n-l]
- end
+ if not n or n==0 then
+ return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
end
local optionalspace=spacer^0
local nospace=optionalspace/""
@@ -6475,130 +6475,130 @@ local notrailing=noleading*endofstring
local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 )
local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 )
local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 )
-local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
+local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
local p_retain_normal=Cs ((normalline+normalempty )^0 )
local p_retain_collapse=Cs ((normalline+doubleempty )^0 )
local p_retain_noempty=Cs ((normalline+singleempty )^0 )
local striplinepatterns={
- ["prune"]=p_prune_normal,
- ["prune and collapse"]=p_prune_collapse,
- ["prune and no empty"]=p_prune_noempty,
- ["prune and to space"]=p_prune_intospace,
- ["retain"]=p_retain_normal,
- ["retain and collapse"]=p_retain_collapse,
- ["retain and no empty"]=p_retain_noempty,
- ["collapse"]=patterns.collapser,
+ ["prune"]=p_prune_normal,
+ ["prune and collapse"]=p_prune_collapse,
+ ["prune and no empty"]=p_prune_noempty,
+ ["prune and to space"]=p_prune_intospace,
+ ["retain"]=p_retain_normal,
+ ["retain and collapse"]=p_retain_collapse,
+ ["retain and no empty"]=p_retain_noempty,
+ ["collapse"]=patterns.collapser,
}
setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end })
strings.striplinepatterns=striplinepatterns
function strings.striplines(str,how)
- return str and lpegmatch(striplinepatterns[how],str) or str
+ return str and lpegmatch(striplinepatterns[how],str) or str
end
function strings.collapse(str)
- return str and lpegmatch(p_prune_intospace,str) or str
+ return str and lpegmatch(p_prune_intospace,str) or str
end
strings.striplong=strings.striplines
function strings.nice(str)
- str=gsub(str,"[:%-+_]+"," ")
- return str
+ str=gsub(str,"[:%-+_]+"," ")
+ return str
end
local n=0
local sequenced=table.sequenced
function string.autodouble(s,sep)
- if s==nil then
- return '""'
- end
- local t=type(s)
- if t=="number" then
- return tostring(s)
- end
- if t=="table" then
- return ('"'..sequenced(s,sep or ",")..'"')
- end
- return ('"'..tostring(s)..'"')
+ if s==nil then
+ return '""'
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ('"'..sequenced(s,sep or ",")..'"')
+ end
+ return ('"'..tostring(s)..'"')
end
function string.autosingle(s,sep)
- if s==nil then
- return "''"
- end
- local t=type(s)
- if t=="number" then
- return tostring(s)
- end
- if t=="table" then
- return ("'"..sequenced(s,sep or ",").."'")
- end
- return ("'"..tostring(s).."'")
+ if s==nil then
+ return "''"
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ("'"..sequenced(s,sep or ",").."'")
+ end
+ return ("'"..tostring(s).."'")
end
local tracedchars={ [0]=
- "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
- "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
- "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
- "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
- "[space]",
+ "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
+ "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
+ "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
+ "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
+ "[space]",
}
string.tracedchars=tracedchars
strings.tracers=tracedchars
function string.tracedchar(b)
- if type(b)=="number" then
- return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
- else
- local c=utfbyte(b)
- return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
- end
+ if type(b)=="number" then
+ return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
+ else
+ local c=utfbyte(b)
+ return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
+ end
end
function number.signed(i)
- if i>0 then
- return "+",i
- else
- return "-",-i
- end
+ if i>0 then
+ return "+",i
+ else
+ return "-",-i
+ end
end
local two=digit*digit
local three=two*digit
local prefix=(Carg(1)*three)^1
local splitter=Cs (
- (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
+ (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
)
local splitter3=Cs (
- three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
+ three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
)
patterns.formattednumber=splitter
function number.formatted(n,sep1,sep2)
- if sep1==false then
- if type(n)=="number" then
- n=tostring(n)
- end
- return lpegmatch(splitter3,n,1,sep2 or ".")
+ if sep1==false then
+ if type(n)=="number" then
+ n=tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n)=="number" then
+ n=format("%0.2f",n)
+ end
+ if sep1==true then
+ return lpegmatch(splitter,n,1,".",",")
+ elseif sep1=="." then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
+ elseif sep1=="," then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
else
- if type(n)=="number" then
- n=format("%0.2f",n)
- end
- if sep1==true then
- return lpegmatch(splitter,n,1,".",",")
- elseif sep1=="." then
- return lpegmatch(splitter,n,1,sep1,sep2 or ",")
- elseif sep1=="," then
- return lpegmatch(splitter,n,1,sep1,sep2 or ".")
- else
- return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
- end
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
end
+ end
end
local p=Cs(
- P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
- )
+ P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
+ )
function number.compactfloat(n,fmt)
- if n==0 then
- return "0"
- elseif n==1 then
- return "1"
- end
- n=lpegmatch(p,format(fmt or "%0.3f",n))
- if n=="." or n=="" or n=="-" then
- return "0"
- end
- return n
+ if n==0 then
+ return "0"
+ elseif n==1 then
+ return "1"
+ end
+ n=lpegmatch(p,format(fmt or "%0.3f",n))
+ if n=="." or n=="" or n=="-" then
+ return "0"
+ end
+ return n
end
local zero=P("0")^1/""
local plus=P("+")/""
@@ -6609,41 +6609,41 @@ local exponent=(S("eE")*(plus+Cs((minus*zero^0*endofstring)/"")+minus)*zero^0*(e
local pattern_a=Cs(minus^0*digit^1*(separator/""*trailing+separator*(trailing+digit)^0)*exponent)
local pattern_b=Cs((exponent+anything)^0)
function number.sparseexponent(f,n)
- if not n then
- n=f
- f="%e"
- end
- local tn=type(n)
- if tn=="string" then
- local m=tonumber(n)
- if m then
- return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
- end
- elseif tn=="number" then
- return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ if not n then
+ n=f
+ f="%e"
+ end
+ local tn=type(n)
+ if tn=="string" then
+ local m=tonumber(n)
+ if m then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
end
- return tostring(n)
+ elseif tn=="number" then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ end
+ return tostring(n)
end
local hf={}
local hs={}
setmetatable(hf,{ __index=function(t,k)
- local v="%."..k.."f"
- t[k]=v
- return v
+ local v="%."..k.."f"
+ t[k]=v
+ return v
end } )
setmetatable(hs,{ __index=function(t,k)
- local v="%"..k.."s"
- t[k]=v
- return v
+ local v="%"..k.."s"
+ t[k]=v
+ return v
end } )
function number.formattedfloat(n,b,a)
- local s=format(hf[a],n)
- local l=(b or 0)+(a or 0)+1
- if #s<l then
- return format(hs[l],s)
- else
- return s
- end
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
end
local template=[[
%s
@@ -6652,7 +6652,7 @@ return function(%s) return %s end
]]
local preamble,environment="",{}
if oldfashioned then
- preamble=[[
+ preamble=[[
local lpeg=lpeg
local type=type
local tostring=tostring
@@ -6678,339 +6678,339 @@ local stripzero=lpeg.patterns.stripzero
local stripzeros=lpeg.patterns.stripzeros
]]
else
- environment={
- global=global or _G,
- lpeg=lpeg,
- type=type,
- tostring=tostring,
- tonumber=tonumber,
- format=string.format,
- concat=table.concat,
- signed=number.signed,
- points=number.points,
- basepoints=number.basepoints,
- utfchar=utf.char,
- utfbyte=utf.byte,
- lpegmatch=lpeg.match,
- nspaces=string.nspaces,
- utfpadding=string.utfpadding,
- tracedchar=string.tracedchar,
- autosingle=string.autosingle,
- autodouble=string.autodouble,
- sequenced=table.sequenced,
- formattednumber=number.formatted,
- sparseexponent=number.sparseexponent,
- formattedfloat=number.formattedfloat,
- stripzero=lpeg.patterns.stripzero,
- stripzeros=lpeg.patterns.stripzeros,
- }
+ environment={
+ global=global or _G,
+ lpeg=lpeg,
+ type=type,
+ tostring=tostring,
+ tonumber=tonumber,
+ format=string.format,
+ concat=table.concat,
+ signed=number.signed,
+ points=number.points,
+ basepoints=number.basepoints,
+ utfchar=utf.char,
+ utfbyte=utf.byte,
+ lpegmatch=lpeg.match,
+ nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
+ tracedchar=string.tracedchar,
+ autosingle=string.autosingle,
+ autodouble=string.autodouble,
+ sequenced=table.sequenced,
+ formattednumber=number.formatted,
+ sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat,
+ stripzero=lpeg.patterns.stripzero,
+ stripzeros=lpeg.patterns.stripzeros,
+ }
end
local arguments={ "a1" }
setmetatable(arguments,{ __index=function(t,k)
- local v=t[k-1]..",a"..k
- t[k]=v
- return v
- end
+ local v=t[k-1]..",a"..k
+ t[k]=v
+ return v
+ end
})
local prefix_any=C((sign+space+period+digit)^0)
local prefix_sub=(C((sign+digit)^0)+Cc(0))*period*(C((sign+digit)^0)+Cc(0))
local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
local format_s=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',a%s)",f,n)
- else
- return format("(a%s or '')",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("(a%s or '')",n)
+ end
end
local format_S=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',tostring(a%s))",f,n)
- else
- return format("tostring(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',tostring(a%s))",f,n)
+ else
+ return format("tostring(a%s)",n)
+ end
end
local format_right=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
- return format("(a%s or '')",n)
- elseif f>0 then
- return format("utfpadding(a%s,%i)..a%s",n,f,n)
- else
- return format("a%s..utfpadding(a%s,%i)",n,n,f)
- end
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ elseif f>0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
end
local format_left=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
- return format("(a%s or '')",n)
- end
- if f<0 then
- return format("utfpadding(a%s,%i)..a%s",n,-f,n)
- else
- return format("a%s..utfpadding(a%s,%i)",n,n,-f)
- end
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ end
+ if f<0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
end
local format_q=function()
- n=n+1
- return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
end
local format_Q=function()
- n=n+1
- return format("format('%%q',tostring(a%s))",n)
+ n=n+1
+ return format("format('%%q',tostring(a%s))",n)
end
local format_i=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%si',a%s)",f,n)
- else
- return format("format('%%i',a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%si',a%s)",f,n)
+ else
+ return format("format('%%i',a%s)",n)
+ end
end
local format_d=format_i
local format_I=function(f)
- n=n+1
- return format("format('%%s%%%si',signed(a%s))",f,n)
+ n=n+1
+ return format("format('%%s%%%si',signed(a%s))",f,n)
end
local format_f=function(f)
- n=n+1
- return format("format('%%%sf',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sf',a%s)",f,n)
end
local format_F=function(f)
- n=n+1
- if not f or f=="" then
- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
- else
- return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
- end
+ n=n+1
+ if not f or f=="" then
+ return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
+ else
+ return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
+ end
end
local format_k=function(b,a)
- n=n+1
- return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
+ n=n+1
+ return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
end
local format_g=function(f)
- n=n+1
- return format("format('%%%sg',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sg',a%s)",f,n)
end
local format_G=function(f)
- n=n+1
- return format("format('%%%sG',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sG',a%s)",f,n)
end
local format_e=function(f)
- n=n+1
- return format("format('%%%se',a%s)",f,n)
+ n=n+1
+ return format("format('%%%se',a%s)",f,n)
end
local format_E=function(f)
- n=n+1
- return format("format('%%%sE',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sE',a%s)",f,n)
end
local format_j=function(f)
- n=n+1
- return format("sparseexponent('%%%se',a%s)",f,n)
+ n=n+1
+ return format("sparseexponent('%%%se',a%s)",f,n)
end
local format_J=function(f)
- n=n+1
- return format("sparseexponent('%%%sE',a%s)",f,n)
+ n=n+1
+ return format("sparseexponent('%%%sE',a%s)",f,n)
end
local format_x=function(f)
- n=n+1
- return format("format('%%%sx',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sx',a%s)",f,n)
end
local format_X=function(f)
- n=n+1
- return format("format('%%%sX',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sX',a%s)",f,n)
end
local format_o=function(f)
- n=n+1
- return format("format('%%%so',a%s)",f,n)
+ n=n+1
+ return format("format('%%%so',a%s)",f,n)
end
local format_c=function()
- n=n+1
- return format("utfchar(a%s)",n)
+ n=n+1
+ return format("utfchar(a%s)",n)
end
local format_C=function()
- n=n+1
- return format("tracedchar(a%s)",n)
+ n=n+1
+ return format("tracedchar(a%s)",n)
end
local format_r=function(f)
- n=n+1
- return format("format('%%%s.0f',a%s)",f,n)
+ n=n+1
+ return format("format('%%%s.0f',a%s)",f,n)
end
local format_h=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_H=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_u=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_U=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_p=function()
- n=n+1
- return format("points(a%s)",n)
+ n=n+1
+ return format("points(a%s)",n)
end
local format_b=function()
- n=n+1
- return format("basepoints(a%s)",n)
+ n=n+1
+ return format("basepoints(a%s)",n)
end
local format_t=function(f)
- n=n+1
- if f and f~="" then
- return format("concat(a%s,%q)",n,f)
- else
- return format("concat(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("concat(a%s,%q)",n,f)
+ else
+ return format("concat(a%s)",n)
+ end
end
local format_T=function(f)
- n=n+1
- if f and f~="" then
- return format("sequenced(a%s,%q)",n,f)
- else
- return format("sequenced(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("sequenced(a%s,%q)",n,f)
+ else
+ return format("sequenced(a%s)",n)
+ end
end
local format_l=function()
- n=n+1
- return format("(a%s and 'true' or 'false')",n)
+ n=n+1
+ return format("(a%s and 'true' or 'false')",n)
end
local format_L=function()
- n=n+1
- return format("(a%s and 'TRUE' or 'FALSE')",n)
+ n=n+1
+ return format("(a%s and 'TRUE' or 'FALSE')",n)
end
local format_n=function()
- n=n+1
- return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+ n=n+1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
end
local format_N=function(f)
- n=n+1
- if not f or f=="" then
- f=".9"
- end
- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+ n=n+1
+ if not f or f=="" then
+ f=".9"
+ end
+ return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
end
local format_a=function(f)
- n=n+1
- if f and f~="" then
- return format("autosingle(a%s,%q)",n,f)
- else
- return format("autosingle(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("autosingle(a%s,%q)",n,f)
+ else
+ return format("autosingle(a%s)",n)
+ end
end
local format_A=function(f)
- n=n+1
- if f and f~="" then
- return format("autodouble(a%s,%q)",n,f)
- else
- return format("autodouble(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("autodouble(a%s,%q)",n,f)
+ else
+ return format("autodouble(a%s)",n)
+ end
end
local format_w=function(f)
- n=n+1
- f=tonumber(f)
- if f then
- return format("nspaces[%s+a%s]",f,n)
- else
- return format("nspaces[a%s]",n)
- end
+ n=n+1
+ f=tonumber(f)
+ if f then
+ return format("nspaces[%s+a%s]",f,n)
+ else
+ return format("nspaces[a%s]",n)
+ end
end
local format_W=function(f)
- return format("nspaces[%s]",tonumber(f) or 0)
+ return format("nspaces[%s]",tonumber(f) or 0)
end
local format_m=function(f)
- n=n+1
- if not f or f=="" then
- f=","
- end
- if f=="0" then
- return format([[formattednumber(a%s,false)]],n)
- else
- return format([[formattednumber(a%s,%q,".")]],n,f)
- end
+ n=n+1
+ if not f or f=="" then
+ f=","
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,".")]],n,f)
+ end
end
local format_M=function(f)
- n=n+1
- if not f or f=="" then
- f="."
- end
- if f=="0" then
- return format([[formattednumber(a%s,false)]],n)
- else
- return format([[formattednumber(a%s,%q,",")]],n,f)
- end
+ n=n+1
+ if not f or f=="" then
+ f="."
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,",")]],n,f)
+ end
end
local format_z=function(f)
- n=n+(tonumber(f) or 1)
- return "''"
+ n=n+(tonumber(f) or 1)
+ return "''"
end
local format_rest=function(s)
- return format("%q",s)
+ return format("%q",s)
end
local format_extension=function(extensions,f,name)
- local extension=extensions[name] or "tostring(%s)"
- local f=tonumber(f) or 1
- local w=find(extension,"%.%.%.")
- if f==0 then
- if w then
- extension=gsub(extension,"%.%.%.","")
- end
- return extension
- elseif f==1 then
- if w then
- extension=gsub(extension,"%.%.%.","%%s")
- end
- n=n+1
- local a="a"..n
- return format(extension,a,a)
- elseif f<0 then
- local a="a"..(n+f+1)
- return format(extension,a,a)
- else
- if w then
- extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
- end
- local t={}
- for i=1,f do
- n=n+1
- t[i]="a"..n
- end
- return format(extension,unpack(t))
+ local extension=extensions[name] or "tostring(%s)"
+ local f=tonumber(f) or 1
+ local w=find(extension,"%.%.%.")
+ if f==0 then
+ if w then
+ extension=gsub(extension,"%.%.%.","")
+ end
+ return extension
+ elseif f==1 then
+ if w then
+ extension=gsub(extension,"%.%.%.","%%s")
+ end
+ n=n+1
+ local a="a"..n
+ return format(extension,a,a)
+ elseif f<0 then
+ local a="a"..(n+f+1)
+ return format(extension,a,a)
+ else
+ if w then
+ extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
end
+ local t={}
+ for i=1,f do
+ n=n+1
+ t[i]="a"..n
+ end
+ return format(extension,unpack(t))
+ end
end
local builder=Cs { "start",
- start=(
- (
- P("%")/""*(
- V("!")
+ start=(
+ (
+ P("%")/""*(
+ V("!")
+V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
+V("c")+V("C")+V("S")
+V("Q")
@@ -7026,119 +7026,119 @@ local builder=Cs { "start",
+V("z")
+V(">")
+V("<")
- )+V("*")
- )*(endofstring+Carg(1))
- )^0,
- ["s"]=(prefix_any*P("s"))/format_s,
- ["q"]=(prefix_any*P("q"))/format_q,
- ["i"]=(prefix_any*P("i"))/format_i,
- ["d"]=(prefix_any*P("d"))/format_d,
- ["f"]=(prefix_any*P("f"))/format_f,
- ["F"]=(prefix_any*P("F"))/format_F,
- ["g"]=(prefix_any*P("g"))/format_g,
- ["G"]=(prefix_any*P("G"))/format_G,
- ["e"]=(prefix_any*P("e"))/format_e,
- ["E"]=(prefix_any*P("E"))/format_E,
- ["x"]=(prefix_any*P("x"))/format_x,
- ["X"]=(prefix_any*P("X"))/format_X,
- ["o"]=(prefix_any*P("o"))/format_o,
- ["S"]=(prefix_any*P("S"))/format_S,
- ["Q"]=(prefix_any*P("Q"))/format_Q,
- ["n"]=(prefix_any*P("n"))/format_n,
- ["N"]=(prefix_any*P("N"))/format_N,
- ["k"]=(prefix_sub*P("k"))/format_k,
- ["c"]=(prefix_any*P("c"))/format_c,
- ["C"]=(prefix_any*P("C"))/format_C,
- ["r"]=(prefix_any*P("r"))/format_r,
- ["h"]=(prefix_any*P("h"))/format_h,
- ["H"]=(prefix_any*P("H"))/format_H,
- ["u"]=(prefix_any*P("u"))/format_u,
- ["U"]=(prefix_any*P("U"))/format_U,
- ["p"]=(prefix_any*P("p"))/format_p,
- ["b"]=(prefix_any*P("b"))/format_b,
- ["t"]=(prefix_tab*P("t"))/format_t,
- ["T"]=(prefix_tab*P("T"))/format_T,
- ["l"]=(prefix_any*P("l"))/format_l,
- ["L"]=(prefix_any*P("L"))/format_L,
- ["I"]=(prefix_any*P("I"))/format_I,
- ["w"]=(prefix_any*P("w"))/format_w,
- ["W"]=(prefix_any*P("W"))/format_W,
- ["j"]=(prefix_any*P("j"))/format_j,
- ["J"]=(prefix_any*P("J"))/format_J,
- ["m"]=(prefix_any*P("m"))/format_m,
- ["M"]=(prefix_any*P("M"))/format_M,
- ["z"]=(prefix_any*P("z"))/format_z,
- ["a"]=(prefix_any*P("a"))/format_a,
- ["A"]=(prefix_any*P("A"))/format_A,
- ["<"]=(prefix_any*P("<"))/format_left,
- [">"]=(prefix_any*P(">"))/format_right,
- ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
- ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
- ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
+ )+V("*")
+ )*(endofstring+Carg(1))
+ )^0,
+ ["s"]=(prefix_any*P("s"))/format_s,
+ ["q"]=(prefix_any*P("q"))/format_q,
+ ["i"]=(prefix_any*P("i"))/format_i,
+ ["d"]=(prefix_any*P("d"))/format_d,
+ ["f"]=(prefix_any*P("f"))/format_f,
+ ["F"]=(prefix_any*P("F"))/format_F,
+ ["g"]=(prefix_any*P("g"))/format_g,
+ ["G"]=(prefix_any*P("G"))/format_G,
+ ["e"]=(prefix_any*P("e"))/format_e,
+ ["E"]=(prefix_any*P("E"))/format_E,
+ ["x"]=(prefix_any*P("x"))/format_x,
+ ["X"]=(prefix_any*P("X"))/format_X,
+ ["o"]=(prefix_any*P("o"))/format_o,
+ ["S"]=(prefix_any*P("S"))/format_S,
+ ["Q"]=(prefix_any*P("Q"))/format_Q,
+ ["n"]=(prefix_any*P("n"))/format_n,
+ ["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
+ ["c"]=(prefix_any*P("c"))/format_c,
+ ["C"]=(prefix_any*P("C"))/format_C,
+ ["r"]=(prefix_any*P("r"))/format_r,
+ ["h"]=(prefix_any*P("h"))/format_h,
+ ["H"]=(prefix_any*P("H"))/format_H,
+ ["u"]=(prefix_any*P("u"))/format_u,
+ ["U"]=(prefix_any*P("U"))/format_U,
+ ["p"]=(prefix_any*P("p"))/format_p,
+ ["b"]=(prefix_any*P("b"))/format_b,
+ ["t"]=(prefix_tab*P("t"))/format_t,
+ ["T"]=(prefix_tab*P("T"))/format_T,
+ ["l"]=(prefix_any*P("l"))/format_l,
+ ["L"]=(prefix_any*P("L"))/format_L,
+ ["I"]=(prefix_any*P("I"))/format_I,
+ ["w"]=(prefix_any*P("w"))/format_w,
+ ["W"]=(prefix_any*P("W"))/format_W,
+ ["j"]=(prefix_any*P("j"))/format_j,
+ ["J"]=(prefix_any*P("J"))/format_J,
+ ["m"]=(prefix_any*P("m"))/format_m,
+ ["M"]=(prefix_any*P("M"))/format_M,
+ ["z"]=(prefix_any*P("z"))/format_z,
+ ["a"]=(prefix_any*P("a"))/format_a,
+ ["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
+ ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
+ ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
+ ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
}
local xx=setmetatable({},{ __index=function(t,k) local v=format("%02x",k) t[k]=v return v end })
local XX=setmetatable({},{ __index=function(t,k) local v=format("%02X",k) t[k]=v return v end })
local preset={
- ["%02x"]=function(n) return xx[n] end,
- ["%02X"]=function(n) return XX[n] end,
+ ["%02x"]=function(n) return xx[n] end,
+ ["%02X"]=function(n) return XX[n] end,
}
local direct=P("%")*(sign+space+period+digit)^0*S("sqidfgGeExXo")*endofstring/[[local format = string.format return function(str) return format("%0",str) end]]
local function make(t,str)
- local f=preset[str]
- if f then
- return f
- end
- local p=lpegmatch(direct,str)
- if p then
- f=loadstripped(p)()
+ local f=preset[str]
+ if f then
+ return f
+ end
+ local p=lpegmatch(direct,str)
+ if p then
+ f=loadstripped(p)()
+ else
+ n=0
+ p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
+ if n>0 then
+ p=format(template,preamble,t._preamble_,arguments[n],p)
+ f=loadstripped(p,t._environment_)()
else
- n=0
- p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
- if n>0 then
- p=format(template,preamble,t._preamble_,arguments[n],p)
- f=loadstripped(p,t._environment_)()
- else
- f=function() return str end
- end
+ f=function() return str end
end
- t[str]=f
- return f
+ end
+ t[str]=f
+ return f
end
local function use(t,fmt,...)
- return t[fmt](...)
+ return t[fmt](...)
end
strings.formatters={}
if oldfashioned then
- function strings.formatters.new(noconcat)
- local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} }
- setmetatable(t,{ __index=make,__call=use })
- return t
- end
+ function strings.formatters.new(noconcat)
+ local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
+ end
else
- function strings.formatters.new(noconcat)
- local e={}
- for k,v in next,environment do
- e[k]=v
- end
- local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e }
- setmetatable(t,{ __index=make,__call=use })
- return t
+ function strings.formatters.new(noconcat)
+ local e={}
+ for k,v in next,environment do
+ e[k]=v
end
+ local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
+ end
end
local formatters=strings.formatters.new()
string.formatters=formatters
string.formatter=function(str,...) return formatters[str](...) end
local function add(t,name,template,preamble)
- if type(t)=="table" and t._type_=="formatter" then
- t._extensions_[name]=template or "%s"
- if type(preamble)=="string" then
- t._preamble_=preamble.."\n"..t._preamble_
- elseif type(preamble)=="table" then
- for k,v in next,preamble do
- t._environment_[k]=v
- end
- end
+ if type(t)=="table" and t._type_=="formatter" then
+ t._extensions_[name]=template or "%s"
+ if type(preamble)=="string" then
+ t._preamble_=preamble.."\n"..t._preamble_
+ elseif type(preamble)=="table" then
+ for k,v in next,preamble do
+ t._environment_[k]=v
+ end
end
+ end
end
strings.formatters.add=add
patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+anything)^0)
@@ -7146,44 +7146,44 @@ patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+anything)^0)
patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0)
patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"'))
if oldfashioned then
- add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
- add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
- add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
+ add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
+ add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
+ add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
else
- add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape })
- add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
- add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
+ add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape })
+ add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
+ add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
end
local dquote=patterns.dquote
local equote=patterns.escaped+dquote/'\\"'+1
local cquote=Cc('"')
-local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
+local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
+Cs(cquote*(equote-space)^0*space*equote^0*cquote)
function string.optionalquoted(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local pattern=Cs((newline/(os.newline or "\r")+1)^0)
function string.replacenewlines(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function strings.newcollector()
- local result,r={},0
- return
- function(fmt,str,...)
- r=r+1
- result[r]=str==nil and fmt or formatters[fmt](str,...)
- end,
- function(connector)
- if result then
- local str=concat(result,connector)
- result,r={},0
- return str
- end
- end
+ local result,r={},0
+ return
+ function(fmt,str,...)
+ r=r+1
+ result[r]=str==nil and fmt or formatters[fmt](str,...)
+ end,
+ function(connector)
+ if result then
+ local str=concat(result,connector)
+ result,r={},0
+ return str
+ end
+ end
end
local f_16_16=formatters["%0.5N"]
function number.to16dot16(n)
- return f_16_16(n/65536.0)
+ return f_16_16(n/65536.0)
end
@@ -7193,14 +7193,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 28756, stripped down to: 17693
+-- original size: 28756, stripped down to: 16104
if not modules then modules={} end modules ['util-tab']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.tables=utilities.tables or {}
@@ -7215,219 +7215,219 @@ local formatters=string.formatters
local utftoeight=utf.toeight
local splitter=lpeg.tsplitat(".")
function utilities.tables.definetable(target,nofirst,nolast)
- local composed,t=nil,{}
- local snippets=lpegmatch(splitter,target)
- for i=1,#snippets-(nolast and 1 or 0) do
- local name=snippets[i]
- if composed then
- composed=composed.."."..name
- t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
- else
- composed=name
- if not nofirst then
- t[#t+1]=formatters["%s = %s or { }"](composed,composed)
- end
- end
- end
+ local composed,t=nil,{}
+ local snippets=lpegmatch(splitter,target)
+ for i=1,#snippets-(nolast and 1 or 0) do
+ local name=snippets[i]
if composed then
- if nolast then
- composed=composed.."."..snippets[#snippets]
- end
- return concat(t,"\n"),composed
+ composed=composed.."."..name
+ t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
else
- return "",target
+ composed=name
+ if not nofirst then
+ t[#t+1]=formatters["%s = %s or { }"](composed,composed)
+ end
end
+ end
+ if composed then
+ if nolast then
+ composed=composed.."."..snippets[#snippets]
+ end
+ return concat(t,"\n"),composed
+ else
+ return "",target
+ end
end
function tables.definedtable(...)
- local t=_G
- for i=1,select("#",...) do
- local li=select(i,...)
- local tl=t[li]
- if not tl then
- tl={}
- t[li]=tl
- end
- t=tl
- end
- return t
+ local t=_G
+ for i=1,select("#",...) do
+ local li=select(i,...)
+ local tl=t[li]
+ if not tl then
+ tl={}
+ t[li]=tl
+ end
+ t=tl
+ end
+ return t
end
function tables.accesstable(target,root)
- local t=root or _G
- for name in gmatch(target,"([^%.]+)") do
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ for name in gmatch(target,"([^%.]+)") do
+ t=t[name]
+ if not t then
+ return
end
- return t
+ end
+ return t
end
function tables.migratetable(target,v,root)
- local t=root or _G
- local names=lpegmatch(splitter,target)
- for i=1,#names-1 do
- local name=names[i]
- t[name]=t[name] or {}
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ local names=lpegmatch(splitter,target)
+ for i=1,#names-1 do
+ local name=names[i]
+ t[name]=t[name] or {}
+ t=t[name]
+ if not t then
+ return
end
- t[names[#names]]=v
+ end
+ t[names[#names]]=v
end
function tables.removevalue(t,value)
- if value then
- for i=1,#t do
- if t[i]==value then
- remove(t,i)
- end
- end
+ if value then
+ for i=1,#t do
+ if t[i]==value then
+ remove(t,i)
+ end
end
+ end
end
function tables.replacevalue(t,oldvalue,newvalue)
- if oldvalue and newvalue then
- for i=1,#t do
- if t[i]==oldvalue then
- t[i]=newvalue
- end
- end
+ if oldvalue and newvalue then
+ for i=1,#t do
+ if t[i]==oldvalue then
+ t[i]=newvalue
+ end
end
+ end
end
function tables.insertbeforevalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i,extra)
+ return
end
- insert(t,1,extra)
+ end
+ insert(t,1,extra)
end
function tables.insertaftervalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i+1,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i+1,extra)
+ return
end
- insert(t,#t+1,extra)
+ end
+ insert(t,#t+1,extra)
end
local escape=Cs(Cc('"')*((P('"')/'""'+P(1))^0)*Cc('"'))
function table.tocsv(t,specification)
- if t and #t>0 then
- local result={}
- local r={}
- specification=specification or {}
- local fields=specification.fields
- if type(fields)~="string" then
- fields=sortedkeys(t[1])
- end
- local separator=specification.separator or ","
- local noffields=#fields
- if specification.preamble==true then
- for f=1,noffields do
- r[f]=lpegmatch(escape,tostring(fields[f]))
- end
- result[1]=concat(r,separator)
- end
- for i=1,#t do
- local ti=t[i]
- for f=1,noffields do
- local field=ti[fields[f]]
- if type(field)=="string" then
- r[f]=lpegmatch(escape,field)
- else
- r[f]=tostring(field)
- end
- end
- result[i+1]=concat(r,separator)
+ if t and #t>0 then
+ local result={}
+ local r={}
+ specification=specification or {}
+ local fields=specification.fields
+ if type(fields)~="string" then
+ fields=sortedkeys(t[1])
+ end
+ local separator=specification.separator or ","
+ local noffields=#fields
+ if specification.preamble==true then
+ for f=1,noffields do
+ r[f]=lpegmatch(escape,tostring(fields[f]))
+ end
+ result[1]=concat(r,separator)
+ end
+ for i=1,#t do
+ local ti=t[i]
+ for f=1,noffields do
+ local field=ti[fields[f]]
+ if type(field)=="string" then
+ r[f]=lpegmatch(escape,field)
+ else
+ r[f]=tostring(field)
end
- return concat(result,"\n")
- else
- return ""
+ end
+ result[i+1]=concat(r,separator)
end
+ return concat(result,"\n")
+ else
+ return ""
+ end
end
local nspaces=utilities.strings.newrepeater(" ")
local function toxml(t,d,result,step)
- local r=#result
- for k,v in sortedpairs(t) do
- local s=nspaces[d]
- local tk=type(k)
- local tv=type(v)
- if tv=="table" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</entry>"](s,k)
- else
- r=r+1 result[r]=formatters["%s<%s>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</%s>"](s,k)
- end
- elseif tv=="string" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
- end
- elseif tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
- end
+ local r=#result
+ for k,v in sortedpairs(t) do
+ local s=nspaces[d]
+ local tk=type(k)
+ local tv=type(v)
+ if tv=="table" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</entry>"](s,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</%s>"](s,k)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
+ end
+ elseif tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
end
+ end
end
function table.toxml(t,specification)
- specification=specification or {}
- local name=specification.name
- local noroot=name==false
- local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
- local indent=specification.indent or 0
- local spaces=specification.spaces or 1
- if noroot then
- toxml(t,indent,result,spaces)
- else
- toxml({ [name or "data"]=t },indent,result,spaces)
- end
- return concat(result,"\n")
+ specification=specification or {}
+ local name=specification.name
+ local noroot=name==false
+ local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
+ local indent=specification.indent or 0
+ local spaces=specification.spaces or 1
+ if noroot then
+ toxml(t,indent,result,spaces)
+ else
+ toxml({ [name or "data"]=t },indent,result,spaces)
+ end
+ return concat(result,"\n")
end
function tables.encapsulate(core,capsule,protect)
- if type(capsule)~="table" then
- protect=true
- capsule={}
- end
+ if type(capsule)~="table" then
+ protect=true
+ capsule={}
+ end
+ for key,value in next,core do
+ if capsule[key] then
+ print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
+ os.exit()
+ else
+ capsule[key]=value
+ end
+ end
+ if protect then
for key,value in next,core do
+ core[key]=nil
+ end
+ setmetatable(core,{
+ __index=capsule,
+ __newindex=function(t,key,value)
if capsule[key] then
- print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
- os.exit()
+ print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
+ os.exit()
else
- capsule[key]=value
+ rawset(t,key,value)
end
- end
- if protect then
- for key,value in next,core do
- core[key]=nil
- end
- setmetatable(core,{
- __index=capsule,
- __newindex=function(t,key,value)
- if capsule[key] then
- print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
- os.exit()
- else
- rawset(t,key,value)
- end
- end
- } )
- end
+ end
+ } )
+ end
end
local f_hashed_string=formatters["[%q]=%q,"]
local f_hashed_number=formatters["[%q]=%s,"]
@@ -7441,157 +7441,157 @@ local f_ordered_string=formatters["%q,"]
local f_ordered_number=formatters["%s,"]
local f_ordered_boolean=formatters["%l,"]
function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- for i=0,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
- end
- end
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ for i=0,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
- end
- end
- else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
- end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ else
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_hashed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_hashed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_hashed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
- return r
+ end
end
- return concat(fastserialize(t,true))
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
+ end
+ return concat(fastserialize(t,true))
end
function table.deserialize(str)
- if not str or str=="" then
- return
- end
- local code=load(str)
- if not code then
- return
- end
- code=code()
- if not code then
- return
- end
- return code
+ if not str or str=="" then
+ return
+ end
+ local code=load(str)
+ if not code then
+ return
+ end
+ code=code()
+ if not code then
+ return
+ end
+ return code
end
function table.load(filename,loader)
- if filename then
- local t=(loader or io.loaddata)(filename)
- if t and t~="" then
- local t=utftoeight(t)
- t=load(t)
- if type(t)=="function" then
- t=t()
- if type(t)=="table" then
- return t
- end
- end
+ if filename then
+ local t=(loader or io.loaddata)(filename)
+ if t and t~="" then
+ local t=utftoeight(t)
+ t=load(t)
+ if type(t)=="function" then
+ t=t()
+ if type(t)=="table" then
+ return t
end
+ end
end
+ end
end
function table.save(filename,t,n,...)
- io.savedata(filename,table.serialize(t,n==nil and true or n,...))
+ io.savedata(filename,table.serialize(t,n==nil and true or n,...))
end
local f_key_value=formatters["%s=%q"]
local f_add_table=formatters[" {%t},\n"]
local f_return_table=formatters["return {\n%t}"]
local function slowdrop(t)
- local r={}
- local l={}
- for i=1,#t do
- local ti=t[i]
- local j=0
- for k,v in next,ti do
- j=j+1
- l[j]=f_key_value(k,v)
- end
- r[i]=f_add_table(l)
- end
- return f_return_table(r)
+ local r={}
+ local l={}
+ for i=1,#t do
+ local ti=t[i]
+ local j=0
+ for k,v in next,ti do
+ j=j+1
+ l[j]=f_key_value(k,v)
+ end
+ r[i]=f_add_table(l)
+ end
+ return f_return_table(r)
end
local function fastdrop(t)
- local r={ "return {\n" }
- local m=1
- for i=1,#t do
- local ti=t[i]
- m=m+1 r[m]=" {"
- for k,v in next,ti do
- m=m+1 r[m]=f_key_value(k,v)
- end
- m=m+1 r[m]="},\n"
- end
- m=m+1
- r[m]="}"
- return concat(r)
+ local r={ "return {\n" }
+ local m=1
+ for i=1,#t do
+ local ti=t[i]
+ m=m+1 r[m]=" {"
+ for k,v in next,ti do
+ m=m+1 r[m]=f_key_value(k,v)
+ end
+ m=m+1 r[m]="},\n"
+ end
+ m=m+1
+ r[m]="}"
+ return concat(r)
end
function table.drop(t,slow)
- if #t==0 then
- return "return { }"
- elseif slow==true then
- return slowdrop(t)
- else
- return fastdrop(t)
- end
+ if #t==0 then
+ return "return { }"
+ elseif slow==true then
+ return slowdrop(t)
+ else
+ return fastdrop(t)
+ end
end
local selfmapper={ __index=function(t,k) t[k]=k return k end }
-function table.twowaymapper(t)
- if not t then
- t={}
- else
- local zero=rawget(t,0)
- for i=zero and 0 or 1,#t do
- local ti=t[i]
- if ti then
- local i=tostring(i)
- t[i]=ti
- t[ti]=i
- end
- end
+function table.twowaymapper(t)
+ if not t then
+ t={}
+ else
+ local zero=rawget(t,0)
+ for i=zero and 0 or 1,#t do
+ local ti=t[i]
+ if ti then
+ local i=tostring(i)
+ t[i]=ti
+ t[ti]=i
+ end
end
- setmetatable(t,selfmapper)
- return t
+ end
+ setmetatable(t,selfmapper)
+ return t
end
local f_start_key_idx=formatters["%w{"]
local f_start_key_num=formatters["%w[%s]={"]
@@ -7629,223 +7629,223 @@ local spaces=utilities.strings.newrepeater(" ")
local original_serialize=table.serialize
local is_simple_table=table.is_simple_table
local function serialize(root,name,specification)
- if type(specification)=="table" then
- return original_serialize(root,name,specification)
- end
- local t
- local n=1
- local unknown=false
- local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- n=n+1
- if indexed then
- t[n]=f_start_key_idx(depth)
+ if type(specification)=="table" then
+ return original_serialize(root,name,specification)
+ end
+ local t
+ local n=1
+ local unknown=false
+ local function do_serialize(root,name,depth,level,indexed)
+ if level>0 then
+ n=n+1
+ if indexed then
+ t[n]=f_start_key_idx(depth)
+ else
+ local tn=type(name)
+ if tn=="number" then
+ t[n]=f_start_key_num(depth,name)
+ elseif tn=="string" then
+ t[n]=f_start_key_str(depth,name)
+ elseif tn=="boolean" then
+ t[n]=f_start_key_boo(depth,name)
+ else
+ t[n]=f_start_key_nop(depth)
+ end
+ end
+ depth=depth+1
+ end
+ if root and next(root)~=nil then
+ local first=nil
+ local last=0
+ last=#root
+ for k=1,last do
+ if rawget(root,k)==nil then
+ last=k-1
+ break
+ end
+ end
+ if last>0 then
+ first=1
+ end
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if first and tk=="number" and k<=last and k>=first then
+ if tv=="number" then
+ n=n+1 t[n]=f_val_num(depth,v)
+ elseif tv=="string" then
+ n=n+1 t[n]=f_val_str(depth,v)
+ elseif tv=="table" then
+ if next(v)==nil then
+ n=n+1 t[n]=f_val_not(depth)
else
- local tn=type(name)
- if tn=="number" then
- t[n]=f_start_key_num(depth,name)
- elseif tn=="string" then
- t[n]=f_start_key_str(depth,name)
- elseif tn=="boolean" then
- t[n]=f_start_key_boo(depth,name)
- else
- t[n]=f_start_key_nop(depth)
- end
- end
- depth=depth+1
- end
- if root and next(root)~=nil then
- local first=nil
- local last=0
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
+ local st=is_simple_table(v)
+ if st then
+ n=n+1 t[n]=f_val_seq(depth,st)
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
end
- if last>0 then
- first=1
+ elseif tv=="boolean" then
+ n=n+1 t[n]=f_val_boo(depth,v)
+ elseif unknown then
+ n=n+1 t[n]=f_val_str(depth,tostring(v))
+ end
+ elseif tv=="number" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_num(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_num(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
+ end
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_not(depth,k)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_not(depth,k)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_not(depth,k)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
end
- local sk=sortedkeys(root)
- for i=1,#sk do
- local k=sk[i]
- local v=root[k]
- local tv=type(v)
- local tk=type(k)
- if first and tk=="number" and k<=last and k>=first then
- if tv=="number" then
- n=n+1 t[n]=f_val_num(depth,v)
- elseif tv=="string" then
- n=n+1 t[n]=f_val_str(depth,v)
- elseif tv=="table" then
- if next(v)==nil then
- n=n+1 t[n]=f_val_not(depth)
- else
- local st=is_simple_table(v)
- if st then
- n=n+1 t[n]=f_val_seq(depth,st)
- else
- do_serialize(v,k,depth,level+1,true)
- end
- end
- elseif tv=="boolean" then
- n=n+1 t[n]=f_val_boo(depth,v)
- elseif unknown then
- n=n+1 t[n]=f_val_str(depth,tostring(v))
- end
- elseif tv=="number" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_num(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_num(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
- end
- elseif tv=="string" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_not(depth,k)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_not(depth,k)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_not(depth,k)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
- end
- else
- local st=is_simple_table(v)
- if not st then
- do_serialize(v,k,depth,level+1)
- elseif tk=="number" then
- n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
- end
- end
- elseif tv=="boolean" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
- end
- else
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
- end
- end
+ else
+ local st=is_simple_table(v)
+ if not st then
+ do_serialize(v,k,depth,level+1)
+ elseif tk=="number" then
+ n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
end
- end
- if level>0 then
- n=n+1 t[n]=f_stop(depth-1)
- end
- end
- local tname=type(name)
- if tname=="string" then
- if name=="return" then
- t={ f_table_return() }
- else
- t={ f_table_name(name) }
- end
- elseif tname=="number" then
- t={ f_table_entry(name) }
- elseif tname=="boolean" then
- if name then
- t={ f_table_return() }
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
+ end
else
- t={ f_table_direct() }
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
+ end
end
+ end
+ end
+ if level>0 then
+ n=n+1 t[n]=f_stop(depth-1)
+ end
+ end
+ local tname=type(name)
+ if tname=="string" then
+ if name=="return" then
+ t={ f_table_return() }
else
- t={ f_table_name("t") }
+ t={ f_table_name(name) }
end
- if root then
- if getmetatable(root) then
- local dummy=root._w_h_a_t_e_v_e_r_
- root._w_h_a_t_e_v_e_r_=nil
- end
- if next(root)~=nil then
- local st=is_simple_table(root)
- if st then
- return t[1]..f_fin_seq(st)
- else
- do_serialize(root,name,1,0)
- end
- end
+ elseif tname=="number" then
+ t={ f_table_entry(name) }
+ elseif tname=="boolean" then
+ if name then
+ t={ f_table_return() }
+ else
+ t={ f_table_direct() }
+ end
+ else
+ t={ f_table_name("t") }
+ end
+ if root then
+ if getmetatable(root) then
+ local dummy=root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_=nil
+ end
+ if next(root)~=nil then
+ local st=is_simple_table(root)
+ if st then
+ return t[1]..f_fin_seq(st)
+ else
+ do_serialize(root,name,1,0)
+ end
end
- n=n+1
- t[n]=f_table_finish()
- return concat(t,"\n")
+ end
+ n=n+1
+ t[n]=f_table_finish()
+ return concat(t,"\n")
end
table.serialize=serialize
if setinspector then
- setinspector("table",function(v)
- if type(v)=="table" then
- print(serialize(v,"table",{ metacheck=false }))
- return true
- end
- end)
+ setinspector("table",function(v)
+ if type(v)=="table" then
+ print(serialize(v,"table",{ metacheck=false }))
+ return true
+ end
+ end)
end
local mt={
- __newindex=function(t,k,v)
- local n=t.last+1
- t.last=n
- t.list[n]=k
- t.hash[k]=v
- end,
- __index=function(t,k)
- return t.hash[k]
- end,
- __len=function(t)
- return t.last
- end,
+ __newindex=function(t,k,v)
+ local n=t.last+1
+ t.last=n
+ t.list[n]=k
+ t.hash[k]=v
+ end,
+ __index=function(t,k)
+ return t.hash[k]
+ end,
+ __len=function(t)
+ return t.last
+ end,
}
function table.orderedhash()
- return setmetatable({ list={},hash={},last=0 },mt)
+ return setmetatable({ list={},hash={},last=0 },mt)
end
function table.ordered(t)
- local n=t.last
- if n>0 then
- local l=t.list
- local i=1
- local h=t.hash
- local f=function()
- if i<=n then
- local k=i
- local v=h[l[k]]
- i=i+1
- return k,v
- end
- end
- return f,1,h[l[1]]
- else
- return function() end
+ local n=t.last
+ if n>0 then
+ local l=t.list
+ local i=1
+ local h=t.hash
+ local f=function()
+ if i<=n then
+ local k=i
+ local v=h[l[k]]
+ i=i+1
+ return k,v
+ end
end
+ return f,1,h[l[1]]
+ else
+ return function() end
+ end
end
@@ -7855,14 +7855,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fil"] = package.loaded["util-fil"] or true
--- original size: 8607, stripped down to: 6990
+-- original size: 8607, stripped down to: 6727
if not modules then modules={} end modules ['util-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber=tonumber
local byte=string.byte
@@ -7872,280 +7872,280 @@ local files={}
utilities.files=files
local zerobased={}
function files.open(filename,zb)
- local f=io.open(filename,"rb")
- if f then
- zerobased[f]=zb or false
- end
- return f
+ local f=io.open(filename,"rb")
+ if f then
+ zerobased[f]=zb or false
+ end
+ return f
end
function files.close(f)
- zerobased[f]=nil
- f:close()
+ zerobased[f]=nil
+ f:close()
end
function files.size(f)
- local current=f:seek()
- local size=f:seek("end")
- f:seek("set",current)
- return size
+ local current=f:seek()
+ local size=f:seek("end")
+ f:seek("set",current)
+ return size
end
files.getsize=files.size
function files.setposition(f,n)
- if zerobased[f] then
- f:seek("set",n)
- else
- f:seek("set",n-1)
- end
+ if zerobased[f] then
+ f:seek("set",n)
+ else
+ f:seek("set",n-1)
+ end
end
function files.getposition(f)
- if zerobased[f] then
- return f:seek()
- else
- return f:seek()+1
- end
+ if zerobased[f] then
+ return f:seek()
+ else
+ return f:seek()+1
+ end
end
function files.look(f,n,chars)
- local p=f:seek()
- local s=f:read(n)
- f:seek("set",p)
- if chars then
- return s
- else
- return byte(s,1,#s)
- end
+ local p=f:seek()
+ local s=f:read(n)
+ f:seek("set",p)
+ if chars then
+ return s
+ else
+ return byte(s,1,#s)
+ end
end
function files.skip(f,n)
- if n==1 then
- f:read(n)
- else
- f:seek("set",f:seek()+n)
- end
+ if n==1 then
+ f:read(n)
+ else
+ f:seek("set",f:seek()+n)
+ end
end
function files.readbyte(f)
- return byte(f:read(1))
+ return byte(f:read(1))
end
function files.readbytes(f,n)
- return byte(f:read(n),1,n)
+ return byte(f:read(n),1,n)
end
function files.readbytetable(f,n)
- local s=f:read(n or 1)
- return { byte(s,1,#s) }
+ local s=f:read(n or 1)
+ return { byte(s,1,#s) }
end
function files.readchar(f)
- return f:read(1)
+ return f:read(1)
end
function files.readstring(f,n)
- return f:read(n or 1)
+ return f:read(n or 1)
end
-function files.readinteger1(f)
- local n=byte(f:read(1))
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+function files.readinteger1(f)
+ local n=byte(f:read(1))
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-files.readcardinal1=files.readbyte
+files.readcardinal1=files.readbyte
files.readcardinal=files.readcardinal1
files.readinteger=files.readinteger1
files.readsignedbyte=files.readinteger1
function files.readcardinal2(f)
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
end
function files.readcardinal2le(f)
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
end
function files.readinteger2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function files.readinteger2le(f)
- local b,a=byte(f:read(2),1,2)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local b,a=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function files.readcardinal3(f)
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
end
function files.readcardinal3le(f)
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
end
function files.readinteger3(f)
- local a,b,c=byte(f:read(3),1,3)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local a,b,c=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function files.readinteger3le(f)
- local c,b,a=byte(f:read(3),1,3)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local c,b,a=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function files.readcardinal4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function files.readcardinal4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function files.readinteger4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function files.readinteger4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local d,c,b,a=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function files.readfixed2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- tonumber((a-0x100).."."..b)
- else
- tonumber((a ).."."..b)
- end
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function files.readfixed4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
- else
- tonumber((0x100*a+b ).."."..(0x100*c+d))
- end
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
end
if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function files.read2dot14(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- local n=-(0x100*a+b)
- return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- else
- local n=0x100*a+b
- return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- end
+ local extract=bit32.extract
+ local band=bit32.band
+ function files.read2dot14(f)
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+ else
+ local n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function files.skipshort(f,n)
- f:read(2*(n or 1))
+ f:read(2*(n or 1))
end
function files.skiplong(f,n)
- f:read(4*(n or 1))
+ f:read(4*(n or 1))
end
if bit32 then
- local rshift=bit32.rshift
- function files.writecardinal2(f,n)
- local a=char(n%256)
- n=rshift(n,8)
- local b=char(n%256)
- f:write(b,a)
- end
-else
- local floor=math.floor
- function files.writecardinal2(f,n)
- local a=char(n%256)
- n=floor(n/256)
- local b=char(n%256)
- f:write(b,a)
- end
-end
-function files.writecardinal4(f,n)
+ local rshift=bit32.rshift
+ function files.writecardinal2(f,n)
local a=char(n%256)
n=rshift(n,8)
local b=char(n%256)
- n=rshift(n,8)
- local c=char(n%256)
- n=rshift(n,8)
- local d=char(n%256)
- f:write(d,c,b,a)
+ f:write(b,a)
+ end
+else
+ local floor=math.floor
+ function files.writecardinal2(f,n)
+ local a=char(n%256)
+ n=floor(n/256)
+ local b=char(n%256)
+ f:write(b,a)
+ end
+end
+function files.writecardinal4(f,n)
+ local a=char(n%256)
+ n=rshift(n,8)
+ local b=char(n%256)
+ n=rshift(n,8)
+ local c=char(n%256)
+ n=rshift(n,8)
+ local d=char(n%256)
+ f:write(d,c,b,a)
end
function files.writestring(f,s)
- f:write(char(byte(s,1,#s)))
+ f:write(char(byte(s,1,#s)))
end
function files.writebyte(f,b)
- f:write(char(b))
+ f:write(char(b))
end
if fio and fio.readcardinal1 then
- files.readcardinal1=fio.readcardinal1
- files.readcardinal2=fio.readcardinal2
- files.readcardinal3=fio.readcardinal3
- files.readcardinal4=fio.readcardinal4
- files.readinteger1=fio.readinteger1
- files.readinteger2=fio.readinteger2
- files.readinteger3=fio.readinteger3
- files.readinteger4=fio.readinteger4
- files.readfixed2=fio.readfixed2
- files.readfixed4=fio.readfixed4
- files.read2dot14=fio.read2dot14
- files.setposition=fio.setposition
- files.getposition=fio.getposition
- files.readbyte=files.readcardinal1
- files.readsignedbyte=files.readinteger1
- files.readcardinal=files.readcardinal1
- files.readinteger=files.readinteger1
- local skipposition=fio.skipposition
- files.skipposition=skipposition
- files.readbytes=fio.readbytes
- files.readbytetable=fio.readbytetable
- function files.skipshort(f,n)
- skipposition(f,2*(n or 1))
- end
- function files.skiplong(f,n)
- skipposition(f,4*(n or 1))
- end
+ files.readcardinal1=fio.readcardinal1
+ files.readcardinal2=fio.readcardinal2
+ files.readcardinal3=fio.readcardinal3
+ files.readcardinal4=fio.readcardinal4
+ files.readinteger1=fio.readinteger1
+ files.readinteger2=fio.readinteger2
+ files.readinteger3=fio.readinteger3
+ files.readinteger4=fio.readinteger4
+ files.readfixed2=fio.readfixed2
+ files.readfixed4=fio.readfixed4
+ files.read2dot14=fio.read2dot14
+ files.setposition=fio.setposition
+ files.getposition=fio.getposition
+ files.readbyte=files.readcardinal1
+ files.readsignedbyte=files.readinteger1
+ files.readcardinal=files.readcardinal1
+ files.readinteger=files.readinteger1
+ local skipposition=fio.skipposition
+ files.skipposition=skipposition
+ files.readbytes=fio.readbytes
+ files.readbytetable=fio.readbytetable
+ function files.skipshort(f,n)
+ skipposition(f,2*(n or 1))
+ end
+ function files.skiplong(f,n)
+ skipposition(f,4*(n or 1))
+ end
end
if fio and fio.readcardinaltable then
- files.readcardinaltable=fio.readcardinaltable
- files.readintegertable=fio.readintegertable
+ files.readcardinaltable=fio.readcardinaltable
+ files.readintegertable=fio.readintegertable
else
- local readcardinal1=files.readcardinal1
- local readcardinal2=files.readcardinal2
- local readcardinal3=files.readcardinal3
- local readcardinal4=files.readcardinal4
- function files.readcardinaltable(f,n,b)
- local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
- return t
- end
- local readinteger1=files.readinteger1
- local readinteger2=files.readinteger2
- local readinteger3=files.readinteger3
- local readinteger4=files.readinteger4
- function files.readintegertable(f,n,b)
- local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
- return t
- end
+ local readcardinal1=files.readcardinal1
+ local readcardinal2=files.readcardinal2
+ local readcardinal3=files.readcardinal3
+ local readcardinal4=files.readcardinal4
+ function files.readcardinaltable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readcardinal1(f) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
+ return t
+ end
+ local readinteger1=files.readinteger1
+ local readinteger2=files.readinteger2
+ local readinteger3=files.readinteger3
+ local readinteger4=files.readinteger4
+ function files.readintegertable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readinteger1(f) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
+ return t
+ end
end
@@ -8155,14 +8155,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sac"] = package.loaded["util-sac"] or true
--- original size: 11065, stripped down to: 8695
+-- original size: 11065, stripped down to: 8209
if not modules then modules={} end modules ['util-sac']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local byte,sub=string.byte,string.sub
local tonumber=tonumber
@@ -8170,397 +8170,397 @@ utilities=utilities or {}
local streams={}
utilities.streams=streams
function streams.open(filename,zerobased)
- local f=filename and io.loaddata(filename)
- if f then
- return { f,1,#f,zerobased or false }
- end
+ local f=filename and io.loaddata(filename)
+ if f then
+ return { f,1,#f,zerobased or false }
+ end
end
function streams.openstring(f,zerobased)
- if f then
- return { f,1,#f,zerobased or false }
- end
+ if f then
+ return { f,1,#f,zerobased or false }
+ end
end
function streams.close()
end
function streams.size(f)
- return f and f[3] or 0
+ return f and f[3] or 0
end
function streams.setposition(f,i)
- if f[4] then
- if i<=0 then
- f[2]=1
- else
- f[2]=i+1
- end
+ if f[4] then
+ if i<=0 then
+ f[2]=1
else
- if i<=1 then
- f[2]=1
- else
- f[2]=i
- end
+ f[2]=i+1
end
-end
-function streams.getposition(f)
- if f[4] then
- return f[2]-1
+ else
+ if i<=1 then
+ f[2]=1
else
- return f[2]
+ f[2]=i
end
+ end
+end
+function streams.getposition(f)
+ if f[4] then
+ return f[2]-1
+ else
+ return f[2]
+ end
end
function streams.look(f,n,chars)
- local b=f[2]
- local e=b+n-1
- if chars then
- return sub(f[1],b,e)
- else
- return byte(f[1],b,e)
- end
+ local b=f[2]
+ local e=b+n-1
+ if chars then
+ return sub(f[1],b,e)
+ else
+ return byte(f[1],b,e)
+ end
end
function streams.skip(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readbyte(f)
- local i=f[2]
- f[2]=i+1
- return byte(f[1],i)
+ local i=f[2]
+ f[2]=i+1
+ return byte(f[1],i)
end
function streams.readbytes(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return byte(f[1],i,j-1)
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return byte(f[1],i,j-1)
end
function streams.readbytetable(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return { byte(f[1],i,j-1) }
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return { byte(f[1],i,j-1) }
end
function streams.skipbytes(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readchar(f)
- local i=f[2]
- f[2]=i+1
- return sub(f[1],i,i)
+ local i=f[2]
+ f[2]=i+1
+ return sub(f[1],i,i)
end
function streams.readstring(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return sub(f[1],i,j-1)
-end
-function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- local n=byte(f[1],i)
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return sub(f[1],i,j-1)
+end
+function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ local n=byte(f[1],i)
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-streams.readcardinal1=streams.readbyte
+streams.readcardinal1=streams.readbyte
streams.readcardinal=streams.readcardinal1
streams.readinteger=streams.readinteger1
function streams.readcardinal2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readcardinal2LE(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readinteger2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readinteger2le(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readcardinal3(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readcardinal3le(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readinteger3(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readinteger3le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readcardinal4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function streams.readinteger4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function streams.readinteger4le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local d,c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local d,c,b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function streams.readfixed2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- tonumber((a-0x100).."."..b)
- else
- tonumber((a ).."."..b)
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function streams.readfixed4(f)
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
+end
+if bit32 then
+ local extract=bit32.extract
+ local band=bit32.band
+ function streams.read2dot14(f)
local i=f[2]
- local j=i+3
+ local j=i+1
f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
+ local a,b=byte(f[1],i,j)
if a>=0x80 then
- tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
else
- tonumber((0x100*a+b ).."."..(0x100*c+d))
- end
-end
-if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function streams.read2dot14(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- local n=-(0x100*a+b)
- return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- else
- local n=0x100*a+b
- return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- end
+ local n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function streams.skipshort(f,n)
- f[2]=f[2]+2*(n or 1)
+ f[2]=f[2]+2*(n or 1)
end
function streams.skiplong(f,n)
- f[2]=f[2]+4*(n or 1)
+ f[2]=f[2]+4*(n or 1)
end
if sio and sio.readcardinal2 then
- local readcardinal1=sio.readcardinal1
- local readcardinal2=sio.readcardinal2
- local readcardinal3=sio.readcardinal3
- local readcardinal4=sio.readcardinal4
- local readinteger1=sio.readinteger1
- local readinteger2=sio.readinteger2
- local readinteger3=sio.readinteger3
- local readinteger4=sio.readinteger4
- local readfixed2=sio.readfixed2
- local readfixed4=sio.readfixed4
- local read2dot14=sio.read2dot14
- local readbytes=sio.readbytes
- local readbytetable=sio.readbytetable
- function streams.readcardinal1(f)
- local i=f[2]
- f[2]=i+1
- return readcardinal1(f[1],i)
- end
- function streams.readcardinal2(f)
- local i=f[2]
- f[2]=i+2
- return readcardinal2(f[1],i)
- end
- function streams.readcardinal3(f)
- local i=f[2]
- f[2]=i+3
- return readcardinal3(f[1],i)
- end
- function streams.readcardinal4(f)
- local i=f[2]
- f[2]=i+4
- return readcardinal4(f[1],i)
- end
- function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- return readinteger1(f[1],i)
- end
- function streams.readinteger2(f)
- local i=f[2]
- f[2]=i+2
- return readinteger2(f[1],i)
- end
- function streams.readinteger3(f)
- local i=f[2]
- f[2]=i+3
- return readinteger3(f[1],i)
- end
- function streams.readinteger4(f)
- local i=f[2]
- f[2]=i+4
- return readinteger4(f[1],i)
- end
- function streams.read2dot4(f)
- local i=f[2]
- f[2]=i+2
- return read2dot4(f[1],i)
- end
- function streams.readbytes(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytes(f[1],i,n)
+ local readcardinal1=sio.readcardinal1
+ local readcardinal2=sio.readcardinal2
+ local readcardinal3=sio.readcardinal3
+ local readcardinal4=sio.readcardinal4
+ local readinteger1=sio.readinteger1
+ local readinteger2=sio.readinteger2
+ local readinteger3=sio.readinteger3
+ local readinteger4=sio.readinteger4
+ local readfixed2=sio.readfixed2
+ local readfixed4=sio.readfixed4
+ local read2dot14=sio.read2dot14
+ local readbytes=sio.readbytes
+ local readbytetable=sio.readbytetable
+ function streams.readcardinal1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readcardinal1(f[1],i)
+ end
+ function streams.readcardinal2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readcardinal2(f[1],i)
+ end
+ function streams.readcardinal3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readcardinal3(f[1],i)
+ end
+ function streams.readcardinal4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readcardinal4(f[1],i)
+ end
+ function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readinteger1(f[1],i)
+ end
+ function streams.readinteger2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readinteger2(f[1],i)
+ end
+ function streams.readinteger3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readinteger3(f[1],i)
+ end
+ function streams.readinteger4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readinteger4(f[1],i)
+ end
+ function streams.read2dot4(f)
+ local i=f[2]
+ f[2]=i+2
+ return read2dot4(f[1],i)
+ end
+ function streams.readbytes(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- function streams.readbytetable(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytetable(f[1],i,n)
+ return readbytes(f[1],i,n)
+ end
+ function streams.readbytetable(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- streams.readbyte=streams.readcardinal1
- streams.readsignedbyte=streams.readinteger1
- streams.readcardinal=streams.readcardinal1
- streams.readinteger=streams.readinteger1
+ return readbytetable(f[1],i,n)
+ end
+ streams.readbyte=streams.readcardinal1
+ streams.readsignedbyte=streams.readinteger1
+ streams.readcardinal=streams.readcardinal1
+ streams.readinteger=streams.readinteger1
end
if sio and sio.readcardinaltable then
- local readcardinaltable=sio.readcardinaltable
- local readintegertable=sio.readintegertable
- function utilities.streams.readcardinaltable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readcardinaltable(f[1],i,n,b)
+ local readcardinaltable=sio.readcardinaltable
+ local readintegertable=sio.readintegertable
+ function utilities.streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- function utilities.streams.readintegertable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readintegertable(f[1],i,n,b)
+ return readcardinaltable(f[1],i,n,b)
+ end
+ function utilities.streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
+ return readintegertable(f[1],i,n,b)
+ end
else
- local readcardinal1=streams.readcardinal1
- local readcardinal2=streams.readcardinal2
- local readcardinal3=streams.readcardinal3
- local readcardinal4=streams.readcardinal4
- function streams.readcardinaltable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
- return t
+ local readcardinal1=streams.readcardinal1
+ local readcardinal2=streams.readcardinal2
+ local readcardinal3=streams.readcardinal3
+ local readcardinal4=streams.readcardinal4
+ function streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- local readinteger1=streams.readinteger1
- local readinteger2=streams.readinteger2
- local readinteger3=streams.readinteger3
- local readinteger4=streams.readinteger4
- function streams.readintegertable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
- return t
+ local t={}
+ if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
+ return t
+ end
+ local readinteger1=streams.readinteger1
+ local readinteger2=streams.readinteger2
+ local readinteger3=streams.readinteger3
+ local readinteger4=streams.readinteger4
+ function streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
+ local t={}
+ if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
+ return t
+ end
end
@@ -8570,168 +8570,168 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sto"] = package.loaded["util-sto"] or true
--- original size: 6661, stripped down to: 3245
+-- original size: 6661, stripped down to: 3074
if not modules then modules={} end modules ['util-sto']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type
utilities=utilities or {}
utilities.storage=utilities.storage or {}
local storage=utilities.storage
function storage.mark(t)
- if not t then
- print("\nfatal error: storage cannot be marked\n")
- os.exit()
- return
- end
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ if not t then
+ print("\nfatal error: storage cannot be marked\n")
+ os.exit()
+ return
+ end
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.allocate(t)
- t=t or {}
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ t=t or {}
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.marked(t)
- local m=getmetatable(t)
- return m and m.__storage__
+ local m=getmetatable(t)
+ return m and m.__storage__
end
function storage.checked(t)
- if not t then
- report("\nfatal error: storage has not been allocated\n")
- os.exit()
- return
- end
- return t
+ if not t then
+ report("\nfatal error: storage has not been allocated\n")
+ os.exit()
+ return
+ end
+ return t
end
function storage.setinitializer(data,initialize)
- local m=getmetatable(data) or {}
- m.__index=function(data,k)
- m.__index=nil
- initialize()
- return data[k]
- end
- setmetatable(data,m)
+ local m=getmetatable(data) or {}
+ m.__index=function(data,k)
+ m.__index=nil
+ initialize()
+ return data[k]
+ end
+ setmetatable(data,m)
end
local keyisvalue={ __index=function(t,k)
- t[k]=k
- return k
+ t[k]=k
+ return k
end }
function storage.sparse(t)
- t=t or {}
- setmetatable(t,keyisvalue)
- return t
-end
-local function f_empty () return "" end
-local function f_self (t,k) t[k]=k return k end
-local function f_table (t,k) local v={} t[k]=v return v end
-local function f_number(t,k) t[k]=0 return 0 end
-local function f_ignore() end
+ t=t or {}
+ setmetatable(t,keyisvalue)
+ return t
+end
+local function f_empty () return "" end
+local function f_self (t,k) t[k]=k return k end
+local function f_table (t,k) local v={} t[k]=v return v end
+local function f_number(t,k) t[k]=0 return 0 end
+local function f_ignore() end
local f_index={
- ["empty"]=f_empty,
- ["self"]=f_self,
- ["table"]=f_table,
- ["number"]=f_number,
+ ["empty"]=f_empty,
+ ["self"]=f_self,
+ ["table"]=f_table,
+ ["number"]=f_number,
}
function table.setmetatableindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- else
- setmetatable(t,{ __index=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ else
+ setmetatable(t,{ __index=i })
+ end
+ return t
end
local f_index={
- ["ignore"]=f_ignore,
+ ["ignore"]=f_ignore,
}
function table.setmetatablenewindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__newindex=i
- else
- setmetatable(t,{ __newindex=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__newindex=i
+ else
+ setmetatable(t,{ __newindex=i })
+ end
+ return t
end
function table.setmetatablecall(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- if m then
- m.__call=f
- else
- setmetatable(t,{ __call=f })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__call=f
+ else
+ setmetatable(t,{ __call=f })
+ end
+ return t
end
function table.setmetatableindices(t,f,n,c)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- m.__newindex=n
- m.__call=c
- else
- setmetatable(t,{
- __index=i,
- __newindex=n,
- __call=c,
- })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ m.__newindex=n
+ m.__call=c
+ else
+ setmetatable(t,{
+ __index=i,
+ __newindex=n,
+ __call=c,
+ })
+ end
+ return t
end
function table.setmetatablekey(t,key,value)
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m[key]=value
- return t
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m[key]=value
+ return t
end
function table.getmetatablekey(t,key,value)
- local m=getmetatable(t)
- return m and m[key]
+ local m=getmetatable(t)
+ return m and m[key]
end
function table.makeweak(t)
- if not t then
- t={}
- end
- local m=getmetatable(t)
- if m then
- m.__mode="v"
- else
- setmetatable(t,{ __mode="v" })
- end
- return t
+ if not t then
+ t={}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__mode="v"
+ else
+ setmetatable(t,{ __mode="v" })
+ end
+ return t
end
@@ -8741,14 +8741,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 23400, stripped down to: 16473
+-- original size: 23400, stripped down to: 15802
if not modules then modules={} end modules ['util-prs']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local lpeg,table,string=lpeg,table,string
local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp
@@ -8790,8 +8790,8 @@ local noparent=1-(lparent+rparent)
local nobracket=1-(lbracket+rbracket)
local escape,left,right=P("\\"),P('{'),P('}')
lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+ [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
+ [2]=left*V(1)*right
}
local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -8799,9 +8799,9 @@ local nestedbrackets=P { lbracket*(nobracket+V(1))^0*rbracket }
local spaces=space^0
local argument=Cs((lbrace/"")*((nobrace+nestedbraces)^0)*(rbrace/""))
local content=(1-endofstring)^0
-lpegpatterns.nestedbraces=nestedbraces
+lpegpatterns.nestedbraces=nestedbraces
lpegpatterns.nestedparents=nestedparents
-lpegpatterns.nested=nestedbraces
+lpegpatterns.nested=nestedbraces
lpegpatterns.argument=argument
lpegpatterns.content=content
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
@@ -8813,7 +8813,7 @@ local key=C((1-space-equal-comma)^1)
local pattern_b=spaces*comma^0*spaces*(key*((spaces*equal*spaces*value)+C("")))
local hash={}
local function set(key,value)
- hash[key]=value
+ hash[key]=value
end
local pattern_a_s=(pattern_a/set)^1
local pattern_b_s=(pattern_b/set)^1
@@ -8824,300 +8824,300 @@ patterns.settings_to_hash_b=pattern_b_s
patterns.settings_to_hash_c=pattern_c_s
patterns.settings_to_hash_d=pattern_d_s
function parsers.make_settings_to_hash_pattern(set,how)
- if how=="strict" then
- return (pattern_c/set)^1
- elseif how=="tolerant" then
- return (pattern_b/set)^1
- else
- return (pattern_a/set)^1
- end
+ if how=="strict" then
+ return (pattern_c/set)^1
+ elseif how=="tolerant" then
+ return (pattern_b/set)^1
+ else
+ return (pattern_a/set)^1
+ end
end
function parsers.settings_to_hash(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_a_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_a_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_colon_too(str)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- else
- hash={}
- lpegmatch(pattern_d_s,str)
- return hash
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ else
+ hash={}
+ lpegmatch(pattern_d_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_tolerant(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_b_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_b_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_strict(str,existing)
- if not str or str=="" then
- return nil
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
- elseif str and str~="" then
- hash=existing or {}
- lpegmatch(pattern_c_s,str)
- return next(hash) and hash
+ if not str or str=="" then
+ return nil
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
+ else
+ return str
end
+ elseif str and str~="" then
+ hash=existing or {}
+ lpegmatch(pattern_c_s,str)
+ return next(hash) and hash
+ end
end
local separator=comma*space^0
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
local pattern=spaces*Ct(value*(separator*value)^0)
patterns.settings_to_array=pattern
function parsers.settings_to_array(str,strict)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- elseif strict then
- if find(str,"{",1,true) then
- return lpegmatch(pattern,str)
- else
- return { str }
- end
- elseif find(str,",",1,true) then
- return lpegmatch(pattern,str)
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ elseif strict then
+ if find(str,"{",1,true) then
+ return lpegmatch(pattern,str)
else
- return { str }
+ return { str }
end
+ elseif find(str,",",1,true) then
+ return lpegmatch(pattern,str)
+ else
+ return { str }
+ end
end
function parsers.settings_to_numbers(str)
- if not str or str=="" then
- return {}
- end
- if type(str)=="table" then
- elseif find(str,",",1,true) then
- str=lpegmatch(pattern,str)
- else
- return { tonumber(str) }
- end
- for i=1,#str do
- str[i]=tonumber(str[i])
- end
- return str
+ if not str or str=="" then
+ return {}
+ end
+ if type(str)=="table" then
+ elseif find(str,",",1,true) then
+ str=lpegmatch(pattern,str)
+ else
+ return { tonumber(str) }
+ end
+ for i=1,#str do
+ str[i]=tonumber(str[i])
+ end
+ return str
end
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
local pattern=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_obey_fences(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache_a={}
local cache_b={}
function parsers.groupedsplitat(symbol,withaction)
- if not symbol then
- symbol=","
- end
- local pattern=(withaction and cache_b or cache_a)[symbol]
- if not pattern then
- local symbols=S(symbol)
- local separator=space^0*symbols*space^0
- local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
- if withaction then
- local withvalue=Carg(1)*value/function(f,s) return f(s) end
- pattern=spaces*withvalue*(separator*withvalue)^0
- cache_b[symbol]=pattern
- else
- pattern=spaces*Ct(value*(separator*value)^0)
- cache_a[symbol]=pattern
- end
- end
- return pattern
+ if not symbol then
+ symbol=","
+ end
+ local pattern=(withaction and cache_b or cache_a)[symbol]
+ if not pattern then
+ local symbols=S(symbol)
+ local separator=space^0*symbols*space^0
+ local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
+ if withaction then
+ local withvalue=Carg(1)*value/function(f,s) return f(s) end
+ pattern=spaces*withvalue*(separator*withvalue)^0
+ cache_b[symbol]=pattern
+ else
+ pattern=spaces*Ct(value*(separator*value)^0)
+ cache_a[symbol]=pattern
+ end
+ end
+ return pattern
end
local pattern_a=parsers.groupedsplitat(",",false)
local pattern_b=parsers.groupedsplitat(",",true)
function parsers.stripped_settings_to_array(str)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_a,str)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_a,str)
+ end
end
function parsers.process_stripped_settings(str,action)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_b,str,1,action)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_b,str,1,action)
+ end
end
local function set(t,v)
- t[#t+1]=v
+ t[#t+1]=v
end
local value=P(Carg(1)*value)/set
local pattern=value*(separator*value)^0*Carg(1)
function parsers.add_settings_to_array(t,str)
- return lpegmatch(pattern,str,nil,t)
+ return lpegmatch(pattern,str,nil,t)
end
function parsers.hash_to_string(h,separator,yes,no,strict,omit)
- if h then
- local t,tn,s={},0,sortedkeys(h)
- omit=omit and tohash(omit)
- for i=1,#s do
- local key=s[i]
- if not omit or not omit[key] then
- local value=h[key]
- if type(value)=="boolean" then
- if yes and no then
- if value then
- tn=tn+1
- t[tn]=key..'='..yes
- elseif not strict then
- tn=tn+1
- t[tn]=key..'='..no
- end
- elseif value or not strict then
- tn=tn+1
- t[tn]=key..'='..tostring(value)
- end
- else
- tn=tn+1
- t[tn]=key..'='..value
- end
- end
+ if h then
+ local t,tn,s={},0,sortedkeys(h)
+ omit=omit and tohash(omit)
+ for i=1,#s do
+ local key=s[i]
+ if not omit or not omit[key] then
+ local value=h[key]
+ if type(value)=="boolean" then
+ if yes and no then
+ if value then
+ tn=tn+1
+ t[tn]=key..'='..yes
+ elseif not strict then
+ tn=tn+1
+ t[tn]=key..'='..no
+ end
+ elseif value or not strict then
+ tn=tn+1
+ t[tn]=key..'='..tostring(value)
+ end
+ else
+ tn=tn+1
+ t[tn]=key..'='..value
end
- return concat(t,separator or ",")
- else
- return ""
+ end
end
+ return concat(t,separator or ",")
+ else
+ return ""
+ end
end
function parsers.array_to_string(a,separator)
- if a then
- return concat(a,separator or ",")
- else
- return ""
- end
+ if a then
+ return concat(a,separator or ",")
+ else
+ return ""
+ end
end
local pattern=Cf(Ct("")*Cg(C((1-S(", "))^1)*S(", ")^0*Cc(true))^1,rawset)
function utilities.parsers.settings_to_set(str)
- return str and lpegmatch(pattern,str) or {}
+ return str and lpegmatch(pattern,str) or {}
end
hashes.settings_to_set=table.setmetatableindex(function(t,k)
- local v=k and lpegmatch(pattern,k) or {}
- t[k]=v
- return v
+ local v=k and lpegmatch(pattern,k) or {}
+ t[k]=v
+ return v
end)
getmetatable(hashes.settings_to_set).__mode="kv"
function parsers.simple_hash_to_string(h,separator)
- local t,tn={},0
- for k,v in sortedhash(h) do
- if v then
- tn=tn+1
- t[tn]=k
- end
+ local t,tn={},0
+ for k,v in sortedhash(h) do
+ if v then
+ tn=tn+1
+ t[tn]=k
end
- return concat(t,separator or ",")
+ end
+ return concat(t,separator or ",")
end
local str=Cs(lpegpatterns.unquoted)+C((1-whitespace-equal)^1)
local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset)
local splitter=setting^1
function utilities.parsers.options_to_hash(str,target)
- return str and lpegmatch(splitter,str,1,target or {}) or {}
+ return str and lpegmatch(splitter,str,1,target or {}) or {}
end
local splitter=lpeg.tsplitat(" ")
function utilities.parsers.options_to_array(str)
- return str and lpegmatch(splitter,str) or {}
+ return str and lpegmatch(splitter,str) or {}
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1)
local pattern_a=spaces*Ct(value*(separator*value)^0)
local function repeater(n,str)
- if not n then
- return str
+ if not n then
+ return str
+ else
+ local s=lpegmatch(pattern_a,str)
+ if n==1 then
+ return unpack(s)
else
- local s=lpegmatch(pattern_a,str)
- if n==1 then
- return unpack(s)
- else
- local t,tn={},0
- for i=1,n do
- for j=1,#s do
- tn=tn+1
- t[tn]=s[j]
- end
- end
- return unpack(t)
+ local t,tn={},0
+ for i=1,n do
+ for j=1,#s do
+ tn=tn+1
+ t[tn]=s[j]
end
+ end
+ return unpack(t)
end
+ end
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+(C(digit^1)/tonumber*lparent*Cs((noparent+nestedparents)^1)*rparent)/repeater+C((nestedbraces+(1-comma))^1)
local pattern_b=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_with_repeat(str,expand)
- if expand then
- return lpegmatch(pattern_b,str) or {}
- else
- return lpegmatch(pattern_a,str) or {}
- end
+ if expand then
+ return lpegmatch(pattern_b,str) or {}
+ else
+ return lpegmatch(pattern_a,str) or {}
+ end
end
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace
local pattern=Ct((space+value)^0)
function parsers.arguments_to_table(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function parsers.getparameters(self,class,parentclass,settings)
- local sc=self[class]
- if not sc then
- sc={}
- self[class]=sc
- if parentclass then
- local sp=self[parentclass]
- if not sp then
- sp={}
- self[parentclass]=sp
- end
- setmetatableindex(sc,sp)
- end
+ local sc=self[class]
+ if not sc then
+ sc={}
+ self[class]=sc
+ if parentclass then
+ local sp=self[parentclass]
+ if not sp then
+ sp={}
+ self[parentclass]=sp
+ end
+ setmetatableindex(sc,sp)
end
- parsers.settings_to_hash(settings,sc)
+ end
+ parsers.settings_to_hash(settings,sc)
end
function parsers.listitem(str)
- return gmatch(str,"[^, ]+")
+ return gmatch(str,"[^, ]+")
end
local pattern=Cs { "start",
- start=V("one")+V("two")+V("three"),
- rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
- thousand=digit*digit*digit,
- one=digit*V("rest"),
- two=digit*digit*V("rest"),
- three=V("thousand")*V("rest"),
+ start=V("one")+V("two")+V("three"),
+ rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
+ thousand=digit*digit*digit,
+ one=digit*V("rest"),
+ two=digit*digit*V("rest"),
+ three=V("thousand")*V("rest"),
}
lpegpatterns.splitthousands=pattern
function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local optionalwhitespace=whitespace^0
lpegpatterns.words=Ct((Cs((1-punctuation-whitespace)^1)+anything)^1)
@@ -9131,75 +9131,75 @@ local key=C((1-equal)^1)
local value=dquote*C((1-dquote-escape*dquote)^0)*dquote
local pattern=Cf(Ct("")*(Cg(key*equal*value)*separator^0)^1,rawset)^0*P(-1)
function parsers.keq_to_hash(str)
- if str and str~="" then
- return lpegmatch(pattern,str)
- else
- return {}
- end
+ if str and str~="" then
+ return lpegmatch(pattern,str)
+ else
+ return {}
+ end
end
local defaultspecification={ separator=",",quote='"' }
function parsers.csvsplitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=specification.quote
- local separator=S(separator~="" and separator or ",")
- local whatever=C((1-separator-newline)^0)
- if quotechar and quotechar~="" then
- local quotedata=nil
- for chr in gmatch(quotechar,".") do
- local quotechar=P(chr)
- local quoteword=quotechar*C((1-quotechar)^0)*quotechar
- if quotedata then
- quotedata=quotedata+quoteword
- else
- quotedata=quoteword
- end
- end
- whatever=quotedata+whatever
- end
- local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
- return function(data)
- return lpegmatch(parser,data)
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=specification.quote
+ local separator=S(separator~="" and separator or ",")
+ local whatever=C((1-separator-newline)^0)
+ if quotechar and quotechar~="" then
+ local quotedata=nil
+ for chr in gmatch(quotechar,".") do
+ local quotechar=P(chr)
+ local quoteword=quotechar*C((1-quotechar)^0)*quotechar
+ if quotedata then
+ quotedata=quotedata+quoteword
+ else
+ quotedata=quoteword
+ end
end
+ whatever=quotedata+whatever
+ end
+ local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
+ return function(data)
+ return lpegmatch(parser,data)
+ end
end
function parsers.rfc4180splitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=P(specification.quote)
- local dquotechar=quotechar*quotechar
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=P(specification.quote)
+ local dquotechar=quotechar*quotechar
/specification.quote
- local separator=S(separator~="" and separator or ",")
- local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
- local non_escaped=C((1-quotechar-newline-separator)^1)
- local field=escaped+non_escaped+Cc("")
- local record=Ct(field*(separator*field)^1)
- local headerline=record*Cp()
- local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
- local headeryes=Ct(morerecords)
- local headernop=Ct(record*morerecords)
- return function(data,getheader)
- if getheader then
- local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(headeryes,data,position)
- return data,header
- else
- return lpegmatch(headernop,data)
- end
- end
+ local separator=S(separator~="" and separator or ",")
+ local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
+ local non_escaped=C((1-quotechar-newline-separator)^1)
+ local field=escaped+non_escaped+Cc("")
+ local record=Ct(field*(separator*field)^1)
+ local headerline=record*Cp()
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
+ return function(data,getheader)
+ if getheader then
+ local header,position=lpegmatch(headerline,data)
+ local data=lpegmatch(headeryes,data,position)
+ return data,header
+ else
+ return lpegmatch(headernop,data)
+ end
+ end
end
local function ranger(first,last,n,action)
- if not first then
- elseif last==true then
- for i=first,n or first do
- action(i)
- end
- elseif last then
- for i=first,last do
- action(i)
- end
- else
- action(first)
+ if not first then
+ elseif last==true then
+ for i=first,n or first do
+ action(i)
+ end
+ elseif last then
+ for i=first,last do
+ action(i)
end
+ else
+ action(first)
+ end
end
local cardinal=lpegpatterns.cardinal/tonumber
local spacers=lpegpatterns.spacer^0
@@ -9207,89 +9207,89 @@ local endofstring=lpegpatterns.endofstring
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
function parsers.stepper(str,n,action)
- if type(n)=="function" then
- lpegmatch(stepper,str,1,false,n or print)
- else
- lpegmatch(stepper,str,1,n,action or print)
- end
+ if type(n)=="function" then
+ lpegmatch(stepper,str,1,false,n or print)
+ else
+ lpegmatch(stepper,str,1,n,action or print)
+ end
end
local pattern_math=Cs((P("%")/"\\percent "+P("^")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
local pattern_text=Cs((P("%")/"\\percent "+(P("^")/"\\high")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
patterns.unittotex=pattern
function parsers.unittotex(str,textmode)
- return lpegmatch(textmode and pattern_text or pattern_math,str)
+ return lpegmatch(textmode and pattern_text or pattern_math,str)
end
local pattern=Cs((P("^")/"<sup>"*lpegpatterns.integer*Cc("</sup>")+anything)^0)
function parsers.unittoxml(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache={}
local spaces=lpegpatterns.space^0
local dummy=function() end
setmetatableindex(cache,function(t,k)
- local separator=P(k)
- local value=(1-separator)^0
- local pattern=spaces*C(value)*separator^0*Cp()
- t[k]=pattern
- return pattern
+ local separator=P(k)
+ local value=(1-separator)^0
+ local pattern=spaces*C(value)*separator^0*Cp()
+ t[k]=pattern
+ return pattern
end)
local commalistiterator=cache[","]
function utilities.parsers.iterator(str,separator)
- local n=#str
- if n==0 then
- return dummy
- else
- local pattern=separator and cache[separator] or commalistiterator
- local p=1
- return function()
- if p<=n then
- local s,e=lpegmatch(pattern,str,p)
- if e then
- p=e
- return s
- end
- end
+ local n=#str
+ if n==0 then
+ return dummy
+ else
+ local pattern=separator and cache[separator] or commalistiterator
+ local p=1
+ return function()
+ if p<=n then
+ local s,e=lpegmatch(pattern,str,p)
+ if e then
+ p=e
+ return s
end
+ end
end
+ end
end
local function initialize(t,name)
- local source=t[name]
- if source then
- local result={}
- for k,v in next,t[name] do
- result[k]=v
- end
- return result
- else
- return {}
+ local source=t[name]
+ if source then
+ local result={}
+ for k,v in next,t[name] do
+ result[k]=v
end
+ return result
+ else
+ return {}
+ end
end
local function fetch(t,name)
- return t[name] or {}
+ return t[name] or {}
end
local function process(result,more)
- for k,v in next,more do
- result[k]=v
- end
- return result
+ for k,v in next,more do
+ result[k]=v
+ end
+ return result
end
local name=C((1-S(", "))^1)
local parser=(Carg(1)*name/initialize)*(S(", ")^1*(Carg(1)*name/fetch))^0
local merge=Cf(parser,process)
function utilities.parsers.mergehashes(hash,list)
- return lpegmatch(merge,list,1,hash)
+ return lpegmatch(merge,list,1,hash)
end
function utilities.parsers.runtime(time)
- if not time then
- time=os.runtime()
- end
- local days=div(time,24*60*60)
- time=mod(time,24*60*60)
- local hours=div(time,60*60)
- time=mod(time,60*60)
- local minutes=div(time,60)
- local seconds=mod(time,60)
- return days,hours,minutes,seconds
+ if not time then
+ time=os.runtime()
+ end
+ local days=div(time,24*60*60)
+ time=mod(time,24*60*60)
+ local hours=div(time,60*60)
+ time=mod(time,60*60)
+ local minutes=div(time,60)
+ local seconds=mod(time,60)
+ return days,hours,minutes,seconds
end
local spacing=whitespace^0
local apply=P("->")
@@ -9297,11 +9297,11 @@ local method=C((1-apply)^1)
local token=lbrace*C((1-rbrace)^1)*rbrace+C(anything^1)
local pattern=spacing*(method*spacing*apply+Carg(1))*spacing*token
function utilities.parsers.splitmethod(str,default)
- if str then
- return lpegmatch(pattern,str,1,default or false)
- else
- return default or false,""
- end
+ if str then
+ return lpegmatch(pattern,str,1,default or false)
+ else
+ return default or false,""
+ end
end
@@ -9311,14 +9311,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fmt"] = package.loaded["util-fmt"] or true
--- original size: 2274, stripped down to: 1781
+-- original size: 2274, stripped down to: 1607
if not modules then modules={} end modules ['util-fmt']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.formatters=utilities.formatters or {}
@@ -9329,60 +9329,60 @@ local strip=string.strip
local lpegmatch=lpeg.match
local stripper=lpeg.patterns.stripzeros
function formatters.stripzeros(str)
- return lpegmatch(stripper,str)
+ return lpegmatch(stripper,str)
end
function formatters.formatcolumns(result,between)
- if result and #result>0 then
- between=between or " "
- local widths,numbers={},{}
- local first=result[1]
- local n=#first
- for i=1,n do
- widths[i]=0
- end
- for i=1,#result do
- local r=result[i]
- for j=1,n do
- local rj=r[j]
- local tj=type(rj)
- if tj=="number" then
- numbers[j]=true
- end
- if tj~="string" then
- rj=tostring(rj)
- r[j]=rj
- end
- local w=#rj
- if w>widths[j] then
- widths[j]=w
- end
- end
+ if result and #result>0 then
+ between=between or " "
+ local widths,numbers={},{}
+ local first=result[1]
+ local n=#first
+ for i=1,n do
+ widths[i]=0
+ end
+ for i=1,#result do
+ local r=result[i]
+ for j=1,n do
+ local rj=r[j]
+ local tj=type(rj)
+ if tj=="number" then
+ numbers[j]=true
+ end
+ if tj~="string" then
+ rj=tostring(rj)
+ r[j]=rj
+ end
+ local w=#rj
+ if w>widths[j] then
+ widths[j]=w
end
- for i=1,n do
- local w=widths[i]
- if numbers[i] then
- if w>80 then
- widths[i]="%s"..between
- else
- widths[i]="%0"..w.."i"..between
- end
- else
- if w>80 then
- widths[i]="%s"..between
- elseif w>0 then
- widths[i]="%-"..w.."s"..between
- else
- widths[i]="%s"
- end
- end
+ end
+ end
+ for i=1,n do
+ local w=widths[i]
+ if numbers[i] then
+ if w>80 then
+ widths[i]="%s"..between
+ else
+ widths[i]="%0"..w.."i"..between
end
- local template=strip(concat(widths))
- for i=1,#result do
- local str=format(template,unpack(result[i]))
- result[i]=strip(str)
+ else
+ if w>80 then
+ widths[i]="%s"..between
+ elseif w>0 then
+ widths[i]="%-"..w.."s"..between
+ else
+ widths[i]="%s"
end
+ end
end
- return result
+ local template=strip(concat(widths))
+ for i=1,#result do
+ local str=format(template,unpack(result[i]))
+ result[i]=strip(str)
+ end
+ end
+ return result
end
@@ -9414,7 +9414,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true
--- original size: 4870, stripped down to: 3861
+-- original size: 4870, stripped down to: 3527
local type,tostring,setmetatable=type,tostring,setmetatable
@@ -9427,67 +9427,67 @@ local tcp6=socket.tcp6
local getaddrinfo=socket.dns.getaddrinfo
local defaulthost="0.0.0.0"
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("socket")
- report(fmt,first,...)
- elseif fmt then
- fmt="socket: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("socket")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="socket: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
socket.report=report
function socket.connect4(address,port,laddress,lport)
- return connect(address,port,laddress,lport,"inet")
+ return connect(address,port,laddress,lport,"inet")
end
function socket.connect6(address,port,laddress,lport)
- return connect(address,port,laddress,lport,"inet6")
+ return connect(address,port,laddress,lport,"inet6")
end
function socket.bind(host,port,backlog)
- if host=="*" or host=="" then
- host=defaulthost
- end
- local addrinfo,err=getaddrinfo(host)
- if not addrinfo then
- return nil,err
- end
- for i=1,#addrinfo do
- local alt=addrinfo[i]
- local sock,err=(alt.family=="inet" and tcp4 or tcp6)()
- if not sock then
- return nil,err or "unknown error"
- end
- sock:setoption("reuseaddr",true)
- local res,err=sock:bind(alt.addr,port)
- if res then
- res,err=sock:listen(backlog)
- if res then
- return sock
- else
- sock:close()
- end
- else
- sock:close()
- end
+ if host=="*" or host=="" then
+ host=defaulthost
+ end
+ local addrinfo,err=getaddrinfo(host)
+ if not addrinfo then
+ return nil,err
+ end
+ for i=1,#addrinfo do
+ local alt=addrinfo[i]
+ local sock,err=(alt.family=="inet" and tcp4 or tcp6)()
+ if not sock then
+ return nil,err or "unknown error"
+ end
+ sock:setoption("reuseaddr",true)
+ local res,err=sock:bind(alt.addr,port)
+ if res then
+ res,err=sock:listen(backlog)
+ if res then
+ return sock
+ else
+ sock:close()
+ end
+ else
+ sock:close()
end
- return nil,"invalid address"
+ end
+ return nil,"invalid address"
end
socket.try=socket.newtry()
function socket.choose(list)
- return function(name,opt1,opt2)
- if type(name)~="string" then
- name,opt1,opt2="default",name,opt1
- end
- local f=list[name or "nil"]
- if f then
- return f(opt1,opt2)
- else
- report("error: unknown key '%s'",tostring(name))
- end
+ return function(name,opt1,opt2)
+ if type(name)~="string" then
+ name,opt1,opt2="default",name,opt1
+ end
+ local f=list[name or "nil"]
+ if f then
+ return f(opt1,opt2)
+ else
+ report("error: unknown key '%s'",tostring(name))
end
+ end
end
local sourcet={}
local sinkt={}
@@ -9495,88 +9495,88 @@ socket.sourcet=sourcet
socket.sinkt=sinkt
socket.BLOCKSIZE=2048
sinkt["close-when-done"]=function(sock)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function(self,chunk,err)
- if chunk then
- return sock:send(chunk)
- else
- sock:close()
- return 1
- end
- end
- }
- )
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },
+ {
+ __call=function(self,chunk,err)
+ if chunk then
+ return sock:send(chunk)
+ else
+ sock:close()
+ return 1
+ end
+ end
+ }
+ )
end
sinkt["keep-open"]=function(sock)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function(self,chunk,err)
- if chunk then
- return sock:send(chunk)
- else
- return 1
- end
- end
- }
- )
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },{
+ __call=function(self,chunk,err)
+ if chunk then
+ return sock:send(chunk)
+ else
+ return 1
+ end
+ end
+ }
+ )
end
sinkt["default"]=sinkt["keep-open"]
socket.sink=socket.choose(sinkt)
sourcet["by-length"]=function(sock,length)
- local blocksize=socket.BLOCKSIZE
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function()
- if length<=0 then
- return nil
- end
- local chunk,err=sock:receive(min(blocksize,length))
- if err then
- return nil,err
- end
- length=length-#chunk
- return chunk
- end
- }
- )
+ local blocksize=socket.BLOCKSIZE
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },
+ {
+ __call=function()
+ if length<=0 then
+ return nil
+ end
+ local chunk,err=sock:receive(min(blocksize,length))
+ if err then
+ return nil,err
+ end
+ length=length-#chunk
+ return chunk
+ end
+ }
+ )
end
sourcet["until-closed"]=function(sock)
- local blocksize=socket.BLOCKSIZE
- local done=false
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function()
- if done then
- return nil
- end
- local chunk,status,partial=sock:receive(blocksize)
- if not status then
- return chunk
- elseif status=="closed" then
- sock:close()
- done=true
- return partial
- else
- return nil,status
- end
- end
- }
- )
+ local blocksize=socket.BLOCKSIZE
+ local done=false
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },{
+ __call=function()
+ if done then
+ return nil
+ end
+ local chunk,status,partial=sock:receive(blocksize)
+ if not status then
+ return chunk
+ elseif status=="closed" then
+ sock:close()
+ done=true
+ return partial
+ else
+ return nil,status
+ end
+ end
+ }
+ )
end
sourcet["default"]=sourcet["until-closed"]
socket.source=socket.choose(sourcet)
@@ -9590,7 +9590,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
--- original size: 25844, stripped down to: 16066
+-- original size: 25844, stripped down to: 14821
local socket=socket or require("socket")
@@ -9608,333 +9608,333 @@ local resumecoroutine=coroutine.resume
local yieldcoroutine=coroutine.yield
local runningcoroutine=coroutine.running
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("copas")
- report(fmt,first,...)
- elseif fmt then
- fmt="copas: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("copas")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="copas: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
local copas={
- _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project",
- _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services",
- _VERSION="Copas 2.0.1",
- autoclose=true,
- running=false,
- report=report,
+ _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project",
+ _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services",
+ _VERSION="Copas 2.0.1",
+ autoclose=true,
+ running=false,
+ report=report,
}
local function statushandler(status,...)
- if status then
- return...
- end
- local err=(...)
- if type(err)=="table" then
- err=err[1]
- end
- report("error: %s",tostring(err))
- return nil,err
+ if status then
+ return...
+ end
+ local err=(...)
+ if type(err)=="table" then
+ err=err[1]
+ end
+ report("error: %s",tostring(err))
+ return nil,err
end
function socket.protect(func)
- return function(...)
- return statushandler(pcall(func,...))
- end
+ return function(...)
+ return statushandler(pcall(func,...))
+ end
end
function socket.newtry(finalizer)
- return function (...)
- local status=(...)
- if not status then
- local detail=select(2,...)
- pcall(finalizer,detail)
- report("error: %s",tostring(detail))
- return
- end
- return...
+ return function (...)
+ local status=(...)
+ if not status then
+ local detail=select(2,...)
+ pcall(finalizer,detail)
+ report("error: %s",tostring(detail))
+ return
end
+ return...
+ end
end
local function newset()
- local reverse={}
- local set={}
- local queue={}
- setmetatable(set,{
- __index={
- insert=function(set,value)
- if not reverse[value] then
- local n=#set+1
- set[n]=value
- reverse[value]=n
- end
- end,
- remove=function(set,value)
- local index=reverse[value]
- if index then
- reverse[value]=nil
- local n=#set
- local top=set[n]
- set[n]=nil
- if top~=value then
- reverse[top]=index
- set[index]=top
- end
- end
- end,
- push=function (set,key,itm)
- local entry=queue[key]
- if entry==nil then
- queue[key]={ itm }
- else
- entry[#entry+1]=itm
- end
- end,
- pop=function (set,key)
- local top=queue[key]
- if top~=nil then
- local ret=remove(top,1)
- if top[1]==nil then
- queue[key]=nil
- end
- return ret
- end
- end
- }
- } )
- return set
-end
-local _sleeping={
- times={},
- cos={},
- lethargy={},
- insert=function()
- end,
- remove=function()
+ local reverse={}
+ local set={}
+ local queue={}
+ setmetatable(set,{
+ __index={
+ insert=function(set,value)
+ if not reverse[value] then
+ local n=#set+1
+ set[n]=value
+ reverse[value]=n
+ end
end,
- push=function(self,sleeptime,co)
- if not co then
- return
- end
- if sleeptime<0 then
- self.lethargy[co]=true
- return
- else
- sleeptime=gettime()+sleeptime
+ remove=function(set,value)
+ local index=reverse[value]
+ if index then
+ reverse[value]=nil
+ local n=#set
+ local top=set[n]
+ set[n]=nil
+ if top~=value then
+ reverse[top]=index
+ set[index]=top
end
- local t=self.times
- local c=self.cos
- local i=1
- local n=#t
- while i<=n and t[i]<=sleeptime do
- i=i+1
- end
- insert(t,i,sleeptime)
- insert(c,i,co)
- end,
- getnext=
- function(self)
- local t=self.times
- local delay=t[1] and t[1]-gettime() or nil
- return delay and max(delay,0) or nil
+ end
end,
- pop=
- function(self,time)
- local t=self.times
- local c=self.cos
- if #t==0 or time<t[1] then
- return
- end
- local co=c[1]
- remove(t,1)
- remove(c,1)
- return co
+ push=function (set,key,itm)
+ local entry=queue[key]
+ if entry==nil then
+ queue[key]={ itm }
+ else
+ entry[#entry+1]=itm
+ end
end,
- wakeup=function(self,co)
- local let=self.lethargy
- if let[co] then
- self:push(0,co)
- let[co]=nil
- else
- local c=self.cos
- local t=self.times
- for i=1,#c do
- if c[i]==co then
- remove(c,i)
- remove(t,i)
- self:push(0,co)
- return
- end
- end
- end
+ pop=function (set,key)
+ local top=queue[key]
+ if top~=nil then
+ local ret=remove(top,1)
+ if top[1]==nil then
+ queue[key]=nil
+ end
+ return ret
+ end
+ end
+ }
+ } )
+ return set
+end
+local _sleeping={
+ times={},
+ cos={},
+ lethargy={},
+ insert=function()
+ end,
+ remove=function()
+ end,
+ push=function(self,sleeptime,co)
+ if not co then
+ return
+ end
+ if sleeptime<0 then
+ self.lethargy[co]=true
+ return
+ else
+ sleeptime=gettime()+sleeptime
+ end
+ local t=self.times
+ local c=self.cos
+ local i=1
+ local n=#t
+ while i<=n and t[i]<=sleeptime do
+ i=i+1
+ end
+ insert(t,i,sleeptime)
+ insert(c,i,co)
+ end,
+ getnext=
+ function(self)
+ local t=self.times
+ local delay=t[1] and t[1]-gettime() or nil
+ return delay and max(delay,0) or nil
+ end,
+ pop=
+ function(self,time)
+ local t=self.times
+ local c=self.cos
+ if #t==0 or time<t[1] then
+ return
+ end
+ local co=c[1]
+ remove(t,1)
+ remove(c,1)
+ return co
+ end,
+ wakeup=function(self,co)
+ local let=self.lethargy
+ if let[co] then
+ self:push(0,co)
+ let[co]=nil
+ else
+ local c=self.cos
+ local t=self.times
+ for i=1,#c do
+ if c[i]==co then
+ remove(c,i)
+ remove(t,i)
+ self:push(0,co)
+ return
end
+ end
+ end
+ end
}
local _servers=newset()
local _reading=newset()
local _writing=newset()
local _reading_log={}
local _writing_log={}
-local _is_timeout={
- timeout=true,
- wantread=true,
- wantwrite=true,
+local _is_timeout={
+ timeout=true,
+ wantread=true,
+ wantwrite=true,
}
local function isTCP(socket)
- return not find(tostring(socket),"^udp")
+ return not find(tostring(socket),"^udp")
end
local function copasreceive(client,pattern,part)
- if not pattern or pattern=="" then
- pattern="*l"
- end
- local current_log=_reading_log
- local s,err
- repeat
- s,err,part=client:receive(pattern,part)
- if s or (not _is_timeout[err]) then
- current_log[client]=nil
- return s,err,part
- end
- if err=="wantwrite" then
- current_log=_writing_log
- current_log[client]=gettime()
- yieldcoroutine(client,_writing)
- else
- current_log=_reading_log
- current_log[client]=gettime()
- yieldcoroutine(client,_reading)
- end
- until false
+ if not pattern or pattern=="" then
+ pattern="*l"
+ end
+ local current_log=_reading_log
+ local s,err
+ repeat
+ s,err,part=client:receive(pattern,part)
+ if s or (not _is_timeout[err]) then
+ current_log[client]=nil
+ return s,err,part
+ end
+ if err=="wantwrite" then
+ current_log=_writing_log
+ current_log[client]=gettime()
+ yieldcoroutine(client,_writing)
+ else
+ current_log=_reading_log
+ current_log[client]=gettime()
+ yieldcoroutine(client,_reading)
+ end
+ until false
end
local function copasreceivefrom(client,size)
- local s,err,port
- if not size or size==0 then
- size=UDP_DATAGRAM_MAX
- end
- repeat
- s,err,port=client:receivefrom(size)
- if s or err~="timeout" then
- _reading_log[client]=nil
- return s,err,port
- end
- _reading_log[client]=gettime()
- yieldcoroutine(client,_reading)
- until false
+ local s,err,port
+ if not size or size==0 then
+ size=UDP_DATAGRAM_MAX
+ end
+ repeat
+ s,err,port=client:receivefrom(size)
+ if s or err~="timeout" then
+ _reading_log[client]=nil
+ return s,err,port
+ end
+ _reading_log[client]=gettime()
+ yieldcoroutine(client,_reading)
+ until false
end
local function copasreceivepartial(client,pattern,part)
- if not pattern or pattern=="" then
- pattern="*l"
- end
- local logger=_reading_log
- local queue=_reading
- local s,err
- repeat
- s,err,part=client:receive(pattern,part)
- if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then
- logger[client]=nil
- return s,err,part
- end
- if err=="wantwrite" then
- logger=_writing_log
- queue=_writing
- else
- logger=_reading_log
- queue=_reading
- end
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- until false
+ if not pattern or pattern=="" then
+ pattern="*l"
+ end
+ local logger=_reading_log
+ local queue=_reading
+ local s,err
+ repeat
+ s,err,part=client:receive(pattern,part)
+ if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then
+ logger[client]=nil
+ return s,err,part
+ end
+ if err=="wantwrite" then
+ logger=_writing_log
+ queue=_writing
+ else
+ logger=_reading_log
+ queue=_reading
+ end
+ logger[client]=gettime()
+ yieldcoroutine(client,queue)
+ until false
end
local function copassend(client,data,from,to)
- if not from then
- from=1
- end
- local lastIndex=from-1
- local logger=_writing_log
- local queue=_writing
- local s,err
- repeat
- s,err,lastIndex=client:send(data,lastIndex+1,to)
- if random(100)>90 then
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- end
- if s or not _is_timeout[err] then
- logger[client]=nil
- return s,err,lastIndex
- end
- if err=="wantread" then
- logger=_reading_log
- queue=_reading
- else
- logger=_writing_log
- queue=_writing
- end
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- until false
+ if not from then
+ from=1
+ end
+ local lastIndex=from-1
+ local logger=_writing_log
+ local queue=_writing
+ local s,err
+ repeat
+ s,err,lastIndex=client:send(data,lastIndex+1,to)
+ if random(100)>90 then
+ logger[client]=gettime()
+ yieldcoroutine(client,queue)
+ end
+ if s or not _is_timeout[err] then
+ logger[client]=nil
+ return s,err,lastIndex
+ end
+ if err=="wantread" then
+ logger=_reading_log
+ queue=_reading
+ else
+ logger=_writing_log
+ queue=_writing
+ end
+ logger[client]=gettime()
+ yieldcoroutine(client,queue)
+ until false
end
local function copassendto(client,data,ip,port)
- repeat
- local s,err=client:sendto(data,ip,port)
- if random(100)>90 then
- _writing_log[client]=gettime()
- yieldcoroutine(client,_writing)
- end
- if s or err~="timeout" then
- _writing_log[client]=nil
- return s,err
- end
- _writing_log[client]=gettime()
- yieldcoroutine(client,_writing)
- until false
+ repeat
+ local s,err=client:sendto(data,ip,port)
+ if random(100)>90 then
+ _writing_log[client]=gettime()
+ yieldcoroutine(client,_writing)
+ end
+ if s or err~="timeout" then
+ _writing_log[client]=nil
+ return s,err
+ end
+ _writing_log[client]=gettime()
+ yieldcoroutine(client,_writing)
+ until false
end
local function copasconnect(skt,host,port)
- skt:settimeout(0)
- local ret,err,tried_more_than_once
- repeat
- ret,err=skt:connect (host,port)
- if ret or (err~="timeout" and err~="Operation already in progress") then
- if not ret and err=="already connected" and tried_more_than_once then
- ret=1
- err=nil
- end
- _writing_log[skt]=nil
- return ret,err
- end
- tried_more_than_once=tried_more_than_once or true
- _writing_log[skt]=gettime()
- yieldcoroutine(skt,_writing)
- until false
+ skt:settimeout(0)
+ local ret,err,tried_more_than_once
+ repeat
+ ret,err=skt:connect (host,port)
+ if ret or (err~="timeout" and err~="Operation already in progress") then
+ if not ret and err=="already connected" and tried_more_than_once then
+ ret=1
+ err=nil
+ end
+ _writing_log[skt]=nil
+ return ret,err
+ end
+ tried_more_than_once=tried_more_than_once or true
+ _writing_log[skt]=gettime()
+ yieldcoroutine(skt,_writing)
+ until false
end
local function copasdohandshake(skt,sslt)
- if not ssl then
- ssl=require("ssl")
- end
- if not ssl then
- report("error: no ssl library")
- return
- end
- local nskt,err=ssl.wrap(skt,sslt)
- if not nskt then
- report("error: %s",tostring(err))
- return
- end
- nskt:settimeout(0)
- local queue
- repeat
- local success,err=nskt:dohandshake()
- if success then
- return nskt
- elseif err=="wantwrite" then
- queue=_writing
- elseif err=="wantread" then
- queue=_reading
- else
- report("error: %s",tostring(err))
- return
- end
- yieldcoroutine(nskt,queue)
- until false
+ if not ssl then
+ ssl=require("ssl")
+ end
+ if not ssl then
+ report("error: no ssl library")
+ return
+ end
+ local nskt,err=ssl.wrap(skt,sslt)
+ if not nskt then
+ report("error: %s",tostring(err))
+ return
+ end
+ nskt:settimeout(0)
+ local queue
+ repeat
+ local success,err=nskt:dohandshake()
+ if success then
+ return nskt
+ elseif err=="wantwrite" then
+ queue=_writing
+ elseif err=="wantread" then
+ queue=_reading
+ else
+ report("error: %s",tostring(err))
+ return
+ end
+ yieldcoroutine(nskt,queue)
+ until false
end
local function copasflush(client)
end
@@ -9948,326 +9948,326 @@ copas.copasreceivePartial=copasreceivepartial
copas.dohandshake=copasdohandshake
copas.flush=copasflush
local function _skt_mt_tostring(self)
- return tostring(self.socket).." (copas wrapped)"
+ return tostring(self.socket).." (copas wrapped)"
end
local _skt_mt_tcp_index={
- send=function(self,data,from,to)
- return copassend (self.socket,data,from,to)
- end,
- receive=function (self,pattern,prefix)
- if self.timeout==0 then
- return copasreceivePartial(self.socket,pattern,prefix)
- else
- return copasreceive(self.socket,pattern,prefix)
- end
- end,
- flush=function (self)
- return copasflush(self.socket)
- end,
- settimeout=function (self,time)
- self.timeout=time
- return true
- end,
- connect=function(self,...)
- local res,err=copasconnect(self.socket,...)
- if res and self.ssl_params then
- res,err=self:dohandshake()
- end
- return res,err
- end,
- close=function(self,...)
- return self.socket:close(...)
- end,
- bind=function(self,...)
- return self.socket:bind(...)
- end,
- getsockname=function(self,...)
- return self.socket:getsockname(...)
- end,
- getstats=function(self,...)
- return self.socket:getstats(...)
- end,
- setstats=function(self,...)
- return self.socket:setstats(...)
- end,
- listen=function(self,...)
- return self.socket:listen(...)
- end,
- accept=function(self,...)
- return self.socket:accept(...)
- end,
- setoption=function(self,...)
- return self.socket:setoption(...)
- end,
- getpeername=function(self,...)
- return self.socket:getpeername(...)
- end,
- shutdown=function(self,...)
- return self.socket:shutdown(...)
- end,
- dohandshake=function(self,sslt)
- self.ssl_params=sslt or self.ssl_params
- local nskt,err=copasdohandshake(self.socket,self.ssl_params)
- if not nskt then
- return nskt,err
- end
- self.socket=nskt
- return self
- end,
+ send=function(self,data,from,to)
+ return copassend (self.socket,data,from,to)
+ end,
+ receive=function (self,pattern,prefix)
+ if self.timeout==0 then
+ return copasreceivePartial(self.socket,pattern,prefix)
+ else
+ return copasreceive(self.socket,pattern,prefix)
+ end
+ end,
+ flush=function (self)
+ return copasflush(self.socket)
+ end,
+ settimeout=function (self,time)
+ self.timeout=time
+ return true
+ end,
+ connect=function(self,...)
+ local res,err=copasconnect(self.socket,...)
+ if res and self.ssl_params then
+ res,err=self:dohandshake()
+ end
+ return res,err
+ end,
+ close=function(self,...)
+ return self.socket:close(...)
+ end,
+ bind=function(self,...)
+ return self.socket:bind(...)
+ end,
+ getsockname=function(self,...)
+ return self.socket:getsockname(...)
+ end,
+ getstats=function(self,...)
+ return self.socket:getstats(...)
+ end,
+ setstats=function(self,...)
+ return self.socket:setstats(...)
+ end,
+ listen=function(self,...)
+ return self.socket:listen(...)
+ end,
+ accept=function(self,...)
+ return self.socket:accept(...)
+ end,
+ setoption=function(self,...)
+ return self.socket:setoption(...)
+ end,
+ getpeername=function(self,...)
+ return self.socket:getpeername(...)
+ end,
+ shutdown=function(self,...)
+ return self.socket:shutdown(...)
+ end,
+ dohandshake=function(self,sslt)
+ self.ssl_params=sslt or self.ssl_params
+ local nskt,err=copasdohandshake(self.socket,self.ssl_params)
+ if not nskt then
+ return nskt,err
+ end
+ self.socket=nskt
+ return self
+ end,
}
local _skt_mt_tcp={
- __tostring=_skt_mt_tostring,
- __index=_skt_mt_tcp_index,
+ __tostring=_skt_mt_tostring,
+ __index=_skt_mt_tcp_index,
}
local _skt_mt_udp_index={
- sendto=function (self,...)
- return copassendto(self.socket,...)
- end,
- receive=function (self,size)
- return copasreceive(self.socket,size or UDP_DATAGRAM_MAX)
- end,
- receivefrom=function (self,size)
- return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX)
- end,
- setpeername=function(self,...)
- return self.socket:getpeername(...)
- end,
- setsockname=function(self,...)
- return self.socket:setsockname(...)
- end,
- close=function(self,...)
- return true
- end
+ sendto=function (self,...)
+ return copassendto(self.socket,...)
+ end,
+ receive=function (self,size)
+ return copasreceive(self.socket,size or UDP_DATAGRAM_MAX)
+ end,
+ receivefrom=function (self,size)
+ return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX)
+ end,
+ setpeername=function(self,...)
+ return self.socket:getpeername(...)
+ end,
+ setsockname=function(self,...)
+ return self.socket:setsockname(...)
+ end,
+ close=function(self,...)
+ return true
+ end
}
local _skt_mt_udp={
- __tostring=_skt_mt_tostring,
- __index=_skt_mt_udp_index,
+ __tostring=_skt_mt_tostring,
+ __index=_skt_mt_udp_index,
}
for k,v in next,_skt_mt_tcp_index do
- if not _skt_mt_udp_index[k] then
- _skt_mt_udp_index[k]=v
- end
+ if not _skt_mt_udp_index[k] then
+ _skt_mt_udp_index[k]=v
+ end
end
local function wrap(skt,sslt)
- if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
- return skt
- end
- skt:settimeout(0)
- if isTCP(skt) then
- return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp)
- else
- return setmetatable ({ socket=skt },_skt_mt_udp)
- end
+ if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
+ return skt
+ end
+ skt:settimeout(0)
+ if isTCP(skt) then
+ return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp)
+ else
+ return setmetatable ({ socket=skt },_skt_mt_udp)
+ end
end
copas.wrap=wrap
function copas.handler(handler,sslparams)
- return function (skt,...)
- skt=wrap(skt)
- if sslparams then
- skt:dohandshake(sslparams)
- end
- return handler(skt,...)
+ return function (skt,...)
+ skt=wrap(skt)
+ if sslparams then
+ skt:dohandshake(sslparams)
end
+ return handler(skt,...)
+ end
end
local _errhandlers={}
function copas.setErrorHandler(err)
- local co=runningcoroutine()
- if co then
- _errhandlers[co]=err
- end
+ local co=runningcoroutine()
+ if co then
+ _errhandlers[co]=err
+ end
end
local function _deferror (msg,co,skt)
- report("%s (%s) (%s)",msg,tostring(co),tostring(skt))
+ report("%s (%s) (%s)",msg,tostring(co),tostring(skt))
end
local function _doTick (co,skt,...)
- if not co then
- return
+ if not co then
+ return
+ end
+ local ok,res,new_q=resumecoroutine(co,skt,...)
+ if ok and res and new_q then
+ new_q:insert(res)
+ new_q:push(res,co)
+ else
+ if not ok then
+ pcall(_errhandlers[co] or _deferror,res,co,skt)
end
- local ok,res,new_q=resumecoroutine(co,skt,...)
- if ok and res and new_q then
- new_q:insert(res)
- new_q:push(res,co)
- else
- if not ok then
- pcall(_errhandlers[co] or _deferror,res,co,skt)
- end
- if skt and copas.autoclose and isTCP(skt) then
- skt:close()
- end
- _errhandlers[co]=nil
+ if skt and copas.autoclose and isTCP(skt) then
+ skt:close()
end
+ _errhandlers[co]=nil
+ end
end
local function _accept(input,handler)
- local client=input:accept()
- if client then
- client:settimeout(0)
- local co=createcoroutine(handler)
- _doTick (co,client)
- end
- return client
+ local client=input:accept()
+ if client then
+ client:settimeout(0)
+ local co=createcoroutine(handler)
+ _doTick (co,client)
+ end
+ return client
end
local function _tickRead(skt)
- _doTick(_reading:pop(skt),skt)
+ _doTick(_reading:pop(skt),skt)
end
local function _tickWrite(skt)
- _doTick(_writing:pop(skt),skt)
+ _doTick(_writing:pop(skt),skt)
end
local function addTCPserver(server,handler,timeout)
- server:settimeout(timeout or 0)
- _servers[server]=handler
- _reading:insert(server)
+ server:settimeout(timeout or 0)
+ _servers[server]=handler
+ _reading:insert(server)
end
local function addUDPserver(server,handler,timeout)
- server:settimeout(timeout or 0)
- local co=createcoroutine(handler)
- _reading:insert(server)
- _doTick(co,server)
+ server:settimeout(timeout or 0)
+ local co=createcoroutine(handler)
+ _reading:insert(server)
+ _doTick(co,server)
end
function copas.addserver(server,handler,timeout)
- if isTCP(server) then
- addTCPserver(server,handler,timeout)
- else
- addUDPserver(server,handler,timeout)
- end
+ if isTCP(server) then
+ addTCPserver(server,handler,timeout)
+ else
+ addUDPserver(server,handler,timeout)
+ end
end
function copas.removeserver(server,keep_open)
- local s=server
- local mt=getmetatable(server)
- if mt==_skt_mt_tcp or mt==_skt_mt_udp then
- s=server.socket
- end
- _servers[s]=nil
- _reading:remove(s)
- if keep_open then
- return true
- end
- return server:close()
+ local s=server
+ local mt=getmetatable(server)
+ if mt==_skt_mt_tcp or mt==_skt_mt_udp then
+ s=server.socket
+ end
+ _servers[s]=nil
+ _reading:remove(s)
+ if keep_open then
+ return true
+ end
+ return server:close()
end
function copas.addthread(handler,...)
- local thread=createcoroutine(function(_,...) return handler(...) end)
- _doTick(thread,nil,...)
- return thread
+ local thread=createcoroutine(function(_,...) return handler(...) end)
+ _doTick(thread,nil,...)
+ return thread
end
local _tasks={}
local function addtaskRead(task)
- task.def_tick=_tickRead
- _tasks[task]=true
+ task.def_tick=_tickRead
+ _tasks[task]=true
end
local function addtaskWrite(task)
- task.def_tick=_tickWrite
- _tasks[task]=true
+ task.def_tick=_tickWrite
+ _tasks[task]=true
end
local function tasks()
- return next,_tasks
+ return next,_tasks
end
local _readable_t={
- events=function(self)
- local i=0
- return function ()
- i=i+1
- return self._evs[i]
- end
- end,
- tick=function(self,input)
- local handler=_servers[input]
- if handler then
- input=_accept(input,handler)
- else
- _reading:remove(input)
- self.def_tick(input)
- end
- end
+ events=function(self)
+ local i=0
+ return function ()
+ i=i+1
+ return self._evs[i]
+ end
+ end,
+ tick=function(self,input)
+ local handler=_servers[input]
+ if handler then
+ input=_accept(input,handler)
+ else
+ _reading:remove(input)
+ self.def_tick(input)
+ end
+ end
}
addtaskRead(_readable_t)
local _writable_t={
- events=function(self)
- local i=0
- return function()
- i=i+1
- return self._evs[i]
- end
- end,
- tick=function(self,output)
- _writing:remove(output)
- self.def_tick(output)
- end
+ events=function(self)
+ local i=0
+ return function()
+ i=i+1
+ return self._evs[i]
+ end
+ end,
+ tick=function(self,output)
+ _writing:remove(output)
+ self.def_tick(output)
+ end
}
addtaskWrite(_writable_t)
local _sleeping_t={
- tick=function(self,time,...)
- _doTick(_sleeping:pop(time),...)
- end
+ tick=function(self,time,...)
+ _doTick(_sleeping:pop(time),...)
+ end
}
function copas.sleep(sleeptime)
- yieldcoroutine((sleeptime or 0),_sleeping)
+ yieldcoroutine((sleeptime or 0),_sleeping)
end
function copas.wakeup(co)
- _sleeping:wakeup(co)
+ _sleeping:wakeup(co)
end
local last_cleansing=0
local function _select(timeout)
- local now=gettime()
- local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout)
- _readable_t._evs=r_evs
- _writable_t._evs=w_evs
- if (last_cleansing-now)>WATCH_DOG_TIMEOUT then
- last_cleansing=now
- for skt,time in next,_reading_log do
- if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
- local n=#r_evs+1
- _reading_log[skt]=nil
- r_evs[n]=skt
- r_evs[skt]=n
- end
- end
- for skt,time in next,_writing_log do
- if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
- local n=#w_evs+1
- _writing_log[skt]=nil
- w_evs[n]=skt
- w_evs[skt]=n
- end
- end
+ local now=gettime()
+ local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout)
+ _readable_t._evs=r_evs
+ _writable_t._evs=w_evs
+ if (last_cleansing-now)>WATCH_DOG_TIMEOUT then
+ last_cleansing=now
+ for skt,time in next,_reading_log do
+ if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
+ local n=#r_evs+1
+ _reading_log[skt]=nil
+ r_evs[n]=skt
+ r_evs[skt]=n
+ end
end
- if err=="timeout" and #r_evs+#w_evs>0 then
- return nil
- else
- return err
+ for skt,time in next,_writing_log do
+ if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
+ local n=#w_evs+1
+ _writing_log[skt]=nil
+ w_evs[n]=skt
+ w_evs[skt]=n
+ end
end
+ end
+ if err=="timeout" and #r_evs+#w_evs>0 then
+ return nil
+ else
+ return err
+ end
end
local function copasfinished()
- return not (next(_reading) or next(_writing) or _sleeping:getnext())
+ return not (next(_reading) or next(_writing) or _sleeping:getnext())
end
local function copasstep(timeout)
- _sleeping_t:tick(gettime())
- local nextwait=_sleeping:getnext()
- if nextwait then
- timeout=timeout and min(nextwait,timeout) or nextwait
- elseif copasfinished() then
- return false
- end
- local err=_select(timeout)
- if err then
- if err=="timeout" then
- return false
- end
- return nil,err
+ _sleeping_t:tick(gettime())
+ local nextwait=_sleeping:getnext()
+ if nextwait then
+ timeout=timeout and min(nextwait,timeout) or nextwait
+ elseif copasfinished() then
+ return false
+ end
+ local err=_select(timeout)
+ if err then
+ if err=="timeout" then
+ return false
end
- for task in tasks() do
- for event in task:events() do
- task:tick(event)
- end
+ return nil,err
+ end
+ for task in tasks() do
+ for event in task:events() do
+ task:tick(event)
end
- return true
+ end
+ return true
end
copas.finished=copasfinished
copas.step=copasstep
function copas.loop(timeout)
- copas.running=true
- while not copasfinished() do
- copasstep(timeout)
- end
- copas.running=false
+ copas.running=true
+ while not copasfinished() do
+ copasstep(timeout)
+ end
+ copas.running=false
end
package.loaded["copas"]=copas
@@ -10278,321 +10278,321 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true
--- original size: 8709, stripped down to: 6105
+-- original size: 8709, stripped down to: 5411
local select,unpack=select,unpack
local insert,remove=table.insert,table.remove
local sub=string.sub
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("ltn12")
- report(fmt,first,...)
- elseif fmt then
- fmt="ltn12: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("ltn12")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="ltn12: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
local filter={}
local source={}
local sink={}
local pump={}
local ltn12={
- _VERSION="LTN12 1.0.3",
- BLOCKSIZE=2048,
- filter=filter,
- source=source,
- sink=sink,
- pump=pump,
- report=report,
+ _VERSION="LTN12 1.0.3",
+ BLOCKSIZE=2048,
+ filter=filter,
+ source=source,
+ sink=sink,
+ pump=pump,
+ report=report,
}
function filter.cycle(low,ctx,extra)
- if low then
- return function(chunk)
- return (low(ctx,chunk,extra))
- end
+ if low then
+ return function(chunk)
+ return (low(ctx,chunk,extra))
end
+ end
end
function filter.chain(...)
- local arg={... }
- local n=select('#',...)
- local top=1
- local index=1
- local retry=""
- return function(chunk)
- retry=chunk and retry
- while true do
- local action=arg[index]
- if index==top then
- chunk=action(chunk)
- if chunk=="" or top==n then
- return chunk
- elseif chunk then
- index=index+1
- else
- top=top+1
- index=top
- end
- else
- chunk=action(chunk or "")
- if chunk=="" then
- index=index-1
- chunk=retry
- elseif chunk then
- if index==n then
- return chunk
- else
- index=index+1
- end
- else
- report("error: filter returned inappropriate 'nil'")
- return
- end
- end
+ local arg={... }
+ local n=select('#',...)
+ local top=1
+ local index=1
+ local retry=""
+ return function(chunk)
+ retry=chunk and retry
+ while true do
+ local action=arg[index]
+ if index==top then
+ chunk=action(chunk)
+ if chunk=="" or top==n then
+ return chunk
+ elseif chunk then
+ index=index+1
+ else
+ top=top+1
+ index=top
+ end
+ else
+ chunk=action(chunk or "")
+ if chunk=="" then
+ index=index-1
+ chunk=retry
+ elseif chunk then
+ if index==n then
+ return chunk
+ else
+ index=index+1
+ end
+ else
+ report("error: filter returned inappropriate 'nil'")
+ return
end
+ end
end
+ end
end
local function empty()
- return nil
+ return nil
end
function source.empty()
- return empty
+ return empty
end
local function sourceerror(err)
- return function()
- return nil,err
- end
+ return function()
+ return nil,err
+ end
end
source.error=sourceerror
function source.file(handle,io_err)
- if handle then
- local blocksize=ltn12.BLOCKSIZE
- return function()
- local chunk=handle:read(blocksize)
- if not chunk then
- handle:close()
- end
- return chunk
- end
- else
- return sourceerror(io_err or "unable to open file")
+ if handle then
+ local blocksize=ltn12.BLOCKSIZE
+ return function()
+ local chunk=handle:read(blocksize)
+ if not chunk then
+ handle:close()
+ end
+ return chunk
end
+ else
+ return sourceerror(io_err or "unable to open file")
+ end
end
function source.simplify(src)
- return function()
- local chunk,err_or_new=src()
- if err_or_new then
- src=err_or_new
- end
- if chunk then
- return chunk
- else
- return nil,err_or_new
- end
+ return function()
+ local chunk,err_or_new=src()
+ if err_or_new then
+ src=err_or_new
+ end
+ if chunk then
+ return chunk
+ else
+ return nil,err_or_new
end
+ end
end
function source.string(s)
- if s then
- local blocksize=ltn12.BLOCKSIZE
- local i=1
- return function()
- local nexti=i+blocksize
- local chunk=sub(s,i,nexti-1)
- i=nexti
- if chunk~="" then
- return chunk
- else
- return nil
- end
- end
- else return source.empty() end
+ if s then
+ local blocksize=ltn12.BLOCKSIZE
+ local i=1
+ return function()
+ local nexti=i+blocksize
+ local chunk=sub(s,i,nexti-1)
+ i=nexti
+ if chunk~="" then
+ return chunk
+ else
+ return nil
+ end
+ end
+ else return source.empty() end
end
function source.rewind(src)
- local t={}
- return function(chunk)
- if chunk then
- insert(t,chunk)
- else
- chunk=remove(t)
- if chunk then
- return chunk
- else
- return src()
- end
- end
+ local t={}
+ return function(chunk)
+ if chunk then
+ insert(t,chunk)
+ else
+ chunk=remove(t)
+ if chunk then
+ return chunk
+ else
+ return src()
+ end
end
+ end
end
function source.chain(src,f,...)
- if... then
- f=filter.chain(f,...)
+ if... then
+ f=filter.chain(f,...)
+ end
+ local last_in=""
+ local last_out=""
+ local state="feeding"
+ local err
+ return function()
+ if not last_out then
+ report("error: source is empty")
+ return
end
- local last_in=""
- local last_out=""
- local state="feeding"
- local err
- return function()
+ while true do
+ if state=="feeding" then
+ last_in,err=src()
+ if err then
+ return nil,err
+ end
+ last_out=f(last_in)
if not last_out then
- report("error: source is empty")
- return
+ if last_in then
+ report("error: filter returned inappropriate 'nil'")
+ end
+ return nil
+ elseif last_out~="" then
+ state="eating"
+ if last_in then
+ last_in=""
+ end
+ return last_out
end
- while true do
- if state=="feeding" then
- last_in,err=src()
- if err then
- return nil,err
- end
- last_out=f(last_in)
- if not last_out then
- if last_in then
- report("error: filter returned inappropriate 'nil'")
- end
- return nil
- elseif last_out~="" then
- state="eating"
- if last_in then
- last_in=""
- end
- return last_out
- end
- else
- last_out=f(last_in)
- if last_out=="" then
- if last_in=="" then
- state="feeding"
- else
- report("error: filter returned nothing")
- return
- end
- elseif not last_out then
- if last_in then
- report("filter returned inappropriate 'nil'")
- end
- return nil
- else
- return last_out
- end
- end
+ else
+ last_out=f(last_in)
+ if last_out=="" then
+ if last_in=="" then
+ state="feeding"
+ else
+ report("error: filter returned nothing")
+ return
+ end
+ elseif not last_out then
+ if last_in then
+ report("filter returned inappropriate 'nil'")
+ end
+ return nil
+ else
+ return last_out
end
+ end
end
+ end
end
function source.cat(...)
- local arg={... }
- local src=remove(arg,1)
- return function()
- while src do
- local chunk,err=src()
- if chunk then
- return chunk
- end
- if err then
- return nil,err
- end
- src=remove(arg,1)
- end
+ local arg={... }
+ local src=remove(arg,1)
+ return function()
+ while src do
+ local chunk,err=src()
+ if chunk then
+ return chunk
+ end
+ if err then
+ return nil,err
+ end
+ src=remove(arg,1)
end
+ end
end
function sink.table(t)
- if not t then
- t={}
- end
- local f=function(chunk,err)
- if chunk then
- insert(t,chunk)
- end
- return 1
+ if not t then
+ t={}
+ end
+ local f=function(chunk,err)
+ if chunk then
+ insert(t,chunk)
end
- return f,t
+ return 1
+ end
+ return f,t
end
function sink.simplify(snk)
- return function(chunk,err)
- local ret,err_or_new=snk(chunk,err)
- if not ret then
- return nil,err_or_new
- end
- if err_or_new then
- snk=err_or_new
- end
- return 1
+ return function(chunk,err)
+ local ret,err_or_new=snk(chunk,err)
+ if not ret then
+ return nil,err_or_new
end
+ if err_or_new then
+ snk=err_or_new
+ end
+ return 1
+ end
end
local function null()
- return 1
+ return 1
end
function sink.null()
- return null
+ return null
end
local function sinkerror(err)
- return function()
- return nil,err
- end
+ return function()
+ return nil,err
+ end
end
sink.error=sinkerror
function sink.file(handle,io_err)
- if handle then
- return function(chunk,err)
- if not chunk then
- handle:close()
- return 1
- else
- return handle:write(chunk)
- end
- end
- else
- return sinkerror(io_err or "unable to open file")
+ if handle then
+ return function(chunk,err)
+ if not chunk then
+ handle:close()
+ return 1
+ else
+ return handle:write(chunk)
+ end
end
+ else
+ return sinkerror(io_err or "unable to open file")
+ end
end
function sink.chain(f,snk,...)
- if... then
- local args={ f,snk,... }
- snk=remove(args,#args)
- f=filter.chain(unpack(args))
- end
- return function(chunk,err)
- if chunk~="" then
- local filtered=f(chunk)
- local done=chunk and ""
- while true do
- local ret,snkerr=snk(filtered,err)
- if not ret then
- return nil,snkerr
- end
- if filtered==done then
- return 1
- end
- filtered=f(done)
- end
- else
- return 1
+ if... then
+ local args={ f,snk,... }
+ snk=remove(args,#args)
+ f=filter.chain(unpack(args))
+ end
+ return function(chunk,err)
+ if chunk~="" then
+ local filtered=f(chunk)
+ local done=chunk and ""
+ while true do
+ local ret,snkerr=snk(filtered,err)
+ if not ret then
+ return nil,snkerr
+ end
+ if filtered==done then
+ return 1
end
+ filtered=f(done)
+ end
+ else
+ return 1
end
+ end
end
function pump.step(src,snk)
- local chunk,src_err=src()
- local ret,snk_err=snk(chunk,src_err)
- if chunk and ret then
- return 1
- else
- return nil,src_err or snk_err
- end
+ local chunk,src_err=src()
+ local ret,snk_err=snk(chunk,src_err)
+ if chunk and ret then
+ return 1
+ else
+ return nil,src_err or snk_err
+ end
end
function pump.all(src,snk,step)
- if not step then
- step=pump.step
- end
- while true do
- local ret,err=step(src,snk)
- if not ret then
- if err then
- return nil,err
- else
- return 1
- end
- end
+ if not step then
+ step=pump.step
+ end
+ while true do
+ local ret,err=step(src,snk)
+ if not ret then
+ if err then
+ return nil,err
+ else
+ return 1
+ end
end
+ end
end
package.loaded["ltn12"]=ltn12
@@ -10603,7 +10603,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true
--- original size: 2328, stripped down to: 1930
+-- original size: 2328, stripped down to: 1874
local type,tostring=type,tostring
@@ -10611,17 +10611,17 @@ local mime=require("mime.core")
local ltn12=ltn12 or require("ltn12")
local filtercycle=ltn12.filter.cycle
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("mime")
- report(fmt,first,...)
- elseif fmt then
- fmt="mime: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("mime")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="mime: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
mime.report=report
local encodet={}
@@ -10639,48 +10639,48 @@ local mime_qpwrp=mime.qpwrp
local mime_eol=mime_eol
local mime_dot=mime_dot
encodet['base64']=function()
- return filtercycle(mime_b64,"")
+ return filtercycle(mime_b64,"")
end
encodet['quoted-printable']=function(mode)
- return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n")
+ return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n")
end
decodet['base64']=function()
- return filtercycle(mime_unb64,"")
+ return filtercycle(mime_unb64,"")
end
decodet['quoted-printable']=function()
- return filtercycle(mime_unqp,"")
+ return filtercycle(mime_unqp,"")
end
local wraptext=function(length)
- if not length then
- length=76
- end
- return filtercycle(mime_wrp,length,length)
+ if not length then
+ length=76
+ end
+ return filtercycle(mime_wrp,length,length)
end
local wrapquoted=function()
- return filtercycle(mime_qpwrp,76,76)
+ return filtercycle(mime_qpwrp,76,76)
end
wrapt['text']=wraptext
wrapt['base64']=wraptext
wrapt['default']=wraptext
wrapt['quoted-printable']=wrapquoted
function mime.normalize(marker)
- return filtercycle(mime_eol,0,marker)
+ return filtercycle(mime_eol,0,marker)
end
function mime.stuff()
- return filtercycle(mime_dot,2)
+ return filtercycle(mime_dot,2)
end
local function choose(list)
- return function(name,opt1,opt2)
- if type(name)~="string" then
- name,opt1,opt2="default",name,opt1
- end
- local filter=list[name or "nil"]
- if filter then
- return filter(opt1,opt2)
- else
- report("error: unknown key '%s'",tostring(name))
- end
+ return function(name,opt1,opt2)
+ if type(name)~="string" then
+ name,opt1,opt2="default",name,opt1
+ end
+ local filter=list[name or "nil"]
+ if filter then
+ return filter(opt1,opt2)
+ else
+ report("error: unknown key '%s'",tostring(name))
end
+ end
end
mime.encode=choose(encodet)
mime.decode=choose(decodet)
@@ -10694,7 +10694,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true
--- original size: 6863, stripped down to: 5657
+-- original size: 6863, stripped down to: 5269
local tonumber,tostring,type=tonumber,tostring,type
@@ -10702,246 +10702,246 @@ local gsub,sub,match,find,format,byte,char=string.gsub,string.sub,string.match,s
local insert=table.insert
local socket=socket or require("socket")
local url={
- _VERSION="URL 1.0.3",
+ _VERSION="URL 1.0.3",
}
socket.url=url
function url.escape(s)
- return (gsub(s,"([^A-Za-z0-9_])",function(c)
- return format("%%%02x",byte(c))
- end))
+ return (gsub(s,"([^A-Za-z0-9_])",function(c)
+ return format("%%%02x",byte(c))
+ end))
end
local function make_set(t)
- local s={}
- for i=1,#t do
- s[t[i]]=true
- end
- return s
+ local s={}
+ for i=1,#t do
+ s[t[i]]=true
+ end
+ return s
end
local segment_set=make_set {
- "-","_",".","!","~","*","'","(",
- ")",":","@","&","=","+","$",",",
+ "-","_",".","!","~","*","'","(",
+ ")",":","@","&","=","+","$",",",
}
local function protect_segment(s)
- return gsub(s,"([^A-Za-z0-9_])",function(c)
- if segment_set[c] then
- return c
- else
- return format("%%%02X",byte(c))
- end
- end)
+ return gsub(s,"([^A-Za-z0-9_])",function(c)
+ if segment_set[c] then
+ return c
+ else
+ return format("%%%02X",byte(c))
+ end
+ end)
end
function url.unescape(s)
- return (gsub(s,"%%(%x%x)",function(hex)
- return char(tonumber(hex,16))
- end))
+ return (gsub(s,"%%(%x%x)",function(hex)
+ return char(tonumber(hex,16))
+ end))
end
local function absolute_path(base_path,relative_path)
- if find(relative_path,"^/") then
- return relative_path
- end
- local path=gsub(base_path,"[^/]*$","")
- path=path..relative_path
- path=gsub(path,"([^/]*%./)",function (s)
- if s~="./" then
- return s
- else
- return ""
- end
+ if find(relative_path,"^/") then
+ return relative_path
+ end
+ local path=gsub(base_path,"[^/]*$","")
+ path=path..relative_path
+ path=gsub(path,"([^/]*%./)",function (s)
+ if s~="./" then
+ return s
+ else
+ return ""
+ end
+ end)
+ path=gsub(path,"/%.$","/")
+ local reduced
+ while reduced~=path do
+ reduced=path
+ path=gsub(reduced,"([^/]*/%.%./)",function (s)
+ if s~="../../" then
+ return ""
+ else
+ return s
+ end
end)
- path=gsub(path,"/%.$","/")
- local reduced
- while reduced~=path do
- reduced=path
- path=gsub(reduced,"([^/]*/%.%./)",function (s)
- if s~="../../" then
- return ""
- else
- return s
- end
- end)
+ end
+ path=gsub(reduced,"([^/]*/%.%.)$",function (s)
+ if s~="../.." then
+ return ""
+ else
+ return s
end
- path=gsub(reduced,"([^/]*/%.%.)$",function (s)
- if s~="../.." then
- return ""
- else
- return s
- end
- end)
- return path
+ end)
+ return path
end
function url.parse(url,default)
- local parsed={}
- for k,v in next,default or parsed do
- parsed[k]=v
- end
- if not url or url=="" then
- return nil,"invalid url"
- end
- url=gsub(url,"#(.*)$",function(f)
- parsed.fragment=f
- return ""
- end)
- url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s)
- parsed.scheme=s
- return ""
- end)
- url=gsub(url,"^//([^/]*)",function(n)
- parsed.authority=n
- return ""
- end)
- url=gsub(url,"%?(.*)",function(q)
- parsed.query=q
- return ""
- end)
- url=gsub(url,"%;(.*)",function(p)
- parsed.params=p
- return ""
- end)
- if url~="" then
- parsed.path=url
- end
- local authority=parsed.authority
- if not authority then
- return parsed
- end
- authority=gsub(authority,"^([^@]*)@",function(u)
- parsed.userinfo=u
- return ""
- end)
- authority=gsub(authority,":([^:%]]*)$",function(p)
- parsed.port=p
- return ""
- end)
- if authority~="" then
- parsed.host=match(authority,"^%[(.+)%]$") or authority
- end
- local userinfo=parsed.userinfo
- if not userinfo then
- return parsed
- end
- userinfo=gsub(userinfo,":([^:]*)$",function(p)
- parsed.password=p
- return ""
- end)
- parsed.user=userinfo
+ local parsed={}
+ for k,v in next,default or parsed do
+ parsed[k]=v
+ end
+ if not url or url=="" then
+ return nil,"invalid url"
+ end
+ url=gsub(url,"#(.*)$",function(f)
+ parsed.fragment=f
+ return ""
+ end)
+ url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s)
+ parsed.scheme=s
+ return ""
+ end)
+ url=gsub(url,"^//([^/]*)",function(n)
+ parsed.authority=n
+ return ""
+ end)
+ url=gsub(url,"%?(.*)",function(q)
+ parsed.query=q
+ return ""
+ end)
+ url=gsub(url,"%;(.*)",function(p)
+ parsed.params=p
+ return ""
+ end)
+ if url~="" then
+ parsed.path=url
+ end
+ local authority=parsed.authority
+ if not authority then
return parsed
+ end
+ authority=gsub(authority,"^([^@]*)@",function(u)
+ parsed.userinfo=u
+ return ""
+ end)
+ authority=gsub(authority,":([^:%]]*)$",function(p)
+ parsed.port=p
+ return ""
+ end)
+ if authority~="" then
+ parsed.host=match(authority,"^%[(.+)%]$") or authority
+ end
+ local userinfo=parsed.userinfo
+ if not userinfo then
+ return parsed
+ end
+ userinfo=gsub(userinfo,":([^:]*)$",function(p)
+ parsed.password=p
+ return ""
+ end)
+ parsed.user=userinfo
+ return parsed
end
function url.build(parsed)
- local url=parsed.path or ""
- if parsed.params then
- url=url..";"..parsed.params
- end
- if parsed.query then
- url=url.."?"..parsed.query
- end
- local authority=parsed.authority
- if parsed.host then
- authority=parsed.host
- if find(authority,":") then
- authority="["..authority.."]"
- end
- if parsed.port then
- authority=authority..":"..tostring(parsed.port)
- end
- local userinfo=parsed.userinfo
- if parsed.user then
- userinfo=parsed.user
- if parsed.password then
- userinfo=userinfo..":"..parsed.password
- end
- end
- if userinfo then authority=userinfo.."@"..authority end
+ local url=parsed.path or ""
+ if parsed.params then
+ url=url..";"..parsed.params
+ end
+ if parsed.query then
+ url=url.."?"..parsed.query
+ end
+ local authority=parsed.authority
+ if parsed.host then
+ authority=parsed.host
+ if find(authority,":") then
+ authority="["..authority.."]"
+ end
+ if parsed.port then
+ authority=authority..":"..tostring(parsed.port)
end
- if authority then
- url="//"..authority..url
- end
- if parsed.scheme then
- url=parsed.scheme..":"..url
- end
- if parsed.fragment then
- url=url.."#"..parsed.fragment
+ local userinfo=parsed.userinfo
+ if parsed.user then
+ userinfo=parsed.user
+ if parsed.password then
+ userinfo=userinfo..":"..parsed.password
+ end
end
- return url
+ if userinfo then authority=userinfo.."@"..authority end
+ end
+ if authority then
+ url="//"..authority..url
+ end
+ if parsed.scheme then
+ url=parsed.scheme..":"..url
+ end
+ if parsed.fragment then
+ url=url.."#"..parsed.fragment
+ end
+ return url
end
function url.absolute(base_url,relative_url)
- local base_parsed
- if type(base_url)=="table" then
- base_parsed=base_url
- base_url=url.build(base_parsed)
- else
- base_parsed=url.parse(base_url)
- end
- local relative_parsed=url.parse(relative_url)
- if not base_parsed then
- return relative_url
- elseif not relative_parsed then
- return base_url
- elseif relative_parsed.scheme then
- return relative_url
- else
- relative_parsed.scheme=base_parsed.scheme
- if not relative_parsed.authority then
- relative_parsed.authority=base_parsed.authority
- if not relative_parsed.path then
- relative_parsed.path=base_parsed.path
- if not relative_parsed.params then
- relative_parsed.params=base_parsed.params
- if not relative_parsed.query then
- relative_parsed.query=base_parsed.query
- end
- end
- else
- relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path)
- end
+ local base_parsed
+ if type(base_url)=="table" then
+ base_parsed=base_url
+ base_url=url.build(base_parsed)
+ else
+ base_parsed=url.parse(base_url)
+ end
+ local relative_parsed=url.parse(relative_url)
+ if not base_parsed then
+ return relative_url
+ elseif not relative_parsed then
+ return base_url
+ elseif relative_parsed.scheme then
+ return relative_url
+ else
+ relative_parsed.scheme=base_parsed.scheme
+ if not relative_parsed.authority then
+ relative_parsed.authority=base_parsed.authority
+ if not relative_parsed.path then
+ relative_parsed.path=base_parsed.path
+ if not relative_parsed.params then
+ relative_parsed.params=base_parsed.params
+ if not relative_parsed.query then
+ relative_parsed.query=base_parsed.query
+ end
end
- return url.build(relative_parsed)
+ else
+ relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path)
+ end
end
+ return url.build(relative_parsed)
+ end
end
function url.parse_path(path)
- local parsed={}
- path=path or ""
- gsub(path,"([^/]+)",function (s)
- insert(parsed,s)
- end)
- for i=1,#parsed do
- parsed[i]=url.unescape(parsed[i])
- end
- if sub(path,1,1)=="/" then
- parsed.is_absolute=1
- end
- if sub(path,-1,-1)=="/" then
- parsed.is_directory=1
- end
- return parsed
+ local parsed={}
+ path=path or ""
+ gsub(path,"([^/]+)",function (s)
+ insert(parsed,s)
+ end)
+ for i=1,#parsed do
+ parsed[i]=url.unescape(parsed[i])
+ end
+ if sub(path,1,1)=="/" then
+ parsed.is_absolute=1
+ end
+ if sub(path,-1,-1)=="/" then
+ parsed.is_directory=1
+ end
+ return parsed
end
function url.build_path(parsed,unsafe)
- local path=""
- local n=#parsed
- if unsafe then
- for i=1,n-1 do
- path=path..parsed[i].."/"
- end
- if n>0 then
- path=path..parsed[n]
- if parsed.is_directory then
- path=path.."/"
- end
- end
- else
- for i=1,n-1 do
- path=path..protect_segment(parsed[i]).."/"
- end
- if n>0 then
- path=path..protect_segment(parsed[n])
- if parsed.is_directory then
- path=path.."/"
- end
- end
+ local path=""
+ local n=#parsed
+ if unsafe then
+ for i=1,n-1 do
+ path=path..parsed[i].."/"
end
- if parsed.is_absolute then
- path="/"..path
+ if n>0 then
+ path=path..parsed[n]
+ if parsed.is_directory then
+ path=path.."/"
+ end
end
- return path
+ else
+ for i=1,n-1 do
+ path=path..protect_segment(parsed[i]).."/"
+ end
+ if n>0 then
+ path=path..protect_segment(parsed[n])
+ if parsed.is_directory then
+ path=path.."/"
+ end
+ end
+ end
+ if parsed.is_absolute then
+ path="/"..path
+ end
+ return path
end
package.loaded["socket.url"]=url
@@ -10952,7 +10952,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true
--- original size: 5721, stripped down to: 3878
+-- original size: 5721, stripped down to: 3754
local next=next
@@ -10962,128 +10962,128 @@ local socket=socket or require("socket")
local headers={}
socket.headers=headers
local canonic={
- ["accept"]="Accept",
- ["accept-charset"]="Accept-Charset",
- ["accept-encoding"]="Accept-Encoding",
- ["accept-language"]="Accept-Language",
- ["accept-ranges"]="Accept-Ranges",
- ["action"]="Action",
- ["alternate-recipient"]="Alternate-Recipient",
- ["age"]="Age",
- ["allow"]="Allow",
- ["arrival-date"]="Arrival-Date",
- ["authorization"]="Authorization",
- ["bcc"]="Bcc",
- ["cache-control"]="Cache-Control",
- ["cc"]="Cc",
- ["comments"]="Comments",
- ["connection"]="Connection",
- ["content-description"]="Content-Description",
- ["content-disposition"]="Content-Disposition",
- ["content-encoding"]="Content-Encoding",
- ["content-id"]="Content-ID",
- ["content-language"]="Content-Language",
- ["content-length"]="Content-Length",
- ["content-location"]="Content-Location",
- ["content-md5"]="Content-MD5",
- ["content-range"]="Content-Range",
- ["content-transfer-encoding"]="Content-Transfer-Encoding",
- ["content-type"]="Content-Type",
- ["cookie"]="Cookie",
- ["date"]="Date",
- ["diagnostic-code"]="Diagnostic-Code",
- ["dsn-gateway"]="DSN-Gateway",
- ["etag"]="ETag",
- ["expect"]="Expect",
- ["expires"]="Expires",
- ["final-log-id"]="Final-Log-ID",
- ["final-recipient"]="Final-Recipient",
- ["from"]="From",
- ["host"]="Host",
- ["if-match"]="If-Match",
- ["if-modified-since"]="If-Modified-Since",
- ["if-none-match"]="If-None-Match",
- ["if-range"]="If-Range",
- ["if-unmodified-since"]="If-Unmodified-Since",
- ["in-reply-to"]="In-Reply-To",
- ["keywords"]="Keywords",
- ["last-attempt-date"]="Last-Attempt-Date",
- ["last-modified"]="Last-Modified",
- ["location"]="Location",
- ["max-forwards"]="Max-Forwards",
- ["message-id"]="Message-ID",
- ["mime-version"]="MIME-Version",
- ["original-envelope-id"]="Original-Envelope-ID",
- ["original-recipient"]="Original-Recipient",
- ["pragma"]="Pragma",
- ["proxy-authenticate"]="Proxy-Authenticate",
- ["proxy-authorization"]="Proxy-Authorization",
- ["range"]="Range",
- ["received"]="Received",
- ["received-from-mta"]="Received-From-MTA",
- ["references"]="References",
- ["referer"]="Referer",
- ["remote-mta"]="Remote-MTA",
- ["reply-to"]="Reply-To",
- ["reporting-mta"]="Reporting-MTA",
- ["resent-bcc"]="Resent-Bcc",
- ["resent-cc"]="Resent-Cc",
- ["resent-date"]="Resent-Date",
- ["resent-from"]="Resent-From",
- ["resent-message-id"]="Resent-Message-ID",
- ["resent-reply-to"]="Resent-Reply-To",
- ["resent-sender"]="Resent-Sender",
- ["resent-to"]="Resent-To",
- ["retry-after"]="Retry-After",
- ["return-path"]="Return-Path",
- ["sender"]="Sender",
- ["server"]="Server",
- ["smtp-remote-recipient"]="SMTP-Remote-Recipient",
- ["status"]="Status",
- ["subject"]="Subject",
- ["te"]="TE",
- ["to"]="To",
- ["trailer"]="Trailer",
- ["transfer-encoding"]="Transfer-Encoding",
- ["upgrade"]="Upgrade",
- ["user-agent"]="User-Agent",
- ["vary"]="Vary",
- ["via"]="Via",
- ["warning"]="Warning",
- ["will-retry-until"]="Will-Retry-Until",
- ["www-authenticate"]="WWW-Authenticate",
- ["x-mailer"]="X-Mailer",
+ ["accept"]="Accept",
+ ["accept-charset"]="Accept-Charset",
+ ["accept-encoding"]="Accept-Encoding",
+ ["accept-language"]="Accept-Language",
+ ["accept-ranges"]="Accept-Ranges",
+ ["action"]="Action",
+ ["alternate-recipient"]="Alternate-Recipient",
+ ["age"]="Age",
+ ["allow"]="Allow",
+ ["arrival-date"]="Arrival-Date",
+ ["authorization"]="Authorization",
+ ["bcc"]="Bcc",
+ ["cache-control"]="Cache-Control",
+ ["cc"]="Cc",
+ ["comments"]="Comments",
+ ["connection"]="Connection",
+ ["content-description"]="Content-Description",
+ ["content-disposition"]="Content-Disposition",
+ ["content-encoding"]="Content-Encoding",
+ ["content-id"]="Content-ID",
+ ["content-language"]="Content-Language",
+ ["content-length"]="Content-Length",
+ ["content-location"]="Content-Location",
+ ["content-md5"]="Content-MD5",
+ ["content-range"]="Content-Range",
+ ["content-transfer-encoding"]="Content-Transfer-Encoding",
+ ["content-type"]="Content-Type",
+ ["cookie"]="Cookie",
+ ["date"]="Date",
+ ["diagnostic-code"]="Diagnostic-Code",
+ ["dsn-gateway"]="DSN-Gateway",
+ ["etag"]="ETag",
+ ["expect"]="Expect",
+ ["expires"]="Expires",
+ ["final-log-id"]="Final-Log-ID",
+ ["final-recipient"]="Final-Recipient",
+ ["from"]="From",
+ ["host"]="Host",
+ ["if-match"]="If-Match",
+ ["if-modified-since"]="If-Modified-Since",
+ ["if-none-match"]="If-None-Match",
+ ["if-range"]="If-Range",
+ ["if-unmodified-since"]="If-Unmodified-Since",
+ ["in-reply-to"]="In-Reply-To",
+ ["keywords"]="Keywords",
+ ["last-attempt-date"]="Last-Attempt-Date",
+ ["last-modified"]="Last-Modified",
+ ["location"]="Location",
+ ["max-forwards"]="Max-Forwards",
+ ["message-id"]="Message-ID",
+ ["mime-version"]="MIME-Version",
+ ["original-envelope-id"]="Original-Envelope-ID",
+ ["original-recipient"]="Original-Recipient",
+ ["pragma"]="Pragma",
+ ["proxy-authenticate"]="Proxy-Authenticate",
+ ["proxy-authorization"]="Proxy-Authorization",
+ ["range"]="Range",
+ ["received"]="Received",
+ ["received-from-mta"]="Received-From-MTA",
+ ["references"]="References",
+ ["referer"]="Referer",
+ ["remote-mta"]="Remote-MTA",
+ ["reply-to"]="Reply-To",
+ ["reporting-mta"]="Reporting-MTA",
+ ["resent-bcc"]="Resent-Bcc",
+ ["resent-cc"]="Resent-Cc",
+ ["resent-date"]="Resent-Date",
+ ["resent-from"]="Resent-From",
+ ["resent-message-id"]="Resent-Message-ID",
+ ["resent-reply-to"]="Resent-Reply-To",
+ ["resent-sender"]="Resent-Sender",
+ ["resent-to"]="Resent-To",
+ ["retry-after"]="Retry-After",
+ ["return-path"]="Return-Path",
+ ["sender"]="Sender",
+ ["server"]="Server",
+ ["smtp-remote-recipient"]="SMTP-Remote-Recipient",
+ ["status"]="Status",
+ ["subject"]="Subject",
+ ["te"]="TE",
+ ["to"]="To",
+ ["trailer"]="Trailer",
+ ["transfer-encoding"]="Transfer-Encoding",
+ ["upgrade"]="Upgrade",
+ ["user-agent"]="User-Agent",
+ ["vary"]="Vary",
+ ["via"]="Via",
+ ["warning"]="Warning",
+ ["will-retry-until"]="Will-Retry-Until",
+ ["www-authenticate"]="WWW-Authenticate",
+ ["x-mailer"]="X-Mailer",
}
headers.canonic=setmetatable(canonic,{
- __index=function(t,k)
- socket.report("invalid header: %s",k)
- t[k]=k
- return k
- end
+ __index=function(t,k)
+ socket.report("invalid header: %s",k)
+ t[k]=k
+ return k
+ end
})
function headers.normalize(headers)
- if not headers then
- return {}
- end
- local normalized={}
- for k,v in next,headers do
- normalized[#normalized+1]=canonic[k]..": "..v
- end
- normalized[#normalized+1]=""
- normalized[#normalized+1]=""
- return concat(normalized,"\r\n")
+ if not headers then
+ return {}
+ end
+ local normalized={}
+ for k,v in next,headers do
+ normalized[#normalized+1]=canonic[k]..": "..v
+ end
+ normalized[#normalized+1]=""
+ normalized[#normalized+1]=""
+ return concat(normalized,"\r\n")
end
function headers.lower(lowered,headers)
- if not lowered then
- return {}
- end
- if not headers then
- lowered,headers={},lowered
- end
- for k,v in next,headers do
- lowered[lower(k)]=v
- end
- return lowered
+ if not lowered then
+ return {}
+ end
+ if not headers then
+ lowered,headers={},lowered
+ end
+ for k,v in next,headers do
+ lowered[lower(k)]=v
+ end
+ return lowered
end
socket.headers=headers
package.loaded["socket.headers"]=headers
@@ -11095,13 +11095,13 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true
--- original size: 3116, stripped down to: 2643
+-- original size: 3116, stripped down to: 2533
local setmetatable,next,type,tonumber=setmetatable,next,type,tonumber
local find,upper=string.find,string.upper
local socket=socket or require("socket")
-local ltn12=ltn12 or require("ltn12")
+local ltn12=ltn12 or require("ltn12")
local skipsocket=socket.skip
local sinksocket=socket.sink
local tcpsocket=socket.tcp
@@ -11109,111 +11109,111 @@ local ltn12pump=ltn12.pump
local pumpall=ltn12pump.all
local pumpstep=ltn12pump.step
local tp={
- TIMEOUT=60,
+ TIMEOUT=60,
}
socket.tp=tp
local function get_reply(c)
- local line,err=c:receive()
- local reply=line
- if err then return
- nil,err
- end
- local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
- if not code then
- return nil,"invalid server reply"
- end
- if sep=="-" then
- local current
- repeat
- line,err=c:receive()
- if err then
- return nil,err
- end
- current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
- reply=reply.."\n"..line
- until code==current and sep==" "
- end
- return code,reply
+ local line,err=c:receive()
+ local reply=line
+ if err then return
+ nil,err
+ end
+ local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
+ if not code then
+ return nil,"invalid server reply"
+ end
+ if sep=="-" then
+ local current
+ repeat
+ line,err=c:receive()
+ if err then
+ return nil,err
+ end
+ current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
+ reply=reply.."\n"..line
+ until code==current and sep==" "
+ end
+ return code,reply
end
local methods={}
local mt={ __index=methods }
function methods.getpeername(self)
- return self.c:getpeername()
+ return self.c:getpeername()
end
function methods.getsockname(self)
- return self.c:getpeername()
+ return self.c:getpeername()
end
function methods.check(self,ok)
- local code,reply=get_reply(self.c)
- if not code then
- return nil,reply
- end
- local c=tonumber(code)
- local t=type(ok)
- if t=="function" then
- return ok(c,reply)
- elseif t=="table" then
- for i=1,#ok do
- if find(code,ok[i]) then
- return c,reply
- end
- end
- return nil,reply
- elseif find(code,ok) then
+ local code,reply=get_reply(self.c)
+ if not code then
+ return nil,reply
+ end
+ local c=tonumber(code)
+ local t=type(ok)
+ if t=="function" then
+ return ok(c,reply)
+ elseif t=="table" then
+ for i=1,#ok do
+ if find(code,ok[i]) then
return c,reply
- else
- return nil,reply
+ end
end
+ return nil,reply
+ elseif find(code,ok) then
+ return c,reply
+ else
+ return nil,reply
+ end
end
function methods.command(self,cmd,arg)
- cmd=upper(cmd)
- if arg then
- cmd=cmd.." "..arg.."\r\n"
- else
- cmd=cmd.."\r\n"
- end
- return self.c:send(cmd)
+ cmd=upper(cmd)
+ if arg then
+ cmd=cmd.." "..arg.."\r\n"
+ else
+ cmd=cmd.."\r\n"
+ end
+ return self.c:send(cmd)
end
function methods.sink(self,snk,pat)
- local chunk,err=self.c:receive(pat)
- return snk(chunk,err)
+ local chunk,err=self.c:receive(pat)
+ return snk(chunk,err)
end
function methods.send(self,data)
- return self.c:send(data)
+ return self.c:send(data)
end
function methods.receive(self,pat)
- return self.c:receive(pat)
+ return self.c:receive(pat)
end
function methods.getfd(self)
- return self.c:getfd()
+ return self.c:getfd()
end
function methods.dirty(self)
- return self.c:dirty()
+ return self.c:dirty()
end
function methods.getcontrol(self)
- return self.c
+ return self.c
end
function methods.source(self,source,step)
- local sink=sinksocket("keep-open",self.c)
- local ret,err=pumpall(source,sink,step or pumpstep)
- return ret,err
+ local sink=sinksocket("keep-open",self.c)
+ local ret,err=pumpall(source,sink,step or pumpstep)
+ return ret,err
end
function methods.close(self)
- self.c:close()
- return 1
+ self.c:close()
+ return 1
end
function tp.connect(host,port,timeout,create)
- local c,e=(create or tcpsocket)()
- if not c then
- return nil,e
- end
- c:settimeout(timeout or tp.TIMEOUT)
- local r,e=c:connect(host,port)
- if not r then
- c:close()
- return nil,e
- end
- return setmetatable({ c=c },mt)
+ local c,e=(create or tcpsocket)()
+ if not c then
+ return nil,e
+ end
+ c:settimeout(timeout or tp.TIMEOUT)
+ local r,e=c:connect(host,port)
+ if not r then
+ c:close()
+ return nil,e
+ end
+ return setmetatable({ c=c },mt)
end
package.loaded["socket.tp"]=tp
@@ -11224,16 +11224,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true
--- original size: 12577, stripped down to: 10069
+-- original size: 12577, stripped down to: 9577
local tostring,tonumber,setmetatable,next,type=tostring,tonumber,setmetatable,next,type
local find,lower,format,gsub,match=string.find,string.lower,string.format,string.gsub,string.match
local concat=table.concat
-local socket=socket or require("socket")
-local url=socket.url or require("socket.url")
-local ltn12=ltn12 or require("ltn12")
-local mime=mime or require("mime")
+local socket=socket or require("socket")
+local url=socket.url or require("socket.url")
+local ltn12=ltn12 or require("ltn12")
+local mime=mime or require("mime")
local headers=socket.headers or require("socket.headers")
local normalizeheaders=headers.normalize
local parseurl=url.parse
@@ -11257,345 +11257,345 @@ local sinktable=ltn12.sink.table
local lowerheaders=headers.lower
local mimeb64=mime.b64
local http={
- TIMEOUT=60,
- USERAGENT=socket._VERSION,
+ TIMEOUT=60,
+ USERAGENT=socket._VERSION,
}
socket.http=http
local PORT=80
local SCHEMES={
- http=true,
+ http=true,
}
local function receiveheaders(sock,headers)
- if not headers then
- headers={}
- end
- local line,err=sock:receive()
+ if not headers then
+ headers={}
+ end
+ local line,err=sock:receive()
+ if err then
+ return nil,err
+ end
+ while line~="" do
+ local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
+ if not (name and value) then
+ return nil,"malformed reponse headers"
+ end
+ name=lower(name)
+ line,err=sock:receive()
if err then
+ return nil,err
+ end
+ while find(line,"^%s") do
+ value=value..line
+ line=sock:receive()
+ if err then
return nil,err
+ end
end
- while line~="" do
- local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
- if not (name and value) then
- return nil,"malformed reponse headers"
- end
- name=lower(name)
- line,err=sock:receive()
+ local found=headers[name]
+ if found then
+ value=found..", "..value
+ end
+ headers[name]=value
+ end
+ return headers
+end
+socket.sourcet["http-chunked"]=function(sock,headers)
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },{
+ __call=function()
+ local line,err=sock:receive()
if err then
- return nil,err
+ return nil,err
end
- while find(line,"^%s") do
- value=value..line
- line=sock:receive()
- if err then
- return nil,err
- end
+ local size=tonumber(gsub(line,";.*",""),16)
+ if not size then
+ return nil,"invalid chunk size"
end
- local found=headers[name]
- if found then
- value=found..", "..value
+ if size>0 then
+ local chunk,err,part=sock:receive(size)
+ if chunk then
+ sock:receive()
+ end
+ return chunk,err
+ else
+ headers,err=receiveheaders(sock,headers)
+ if not headers then
+ return nil,err
+ end
end
- headers[name]=value
- end
- return headers
-end
-socket.sourcet["http-chunked"]=function(sock,headers)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function()
- local line,err=sock:receive()
- if err then
- return nil,err
- end
- local size=tonumber(gsub(line,";.*",""),16)
- if not size then
- return nil,"invalid chunk size"
- end
- if size>0 then
- local chunk,err,part=sock:receive(size)
- if chunk then
- sock:receive()
- end
- return chunk,err
- else
- headers,err=receiveheaders(sock,headers)
- if not headers then
- return nil,err
- end
- end
- end
- }
- )
+ end
+ }
+ )
end
socket.sinkt["http-chunked"]=function(sock)
- return setmetatable(
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function(self,chunk,err)
- if not chunk then
- chunk=""
- end
- return sock:send(format("%X\r\n%s\r\n",#chunk,chunk))
- end
- })
+ return setmetatable(
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },
+ {
+ __call=function(self,chunk,err)
+ if not chunk then
+ chunk=""
+ end
+ return sock:send(format("%X\r\n%s\r\n",#chunk,chunk))
+ end
+ })
end
local methods={}
local mt={ __index=methods }
local function openhttp(host,port,create)
- local c=trysocket((create or tcpsocket)())
- local h=setmetatable({ c=c },mt)
- local try=newtrysocket(function() h:close() end)
- h.try=try
- try(c:settimeout(http.TIMEOUT))
- try(c:connect(host,port or PORT))
- return h
+ local c=trysocket((create or tcpsocket)())
+ local h=setmetatable({ c=c },mt)
+ local try=newtrysocket(function() h:close() end)
+ h.try=try
+ try(c:settimeout(http.TIMEOUT))
+ try(c:connect(host,port or PORT))
+ return h
end
http.open=openhttp
function methods.sendrequestline(self,method,uri)
- local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri)
- return self.try(self.c:send(requestline))
+ local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri)
+ return self.try(self.c:send(requestline))
end
function methods.sendheaders(self,headers)
- self.try(self.c:send(normalizeheaders(headers)))
- return 1
+ self.try(self.c:send(normalizeheaders(headers)))
+ return 1
end
function methods.sendbody(self,headers,source,step)
- if not source then
- source=emptysource()
- end
- if not step then
- step=pumpstep
- end
- local mode="http-chunked"
- if headers["content-length"] then
- mode="keep-open"
- end
- return self.try(pumpall(source,sinksocket(mode,self.c),step))
+ if not source then
+ source=emptysource()
+ end
+ if not step then
+ step=pumpstep
+ end
+ local mode="http-chunked"
+ if headers["content-length"] then
+ mode="keep-open"
+ end
+ return self.try(pumpall(source,sinksocket(mode,self.c),step))
end
function methods.receivestatusline(self)
- local try=self.try
- local status=try(self.c:receive(5))
- if status~="HTTP/" then
- return nil,status
- end
- status=try(self.c:receive("*l",status))
- local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)"))
- return try(tonumber(code),status)
+ local try=self.try
+ local status=try(self.c:receive(5))
+ if status~="HTTP/" then
+ return nil,status
+ end
+ status=try(self.c:receive("*l",status))
+ local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)"))
+ return try(tonumber(code),status)
end
function methods.receiveheaders(self)
- return self.try(receiveheaders(self.c))
+ return self.try(receiveheaders(self.c))
end
function methods.receivebody(self,headers,sink,step)
- if not sink then
- sink=sinknull()
- end
- if not step then
- step=pumpstep
- end
- local length=tonumber(headers["content-length"])
- local encoding=headers["transfer-encoding"]
- local mode="default"
- if encoding and encoding~="identity" then
- mode="http-chunked"
- elseif length then
- mode="by-length"
- end
- return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step))
+ if not sink then
+ sink=sinknull()
+ end
+ if not step then
+ step=pumpstep
+ end
+ local length=tonumber(headers["content-length"])
+ local encoding=headers["transfer-encoding"]
+ local mode="default"
+ if encoding and encoding~="identity" then
+ mode="http-chunked"
+ elseif length then
+ mode="by-length"
+ end
+ return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step))
end
function methods.receive09body(self,status,sink,step)
- local source=rewindsource(sourcesocket("until-closed",self.c))
- source(status)
- return self.try(pumpall(source,sink,step))
+ local source=rewindsource(sourcesocket("until-closed",self.c))
+ source(status)
+ return self.try(pumpall(source,sink,step))
end
function methods.close(self)
- return self.c:close()
+ return self.c:close()
end
local function adjusturi(request)
- if not request.proxy and not http.PROXY then
- request={
- path=trysocket(request.path,"invalid path 'nil'"),
- params=request.params,
- query=request.query,
- fragment=request.fragment,
- }
- end
- return buildurl(request)
+ if not request.proxy and not http.PROXY then
+ request={
+ path=trysocket(request.path,"invalid path 'nil'"),
+ params=request.params,
+ query=request.query,
+ fragment=request.fragment,
+ }
+ end
+ return buildurl(request)
end
local function adjustheaders(request)
- local headers={
- ["user-agent"]=http.USERAGENT,
- ["host"]=gsub(request.authority,"^.-@",""),
- ["connection"]="close, TE",
- ["te"]="trailers"
- }
- local username=request.user
- local password=request.password
+ local headers={
+ ["user-agent"]=http.USERAGENT,
+ ["host"]=gsub(request.authority,"^.-@",""),
+ ["connection"]="close, TE",
+ ["te"]="trailers"
+ }
+ local username=request.user
+ local password=request.password
+ if username and password then
+ headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password)))
+ end
+ local proxy=request.proxy or http.PROXY
+ if proxy then
+ proxy=parseurl(proxy)
+ local username=proxy.user
+ local password=proxy.password
if username and password then
- headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password)))
- end
- local proxy=request.proxy or http.PROXY
- if proxy then
- proxy=parseurl(proxy)
- local username=proxy.user
- local password=proxy.password
- if username and password then
- headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password))
- end
- end
- local requestheaders=request.headers
- if requestheaders then
- headers=lowerheaders(headers,requestheaders)
+ headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password))
end
- return headers
+ end
+ local requestheaders=request.headers
+ if requestheaders then
+ headers=lowerheaders(headers,requestheaders)
+ end
+ return headers
end
local default={
- host="",
- port=PORT,
- path="/",
- scheme="http"
+ host="",
+ port=PORT,
+ path="/",
+ scheme="http"
}
local function adjustrequest(originalrequest)
- local url=originalrequest.url
- local request=url and parseurl(url,default) or {}
- for k,v in next,originalrequest do
- request[k]=v
- end
- local host=request.host
- local port=request.port
- local uri=request.uri
- if not host or host=="" then
- trysocket(nil,"invalid host '"..tostring(host).."'")
- end
- if port=="" then
- request.port=PORT
- end
- if not uri or uri=="" then
- request.uri=adjusturi(request)
- end
- request.headers=adjustheaders(request)
- local proxy=request.proxy or http.PROXY
- if proxy then
- proxy=parseurl(proxy)
- request.host=proxy.host
- request.port=proxy.port or 3128
- end
- return request
+ local url=originalrequest.url
+ local request=url and parseurl(url,default) or {}
+ for k,v in next,originalrequest do
+ request[k]=v
+ end
+ local host=request.host
+ local port=request.port
+ local uri=request.uri
+ if not host or host=="" then
+ trysocket(nil,"invalid host '"..tostring(host).."'")
+ end
+ if port=="" then
+ request.port=PORT
+ end
+ if not uri or uri=="" then
+ request.uri=adjusturi(request)
+ end
+ request.headers=adjustheaders(request)
+ local proxy=request.proxy or http.PROXY
+ if proxy then
+ proxy=parseurl(proxy)
+ request.host=proxy.host
+ request.port=proxy.port or 3128
+ end
+ return request
end
local maxredericts=4
local validredirects={ [301]=true,[302]=true,[303]=true,[307]=true }
local validmethods={ [false]=true,GET=true,HEAD=true }
local function shouldredirect(request,code,headers)
- local location=headers.location
- if not location then
- return false
- end
- location=gsub(location,"%s","")
- if location=="" then
- return false
- end
- local scheme=match(location,"^([%w][%w%+%-%.]*)%:")
- if scheme and not SCHEMES[scheme] then
- return false
- end
- local method=request.method
- local redirect=request.redirect
- local redirects=request.nredirects or 0
- return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts
+ local location=headers.location
+ if not location then
+ return false
+ end
+ location=gsub(location,"%s","")
+ if location=="" then
+ return false
+ end
+ local scheme=match(location,"^([%w][%w%+%-%.]*)%:")
+ if scheme and not SCHEMES[scheme] then
+ return false
+ end
+ local method=request.method
+ local redirect=request.redirect
+ local redirects=request.nredirects or 0
+ return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts
end
local function shouldreceivebody(request,code)
- if request.method=="HEAD" then
- return nil
- end
- if code==204 or code==304 then
- return nil
- end
- if code>=100 and code<200 then
- return nil
- end
- return 1
+ if request.method=="HEAD" then
+ return nil
+ end
+ if code==204 or code==304 then
+ return nil
+ end
+ if code>=100 and code<200 then
+ return nil
+ end
+ return 1
end
local tredirect,trequest,srequest
tredirect=function(request,location)
- local result,code,headers,status=trequest {
- url=absoluteurl(request.url,location),
- source=request.source,
- sink=request.sink,
- headers=request.headers,
- proxy=request.proxy,
- nredirects=(request.nredirects or 0)+1,
- create=request.create,
- }
- if not headers then
- headers={}
- end
- if not headers.location then
- headers.location=location
- end
- return result,code,headers,status
+ local result,code,headers,status=trequest {
+ url=absoluteurl(request.url,location),
+ source=request.source,
+ sink=request.sink,
+ headers=request.headers,
+ proxy=request.proxy,
+ nredirects=(request.nredirects or 0)+1,
+ create=request.create,
+ }
+ if not headers then
+ headers={}
+ end
+ if not headers.location then
+ headers.location=location
+ end
+ return result,code,headers,status
end
trequest=function(originalrequest)
- local request=adjustrequest(originalrequest)
- local connection=openhttp(request.host,request.port,request.create)
- local headers=request.headers
- connection:sendrequestline(request.method,request.uri)
- connection:sendheaders(headers)
- if request.source then
- connection:sendbody(headers,request.source,request.step)
- end
- local code,status=connection:receivestatusline()
- if not code then
- connection:receive09body(status,request.sink,request.step)
- return 1,200
- end
- while code==100 do
- headers=connection:receiveheaders()
- code,status=connection:receivestatusline()
- end
+ local request=adjustrequest(originalrequest)
+ local connection=openhttp(request.host,request.port,request.create)
+ local headers=request.headers
+ connection:sendrequestline(request.method,request.uri)
+ connection:sendheaders(headers)
+ if request.source then
+ connection:sendbody(headers,request.source,request.step)
+ end
+ local code,status=connection:receivestatusline()
+ if not code then
+ connection:receive09body(status,request.sink,request.step)
+ return 1,200
+ end
+ while code==100 do
headers=connection:receiveheaders()
- if shouldredirect(request,code,headers) and not request.source then
- connection:close()
- return tredirect(originalrequest,headers.location)
- end
- if shouldreceivebody(request,code) then
- connection:receivebody(headers,request.sink,request.step)
- end
+ code,status=connection:receivestatusline()
+ end
+ headers=connection:receiveheaders()
+ if shouldredirect(request,code,headers) and not request.source then
connection:close()
- return 1,code,headers,status
+ return tredirect(originalrequest,headers.location)
+ end
+ if shouldreceivebody(request,code) then
+ connection:receivebody(headers,request.sink,request.step)
+ end
+ connection:close()
+ return 1,code,headers,status
end
local function genericform(url,body)
- local buffer={}
- local request={
- url=url,
- sink=sinktable(buffer),
- target=buffer,
+ local buffer={}
+ local request={
+ url=url,
+ sink=sinktable(buffer),
+ target=buffer,
+ }
+ if body then
+ request.source=stringsource(body)
+ request.method="POST"
+ request.headers={
+ ["content-length"]=#body,
+ ["content-type"]="application/x-www-form-urlencoded"
}
- if body then
- request.source=stringsource(body)
- request.method="POST"
- request.headers={
- ["content-length"]=#body,
- ["content-type"]="application/x-www-form-urlencoded"
- }
- end
- return request
+ end
+ return request
end
http.genericform=genericform
srequest=function(url,body)
- local request=genericform(url,body)
- local _,code,headers,status=trequest(request)
- return concat(request.target),code,headers,status
+ local request=genericform(url,body)
+ local _,code,headers,status=trequest(request)
+ return concat(request.target),code,headers,status
end
http.request=protectsocket(function(request,body)
- if type(request)=="string" then
- return srequest(request,body)
- else
- return trequest(request)
- end
+ if type(request)=="string" then
+ return srequest(request,body)
+ else
+ return trequest(request)
+ end
end)
package.loaded["socket.http"]=http
@@ -11606,16 +11606,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true
--- original size: 10357, stripped down to: 8900
+-- original size: 10357, stripped down to: 8548
local setmetatable,type,next=setmetatable,type,next
local find,format,gsub,match=string.find,string.format,string.gsub,string.match
local concat=table.concat
local mod=math.mod
-local socket=socket or require("socket")
+local socket=socket or require("socket")
local url=socket.url or require("socket.url")
-local tp=socket.tp or require("socket.tp")
+local tp=socket.tp or require("socket.tp")
local ltn12=ltn12 or require("ltn12")
local tcpsocket=socket.tcp
local trysocket=socket.try
@@ -11633,341 +11633,341 @@ local pumpstep=ltn12.pump.step
local sourcestring=ltn12.source.string
local sinktable=ltn12.sink.table
local ftp={
- TIMEOUT=60,
- USER="ftp",
- PASSWORD="anonymous@anonymous.org",
+ TIMEOUT=60,
+ USER="ftp",
+ PASSWORD="anonymous@anonymous.org",
}
socket.ftp=ftp
local PORT=21
local methods={}
local mt={ __index=methods }
function ftp.open(server,port,create)
- local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create))
- local f=setmetatable({ tp=tp },metat)
- f.try=newtrysocket(function() f:close() end)
- return f
+ local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create))
+ local f=setmetatable({ tp=tp },metat)
+ f.try=newtrysocket(function() f:close() end)
+ return f
end
function methods.portconnect(self)
- local try=self.try
- local server=self.server
- try(server:settimeout(ftp.TIMEOUT))
- self.data=try(server:accept())
- try(self.data:settimeout(ftp.TIMEOUT))
+ local try=self.try
+ local server=self.server
+ try(server:settimeout(ftp.TIMEOUT))
+ self.data=try(server:accept())
+ try(self.data:settimeout(ftp.TIMEOUT))
end
function methods.pasvconnect(self)
- local try=self.try
- self.data=try(tcpsocket())
- self(self.data:settimeout(ftp.TIMEOUT))
- self(self.data:connect(self.pasvt.address,self.pasvt.port))
+ local try=self.try
+ self.data=try(tcpsocket())
+ self(self.data:settimeout(ftp.TIMEOUT))
+ self(self.data:connect(self.pasvt.address,self.pasvt.port))
end
function methods.login(self,user,password)
- local try=self.try
- local tp=self.tp
- try(tp:command("user",user or ftp.USER))
- local code,reply=try(tp:check{"2..",331})
- if code==331 then
- try(tp:command("pass",password or ftp.PASSWORD))
- try(tp:check("2.."))
- end
- return 1
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("user",user or ftp.USER))
+ local code,reply=try(tp:check{"2..",331})
+ if code==331 then
+ try(tp:command("pass",password or ftp.PASSWORD))
+ try(tp:check("2.."))
+ end
+ return 1
end
function methods.pasv(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("pasv"))
- local code,reply=try(self.tp:check("2.."))
- local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
- local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern))
- try(a and b and c and d and p1 and p2,reply)
- local address=format("%d.%d.%d.%d",a,b,c,d)
- local port=p1*256+p2
- local server=self.server
- self.pasvt={
- address=address,
- port=port,
- }
- if server then
- server:close()
- self.server=nil
- end
- return address,port
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("pasv"))
+ local code,reply=try(self.tp:check("2.."))
+ local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
+ local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern))
+ try(a and b and c and d and p1 and p2,reply)
+ local address=format("%d.%d.%d.%d",a,b,c,d)
+ local port=p1*256+p2
+ local server=self.server
+ self.pasvt={
+ address=address,
+ port=port,
+ }
+ if server then
+ server:close()
+ self.server=nil
+ end
+ return address,port
end
function methods.epsv(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("epsv"))
- local code,reply=try(tp:check("229"))
- local pattern="%((.)(.-)%1(.-)%1(.-)%1%)"
- local d,prt,address,port=match(reply,pattern)
- try(port,"invalid epsv response")
- local address=tp:getpeername()
- local server=self.server
- self.pasvt={
- address=address,
- port=port,
- }
- if self.server then
- server:close()
- self.server=nil
- end
- return address,port
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("epsv"))
+ local code,reply=try(tp:check("229"))
+ local pattern="%((.)(.-)%1(.-)%1(.-)%1%)"
+ local d,prt,address,port=match(reply,pattern)
+ try(port,"invalid epsv response")
+ local address=tp:getpeername()
+ local server=self.server
+ self.pasvt={
+ address=address,
+ port=port,
+ }
+ if self.server then
+ server:close()
+ self.server=nil
+ end
+ return address,port
end
function methods.port(self,address,port)
- local try=self.try
- local tp=self.tp
- self.pasvt=nil
- if not address then
- address,port=try(tp:getsockname())
- self.server=try(bindsocket(address,0))
- address,port=try(self.server:getsockname())
- try(self.server:settimeout(ftp.TIMEOUT))
- end
- local pl=mod(port,256)
- local ph=(port-pl)/256
- local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",")
- try(tp:command("port",arg))
- try(tp:check("2.."))
- return 1
+ local try=self.try
+ local tp=self.tp
+ self.pasvt=nil
+ if not address then
+ address,port=try(tp:getsockname())
+ self.server=try(bindsocket(address,0))
+ address,port=try(self.server:getsockname())
+ try(self.server:settimeout(ftp.TIMEOUT))
+ end
+ local pl=mod(port,256)
+ local ph=(port-pl)/256
+ local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",")
+ try(tp:command("port",arg))
+ try(tp:check("2.."))
+ return 1
end
function methods.eprt(self,family,address,port)
- local try=self.try
- local tp=self.tp
- self.pasvt=nil
- if not address then
- address,port=try(tp:getsockname())
- self.server=try(bindsocket(address,0))
- address,port=try(self.server:getsockname())
- try(self.server:settimeout(ftp.TIMEOUT))
- end
- local arg=format("|%s|%s|%d|",family,address,port)
- try(tp:command("eprt",arg))
- try(tp:check("2.."))
- return 1
+ local try=self.try
+ local tp=self.tp
+ self.pasvt=nil
+ if not address then
+ address,port=try(tp:getsockname())
+ self.server=try(bindsocket(address,0))
+ address,port=try(self.server:getsockname())
+ try(self.server:settimeout(ftp.TIMEOUT))
+ end
+ local arg=format("|%s|%s|%d|",family,address,port)
+ try(tp:command("eprt",arg))
+ try(tp:check("2.."))
+ return 1
end
function methods.send(self,sendt)
- local try=self.try
- local tp=self.tp
- try(self.pasvt or self.server,"need port or pasv first")
- if self.pasvt then
- self:pasvconnect()
- end
- local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]",""))
- if argument=="" then
- argument=nil
- end
- local command=sendt.command or "stor"
- try(tp:command(command,argument))
- local code,reply=try(tp:check{"2..","1.."})
- if not self.pasvt then
- self:portconnect()
- end
- local step=sendt.step or pumpstep
- local readt={ tp }
- local checkstep=function(src,snk)
- local readyt=selectsocket(readt,nil,0)
- if readyt[tp] then
- code=try(tp:check("2.."))
- end
- return step(src,snk)
- end
- local sink=sinksocket("close-when-done",self.data)
- try(pumpall(sendt.source,sink,checkstep))
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- self.data:close()
- local sent=skipsocket(1,self.data:getstats())
- self.data=nil
- return sent
+ local try=self.try
+ local tp=self.tp
+ try(self.pasvt or self.server,"need port or pasv first")
+ if self.pasvt then
+ self:pasvconnect()
+ end
+ local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]",""))
+ if argument=="" then
+ argument=nil
+ end
+ local command=sendt.command or "stor"
+ try(tp:command(command,argument))
+ local code,reply=try(tp:check{"2..","1.."})
+ if not self.pasvt then
+ self:portconnect()
+ end
+ local step=sendt.step or pumpstep
+ local readt={ tp }
+ local checkstep=function(src,snk)
+ local readyt=selectsocket(readt,nil,0)
+ if readyt[tp] then
+ code=try(tp:check("2.."))
+ end
+ return step(src,snk)
+ end
+ local sink=sinksocket("close-when-done",self.data)
+ try(pumpall(sendt.source,sink,checkstep))
+ if find(code,"1..") then
+ try(tp:check("2.."))
+ end
+ self.data:close()
+ local sent=skipsocket(1,self.data:getstats())
+ self.data=nil
+ return sent
end
function methods.receive(self,recvt)
- local try=self.try
- local tp=self.tp
- try(self.pasvt or self.server,"need port or pasv first")
- if self.pasvt then self:pasvconnect() end
- local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]",""))
- if argument=="" then
- argument=nil
- end
- local command=recvt.command or "retr"
- try(tp:command(command,argument))
- local code,reply=try(tp:check{"1..","2.."})
- if code>=200 and code<=299 then
- recvt.sink(reply)
- return 1
- end
- if not self.pasvt then
- self:portconnect()
- end
- local source=sourcesocket("until-closed",self.data)
- local step=recvt.step or pumpstep
- try(pumpall(source,recvt.sink,step))
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- self.data:close()
- self.data=nil
+ local try=self.try
+ local tp=self.tp
+ try(self.pasvt or self.server,"need port or pasv first")
+ if self.pasvt then self:pasvconnect() end
+ local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]",""))
+ if argument=="" then
+ argument=nil
+ end
+ local command=recvt.command or "retr"
+ try(tp:command(command,argument))
+ local code,reply=try(tp:check{"1..","2.."})
+ if code>=200 and code<=299 then
+ recvt.sink(reply)
return 1
+ end
+ if not self.pasvt then
+ self:portconnect()
+ end
+ local source=sourcesocket("until-closed",self.data)
+ local step=recvt.step or pumpstep
+ try(pumpall(source,recvt.sink,step))
+ if find(code,"1..") then
+ try(tp:check("2.."))
+ end
+ self.data:close()
+ self.data=nil
+ return 1
end
function methods.cwd(self,dir)
- local try=self.try
- local tp=self.tp
- try(tp:command("cwd",dir))
- try(tp:check(250))
- return 1
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("cwd",dir))
+ try(tp:check(250))
+ return 1
end
function methods.type(self,typ)
- local try=self.try
- local tp=self.tp
- try(tp:command("type",typ))
- try(tp:check(200))
- return 1
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("type",typ))
+ try(tp:check(200))
+ return 1
end
function methods.greet(self)
- local try=self.try
- local tp=self.tp
- local code=try(tp:check{"1..","2.."})
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- return 1
+ local try=self.try
+ local tp=self.tp
+ local code=try(tp:check{"1..","2.."})
+ if find(code,"1..") then
+ try(tp:check("2.."))
+ end
+ return 1
end
function methods.quit(self)
- local try=self.try
- try(self.tp:command("quit"))
- try(self.tp:check("2.."))
- return 1
+ local try=self.try
+ try(self.tp:command("quit"))
+ try(self.tp:check("2.."))
+ return 1
end
function methods.close(self)
- local data=self.data
- if data then
- data:close()
- end
- local server=self.server
- if server then
- server:close()
- end
- local tp=self.tp
- if tp then
- tp:close()
- end
+ local data=self.data
+ if data then
+ data:close()
+ end
+ local server=self.server
+ if server then
+ server:close()
+ end
+ local tp=self.tp
+ if tp then
+ tp:close()
+ end
end
local function override(t)
- if t.url then
- local u=parseurl(t.url)
- for k,v in next,t do
- u[k]=v
- end
- return u
- else
- return t
+ if t.url then
+ local u=parseurl(t.url)
+ for k,v in next,t do
+ u[k]=v
end
+ return u
+ else
+ return t
+ end
end
local function tput(putt)
- putt=override(putt)
- local host=putt.host
- trysocket(host,"missing hostname")
- local f=ftp.open(host,putt.port,putt.create)
- f:greet()
- f:login(putt.user,putt.password)
- local typ=putt.type
- if typ then
- f:type(typ)
- end
- f:epsv()
- local sent=f:send(putt)
- f:quit()
- f:close()
- return sent
+ putt=override(putt)
+ local host=putt.host
+ trysocket(host,"missing hostname")
+ local f=ftp.open(host,putt.port,putt.create)
+ f:greet()
+ f:login(putt.user,putt.password)
+ local typ=putt.type
+ if typ then
+ f:type(typ)
+ end
+ f:epsv()
+ local sent=f:send(putt)
+ f:quit()
+ f:close()
+ return sent
end
local default={
- path="/",
- scheme="ftp",
+ path="/",
+ scheme="ftp",
}
local function genericform(u)
- local t=trysocket(parseurl(u,default))
- trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'")
- trysocket(t.host,"missing hostname")
- local pat="^type=(.)$"
- if t.params then
- local typ=skipsocket(2,find(t.params,pat))
- t.type=typ
- trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'")
- end
- return t
+ local t=trysocket(parseurl(u,default))
+ trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'")
+ trysocket(t.host,"missing hostname")
+ local pat="^type=(.)$"
+ if t.params then
+ local typ=skipsocket(2,find(t.params,pat))
+ t.type=typ
+ trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'")
+ end
+ return t
end
ftp.genericform=genericform
local function sput(u,body)
- local putt=genericform(u)
- putt.source=sourcestring(body)
- return tput(putt)
+ local putt=genericform(u)
+ putt.source=sourcestring(body)
+ return tput(putt)
end
ftp.put=protectsocket(function(putt,body)
- if type(putt)=="string" then
- return sput(putt,body)
- else
- return tput(putt)
- end
+ if type(putt)=="string" then
+ return sput(putt,body)
+ else
+ return tput(putt)
+ end
end)
local function tget(gett)
- gett=override(gett)
- local host=gett.host
- trysocket(host,"missing hostname")
- local f=ftp.open(host,gett.port,gett.create)
- f:greet()
- f:login(gett.user,gett.password)
- if gett.type then
- f:type(gett.type)
- end
- f:epsv()
- f:receive(gett)
- f:quit()
- return f:close()
+ gett=override(gett)
+ local host=gett.host
+ trysocket(host,"missing hostname")
+ local f=ftp.open(host,gett.port,gett.create)
+ f:greet()
+ f:login(gett.user,gett.password)
+ if gett.type then
+ f:type(gett.type)
+ end
+ f:epsv()
+ f:receive(gett)
+ f:quit()
+ return f:close()
end
local function sget(u)
- local gett=genericform(u)
- local t={}
- gett.sink=sinktable(t)
- tget(gett)
- return concat(t)
+ local gett=genericform(u)
+ local t={}
+ gett.sink=sinktable(t)
+ tget(gett)
+ return concat(t)
end
ftp.command=protectsocket(function(cmdt)
- cmdt=override(cmdt)
- local command=cmdt.command
- local argument=cmdt.argument
- local check=cmdt.check
- local host=cmdt.host
- trysocket(host,"missing hostname")
- trysocket(command,"missing command")
- local f=ftp.open(host,cmdt.port,cmdt.create)
- local try=f.try
- local tp=f.tp
- f:greet()
- f:login(cmdt.user,cmdt.password)
- if type(command)=="table" then
- local argument=argument or {}
- for i=1,#command do
- local cmd=command[i]
- try(tp:command(cmd,argument[i]))
- if check and check[i] then
- try(tp:check(check[i]))
- end
- end
- else
- try(tp:command(command,argument))
- if check then
- try(tp:check(check))
- end
+ cmdt=override(cmdt)
+ local command=cmdt.command
+ local argument=cmdt.argument
+ local check=cmdt.check
+ local host=cmdt.host
+ trysocket(host,"missing hostname")
+ trysocket(command,"missing command")
+ local f=ftp.open(host,cmdt.port,cmdt.create)
+ local try=f.try
+ local tp=f.tp
+ f:greet()
+ f:login(cmdt.user,cmdt.password)
+ if type(command)=="table" then
+ local argument=argument or {}
+ for i=1,#command do
+ local cmd=command[i]
+ try(tp:command(cmd,argument[i]))
+ if check and check[i] then
+ try(tp:check(check[i]))
+ end
end
- f:quit()
- return f:close()
+ else
+ try(tp:command(command,argument))
+ if check then
+ try(tp:check(check))
+ end
+ end
+ f:quit()
+ return f:close()
end)
ftp.get=protectsocket(function(gett)
- if type(gett)=="string" then
- return sget(gett)
- else
- return tget(gett)
- end
+ if type(gett)=="string" then
+ return sget(gett)
+ else
+ return tget(gett)
+ end
end)
package.loaded["socket.ftp"]=ftp
@@ -11978,18 +11978,18 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true
--- original size: 7018, stripped down to: 6095
+-- original size: 7018, stripped down to: 5883
local type,setmetatable,next=type,setmetatable,next
local find,lower,format=string.find,string.lower,string.format
local osdate,osgetenv=os.date,os.getenv
local random=math.random
-local socket=socket or require("socket")
+local socket=socket or require("socket")
local headers=socket.headers or require("socket.headers")
-local ltn12=ltn12 or require("ltn12")
+local ltn12=ltn12 or require("ltn12")
local tp=socket.tp or require("socket.tp")
-local mime=mime or require("mime")
+local mime=mime or require("mime")
local mimeb64=mime.b64
local mimestuff=mime.stuff
local skipsocket=socket.skip
@@ -12002,212 +12002,212 @@ local createcoroutine=coroutine.create
local resumecoroutine=coroutine.resume
local yieldcoroutine=coroutine.resume
local smtp={
- TIMEOUT=60,
- SERVER="localhost",
- PORT=25,
- DOMAIN=osgetenv("SERVER_NAME") or "localhost",
- ZONE="-0000",
+ TIMEOUT=60,
+ SERVER="localhost",
+ PORT=25,
+ DOMAIN=osgetenv("SERVER_NAME") or "localhost",
+ ZONE="-0000",
}
socket.smtp=smtp
local methods={}
local mt={ __index=methods }
function methods.greet(self,domain)
- local try=self.try
- local tp=self.tp
- try(tp:check("2.."))
- try(tp:command("EHLO",domain or _M.DOMAIN))
- return skipsocket(1,try(tp:check("2..")))
+ local try=self.try
+ local tp=self.tp
+ try(tp:check("2.."))
+ try(tp:command("EHLO",domain or _M.DOMAIN))
+ return skipsocket(1,try(tp:check("2..")))
end
function methods.mail(self,from)
- local try=self.try
- local tp=self.tp
- try(tp:command("MAIL","FROM:"..from))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("MAIL","FROM:"..from))
+ return try(tp:check("2.."))
end
function methods.rcpt(self,to)
- local try=self.try
- local tp=self.tp
- try(tp:command("RCPT","TO:"..to))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("RCPT","TO:"..to))
+ return try(tp:check("2.."))
end
function methods.data(self,src,step)
- local try=self.try
- local tp=self.tp
- try(tp:command("DATA"))
- try(tp:check("3.."))
- try(tp:source(src,step))
- try(tp:send("\r\n.\r\n"))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("DATA"))
+ try(tp:check("3.."))
+ try(tp:source(src,step))
+ try(tp:send("\r\n.\r\n"))
+ return try(tp:check("2.."))
end
function methods.quit(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("QUIT"))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("QUIT"))
+ return try(tp:check("2.."))
end
function methods.close(self)
- return self.tp:close()
+ return self.tp:close()
end
function methods.login(self,user,password)
- local try=self.try
- local tp=self.tp
- try(tp:command("AUTH","LOGIN"))
- try(tp:check("3.."))
- try(tp:send(mimeb64(user).."\r\n"))
- try(tp:check("3.."))
- try(tp:send(mimeb64(password).."\r\n"))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("AUTH","LOGIN"))
+ try(tp:check("3.."))
+ try(tp:send(mimeb64(user).."\r\n"))
+ try(tp:check("3.."))
+ try(tp:send(mimeb64(password).."\r\n"))
+ return try(tp:check("2.."))
end
function methods.plain(self,user,password)
- local try=self.try
- local tp=self.tp
- local auth="PLAIN "..mimeb64("\0"..user.."\0"..password)
- try(tp:command("AUTH",auth))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ local auth="PLAIN "..mimeb64("\0"..user.."\0"..password)
+ try(tp:command("AUTH",auth))
+ return try(tp:check("2.."))
end
function methods.auth(self,user,password,ext)
- if not user or not password then
- return 1
- end
- local try=self.try
- if find(ext,"AUTH[^\n]+LOGIN") then
- return self:login(user,password)
- elseif find(ext,"AUTH[^\n]+PLAIN") then
- return self:plain(user,password)
- else
- try(nil,"authentication not supported")
- end
+ if not user or not password then
+ return 1
+ end
+ local try=self.try
+ if find(ext,"AUTH[^\n]+LOGIN") then
+ return self:login(user,password)
+ elseif find(ext,"AUTH[^\n]+PLAIN") then
+ return self:plain(user,password)
+ else
+ try(nil,"authentication not supported")
+ end
end
function methods.send(self,mail)
- self:mail(mail.from)
- local receipt=mail.rcpt
- if type(receipt)=="table" then
- for i=1,#receipt do
- self:rcpt(receipt[i])
- end
- elseif receipt then
- self:rcpt(receipt)
+ self:mail(mail.from)
+ local receipt=mail.rcpt
+ if type(receipt)=="table" then
+ for i=1,#receipt do
+ self:rcpt(receipt[i])
end
- self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step)
+ elseif receipt then
+ self:rcpt(receipt)
+ end
+ self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step)
end
local function opensmtp(self,server,port,create)
- if not server or server=="" then
- server=smtp.SERVER
- end
- if not port or port=="" then
- port=smtp.PORT
- end
- local s={
- tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)),
- try=newtrysocket(function()
- s:close()
- end),
- }
- setmetatable(s,mt)
- return s
+ if not server or server=="" then
+ server=smtp.SERVER
+ end
+ if not port or port=="" then
+ port=smtp.PORT
+ end
+ local s={
+ tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)),
+ try=newtrysocket(function()
+ s:close()
+ end),
+ }
+ setmetatable(s,mt)
+ return s
end
smtp.open=opensmtp
local nofboundaries=0
local function newboundary()
- nofboundaries=nofboundaries+1
- return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries)
+ nofboundaries=nofboundaries+1
+ return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries)
end
local send_message
local function send_headers(headers)
- yieldcoroutine(normalizeheaders(headers))
+ yieldcoroutine(normalizeheaders(headers))
end
local function send_multipart(message)
- local boundary=newboundary()
- local headers=lowerheaders(message.headers)
- local body=message.body
- local preamble=body.preamble
- local epilogue=body.epilogue
- local content=headers['content-type'] or 'multipart/mixed'
- headers['content-type']=content..'; boundary="'..boundary..'"'
- send_headers(headers)
- if preamble then
- yieldcoroutine(preamble)
- yieldcoroutine("\r\n")
- end
- for i=1,#body do
- yieldcoroutine("\r\n--"..boundary.."\r\n")
- send_message(body[i])
- end
- yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n")
- if epilogue then
- yieldcoroutine(epilogue)
- yieldcoroutine("\r\n")
- end
+ local boundary=newboundary()
+ local headers=lowerheaders(message.headers)
+ local body=message.body
+ local preamble=body.preamble
+ local epilogue=body.epilogue
+ local content=headers['content-type'] or 'multipart/mixed'
+ headers['content-type']=content..'; boundary="'..boundary..'"'
+ send_headers(headers)
+ if preamble then
+ yieldcoroutine(preamble)
+ yieldcoroutine("\r\n")
+ end
+ for i=1,#body do
+ yieldcoroutine("\r\n--"..boundary.."\r\n")
+ send_message(body[i])
+ end
+ yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n")
+ if epilogue then
+ yieldcoroutine(epilogue)
+ yieldcoroutine("\r\n")
+ end
end
local default_content_type='text/plain; charset="UTF-8"'
local function send_source(message)
- local headers=lowerheaders(message.headers)
- if not headers['content-type'] then
- headers['content-type']=default_content_type
- end
- send_headers(headers)
- local getchunk=message.body
- while true do
- local chunk,err=getchunk()
- if err then
- yieldcoroutine(nil,err)
- elseif chunk then
- yieldcoroutine(chunk)
- else
- break
- end
+ local headers=lowerheaders(message.headers)
+ if not headers['content-type'] then
+ headers['content-type']=default_content_type
+ end
+ send_headers(headers)
+ local getchunk=message.body
+ while true do
+ local chunk,err=getchunk()
+ if err then
+ yieldcoroutine(nil,err)
+ elseif chunk then
+ yieldcoroutine(chunk)
+ else
+ break
end
+ end
end
local function send_string(message)
- local headers=lowerheaders(message.headers)
- if not headers['content-type'] then
- headers['content-type']=default_content_type
- end
- send_headers(headers)
- yieldcoroutine(message.body)
+ local headers=lowerheaders(message.headers)
+ if not headers['content-type'] then
+ headers['content-type']=default_content_type
+ end
+ send_headers(headers)
+ yieldcoroutine(message.body)
end
function send_message(message)
- local body=message.body
- if type(body)=="table" then
- send_multipart(message)
- elseif type(body)=="function" then
- send_source(message)
- else
- send_string(message)
- end
+ local body=message.body
+ if type(body)=="table" then
+ send_multipart(message)
+ elseif type(body)=="function" then
+ send_source(message)
+ else
+ send_string(message)
+ end
end
local function adjust_headers(message)
- local headers=lowerheaders(message.headers)
- if not headers["date"] then
- headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE)
- end
- if not headers["x-mailer"] then
- headers["x-mailer"]=socket._VERSION
- end
- headers["mime-version"]="1.0"
- return headers
+ local headers=lowerheaders(message.headers)
+ if not headers["date"] then
+ headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE)
+ end
+ if not headers["x-mailer"] then
+ headers["x-mailer"]=socket._VERSION
+ end
+ headers["mime-version"]="1.0"
+ return headers
end
function smtp.message(message)
- message.headers=adjust_headers(message)
- local action=createcoroutine(function()
- send_message(message)
- end)
- return function()
- local ret,a,b=resumecoroutine(action)
- if ret then
- return a,b
- else
- return nil,a
- end
+ message.headers=adjust_headers(message)
+ local action=createcoroutine(function()
+ send_message(message)
+ end)
+ return function()
+ local ret,a,b=resumecoroutine(action)
+ if ret then
+ return a,b
+ else
+ return nil,a
end
+ end
end
smtp.send=protectsocket(function(mail)
- local snd=opensmtp(smtp,mail.server,mail.port,mail.create)
- local ext=snd:greet(mail.domain)
- snd:auth(mail.user,mail.password,ext)
- snd:send(mail)
- snd:quit()
- return snd:close()
+ local snd=opensmtp(smtp,mail.server,mail.port,mail.create)
+ local ext=snd:greet(mail.domain)
+ snd:auth(mail.user,mail.password,ext)
+ snd:send(mail)
+ snd:quit()
+ return snd:close()
end)
package.loaded["socket.smtp"]=smtp
@@ -12218,14 +12218,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-set"] = package.loaded["trac-set"] or true
--- original size: 13340, stripped down to: 9459
+-- original size: 13340, stripped down to: 8826
if not modules then modules={} end modules ['trac-set']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber=type,next,tostring,tonumber
local concat,sortedhash=table.concat,table.sortedhash
@@ -12240,317 +12240,317 @@ utilities.setters=setters
local data={}
local trace_initialize=false
function setters.initialize(filename,name,values)
- local setter=data[name]
- if setter then
- frozen=true
- local data=setter.data
- if data then
- for key,newvalue in sortedhash(values) do
- local newvalue=is_boolean(newvalue,newvalue,true)
- local functions=data[key]
- if functions then
- local oldvalue=functions.value
- if functions.frozen then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
- end
- elseif #functions>0 and not oldvalue then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
- end
- for i=1,#functions do
- functions[i](newvalue)
- end
- functions.value=newvalue
- functions.frozen=functions.frozen or frozen
- else
- if trace_initialize then
- setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
- end
- end
- else
- functions={ default=newvalue,frozen=frozen }
- data[key]=functions
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
- end
- end
+ local setter=data[name]
+ if setter then
+ frozen=true
+ local data=setter.data
+ if data then
+ for key,newvalue in sortedhash(values) do
+ local newvalue=is_boolean(newvalue,newvalue,true)
+ local functions=data[key]
+ if functions then
+ local oldvalue=functions.value
+ if functions.frozen then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
+ end
+ elseif #functions>0 and not oldvalue then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
+ end
+ for i=1,#functions do
+ functions[i](newvalue)
+ end
+ functions.value=newvalue
+ functions.frozen=functions.frozen or frozen
+ else
+ if trace_initialize then
+ setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
end
- return true
+ end
+ else
+ functions={ default=newvalue,frozen=frozen }
+ data[key]=functions
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
+ end
end
+ end
+ return true
end
+ end
end
local function set(t,what,newvalue)
- local data=t.data
- if not data.frozen then
- local done=t.done
- if type(what)=="string" then
- what=settings_to_hash(what)
- end
- if type(what)~="table" then
- return
- end
- if not done then
- done={}
- t.done=done
- end
- for w,value in sortedhash(what) do
- if value=="" then
- value=newvalue
- elseif not value then
- value=false
- else
- value=is_boolean(value,value,true)
- end
- w=topattern(w,true,true)
- for name,functions in sortedhash(data) do
- if done[name] then
- elseif find(name,w) then
- done[name]=true
- for i=1,#functions do
- functions[i](value)
- end
- functions.value=value
- end
- end
+ local data=t.data
+ if not data.frozen then
+ local done=t.done
+ if type(what)=="string" then
+ what=settings_to_hash(what)
+ end
+ if type(what)~="table" then
+ return
+ end
+ if not done then
+ done={}
+ t.done=done
+ end
+ for w,value in sortedhash(what) do
+ if value=="" then
+ value=newvalue
+ elseif not value then
+ value=false
+ else
+ value=is_boolean(value,value,true)
+ end
+ w=topattern(w,true,true)
+ for name,functions in sortedhash(data) do
+ if done[name] then
+ elseif find(name,w) then
+ done[name]=true
+ for i=1,#functions do
+ functions[i](value)
+ end
+ functions.value=value
end
+ end
end
+ end
end
local function reset(t)
- local data=t.data
- if not data.frozen then
- for name,functions in sortedthash(data) do
- for i=1,#functions do
- functions[i](false)
- end
- functions.value=false
- end
+ local data=t.data
+ if not data.frozen then
+ for name,functions in sortedthash(data) do
+ for i=1,#functions do
+ functions[i](false)
+ end
+ functions.value=false
end
+ end
end
local function enable(t,what)
- set(t,what,true)
+ set(t,what,true)
end
local function disable(t,what)
- local data=t.data
- if not what or what=="" then
- t.done={}
- reset(t)
- else
- set(t,what,false)
- end
+ local data=t.data
+ if not what or what=="" then
+ t.done={}
+ reset(t)
+ else
+ set(t,what,false)
+ end
end
function setters.register(t,what,...)
- local data=t.data
- what=lower(what)
- local functions=data[what]
- if not functions then
- functions={}
- data[what]=functions
- if trace_initialize then
- t.report("defining %a",what)
- end
- end
- local default=functions.default
- for i=1,select("#",...) do
- local fnc=select(i,...)
- local typ=type(fnc)
- if typ=="string" then
- if trace_initialize then
- t.report("coupling %a to %a",what,fnc)
- end
- local s=fnc
- fnc=function(value) set(t,s,value) end
- elseif typ~="function" then
- fnc=nil
- end
- if fnc then
- functions[#functions+1]=fnc
- local value=functions.value or default
- if value~=nil then
- fnc(value)
- functions.value=value
- end
- end
+ local data=t.data
+ what=lower(what)
+ local functions=data[what]
+ if not functions then
+ functions={}
+ data[what]=functions
+ if trace_initialize then
+ t.report("defining %a",what)
+ end
+ end
+ local default=functions.default
+ for i=1,select("#",...) do
+ local fnc=select(i,...)
+ local typ=type(fnc)
+ if typ=="string" then
+ if trace_initialize then
+ t.report("coupling %a to %a",what,fnc)
+ end
+ local s=fnc
+ fnc=function(value) set(t,s,value) end
+ elseif typ~="function" then
+ fnc=nil
+ end
+ if fnc then
+ functions[#functions+1]=fnc
+ local value=functions.value or default
+ if value~=nil then
+ fnc(value)
+ functions.value=value
+ end
end
- return false
+ end
+ return false
end
function setters.enable(t,what)
- local e=t.enable
- t.enable,t.done=enable,{}
- enable(t,what)
- t.enable,t.done=e,{}
+ local e=t.enable
+ t.enable,t.done=enable,{}
+ enable(t,what)
+ t.enable,t.done=e,{}
end
function setters.disable(t,what)
- local e=t.disable
- t.disable,t.done=disable,{}
- disable(t,what)
- t.disable,t.done=e,{}
+ local e=t.disable
+ t.disable,t.done=disable,{}
+ disable(t,what)
+ t.disable,t.done=e,{}
end
function setters.reset(t)
- t.done={}
- reset(t)
+ t.done={}
+ reset(t)
end
function setters.list(t)
- local list=table.sortedkeys(t.data)
- local user,system={},{}
- for l=1,#list do
- local what=list[l]
- if find(what,"^%*") then
- system[#system+1]=what
- else
- user[#user+1]=what
- end
+ local list=table.sortedkeys(t.data)
+ local user,system={},{}
+ for l=1,#list do
+ local what=list[l]
+ if find(what,"^%*") then
+ system[#system+1]=what
+ else
+ user[#user+1]=what
end
- return user,system
+ end
+ return user,system
end
function setters.show(t)
- local list=setters.list(t)
- t.report()
- for k=1,#list do
- local name=list[k]
- local functions=t.data[name]
- if functions then
- local value=functions.value
- local default=functions.default
- local modules=#functions
- if default==nil then
- default="unset"
- elseif type(default)=="table" then
- default=concat(default,"|")
- else
- default=tostring(default)
- end
- if value==nil then
- value="unset"
- elseif type(value)=="table" then
- value=concat(value,"|")
- else
- value=tostring(value)
- end
- t.report(name)
- t.report(" modules : %i",modules)
- t.report(" default : %s",default)
- t.report(" value : %s",value)
- t.report()
- end
+ local list=setters.list(t)
+ t.report()
+ for k=1,#list do
+ local name=list[k]
+ local functions=t.data[name]
+ if functions then
+ local value=functions.value
+ local default=functions.default
+ local modules=#functions
+ if default==nil then
+ default="unset"
+ elseif type(default)=="table" then
+ default=concat(default,"|")
+ else
+ default=tostring(default)
+ end
+ if value==nil then
+ value="unset"
+ elseif type(value)=="table" then
+ value=concat(value,"|")
+ else
+ value=tostring(value)
+ end
+ t.report(name)
+ t.report(" modules : %i",modules)
+ t.report(" default : %s",default)
+ t.report(" value : %s",value)
+ t.report()
end
+ end
end
local enable,disable,register,list,show=setters.enable,setters.disable,setters.register,setters.list,setters.show
function setters.report(setter,...)
- print(format("%-15s : %s\n",setter.name,format(...)))
+ print(format("%-15s : %s\n",setter.name,format(...)))
end
local function default(setter,name)
- local d=setter.data[name]
- return d and d.default
+ local d=setter.data[name]
+ return d and d.default
end
local function value(setter,name)
- local d=setter.data[name]
- return d and (d.value or d.default)
+ local d=setter.data[name]
+ return d and (d.value or d.default)
end
function setters.new(name)
- local setter
- setter={
- data=allocate(),
- name=name,
- report=function(...) setters.report (setter,...) end,
- enable=function(...) enable (setter,...) end,
- disable=function(...) disable (setter,...) end,
- reset=function(...) reset (setter,...) end,
- register=function(...) register(setter,...) end,
- list=function(...) list (setter,...) end,
- show=function(...) show (setter,...) end,
- default=function(...) return default (setter,...) end,
- value=function(...) return value (setter,...) end,
- }
- data[name]=setter
- return setter
+ local setter
+ setter={
+ data=allocate(),
+ name=name,
+ report=function(...) setters.report (setter,...) end,
+ enable=function(...) enable (setter,...) end,
+ disable=function(...) disable (setter,...) end,
+ reset=function(...) reset (setter,...) end,
+ register=function(...) register(setter,...) end,
+ list=function(...) list (setter,...) end,
+ show=function(...) show (setter,...) end,
+ default=function(...) return default (setter,...) end,
+ value=function(...) return value (setter,...) end,
+ }
+ data[name]=setter
+ return setter
end
trackers=setters.new("trackers")
directives=setters.new("directives")
experiments=setters.new("experiments")
-local t_enable,t_disable=trackers .enable,trackers .disable
+local t_enable,t_disable=trackers .enable,trackers .disable
local d_enable,d_disable=directives .enable,directives .disable
local e_enable,e_disable=experiments.enable,experiments.disable
-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 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)
function directives.enable(...)
- if trace_directives then
- directives.report("enabling: % t",{...})
- end
- d_enable(...)
+ if trace_directives then
+ directives.report("enabling: % t",{...})
+ end
+ d_enable(...)
end
function directives.disable(...)
- if trace_directives then
- directives.report("disabling: % t",{...})
- end
- d_disable(...)
+ if trace_directives then
+ directives.report("disabling: % t",{...})
+ end
+ d_disable(...)
end
function experiments.enable(...)
- if trace_experiments then
- experiments.report("enabling: % t",{...})
- end
- e_enable(...)
+ if trace_experiments then
+ experiments.report("enabling: % t",{...})
+ end
+ e_enable(...)
end
function experiments.disable(...)
- if trace_experiments then
- experiments.report("disabling: % t",{...})
- end
- e_disable(...)
+ if trace_experiments then
+ experiments.report("disabling: % t",{...})
+ end
+ e_disable(...)
end
directives.register("system.nostatistics",function(v)
- if statistics then
- statistics.enable=not v
- else
- end
+ if statistics then
+ statistics.enable=not v
+ else
+ end
end)
directives.register("system.nolibraries",function(v)
- if libraries then
- libraries=nil
- else
- end
+ if libraries then
+ libraries=nil
+ else
+ end
end)
if environment then
- local engineflags=environment.engineflags
- if engineflags then
- local list=engineflags["c:trackers"] or engineflags["trackers"]
- if type(list)=="string" then
- setters.initialize("commandline flags","trackers",settings_to_hash(list))
- end
- local list=engineflags["c:directives"] or engineflags["directives"]
- if type(list)=="string" then
- setters.initialize("commandline flags","directives",settings_to_hash(list))
- end
+ local engineflags=environment.engineflags
+ if engineflags then
+ local list=engineflags["c:trackers"] or engineflags["trackers"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","trackers",settings_to_hash(list))
end
+ local list=engineflags["c:directives"] or engineflags["directives"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","directives",settings_to_hash(list))
+ end
+ end
end
if texconfig then
- local function set(k,v)
- v=tonumber(v)
- if v then
- texconfig[k]=v
- end
- end
- directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
- directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
- directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
- directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
- directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
- directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
- directives.register("luatex.paramsize",function(v) set("param_size",v) end)
- directives.register("luatex.savesize",function(v) set("save_size",v) end)
- directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
+ local function set(k,v)
+ v=tonumber(v)
+ if v then
+ texconfig[k]=v
+ end
+ end
+ directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
+ directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
+ directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
+ directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
+ directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
+ directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
+ directives.register("luatex.paramsize",function(v) set("param_size",v) end)
+ directives.register("luatex.savesize",function(v) set("save_size",v) end)
+ directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
end
local data=table.setmetatableindex("table")
updaters={
- register=function(what,f)
- local d=data[what]
- d[#d+1]=f
- end,
- apply=function(what,...)
- local d=data[what]
- for i=1,#d do
- d[i](...)
- end
- end,
+ register=function(what,f)
+ local d=data[what]
+ d[#d+1]=f
+ end,
+ apply=function(what,...)
+ local d=data[what]
+ for i=1,#d do
+ d[i](...)
+ end
+ end,
}
@@ -12560,14 +12560,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-log"] = package.loaded["trac-log"] or true
--- original size: 32608, stripped down to: 22574
+-- original size: 32608, stripped down to: 20925
if not modules then modules={} end modules ['trac-log']={
- version=1.001,
- comment="companion to trac-log.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,select,print=next,type,select,print
local format,gmatch,find=string.format,string.gmatch,string.find
@@ -12578,7 +12578,7 @@ local datetime=os.date
local openfile=io.open
local runningtex=tex and (tex.jobname or tex.formatname)
local write_nl=runningtex and texio and texio.write_nl or print
-local write=runningtex and texio and texio.write or io.write
+local write=runningtex and texio and texio.write or io.write
local setmetatableindex=table.setmetatableindex
local formatters=string.formatters
local settings_to_hash=utilities.parsers.settings_to_hash
@@ -12594,404 +12594,404 @@ webpage : http://www.pragma-ade.nl / http://tex.aanhet.net
wiki : http://contextgarden.net
]]
formatters.add (
- formatters,"unichr",
- [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
+ formatters,"unichr",
+ [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
)
formatters.add (
- formatters,"chruni",
- [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
+ formatters,"chruni",
+ [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
)
local function ignore() end
setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end)
local report,subreport,status,settarget,setformats,settranslations
local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters,newline
if runningtex then
- if texio.setescape then
- texio.setescape(0)
- end
- if arg then
- for k,v in next,arg do
- if v=="--ansi" or v=="--c:ansi" then
- variant="ansi"
- break
- end
- end
- end
- local function useluawrites()
- local texio_write_nl=texio.write_nl
- local texio_write=texio.write
- local io_write=io.write
- write_nl=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write_nl("log",...)
- texio_write_nl("term","")
- io_write(...)
- elseif target=="log" then
- texio_write_nl("log",...)
- elseif target=="term" then
- texio_write_nl("term","")
- io_write(...)
- elseif type(target)=="number" then
- texio_write_nl(target,...)
- elseif target~="none" then
- texio_write_nl("log",target,...)
- texio_write_nl("term","")
- io_write(target,...)
- end
- end
- write=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write("log",...)
- io_write(...)
- elseif target=="log" then
- texio_write("log",...)
- elseif target=="term" then
- io_write(...)
- elseif type(target)=="number" then
- texio_write(target,...)
- elseif target~="none" then
- texio_write("log",target,...)
- io_write(target,...)
- end
- end
- texio.write=write
- texio.write_nl=write_nl
- useluawrites=ignore
- end
- local whereto="both"
- local target=nil
- local targets=nil
- local formats=table.setmetatableindex("self")
- local translations=table.setmetatableindex("self")
- local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
- local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="log",
- log="log",
- file="log",
- console="term",
- terminal="term",
- both="term and log",
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="none",
- log="none",
- file="none",
- console="term",
- terminal="term",
- both="term",
- },
- }
- }
- logs.flush=io.flush
- writer=function(...)
- write_nl(target,...)
- end
- newline=function()
- write_nl(target,"\n")
- end
- report=function(a,b,c,...)
- if c~=nil then
- write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,report_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,report_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
- end
- direct=function(a,b,c,...)
- if c~=nil then
- return direct_yes(translations[a],formatters[formats[b]](c,...))
- elseif b then
- return direct_yes(translations[a],formats[b])
- elseif a then
- return direct_nop(translations[a])
- else
- return ""
- end
- end
- subreport=function(a,s,b,c,...)
- if c~=nil then
- write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
- elseif a then
- write_nl(target,subreport_nop(translations[a],translations[s]))
- else
- write_nl(target,"\n")
- end
- end
- subdirect=function(a,s,b,c,...)
- if c~=nil then
- return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
- elseif b then
- return subdirect_yes(translations[a],translations[s],formats[b])
- elseif a then
- return subdirect_nop(translations[a],translations[s])
- else
- return ""
- end
+ if texio.setescape then
+ texio.setescape(0)
+ end
+ if arg then
+ for k,v in next,arg do
+ if v=="--ansi" or v=="--c:ansi" then
+ variant="ansi"
+ break
+ end
end
- status=function(a,b,c,...)
- if c~=nil then
- write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,status_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,status_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
+ end
+ local function useluawrites()
+ local texio_write_nl=texio.write_nl
+ local texio_write=texio.write
+ local io_write=io.write
+ write_nl=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write_nl("log",...)
+ texio_write_nl("term","")
+ io_write(...)
+ elseif target=="log" then
+ texio_write_nl("log",...)
+ elseif target=="term" then
+ texio_write_nl("term","")
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write_nl(target,...)
+ elseif target~="none" then
+ texio_write_nl("log",target,...)
+ texio_write_nl("term","")
+ io_write(target,...)
+ end
end
- settarget=function(askedwhereto)
- whereto=askedwhereto or whereto or "both"
- target=targets[whereto]
- if not target then
- whereto="both"
- target=targets[whereto]
- end
- if target=="term" or target=="term and log" then
- logs.flush=io.flush
- else
- logs.flush=ignore
- end
+ write=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write("log",...)
+ io_write(...)
+ elseif target=="log" then
+ texio_write("log",...)
+ elseif target=="term" then
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write(target,...)
+ elseif target~="none" then
+ texio_write("log",target,...)
+ io_write(target,...)
+ end
end
- local stack={}
- pushtarget=function(newtarget)
- insert(stack,target)
- settarget(newtarget)
+ texio.write=write
+ texio.write_nl=write_nl
+ useluawrites=ignore
+ end
+ local whereto="both"
+ local target=nil
+ local targets=nil
+ local formats=table.setmetatableindex("self")
+ local translations=table.setmetatableindex("self")
+ local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
+ local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="log",
+ log="log",
+ file="log",
+ console="term",
+ terminal="term",
+ both="term and log",
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="none",
+ log="none",
+ file="none",
+ console="term",
+ terminal="term",
+ both="term",
+ },
+ }
+ }
+ logs.flush=io.flush
+ writer=function(...)
+ write_nl(target,...)
+ end
+ newline=function()
+ write_nl(target,"\n")
+ end
+ report=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,report_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,report_nop(translations[a]))
+ else
+ write_nl(target,"\n")
end
- poptarget=function()
- if #stack>0 then
- settarget(remove(stack))
- end
+ end
+ direct=function(a,b,c,...)
+ if c~=nil then
+ return direct_yes(translations[a],formatters[formats[b]](c,...))
+ elseif b then
+ return direct_yes(translations[a],formats[b])
+ elseif a then
+ return direct_nop(translations[a])
+ else
+ return ""
end
- setformats=function(f)
- formats=f
+ end
+ subreport=function(a,s,b,c,...)
+ if c~=nil then
+ write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
+ elseif a then
+ write_nl(target,subreport_nop(translations[a],translations[s]))
+ else
+ write_nl(target,"\n")
end
- settranslations=function(t)
- translations=t
+ end
+ subdirect=function(a,s,b,c,...)
+ if c~=nil then
+ return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
+ elseif b then
+ return subdirect_yes(translations[a],translations[s],formats[b])
+ elseif a then
+ return subdirect_nop(translations[a],translations[s])
+ else
+ return ""
end
- setprocessor=function(f)
- local writeline=write_nl
- write_nl=function(target,...)
- writeline(target,f(...))
- end
+ end
+ status=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,status_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,status_nop(translations[a]))
+ else
+ write_nl(target,"\n")
+ end
+ end
+ settarget=function(askedwhereto)
+ whereto=askedwhereto or whereto or "both"
+ target=targets[whereto]
+ if not target then
+ whereto="both"
+ target=targets[whereto]
+ end
+ if target=="term" or target=="term and log" then
+ logs.flush=io.flush
+ else
+ logs.flush=ignore
+ end
+ end
+ local stack={}
+ pushtarget=function(newtarget)
+ insert(stack,target)
+ settarget(newtarget)
+ end
+ poptarget=function()
+ if #stack>0 then
+ settarget(remove(stack))
+ end
+ end
+ setformats=function(f)
+ formats=f
+ end
+ settranslations=function(t)
+ translations=t
+ end
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(target,...)
+ writeline(target,f(...))
+ end
+ end
+ setformatters=function(specification)
+ local t=nil
+ local f=nil
+ local d=variants.default
+ if not specification then
+ elseif type(specification)=="table" then
+ t=specification.targets
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ t=v.targets
+ f=v.formats
+ variant=specification
+ end
end
- setformatters=function(specification)
- local t=nil
- local f=nil
- local d=variants.default
- if not specification then
- elseif type(specification)=="table" then
- t=specification.targets
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- t=v.targets
- f=v.formats
- variant=specification
- end
- end
- targets=t or d.targets
- target=targets[whereto] or target
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- direct_yes=f.direct_yes
- direct_nop=f.direct_nop
- subdirect_yes=f.subdirect_yes
- subdirect_nop=f.subdirect_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- if variant=="ansi" then
- useluawrites()
- end
- settarget(whereto)
- end
- setformatters(variant)
- setlogfile=ignore
- settimedlog=ignore
+ targets=t or d.targets
+ target=targets[whereto] or target
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ direct_yes=f.direct_yes
+ direct_nop=f.direct_nop
+ subdirect_yes=f.subdirect_yes
+ subdirect_nop=f.subdirect_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ if variant=="ansi" then
+ useluawrites()
+ end
+ settarget(whereto)
+ end
+ setformatters(variant)
+ setlogfile=ignore
+ settimedlog=ignore
else
- local report_yes,subreport_yes,status_yes
- local report_nop,subreport_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- }
- logs.flush=ignore
- writer=function(s)
- write_nl(s)
- end
- newline=function()
- write_nl("\n")
+ local report_yes,subreport_yes,status_yes
+ local report_nop,subreport_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ }
+ logs.flush=ignore
+ writer=function(s)
+ write_nl(s)
+ end
+ newline=function()
+ write_nl("\n")
+ end
+ report=function(a,b,c,...)
+ if c then
+ write_nl(report_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(report_yes(a,b))
+ elseif a then
+ write_nl(report_nop(a))
+ else
+ write_nl("")
end
- report=function(a,b,c,...)
- if c then
- write_nl(report_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(report_yes(a,b))
- elseif a then
- write_nl(report_nop(a))
- else
- write_nl("")
- end
+ end
+ subreport=function(a,sub,b,c,...)
+ if c then
+ write_nl(subreport_yes(a,sub,formatters[b](c,...)))
+ elseif b then
+ write_nl(subreport_yes(a,sub,b))
+ elseif a then
+ write_nl(subreport_nop(a,sub))
+ else
+ write_nl("")
end
- subreport=function(a,sub,b,c,...)
- if c then
- write_nl(subreport_yes(a,sub,formatters[b](c,...)))
- elseif b then
- write_nl(subreport_yes(a,sub,b))
- elseif a then
- write_nl(subreport_nop(a,sub))
- else
- write_nl("")
+ end
+ status=function(a,b,c,...)
+ if c then
+ write_nl(status_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(status_yes(a,b))
+ elseif a then
+ write_nl(status_nop(a))
+ else
+ write_nl("\n")
+ end
+ end
+ direct=ignore
+ subdirect=ignore
+ settarget=ignore
+ pushtarget=ignore
+ poptarget=ignore
+ setformats=ignore
+ settranslations=ignore
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(f(s))
+ end
+ end
+ setformatters=function(specification)
+ local f=nil
+ local d=variants.default
+ if specification then
+ if type(specification)=="table" then
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ f=v.formats
end
+ end
end
- status=function(a,b,c,...)
- if c then
- write_nl(status_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(status_yes(a,b))
- elseif a then
- write_nl(status_nop(a))
- else
- write_nl("\n")
- end
- end
- direct=ignore
- subdirect=ignore
- settarget=ignore
- pushtarget=ignore
- poptarget=ignore
- setformats=ignore
- settranslations=ignore
- setprocessor=function(f)
- local writeline=write_nl
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ end
+ setformatters(variant)
+ setlogfile=function(name,keepopen)
+ if name and name~="" then
+ local localtime=os.localtime
+ local writeline=write_nl
+ if keepopen then
+ local f=io.open(name,"ab")
write_nl=function(s)
- writeline(f(s))
+ writeline(s)
+ f:write(localtime()," | ",s,"\n")
end
- end
- setformatters=function(specification)
- local f=nil
- local d=variants.default
- if specification then
- if type(specification)=="table" then
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- f=v.formats
- end
- end
- end
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- end
- setformatters(variant)
- setlogfile=function(name,keepopen)
- if name and name~="" then
- local localtime=os.localtime
- local writeline=write_nl
- if keepopen then
- local f=io.open(name,"ab")
- write_nl=function(s)
- writeline(s)
- f:write(localtime()," | ",s,"\n")
- end
- else
- write_nl=function(s)
- writeline(s)
- local f=io.open(name,"ab")
- f:write(localtime()," | ",s,"\n")
- f:close()
- end
- end
- end
- setlogfile=ignore
- end
- settimedlog=function()
- local localtime=os.localtime
- local writeline=write_nl
+ else
write_nl=function(s)
- writeline(localtime().." | "..s)
+ writeline(s)
+ local f=io.open(name,"ab")
+ f:write(localtime()," | ",s,"\n")
+ f:close()
end
- settimedlog=ignore
+ end
end
+ setlogfile=ignore
+ end
+ settimedlog=function()
+ local localtime=os.localtime
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(localtime().." | "..s)
+ end
+ settimedlog=ignore
+ end
end
logs.report=report
logs.subreport=subreport
@@ -13013,186 +13013,186 @@ local data={}
local states=nil
local force=false
function logs.reporter(category,subcategory)
- local logger=data[category]
- if not logger then
- local state=states==true
- if not state and type(states)=="table" then
- for c,_ in next,states do
- if find(category,c) then
- state=true
- break
- end
- end
+ local logger=data[category]
+ if not logger then
+ local state=states==true
+ if not state and type(states)=="table" then
+ for c,_ in next,states do
+ if find(category,c) then
+ state=true
+ break
end
- logger={
- reporters={},
- state=state,
- }
- data[category]=logger
- end
- local reporter=logger.reporters[subcategory or "default"]
- if not reporter then
- if subcategory then
- reporter=function(...)
- if force or not logger.state then
- subreport(category,subcategory,...)
- end
- end
- logger.reporters[subcategory]=reporter
- else
- local tag=category
- reporter=function(...)
- if force or not logger.state then
- report(category,...)
- end
- end
- logger.reporters.default=reporter
+ end
+ end
+ logger={
+ reporters={},
+ state=state,
+ }
+ data[category]=logger
+ end
+ local reporter=logger.reporters[subcategory or "default"]
+ if not reporter then
+ if subcategory then
+ reporter=function(...)
+ if force or not logger.state then
+ subreport(category,subcategory,...)
+ end
+ end
+ logger.reporters[subcategory]=reporter
+ else
+ local tag=category
+ reporter=function(...)
+ if force or not logger.state then
+ report(category,...)
end
+ end
+ logger.reporters.default=reporter
end
- return reporter
+ end
+ return reporter
end
logs.new=logs.reporter
local ctxreport=logs.writer
function logs.setmessenger(m)
- ctxreport=m
+ ctxreport=m
end
function logs.messenger(category,subcategory)
- if subcategory then
- return function(...)
- ctxreport(subdirect(category,subcategory,...))
- end
- else
- return function(...)
- ctxreport(direct(category,...))
- end
+ if subcategory then
+ return function(...)
+ ctxreport(subdirect(category,subcategory,...))
end
+ else
+ return function(...)
+ ctxreport(direct(category,...))
+ end
+ end
end
local function setblocked(category,value)
- if category==true or category=="all" then
- category,value="*",true
- elseif category==false then
- category,value="*",false
- elseif value==nil then
- value=true
- end
- if category=="*" then
- states=value
+ if category==true or category=="all" then
+ category,value="*",true
+ elseif category==false then
+ category,value="*",false
+ elseif value==nil then
+ value=true
+ end
+ if category=="*" then
+ states=value
+ for k,v in next,data do
+ v.state=value
+ end
+ else
+ alllocked=false
+ states=settings_to_hash(category,type(states)=="table" and states or nil)
+ for c in next,states do
+ local v=data[c]
+ if v then
+ v.state=value
+ else
+ c=topattern(c,true,true)
for k,v in next,data do
+ if find(k,c) then
v.state=value
+ end
end
- else
- alllocked=false
- states=settings_to_hash(category,type(states)=="table" and states or nil)
- for c in next,states do
- local v=data[c]
- if v then
- v.state=value
- else
- c=topattern(c,true,true)
- for k,v in next,data do
- if find(k,c) then
- v.state=value
- end
- end
- end
- end
+ end
end
+ end
end
function logs.disable(category,value)
- setblocked(category,value==nil and true or value)
+ setblocked(category,value==nil and true or value)
end
function logs.enable(category)
- setblocked(category,false)
+ setblocked(category,false)
end
function logs.categories()
- return sortedkeys(data)
+ return sortedkeys(data)
end
function logs.show()
- local n,c,s,max=0,0,0,0
- for category,v in table.sortedpairs(data) do
- n=n+1
- local state=v.state
- local reporters=v.reporters
- local nc=#category
- if nc>c then
- c=nc
- end
- for subcategory,_ in next,reporters do
- local ns=#subcategory
- if ns>c then
- s=ns
- end
- local m=nc+ns
- if m>max then
- max=m
- end
- end
- local subcategories=concat(sortedkeys(reporters),", ")
- if state==true then
- state="disabled"
- elseif state==false then
- state="enabled"
- else
- state="unknown"
- end
- report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ local n,c,s,max=0,0,0,0
+ for category,v in table.sortedpairs(data) do
+ n=n+1
+ local state=v.state
+ local reporters=v.reporters
+ local nc=#category
+ if nc>c then
+ c=nc
+ end
+ for subcategory,_ in next,reporters do
+ local ns=#subcategory
+ if ns>c then
+ s=ns
+ end
+ local m=nc+ns
+ if m>max then
+ max=m
+ end
+ end
+ local subcategories=concat(sortedkeys(reporters),", ")
+ if state==true then
+ state="disabled"
+ elseif state==false then
+ state="enabled"
+ else
+ state="unknown"
end
- report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
+ report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ end
+ report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
end
local delayed_reporters={}
setmetatableindex(delayed_reporters,function(t,k)
- local v=logs.reporter(k.name)
- t[k]=v
- return v
+ local v=logs.reporter(k.name)
+ t[k]=v
+ return v
end)
function utilities.setters.report(setter,...)
- delayed_reporters[setter](...)
+ delayed_reporters[setter](...)
end
directives.register("logs.blocked",function(v)
- setblocked(v,true)
+ setblocked(v,true)
end)
directives.register("logs.target",function(v)
- settarget(v)
+ settarget(v)
end)
if tex then
- local report=logs.reporter("pages")
- local texgetcount=tex and tex.getcount
- local real,user,sub=0,0,0
- function logs.start_page_number()
- real=texgetcount("realpageno")
- user=texgetcount("userpageno")
- sub=texgetcount("subpageno")
- end
- local timing=false
- local lasttime=nil
- trackers.register("pages.timing",function(v)
- timing=""
- end)
- function logs.stop_page_number()
- if timing then
- local elapsed=statistics.currenttime(statistics)
- local average,page
- if not lasttime or real<2 then
- average=elapsed
- page=elapsed
- else
- average=elapsed/(real-1)
- page=elapsed-lasttime
- end
- lasttime=elapsed
- timing=formatters[", total %0.03f, page %0.03f, average %0.03f"](elapsed,page,average)
- end
- if real<=0 then
- report("flushing page%s",timing)
- elseif user<=0 then
- report("flushing realpage %s%s",real,timing)
- elseif sub<=0 then
- report("flushing realpage %s, userpage %s%s",real,user,timing)
- else
- report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
- end
- logs.flush()
+ local report=logs.reporter("pages")
+ local texgetcount=tex and tex.getcount
+ local real,user,sub=0,0,0
+ function logs.start_page_number()
+ real=texgetcount("realpageno")
+ user=texgetcount("userpageno")
+ sub=texgetcount("subpageno")
+ end
+ local timing=false
+ local lasttime=nil
+ trackers.register("pages.timing",function(v)
+ timing=""
+ end)
+ function logs.stop_page_number()
+ if timing then
+ local elapsed=statistics.currenttime(statistics)
+ local average,page
+ if not lasttime or real<2 then
+ average=elapsed
+ page=elapsed
+ else
+ average=elapsed/(real-1)
+ page=elapsed-lasttime
+ end
+ lasttime=elapsed
+ timing=formatters[", total %0.03f, page %0.03f, average %0.03f"](elapsed,page,average)
end
+ if real<=0 then
+ report("flushing page%s",timing)
+ elseif user<=0 then
+ report("flushing realpage %s%s",real,timing)
+ elseif sub<=0 then
+ report("flushing realpage %s, userpage %s%s",real,user,timing)
+ else
+ report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
+ end
+ logs.flush()
+ end
end
local nesting=0
local verbose=false
@@ -13216,222 +13216,222 @@ logs.help=ignore
local Carg,C,lpegmatch=lpeg.Carg,lpeg.C,lpeg.match
local p_newline=lpeg.patterns.newline
local linewise=(
- Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
+ Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
)^1
local function reportlines(t,str)
- if str then
- lpegmatch(linewise,str,1,t)
- end
+ if str then
+ lpegmatch(linewise,str,1,t)
+ end
end
local function reportbanner(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- t.report()
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ t.report()
+ end
end
local function reportversion(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ end
end
local function reporthelp(t,...)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="string" then
- reportlines(t,helpinfo)
- elseif type(helpinfo)=="table" then
- for i=1,select("#",...) do
- reportlines(t,t.helpinfo[select(i,...)])
- if i<n then
- t.report()
- end
- end
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="string" then
+ reportlines(t,helpinfo)
+ elseif type(helpinfo)=="table" then
+ for i=1,select("#",...) do
+ reportlines(t,t.helpinfo[select(i,...)])
+ if i<n then
+ t.report()
+ end
end
+ end
end
local function reportinfo(t)
- t.report()
- reportlines(t,t.moreinfo)
+ t.report()
+ reportlines(t,t.moreinfo)
end
local function reportexport(t,method)
- report(t.helpinfo)
+ report(t.helpinfo)
end
local reporters={
- lines=reportlines,
- banner=reportbanner,
- version=reportversion,
- help=reporthelp,
- info=reportinfo,
- export=reportexport,
+ lines=reportlines,
+ banner=reportbanner,
+ version=reportversion,
+ help=reporthelp,
+ info=reportinfo,
+ export=reportexport,
}
local exporters={
}
logs.reporters=reporters
logs.exporters=exporters
function logs.application(t)
- t.name=t.name or "unknown"
- t.banner=t.banner
- t.moreinfo=moreinfo
- t.report=logs.reporter(t.name)
- t.help=function(...)
- reporters.banner(t)
- reporters.help(t,...)
- reporters.info(t)
- end
- t.export=function(...)
- reporters.export(t,...)
- end
- t.identify=function()
- reporters.banner(t)
- end
- t.version=function()
- reporters.version(t)
- end
- return t
+ t.name=t.name or "unknown"
+ t.banner=t.banner
+ t.moreinfo=moreinfo
+ t.report=logs.reporter(t.name)
+ t.help=function(...)
+ reporters.banner(t)
+ reporters.help(t,...)
+ reporters.info(t)
+ end
+ t.export=function(...)
+ reporters.export(t,...)
+ end
+ t.identify=function()
+ reporters.banner(t)
+ end
+ t.version=function()
+ reporters.version(t)
+ end
+ return t
end
local f_syslog=formatters["%s %s => %s => %s => %s\r"]
function logs.system(whereto,process,jobname,category,fmt,arg,...)
- local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
- for i=1,10 do
- local f=openfile(whereto,"a")
- if f then
- f:write(message)
- f:close()
- break
- else
- sleep(0.1)
- end
+ local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
+ for i=1,10 do
+ local f=openfile(whereto,"a")
+ if f then
+ f:write(message)
+ f:close()
+ break
+ else
+ sleep(0.1)
end
+ end
end
local report_system=logs.reporter("system","logs")
function logs.obsolete(old,new)
- local o=loadstring("return "..new)()
- if type(o)=="function" then
- return function(...)
- report_system("function %a is obsolete, use %a",old,new)
- loadstring(old.."="..new.." return "..old)()(...)
- end
- elseif type(o)=="table" then
- local t,m={},{}
- m.__index=function(t,k)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- return o[k]
- end
- m.__newindex=function(t,k,v)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- o[k]=v
- end
- if libraries then
- libraries.obsolete[old]=t
- end
- setmetatable(t,m)
- return t
+ local o=loadstring("return "..new)()
+ if type(o)=="function" then
+ return function(...)
+ report_system("function %a is obsolete, use %a",old,new)
+ loadstring(old.."="..new.." return "..old)()(...)
+ end
+ elseif type(o)=="table" then
+ local t,m={},{}
+ m.__index=function(t,k)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ return o[k]
+ end
+ m.__newindex=function(t,k,v)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ o[k]=v
+ end
+ if libraries then
+ libraries.obsolete[old]=t
end
+ setmetatable(t,m)
+ return t
+ end
end
if utilities then
- utilities.report=report_system
+ utilities.report=report_system
end
if tex and tex.error then
- function logs.texerrormessage(...)
- tex.error(format(...))
- end
+ function logs.texerrormessage(...)
+ tex.error(format(...))
+ end
else
- function logs.texerrormessage(...)
- print(format(...))
- end
+ function logs.texerrormessage(...)
+ print(format(...))
+ end
end
io.stdout:setvbuf('no')
io.stderr:setvbuf('no')
if package.helpers.report then
- package.helpers.report=logs.reporter("package loader")
+ package.helpers.report=logs.reporter("package loader")
end
if tex then
- local finalactions={}
- local fatalerrors={}
- local possiblefatal={}
- local loggingerrors=false
- function logs.loggingerrors()
- return loggingerrors
- end
- directives.register("logs.errors",function(v)
- loggingerrors=v
- if type(v)=="string" then
- fatalerrors=settings_to_hash(v)
- else
- fatalerrors={}
- end
- end)
- function logs.registerfinalactions(...)
- insert(finalactions,...)
- end
- local what=nil
- local report=nil
- local state=nil
- local target=nil
- local function startlogging(t,r,w,s)
- target=t
- state=force
- force=true
- report=type(r)=="function" and r or logs.reporter(r)
- what=w
- pushtarget(target)
+ local finalactions={}
+ local fatalerrors={}
+ local possiblefatal={}
+ local loggingerrors=false
+ function logs.loggingerrors()
+ return loggingerrors
+ end
+ directives.register("logs.errors",function(v)
+ loggingerrors=v
+ if type(v)=="string" then
+ fatalerrors=settings_to_hash(v)
+ else
+ fatalerrors={}
+ end
+ end)
+ function logs.registerfinalactions(...)
+ insert(finalactions,...)
+ end
+ local what=nil
+ local report=nil
+ local state=nil
+ local target=nil
+ local function startlogging(t,r,w,s)
+ target=t
+ state=force
+ force=true
+ report=type(r)=="function" and r or logs.reporter(r)
+ what=w
+ pushtarget(target)
+ newline()
+ if s then
+ report("start %s: %s",what,s)
+ else
+ report("start %s",what)
+ end
+ if target=="logfile" then
+ newline()
+ end
+ return report
+ end
+ local function stoplogging()
+ if target=="logfile" then
+ newline()
+ end
+ report("stop %s",what)
+ if target=="logfile" then
+ newline()
+ end
+ poptarget()
+ state=oldstate
+ end
+ function logs.startfilelogging(...)
+ return startlogging("logfile",...)
+ end
+ logs.stopfilelogging=stoplogging
+ local done=false
+ function logs.starterrorlogging(r,w,...)
+ if not done then
+ pushtarget("terminal")
+ newline()
+ logs.report("error logging","start possible issues")
+ poptarget()
+ done=true
+ end
+ if fatalerrors[w] then
+ possiblefatal[w]=true
+ end
+ return startlogging("terminal",r,w,...)
+ end
+ logs.stoperrorlogging=stoplogging
+ function logs.finalactions()
+ if #finalactions>0 then
+ for i=1,#finalactions do
+ finalactions[i]()
+ end
+ if done then
+ pushtarget("terminal")
newline()
- if s then
- report("start %s: %s",what,s)
- else
- report("start %s",what)
- end
- if target=="logfile" then
- newline()
- end
- return report
- end
- local function stoplogging()
- if target=="logfile" then
- newline()
- end
- report("stop %s",what)
- if target=="logfile" then
- newline()
- end
+ logs.report("error logging","stop possible issues")
poptarget()
- state=oldstate
- end
- function logs.startfilelogging(...)
- return startlogging("logfile",...)
- end
- logs.stopfilelogging=stoplogging
- local done=false
- function logs.starterrorlogging(r,w,...)
- if not done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","start possible issues")
- poptarget()
- done=true
- end
- if fatalerrors[w] then
- possiblefatal[w]=true
- end
- return startlogging("terminal",r,w,...)
- end
- logs.stoperrorlogging=stoplogging
- function logs.finalactions()
- if #finalactions>0 then
- for i=1,#finalactions do
- finalactions[i]()
- end
- if done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","stop possible issues")
- poptarget()
- end
- return next(possiblefatal) and sortedkeys(possiblefatal) or false
- end
+ end
+ return next(possiblefatal) and sortedkeys(possiblefatal) or false
end
+ end
end
@@ -13441,14 +13441,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
--- original size: 8684, stripped down to: 6000
+-- original size: 9000, stripped down to: 6003
if not modules then modules={} end modules ['trac-inf']={
- version=1.001,
- comment="companion to trac-inf.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-inf.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber,select=type,tonumber,select
local format,lower,find=string.format,string.lower,string.find
@@ -13463,86 +13463,86 @@ statistics.enable=true
statistics.threshold=0.01
local statusinfo,n,registered,timers={},0,{},{}
setmetatableindex(timers,function(t,k)
- local v={ timing=0,loadtime=0 }
- t[k]=v
- return v
+ local v={ timing=0,loadtime=0 }
+ t[k]=v
+ return v
end)
local function hastiming(instance)
- return instance and timers[instance]
+ return instance and timers[instance]
end
local function resettiming(instance)
- timers[instance or "notimer"]={ timing=0,loadtime=0 }
+ timers[instance or "notimer"]={ timing=0,loadtime=0 }
end
local ticks=clock
local seconds=function(n) return n or 0 end
local function starttiming(instance,reset)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if reset then
- it=0
- timer.loadtime=0
- end
- if it==0 then
- timer.starttime=ticks()
- if not timer.loadtime then
- timer.loadtime=0
- end
- end
- timer.timing=it+1
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if reset then
+ it=0
+ timer.loadtime=0
+ end
+ if it==0 then
+ timer.starttime=ticks()
+ if not timer.loadtime then
+ timer.loadtime=0
+ end
+ end
+ timer.timing=it+1
end
local function stoptiming(instance)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it>1 then
- timer.timing=it-1
- else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- local stoptime=ticks()
- local loadtime=stoptime-starttime
- timer.stoptime=stoptime
- timer.loadtime=timer.loadtime+loadtime
- timer.timing=0
- timer.starttime=0
- return loadtime
- end
- end
- return 0
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
+ timer.timing=it-1
+ else
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ local stoptime=ticks()
+ local loadtime=stoptime-starttime
+ timer.stoptime=stoptime
+ timer.loadtime=timer.loadtime+loadtime
+ timer.timing=0
+ timer.starttime=0
+ return loadtime
+ end
+ end
+ return 0
end
local function elapsed(instance)
- if type(instance)=="number" then
- return instance
- else
- local timer=timers[instance or "notimer"]
- return timer and seconds(timer.loadtime) or 0
- end
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ return timer and seconds(timer.loadtime) or 0
+ end
end
local function currenttime(instance)
- if type(instance)=="number" then
- return instance
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
else
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it>1 then
- else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- return seconds(timer.loadtime+ticks()-starttime)
- end
- end
- return 0
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ return seconds(timer.loadtime+ticks()-starttime)
+ end
end
+ return 0
+ end
end
local function elapsedtime(instance)
- return format("%0.3f",elapsed(instance))
+ return format("%0.3f",elapsed(instance))
end
local function elapsedindeed(instance)
- return elapsed(instance)>statistics.threshold
+ return elapsed(instance)>statistics.threshold
end
local function elapsedseconds(instance,rest)
- if elapsedindeed(instance) then
- return format("%0.3f seconds %s",elapsed(instance),rest or "")
- end
+ if elapsedindeed(instance) then
+ return format("%0.3f seconds %s",elapsed(instance),rest or "")
+ end
end
statistics.hastiming=hastiming
statistics.resettiming=resettiming
@@ -13554,91 +13554,98 @@ statistics.elapsedtime=elapsedtime
statistics.elapsedindeed=elapsedindeed
statistics.elapsedseconds=elapsedseconds
function statistics.register(tag,fnc)
- if statistics.enable and type(fnc)=="function" then
- local rt=registered[tag] or (#statusinfo+1)
- statusinfo[rt]={ tag,fnc }
- registered[tag]=rt
- if #tag>n then n=#tag end
- end
+ if statistics.enable and type(fnc)=="function" then
+ local rt=registered[tag] or (#statusinfo+1)
+ statusinfo[rt]={ tag,fnc }
+ registered[tag]=rt
+ if #tag>n then n=#tag end
+ end
end
local report=logs.reporter("mkiv lua stats")
function statistics.show()
- if statistics.enable then
- local register=statistics.register
- register("used platform",function()
- return format("%s, type: %s, binary subtree: %s",
- os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
- end)
- register("used engine",function()
- return format("%s version %s with functionality level %s, banner: %s",
- LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
- end)
- register("control sequences",function()
- return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
- end)
- register("callbacks",statistics.callbacks)
- if TEXENGINE=="luajittex" and JITSUPPORTED then
- local jitstatus=jit.status
- if jitstatus then
- local jitstatus={ jitstatus() }
- if jitstatus[1] then
- register("luajit options",concat(jitstatus," ",2))
- end
- end
- end
- register("lua properties",function()
- local hashchar=tonumber(status.luatex_hashchars)
- local hashtype=status.luatex_hashtype
- local mask=lua.mask or "ascii"
- return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
- jit and "luajit" or "lua",
- LUAVERSION,
- statistics.memused(),
- hashtype or "default",
- hashchar and 2^hashchar or "unknown",
- mask,
- mask=="utf" and "τεχ" or "tex")
- end)
- register("runtime",statistics.runtime)
- logs.newline()
- for i=1,#statusinfo do
- local s=statusinfo[i]
- local r=s[2]()
- if r then
- report("%s: %s",s[1],r)
- end
+ if statistics.enable then
+ local register=statistics.register
+ register("used platform",function()
+ return format("%s, type: %s, binary subtree: %s",
+ os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
+ end)
+ register("used engine",function()
+ return format("%s version %s with functionality level %s, banner: %s",
+ LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
+ end)
+ register("control sequences",function()
+ return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
+ end)
+ register("callbacks",statistics.callbacks)
+ if TEXENGINE=="luajittex" and JITSUPPORTED then
+ local jitstatus=jit.status
+ if jitstatus then
+ local jitstatus={ jitstatus() }
+ if jitstatus[1] then
+ register("luajit options",concat(jitstatus," ",2))
end
- statistics.enable=false
+ end
+ end
+ register("lua properties",function()
+ local hashchar=tonumber(status.luatex_hashchars)
+ local hashtype=status.luatex_hashtype
+ local mask=lua.mask or "ascii"
+ return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
+ jit and "luajit" or "lua",
+ LUAVERSION,
+ statistics.memused(),
+ hashtype or "default",
+ hashchar and 2^hashchar or "unknown",
+ mask,
+ mask=="utf" and "τεχ" or "tex")
+ end)
+ register("runtime",statistics.runtime)
+ logs.newline()
+ for i=1,#statusinfo do
+ local s=statusinfo[i]
+ local r=s[2]()
+ if r then
+ report("%s: %s",s[1],r)
+ end
end
+ statistics.enable=false
+ end
end
function statistics.memused()
- local round=math.round or math.floor
- return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
+ local round=math.round or math.floor
+ return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
end
starttiming(statistics)
function statistics.formatruntime(runtime)
- return format("%s seconds",runtime)
+ return format("%s seconds",runtime)
end
function statistics.runtime()
- stoptiming(statistics)
- return statistics.formatruntime(elapsedtime(statistics))
+ stoptiming(statistics)
+ local runtime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
end
local report=logs.reporter("system")
-function statistics.timed(action)
- starttiming("run")
- action()
- stoptiming("run")
- report("total runtime: %s seconds",elapsedtime("run"))
+function statistics.timed(action,all)
+ starttiming("run")
+ action()
+ stoptiming("run")
+ local runtime=tonumber(elapsedtime("run"))
+ if all then
+ local alltime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime)
+ else
+ report("total runtime: %0.3f seconds",runtime)
+ end
end
function statistics.tracefunction(base,tag,...)
- for i=1,select("#",...) do
- local name=select(i,...)
- local stat={}
- local func=base[name]
- setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
- base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
- statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
- end
+ for i=1,select("#",...) do
+ local name=select(i,...)
+ local stat={}
+ local func=base[name]
+ setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
+ base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
+ statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
+ end
end
@@ -13648,144 +13655,144 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
--- original size: 5841, stripped down to: 3511
+-- original size: 5841, stripped down to: 3352
if not modules then modules={} end modules ['trac-pro']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
-local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
+local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
local report_system=logs.reporter("system","protection")
namespaces=namespaces or {}
local namespaces=namespaces
local registered={}
local function report_index(k,name)
- if trace_namespaces then
- report_system("reference to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("reference to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("reference to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("reference to %a in protected namespace %a",k,name)
+ end
end
local function report_newindex(k,name)
- if trace_namespaces then
- report_system("assignment to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("assignment to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("assignment to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("assignment to %a in protected namespace %a",k,name)
+ end
end
local function register(name)
- local data=name=="global" and _G or _G[name]
- if not data then
- return
- end
- registered[name]=data
- local m=getmetatable(data)
- if not m then
- m={}
- setmetatable(data,m)
- end
- local index,newindex={},{}
- m.__saved__index=m.__index
- m.__no__index=function(t,k)
- if not index[k] then
- index[k]=true
- report_index(k,name)
- end
- return nil
+ local data=name=="global" and _G or _G[name]
+ if not data then
+ return
+ end
+ registered[name]=data
+ local m=getmetatable(data)
+ if not m then
+ m={}
+ setmetatable(data,m)
+ end
+ local index,newindex={},{}
+ m.__saved__index=m.__index
+ m.__no__index=function(t,k)
+ if not index[k] then
+ index[k]=true
+ report_index(k,name)
end
- m.__saved__newindex=m.__newindex
- m.__no__newindex=function(t,k,v)
- if not newindex[k] then
- newindex[k]=true
- report_newindex(k,name)
- end
- rawset(t,k,v)
+ return nil
+ end
+ m.__saved__newindex=m.__newindex
+ m.__no__newindex=function(t,k,v)
+ if not newindex[k] then
+ newindex[k]=true
+ report_newindex(k,name)
end
- m.__protection__depth=0
+ rawset(t,k,v)
+ end
+ m.__protection__depth=0
end
local function private(name)
- local data=registered[name]
+ local data=registered[name]
+ if not data then
+ data=_G[name]
if not data then
- data=_G[name]
- if not data then
- data={}
- _G[name]=data
- end
- register(name)
+ data={}
+ _G[name]=data
end
- return data
+ register(name)
+ end
+ return data
end
local function protect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>0 then
- m.__protection__depth=pd+1
- else
- m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
- m.__index,m.__newindex=m.__no__index,m.__no__newindex
- m.__protection__depth=1
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>0 then
+ m.__protection__depth=pd+1
+ else
+ m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
+ m.__index,m.__newindex=m.__no__index,m.__no__newindex
+ m.__protection__depth=1
+ end
end
local function unprotect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>1 then
- m.__protection__depth=pd-1
- else
- m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
- m.__protection__depth=0
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>1 then
+ m.__protection__depth=pd-1
+ else
+ m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
+ m.__protection__depth=0
+ end
end
local function protectall()
- for name,_ in next,registered do
- if name~="global" then
- protect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ protect(name)
end
+ end
end
local function unprotectall()
- for name,_ in next,registered do
- if name~="global" then
- unprotect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ unprotect(name)
end
+ end
end
-namespaces.register=register
-namespaces.private=private
+namespaces.register=register
+namespaces.private=private
namespaces.protect=protect
namespaces.unprotect=unprotect
namespaces.protectall=protectall
namespaces.unprotectall=unprotectall
namespaces.private("namespaces") registered={} register("global")
directives.register("system.protect",function(v)
- if v then
- protectall()
- else
- unprotectall()
- end
+ if v then
+ protectall()
+ else
+ unprotectall()
+ end
end)
directives.register("system.checkglobals",function(v)
- if v then
- report_system("enabling global namespace guard")
- protect("global")
- else
- report_system("disabling global namespace guard")
- unprotect("global")
- end
+ if v then
+ report_system("enabling global namespace guard")
+ protect("global")
+ else
+ report_system("disabling global namespace guard")
+ unprotect("global")
+ end
end)
@@ -13795,15 +13802,15 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lua"] = package.loaded["util-lua"] or true
--- original size: 6664, stripped down to: 4800
+-- original size: 6664, stripped down to: 4589
if not modules then modules={} end modules ['util-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment="the strip code is written by Peter Cawley",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ comment="the strip code is written by Peter Cawley",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format
local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage
@@ -13814,151 +13821,151 @@ local report_lua=logs.reporter("system","lua")
local report_mem=logs.reporter("system","lua memory")
local tracestripping=false
local tracememory=false
-luautilities.stripcode=true
+luautilities.stripcode=true
luautilities.alwaysstripcode=false
luautilities.nofstrippedchunks=0
luautilities.nofstrippedbytes=0
local strippedchunks={}
luautilities.strippedchunks=strippedchunks
luautilities.suffixes={
- tma="tma",
- tmc=jit and "tmb" or "tmc",
- lua="lua",
- luc=jit and "lub" or "luc",
- lui="lui",
- luv="luv",
- luj="luj",
- tua="tua",
- tuc="tuc",
+ tma="tma",
+ tmc=jit and "tmb" or "tmc",
+ lua="lua",
+ luc=jit and "lub" or "luc",
+ lui="lui",
+ luv="luv",
+ luj="luj",
+ tua="tua",
+ tuc="tuc",
}
local function register(name)
- if tracestripping then
- report_lua("stripped bytecode from %a",name or "unknown")
- end
- strippedchunks[#strippedchunks+1]=name
- luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
+ if tracestripping then
+ report_lua("stripped bytecode from %a",name or "unknown")
+ end
+ strippedchunks[#strippedchunks+1]=name
+ luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
end
local function stupidcompile(luafile,lucfile,strip)
- local code=io.loaddata(luafile)
- if code and code~="" then
- code=load(code)
- if code then
- code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
- if code and code~="" then
- register(name)
- io.savedata(lucfile,code)
- return true,0
- end
- else
- report_lua("fatal error %a in file %a",1,luafile)
- end
- else
- report_lua("fatal error %a in file %a",2,luafile)
- end
- return false,0
-end
-function luautilities.loadedluacode(fullname,forcestrip,name,macros)
- name=name or fullname
- if macros then
- macros=lua.macros
- end
- local code,message
- if macros then
- code,message=macros.loaded(fullname,true,false)
- else
- code,message=loadfile(fullname)
- end
+ local code=io.loaddata(luafile)
+ if code and code~="" then
+ code=load(code)
if code then
- code()
- else
- report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
- code,message=loadfile(fullname)
- end
- if forcestrip and luautilities.stripcode then
- if type(forcestrip)=="function" then
- forcestrip=forcestrip(fullname)
- end
- if forcestrip or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
- elseif luautilities.alwaysstripcode then
+ code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
+ if code and code~="" then
register(name)
- return load(dump(code,true)),0
+ io.savedata(lucfile,code)
+ return true,0
+ end
else
- return code,0
+ report_lua("fatal error %a in file %a",1,luafile)
end
+ else
+ report_lua("fatal error %a in file %a",2,luafile)
+ end
+ return false,0
+end
+function luautilities.loadedluacode(fullname,forcestrip,name,macros)
+ name=name or fullname
+ if macros then
+ macros=lua.macros
+ end
+ local code,message
+ if macros then
+ code,message=macros.loaded(fullname,true,false)
+ else
+ code,message=loadfile(fullname)
+ end
+ if code then
+ code()
+ else
+ report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
+ code,message=loadfile(fullname)
+ end
+ if forcestrip and luautilities.stripcode then
+ if type(forcestrip)=="function" then
+ forcestrip=forcestrip(fullname)
+ end
+ if forcestrip or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
+ elseif luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.strippedloadstring(code,name,forcestrip)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.loadstring(code,name)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- return code,0
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ return code,0
end
function luautilities.compile(luafile,lucfile,cleanup,strip,fallback)
- report_lua("compiling %a into %a",luafile,lucfile)
- os.remove(lucfile)
- local done=stupidcompile(luafile,lucfile,strip~=false)
- if done then
- report_lua("dumping %a into %a stripped",luafile,lucfile)
- if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
- report_lua("removing %a",luafile)
- os.remove(luafile)
- end
- end
- return done
+ report_lua("compiling %a into %a",luafile,lucfile)
+ os.remove(lucfile)
+ local done=stupidcompile(luafile,lucfile,strip~=false)
+ if done then
+ report_lua("dumping %a into %a stripped",luafile,lucfile)
+ if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+ report_lua("removing %a",luafile)
+ os.remove(luafile)
+ end
+ end
+ return done
end
function luautilities.loadstripped(...)
- local l=load(...)
- if l then
- return load(dump(l,true))
- end
+ local l=load(...)
+ if l then
+ return load(dump(l,true))
+ end
end
local finalizers={}
setmetatable(finalizers,{
- __gc=function(t)
- for i=1,#t do
- pcall(t[i])
- end
+ __gc=function(t)
+ for i=1,#t do
+ pcall(t[i])
end
+ end
} )
function luautilities.registerfinalizer(f)
- finalizers[#finalizers+1]=f
+ finalizers[#finalizers+1]=f
end
function luautilities.checkmemory(previous,threshold,trace)
- local current=collectgarbage("count")
- if previous then
- local checked=(threshold or 64)*1024
- local delta=current-previous
- if current-previous>checked then
- collectgarbage("collect")
- local afterwards=collectgarbage("count")
- if trace or tracememory then
- report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
- previous/1024,current/1024,delta/1024,threshold,afterwards)
- end
- return afterwards
- elseif trace or tracememory then
- report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
- previous/1024,current/1024,delta/1024,threshold)
- end
+ local current=collectgarbage("count")
+ if previous then
+ local checked=(threshold or 64)*1024
+ local delta=current-previous
+ if current-previous>checked then
+ collectgarbage("collect")
+ local afterwards=collectgarbage("count")
+ if trace or tracememory then
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
+ previous/1024,current/1024,delta/1024,threshold,afterwards)
+ end
+ return afterwards
+ elseif trace or tracememory then
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
+ previous/1024,current/1024,delta/1024,threshold)
end
- return current
+ end
+ return current
end
@@ -13968,14 +13975,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-deb"] = package.loaded["util-deb"] or true
--- original size: 9955, stripped down to: 7311
+-- original size: 9955, stripped down to: 6693
if not modules then modules={} end modules ['util-deb']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber=type,next,tostring,tonumber
local format,find,sub,gsub=string.format,string.find,string.sub,string.gsub
@@ -13994,266 +14001,266 @@ local names={}
local initialize=false
if not (FFISUPPORTED and ffi) then
elseif os.type=="windows" then
- initialize=function()
- local kernel=ffilib("kernel32","system")
- if kernel then
- local tonumber=ffi.number or tonumber
- ffi.cdef[[
+ initialize=function()
+ local kernel=ffilib("kernel32","system")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ ffi.cdef[[
int QueryPerformanceFrequency(int64_t *lpFrequency);
int QueryPerformanceCounter(int64_t *lpPerformanceCount);
]]
- local target=ffi.new("__int64[1]")
- ticks=function()
- if kernel.QueryPerformanceCounter(target)==1 then
- return tonumber(target[0])
- else
- return 0
- end
- end
- local target=ffi.new("__int64[1]")
- seconds=function(ticks)
- if kernel.QueryPerformanceFrequency(target)==1 then
- return ticks/tonumber(target[0])
- else
- return 0
- end
- end
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
end
- initialize=false
+ end
end
+ initialize=false
+ end
elseif os.type=="unix" then
- initialize=function()
- local C=ffi.C
- local tonumber=ffi.number or tonumber
- ffi.cdef [[
+ initialize=function()
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ ffi.cdef [[
/* what a mess */
typedef int clk_id_t;
typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
typedef struct timespec { long sec; long nsec; } ctx_timespec;
int clock_gettime(clk_id_t timerid, struct timespec *t);
]]
- local target=ffi.new("ctx_timespec[?]",1)
- local clock=C.CLOCK_PROCESS_CPUTIME_ID
- ticks=function ()
- C.clock_gettime(clock,target)
- return tonumber(target[0].sec*1000000000+target[0].nsec)
- end
- seconds=function(ticks)
- return ticks/1000000000
- end
- initialize=false
+ local target=ffi.new("ctx_timespec[?]",1)
+ local clock=C.CLOCK_PROCESS_CPUTIME_ID
+ ticks=function ()
+ C.clock_gettime(clock,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
end
+ seconds=function(ticks)
+ return ticks/1000000000
+ end
+ initialize=false
+ end
end
setmetatableindex(names,function(t,name)
- local v=setmetatableindex(function(t,source)
- local v=setmetatableindex(function(t,line)
- local v={ total=0,count=0,nesting=0 }
- t[line]=v
- return v
- end)
- t[source]=v
- return v
+ local v=setmetatableindex(function(t,source)
+ local v=setmetatableindex(function(t,line)
+ local v={ total=0,count=0,nesting=0 }
+ t[line]=v
+ return v
end)
- t[name]=v
+ t[source]=v
return v
+ end)
+ t[name]=v
+ return v
end)
local getinfo=nil
local sethook=nil
local function hook(where)
- local f=getinfo(2,"nSl")
- if f then
- local source=f.short_src
- if not source then
- return
- end
- local line=f.linedefined or 0
- local name=f.name
- if not name then
- local what=f.what
- if what=="C" then
- name="<anonymous>"
- else
- name=f.namewhat or what or "<unknown>"
- end
- end
- local data=names[name][source][line]
- if where=="call" then
- local nesting=data.nesting
- if nesting==0 then
- data.count=data.count+1
- insert(data,ticks())
- data.nesting=1
- else
- data.nesting=nesting+1
- end
- elseif where=="return" then
- local nesting=data.nesting
- if nesting==1 then
- local t=remove(data)
- if t then
- data.total=data.total+ticks()-t
- end
- data.nesting=0
- else
- data.nesting=nesting-1
- end
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
+ end
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ local nesting=data.nesting
+ if nesting==0 then
+ data.count=data.count+1
+ insert(data,ticks())
+ data.nesting=1
+ else
+ data.nesting=nesting+1
+ end
+ elseif where=="return" then
+ local nesting=data.nesting
+ if nesting==1 then
+ local t=remove(data)
+ if t then
+ data.total=data.total+ticks()-t
end
+ data.nesting=0
+ else
+ data.nesting=nesting-1
+ end
end
+ end
end
function debugger.showstats(printer,threshold)
- local printer=printer or report
- local calls=0
- local functions=0
- local dataset={}
- local length=0
- local realtime=0
- local totaltime=0
- local threshold=threshold or 0
- for name,sources in next,names do
- for source,lines in next,sources do
- for line,data in next,lines do
- local count=data.count
- if count>threshold then
- if #name>length then
- length=#name
- end
- local total=data.total
- local real=total
- if real>0 then
- real=total-(count*overhead/dummycalls)
- if real<0 then
- real=0
- end
- realtime=realtime+real
- end
- totaltime=totaltime+total
- if line<0 then
- line=0
- end
- dataset[#dataset+1]={ real,total,count,name,source,line }
- end
- end
+ local printer=printer or report
+ local calls=0
+ local functions=0
+ local dataset={}
+ local length=0
+ local realtime=0
+ local totaltime=0
+ local threshold=threshold or 0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ local count=data.count
+ if count>threshold then
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ realtime=realtime+real
+ end
+ totaltime=totaltime+total
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
end
+ end
end
- sort(dataset,function(a,b)
- if a[1]==b[1] then
- if a[2]==b[2] then
- if a[3]==b[3] then
- if a[4]==b[4] then
- if a[5]==b[5] then
- return a[6]<b[6]
- else
- return a[5]<b[5]
- end
- else
- return a[4]<b[4]
- end
- else
- return b[3]<a[3]
- end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
else
- return b[2]<a[2]
+ return a[5]<b[5]
end
+ else
+ return a[4]<b[4]
+ end
else
- return b[1]<a[1]
+ return b[3]<a[3]
end
- end)
- if length>50 then
- length=50
- end
- local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
- for i=1,#dataset do
- local data=dataset[i]
- local real=data[1]
- local total=data[2]
- local count=data[3]
- local name=data[4]
- local source=data[5]
- local line=data[6]
- calls=calls+count
- functions=functions+1
- name=gsub(name,"%s+"," ")
- if #name>length then
- name=sub(name,1,length)
- end
- printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
- end
- printer("")
- printer(format("functions : %i",functions))
- printer(format("calls : %i",calls))
- printer(format("overhead : %f",seconds(overhead/1000)))
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
+ end
+ local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
+ for i=1,#dataset do
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ calls=calls+count
+ functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
+ end
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
end
local function getdebug()
- if sethook and getinfo then
- return
- end
- if not debug then
- local okay
- okay,debug=pcall(require,"debug")
- end
- if type(debug)~="table" then
- return
- end
- getinfo=debug.getinfo
- sethook=debug.sethook
- if type(getinfo)~="function" then
- getinfo=nil
- end
- if type(sethook)~="function" then
- sethook=nil
- end
+ if sethook and getinfo then
+ return
+ end
+ if not debug then
+ local okay
+ okay,debug=pcall(require,"debug")
+ end
+ if type(debug)~="table" then
+ return
+ end
+ getinfo=debug.getinfo
+ sethook=debug.sethook
+ if type(getinfo)~="function" then
+ getinfo=nil
+ end
+ if type(sethook)~="function" then
+ sethook=nil
+ end
end
function debugger.savestats(filename,threshold)
- local f=io.open(filename,'w')
- if f then
- debugger.showstats(function(str) f:write(str,"\n") end,threshold)
- f:close()
- end
+ local f=io.open(filename,'w')
+ if f then
+ debugger.showstats(function(str) f:write(str,"\n") end,threshold)
+ f:close()
+ end
end
function debugger.enable()
- getdebug()
- if sethook and getinfo and nesting==0 then
- running=true
- if initialize then
- initialize()
- end
- sethook(hook,"cr")
- local function dummy() end
- local t=ticks()
- for i=1,dummycalls do
- dummy()
- end
- overhead=ticks()-t
- end
- if nesting>0 then
- nesting=nesting+1
- end
+ getdebug()
+ if sethook and getinfo and nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
end
function debugger.disable()
- if nesting>0 then
- nesting=nesting-1
- end
- if sethook and getinfo and nesting==0 then
- sethook()
- end
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if sethook and getinfo and nesting==0 then
+ sethook()
+ end
end
local function showtraceback(rep)
- getdebug()
- if getinfo then
- local level=2
- local reporter=rep or report
- while true do
- local info=getinfo(level,"Sl")
- if not info then
- break
- elseif info.what=="C" then
- reporter("%2i : %s",level-1,"C function")
- else
- reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
- end
- level=level+1
- end
+ getdebug()
+ if getinfo then
+ local level=2
+ local reporter=rep or report
+ while true do
+ local info=getinfo(level,"Sl")
+ if not info then
+ break
+ elseif info.what=="C" then
+ reporter("%2i : %s",level-1,"C function")
+ else
+ reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
+ end
+ level=level+1
end
+ end
end
debugger.showtraceback=showtraceback
@@ -14264,91 +14271,91 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
--- original size: 7112, stripped down to: 3988
+-- original size: 7112, stripped down to: 3887
if not modules then modules={} end modules ['util-tpl']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities.templates=utilities.templates or {}
local templates=utilities.templates
-local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
+local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
local report_template=logs.reporter("template")
local tostring,next=tostring,next
local format,sub,byte=string.format,string.sub,string.byte
local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
local replacer
local function replacekey(k,t,how,recursive)
- local v=t[k]
- if not v then
- if trace_template then
- report_template("unknown key %a",k)
- end
- return ""
+ local v=t[k]
+ if not v then
+ if trace_template then
+ report_template("unknown key %a",k)
+ end
+ return ""
+ else
+ v=tostring(v)
+ if trace_template then
+ report_template("setting key %a to value %a",k,v)
+ end
+ if recursive then
+ return lpegmatch(replacer,v,1,t,how,recursive)
else
- v=tostring(v)
- if trace_template then
- report_template("setting key %a to value %a",k,v)
- end
- if recursive then
- return lpegmatch(replacer,v,1,t,how,recursive)
- else
- return v
- end
+ return v
end
+ end
end
local sqlescape=lpeg.replacer {
- { "'","''" },
- { "\\","\\\\" },
- { "\r\n","\\n" },
- { "\r","\\n" },
+ { "'","''" },
+ { "\\","\\\\" },
+ { "\r\n","\\n" },
+ { "\r","\\n" },
}
local sqlquoted=Cs(Cc("'")*sqlescape*Cc("'"))
lpegpatterns.sqlescape=sqlescape
lpegpatterns.sqlquoted=sqlquoted
local luaescape=lpegpatterns.luaescape
local escapers={
- lua=function(s)
- return lpegmatch(luaescape,s)
- end,
- sql=function(s)
- return lpegmatch(sqlescape,s)
- end,
+ lua=function(s)
+ return lpegmatch(luaescape,s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlescape,s)
+ end,
}
local quotedescapers={
- lua=function(s)
- return format("%q",s)
- end,
- sql=function(s)
- return lpegmatch(sqlquoted,s)
- end,
+ lua=function(s)
+ return format("%q",s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlquoted,s)
+ end,
}
local luaescaper=escapers.lua
local quotedluaescaper=quotedescapers.lua
local function replacekeyunquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and escapers[how] or luaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and escapers[how] or luaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replacekeyquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and quotedescapers[how] or quotedluaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and quotedescapers[how] or quotedluaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replaceoptional(l,m,r,t,how,recurse)
- local v=t[l]
- return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
+ local v=t[l]
+ return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
end
-local single=P("%")
+local single=P("%")
local double=P("%%")
local lquoted=P("%[")
local rquoted=P("]%")
@@ -14365,41 +14372,41 @@ local noloptional=P("%?")/''
local noroptional=P("?%")/''
local nomoptional=P(":")/''
local args=Carg(1)*Carg(2)*Carg(3)
-local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
-local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
-local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
+local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
+local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
+local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
local optional=noloptional*((C((1-nomoptional)^1)*nomoptional*C((1-noroptional)^1)*args)/replaceoptional)*noroptional
local any=P(1)
replacer=Cs((unquoted+quoted+escape+optional+key+any)^0)
local function replace(str,mapping,how,recurse)
- if mapping and str then
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
- return str
- end
+ if mapping and str then
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ else
+ return str
+ end
end
templates.replace=replace
function templates.replacer(str,how,recurse)
- return function(mapping)
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- end
+ return function(mapping)
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ end
end
function templates.load(filename,mapping,how,recurse)
- local data=io.loaddata(filename) or ""
- if mapping and next(mapping) then
- return replace(data,mapping,how,recurse)
- else
- return data
- end
+ local data=io.loaddata(filename) or ""
+ if mapping and next(mapping) then
+ return replace(data,mapping,how,recurse)
+ else
+ return data
+ end
end
function templates.resolve(t,mapping,how,recurse)
- if not mapping then
- mapping=t
- end
- for k,v in next,t do
- t[k]=replace(v,mapping,how,recurse)
- end
- return t
+ if not mapping then
+ mapping=t
+ end
+ for k,v in next,t do
+ t[k]=replace(v,mapping,how,recurse)
+ end
+ return t
end
@@ -14409,14 +14416,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sbx"] = package.loaded["util-sbx"] or true
--- original size: 20393, stripped down to: 13924
+-- original size: 20393, stripped down to: 13121
if not modules then modules={} end modules ['util-sbx']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not sandbox then require("l-sandbox") end
local next,type=next,type
@@ -14449,144 +14456,144 @@ local report=logs.reporter("sandbox")
trackers.register("sandbox",function(v) trace=v end)
sandbox.setreporter(report)
sandbox.finalizer {
- category="files",
- action=function()
- finalized=true
- end
+ category="files",
+ action=function()
+ finalized=true
+ end
}
local function registerroot(root,what)
- if finalized then
- report("roots are already finalized")
- else
- if type(root)=="table" then
- root,what=root[1],root[2]
- end
- if type(root)=="string" and root~="" then
- root=collapsepath(expandname(root))
- if what=="r" or what=="ro" or what=="readable" then
- what="read"
- elseif what=="w" or what=="wo" or what=="writable" then
- what="write"
- end
- validroots[root]=what=="write" or false
- end
+ if finalized then
+ report("roots are already finalized")
+ else
+ if type(root)=="table" then
+ root,what=root[1],root[2]
+ end
+ if type(root)=="string" and root~="" then
+ root=collapsepath(expandname(root))
+ if what=="r" or what=="ro" or what=="readable" then
+ what="read"
+ elseif what=="w" or what=="wo" or what=="writable" then
+ what="write"
+ end
+ validroots[root]=what=="write" or false
end
+ end
end
sandbox.finalizer {
- category="files",
- action=function()
+ category="files",
+ action=function()
+ if p_validroot then
+ report("roots are already initialized")
+ else
+ sandbox.registerroot(".","write")
+ for name in sortedhash(validroots) do
if p_validroot then
- report("roots are already initialized")
+ p_validroot=P(name)+p_validroot
else
- sandbox.registerroot(".","write")
- for name in sortedhash(validroots) do
- if p_validroot then
- p_validroot=P(name)+p_validroot
- else
- p_validroot=P(name)
- end
- end
- p_validroot=p_validroot/validroots
+ p_validroot=P(name)
end
+ end
+ p_validroot=p_validroot/validroots
end
+ end
}
local function registerbinary(name)
- if finalized then
- report("binaries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validbinaries then
- return
- end
- if validbinaries==true then
- validbinaries={ [name]=true }
- else
- validbinaries[name]=true
- end
- elseif name==true then
- validbinaries={}
+ if finalized then
+ report("binaries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validbinaries then
+ return
end
+ if validbinaries==true then
+ validbinaries={ [name]=true }
+ else
+ validbinaries[name]=true
+ end
+ elseif name==true then
+ validbinaries={}
+ end
end
local function registerlibrary(name)
- if finalized then
- report("libraries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validlibraries then
- return
- end
- if validlibraries==true then
- validlibraries={ [nameonly(name)]=true }
- else
- validlibraries[nameonly(name)]=true
- end
- elseif name==true then
- validlibraries={}
+ if finalized then
+ report("libraries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validlibraries then
+ return
end
+ if validlibraries==true then
+ validlibraries={ [nameonly(name)]=true }
+ else
+ validlibraries[nameonly(name)]=true
+ end
+ elseif name==true then
+ validlibraries={}
+ end
end
local p_write=S("wa") p_write=(1-p_write)^0*p_write
-local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
+local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
local function normalized(name)
- if platform=="windows" then
- name=gsub(name,"/","\\")
- end
- return name
+ if platform=="windows" then
+ name=gsub(name,"/","\\")
+ end
+ return name
end
function sandbox.possiblepath(name)
- return lpegmatch(p_path,name) and true or false
+ return lpegmatch(p_path,name) and true or false
end
local filenamelogger=false
function sandbox.setfilenamelogger(l)
- filenamelogger=type(l)=="function" and l or false
+ filenamelogger=type(l)=="function" and l or false
end
local function validfilename(name,what)
- if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
- local asked=collapsepath(expandname(name))
- local okay=lpegmatch(p_validroot,asked)
- if okay==true then
- if filenamelogger then
- filenamelogger(name,"w",asked,true)
- end
- return name
- elseif okay==false then
- if not what then
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- elseif lpegmatch(p_write,what) then
- if filenamelogger then
- filenamelogger(name,"w",asked,false)
- end
- return
- else
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- end
- elseif filenamelogger then
- filenamelogger(name,"*",name,false)
+ if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
+ local asked=collapsepath(expandname(name))
+ local okay=lpegmatch(p_validroot,asked)
+ if okay==true then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,true)
+ end
+ return name
+ elseif okay==false then
+ if not what then
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
+ end
+ return name
+ elseif lpegmatch(p_write,what) then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,false)
+ end
+ return
+ else
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
end
- else
return name
+ end
+ elseif filenamelogger then
+ filenamelogger(name,"*",name,false)
end
+ else
+ return name
+ end
end
local function readable(name,finalized)
- return validfilename(name,"r")
+ return validfilename(name,"r")
end
local function normalizedreadable(name,finalized)
- local valid=validfilename(name,"r")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"r")
+ if valid then
+ return normalized(valid)
+ end
end
local function writeable(name,finalized)
- return validfilename(name,"w")
+ return validfilename(name,"w")
end
local function normalizedwriteable(name,finalized)
- local valid=validfilename(name,"w")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"w")
+ if valid then
+ return normalized(valid)
+ end
end
validators.readable=readable
validators.writeable=normalizedwriteable
@@ -14594,316 +14601,316 @@ validators.normalizedreadable=normalizedreadable
validators.normalizedwriteable=writeable
validators.filename=readable
table.setmetatableindex(validators,function(t,k)
- if k then
- t[k]=readable
- end
- return readable
+ if k then
+ t[k]=readable
+ end
+ return readable
end)
function validators.string(s,finalized)
- if finalized and suspicious(s) then
- return ""
- else
- return s
- end
+ if finalized and suspicious(s) then
+ return ""
+ else
+ return s
+ end
end
function validators.cache(s)
- if finalized then
- return basename(s)
- else
- return s
- end
+ if finalized then
+ return basename(s)
+ else
+ return s
+ end
end
function validators.url(s)
- if finalized and find("^file:") then
- return ""
- else
- return s
- end
+ if finalized and find("^file:") then
+ return ""
+ else
+ return s
+ end
end
local function filehandlerone(action,one,...)
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
+ else
+ end
end
local function filehandlertwo(action,one,two,...)
- local checkedone=validfilename(one)
- if checkedone then
- local checkedtwo=validfilename(two)
- if checkedtwo then
- return action(one,two,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ local checkedtwo=validfilename(two)
+ if checkedtwo then
+ return action(one,two,...)
else
end
+ else
+ end
end
local function iohandler(action,one,...)
- if type(one)=="string" then
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- end
- elseif one then
- return action(one,...)
- else
- return action()
+ if type(one)=="string" then
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
end
+ elseif one then
+ return action(one,...)
+ else
+ return action()
+ end
end
local osexecute=sandbox.original(os.execute)
local iopopen=sandbox.original(io.popen)
local reported={}
local function validcommand(name,program,template,checkers,defaults,variables,reporter,strict)
- if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
- if variables then
- for variable,value in next,variables do
- local checker=validators[checkers[variable]]
- if checker then
- value=checker(unquoted(value),strict)
- if value then
- variables[variable]=optionalquoted(value)
- else
- report("variable %a with value %a fails the check",variable,value)
- return
- end
- else
- report("variable %a has no checker",variable)
- return
- end
- end
- for variable,default in next,defaults do
- local value=variables[variable]
- if not value or value=="" then
- local checker=validators[checkers[variable]]
- if checker then
- default=checker(unquoted(default),strict)
- if default then
- variables[variable]=optionalquoted(default)
- else
- report("variable %a with default %a fails the check",variable,default)
- return
- end
- end
- end
- end
- end
- local command=program.." "..replace(template,variables)
- if reporter then
- reporter("executing runner %a: %s",name,command)
- elseif trace then
- report("executing runner %a: %s",name,command)
- end
- return command
- elseif not reported[name] then
- report("executing program %a of runner %a is not permitted",program,name)
- reported[name]=true
- end
-end
-local runners={
- resultof=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("resultof: %s",command)
- end
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- end
- end
- end,
- execute=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("execute: %s",command)
- end
- return osexecute(command)
+ if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
+ if variables then
+ for variable,value in next,variables do
+ local checker=validators[checkers[variable]]
+ if checker then
+ value=checker(unquoted(value),strict)
+ if value then
+ variables[variable]=optionalquoted(value)
+ else
+ report("variable %a with value %a fails the check",variable,value)
+ return
+ end
+ else
+ report("variable %a has no checker",variable)
+ return
end
- end,
- pipeto=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("pipeto: %s",command)
+ end
+ for variable,default in next,defaults do
+ local value=variables[variable]
+ if not value or value=="" then
+ local checker=validators[checkers[variable]]
+ if checker then
+ default=checker(unquoted(default),strict)
+ if default then
+ variables[variable]=optionalquoted(default)
+ else
+ report("variable %a with default %a fails the check",variable,default)
+ return
end
- return iopopen(command,"w")
- end
- end,
-}
-function sandbox.registerrunner(specification)
- if type(specification)=="string" then
- local wrapped=validrunners[specification]
- inspect(table.sortedkeys(validrunners))
- if wrapped then
- return wrapped
- else
- report("unknown predefined runner %a",specification)
- return
+ end
end
+ end
end
- if type(specification)~="table" then
- report("specification should be a table (or string)")
- return
- end
- local name=specification.name
- if type(name)~="string" then
- report("invalid name, string expected",name)
- return
- end
- if validrunners[name] then
- report("invalid name, runner %a already defined")
- return
- end
- local program=specification.program
- if type(program)=="string" then
- elseif type(program)=="table" then
- program=program[platform] or program.default or program.unix
- end
- if type(program)~="string" or program=="" then
- report("invalid runner %a specified for platform %a",name,platform)
- return
+ local command=program.." "..replace(template,variables)
+ if reporter then
+ reporter("executing runner %a: %s",name,command)
+ elseif trace then
+ report("executing runner %a: %s",name,command)
end
- local template=specification.template
- if not template then
- report("missing template for runner %a",name)
- return
+ return command
+ elseif not reported[name] then
+ report("executing program %a of runner %a is not permitted",program,name)
+ reported[name]=true
+ end
+end
+local runners={
+ resultof=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("resultof: %s",command)
+ end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ end
end
- local method=specification.method or "execute"
- local checkers=specification.checkers or {}
- local defaults=specification.defaults or {}
- local runner=runners[method]
- if runner then
- local finalized=finalized
- local wrapped=function(variables)
- return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
- end
- validrunners[name]=wrapped
- return wrapped
- else
- validrunners[name]=nil
- report("invalid method for runner %a",name)
+ end,
+ execute=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("execute: %s",command)
+ end
+ return osexecute(command)
+ end
+ end,
+ pipeto=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("pipeto: %s",command)
+ end
+ return iopopen(command,"w")
end
+ end,
+}
+function sandbox.registerrunner(specification)
+ if type(specification)=="string" then
+ local wrapped=validrunners[specification]
+ inspect(table.sortedkeys(validrunners))
+ if wrapped then
+ return wrapped
+ else
+ report("unknown predefined runner %a",specification)
+ return
+ end
+ end
+ if type(specification)~="table" then
+ report("specification should be a table (or string)")
+ return
+ end
+ local name=specification.name
+ if type(name)~="string" then
+ report("invalid name, string expected",name)
+ return
+ end
+ if validrunners[name] then
+ report("invalid name, runner %a already defined")
+ return
+ end
+ local program=specification.program
+ if type(program)=="string" then
+ elseif type(program)=="table" then
+ program=program[platform] or program.default or program.unix
+ end
+ if type(program)~="string" or program=="" then
+ report("invalid runner %a specified for platform %a",name,platform)
+ return
+ end
+ local template=specification.template
+ if not template then
+ report("missing template for runner %a",name)
+ return
+ end
+ local method=specification.method or "execute"
+ local checkers=specification.checkers or {}
+ local defaults=specification.defaults or {}
+ local runner=runners[method]
+ if runner then
+ local finalized=finalized
+ local wrapped=function(variables)
+ return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
+ end
+ validrunners[name]=wrapped
+ return wrapped
+ else
+ validrunners[name]=nil
+ report("invalid method for runner %a",name)
+ end
end
function sandbox.getrunner(name)
- return name and validrunners[name]
+ return name and validrunners[name]
end
local function suspicious(str)
- return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
+ return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
end
local function binaryrunner(action,command,...)
- if validbinaries==false then
- report("no binaries permitted, ignoring command: %s",command)
- return
- end
- if type(command)~="string" then
- report("command should be a string")
- return
- end
- local program=lpegmatch(p_split,command)
- if not program or program=="" then
- report("unable to filter binary from command: %s",command)
- return
- end
- if validbinaries==true then
- elseif not validbinaries[program] then
- report("binary not permitted, ignoring command: %s",command)
- return
- elseif suspicious(command) then
- report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
- return
- end
- return action(command,...)
+ if validbinaries==false then
+ report("no binaries permitted, ignoring command: %s",command)
+ return
+ end
+ if type(command)~="string" then
+ report("command should be a string")
+ return
+ end
+ local program=lpegmatch(p_split,command)
+ if not program or program=="" then
+ report("unable to filter binary from command: %s",command)
+ return
+ end
+ if validbinaries==true then
+ elseif not validbinaries[program] then
+ report("binary not permitted, ignoring command: %s",command)
+ return
+ elseif suspicious(command) then
+ report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
+ return
+ end
+ return action(command,...)
end
local function dummyrunner(action,command,...)
- if type(command)=="table" then
- command=concat(command," ",command[0] and 0 or 1)
- end
- report("ignoring command: %s",command)
+ if type(command)=="table" then
+ command=concat(command," ",command[0] and 0 or 1)
+ end
+ report("ignoring command: %s",command)
end
sandbox.filehandlerone=filehandlerone
sandbox.filehandlertwo=filehandlertwo
sandbox.iohandler=iohandler
function sandbox.disablerunners()
- validbinaries=false
+ validbinaries=false
end
function sandbox.disablelibraries()
- validlibraries=false
+ validlibraries=false
end
if FFISUPPORTED and ffi then
- function sandbox.disablelibraries()
- validlibraries=false
- for k,v in next,ffi do
- if k~="gc" then
- ffi[k]=nil
- end
- end
+ function sandbox.disablelibraries()
+ validlibraries=false
+ for k,v in next,ffi do
+ if k~="gc" then
+ ffi[k]=nil
+ end
end
- local fiiload=ffi.load
- if fiiload then
- local reported={}
- function ffi.load(name,...)
- if validlibraries==false then
- elseif validlibraries==true then
- return fiiload(name,...)
- elseif validlibraries[nameonly(name)] then
- return fiiload(name,...)
- else
- end
- if not reported[name] then
- report("using library %a is not permitted",name)
- reported[name]=true
- end
- return nil
- end
+ end
+ local fiiload=ffi.load
+ if fiiload then
+ local reported={}
+ function ffi.load(name,...)
+ if validlibraries==false then
+ elseif validlibraries==true then
+ return fiiload(name,...)
+ elseif validlibraries[nameonly(name)] then
+ return fiiload(name,...)
+ else
+ end
+ if not reported[name] then
+ report("using library %a is not permitted",name)
+ reported[name]=true
+ end
+ return nil
end
+ end
end
local overload=sandbox.overload
local register=sandbox.register
- overload(loadfile,filehandlerone,"loadfile")
+ overload(loadfile,filehandlerone,"loadfile")
if io then
- overload(io.open,filehandlerone,"io.open")
- overload(io.popen,binaryrunner,"io.popen")
- overload(io.input,iohandler,"io.input")
- overload(io.output,iohandler,"io.output")
- overload(io.lines,filehandlerone,"io.lines")
+ overload(io.open,filehandlerone,"io.open")
+ overload(io.popen,binaryrunner,"io.popen")
+ overload(io.input,iohandler,"io.input")
+ overload(io.output,iohandler,"io.output")
+ overload(io.lines,filehandlerone,"io.lines")
end
if os then
- overload(os.execute,binaryrunner,"os.execute")
- overload(os.spawn,dummyrunner,"os.spawn")
- overload(os.exec,dummyrunner,"os.exec")
- overload(os.resultof,binaryrunner,"os.resultof")
- overload(os.pipeto,binaryrunner,"os.pipeto")
- overload(os.rename,filehandlertwo,"os.rename")
- overload(os.remove,filehandlerone,"os.remove")
+ overload(os.execute,binaryrunner,"os.execute")
+ overload(os.spawn,dummyrunner,"os.spawn")
+ overload(os.exec,dummyrunner,"os.exec")
+ overload(os.resultof,binaryrunner,"os.resultof")
+ overload(os.pipeto,binaryrunner,"os.pipeto")
+ overload(os.rename,filehandlertwo,"os.rename")
+ overload(os.remove,filehandlerone,"os.remove")
end
if lfs then
- overload(lfs.chdir,filehandlerone,"lfs.chdir")
- overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
- overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
- overload(lfs.isfile,filehandlerone,"lfs.isfile")
- overload(lfs.isdir,filehandlerone,"lfs.isdir")
- overload(lfs.attributes,filehandlerone,"lfs.attributes")
- overload(lfs.dir,filehandlerone,"lfs.dir")
- overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
- overload(lfs.touch,filehandlerone,"lfs.touch")
- overload(lfs.link,filehandlertwo,"lfs.link")
- overload(lfs.setmode,filehandlerone,"lfs.setmode")
- overload(lfs.readlink,filehandlerone,"lfs.readlink")
- overload(lfs.shortname,filehandlerone,"lfs.shortname")
- overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
+ overload(lfs.chdir,filehandlerone,"lfs.chdir")
+ overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
+ overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
+ overload(lfs.isfile,filehandlerone,"lfs.isfile")
+ overload(lfs.isdir,filehandlerone,"lfs.isdir")
+ overload(lfs.attributes,filehandlerone,"lfs.attributes")
+ overload(lfs.dir,filehandlerone,"lfs.dir")
+ overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
+ overload(lfs.touch,filehandlerone,"lfs.touch")
+ overload(lfs.link,filehandlertwo,"lfs.link")
+ overload(lfs.setmode,filehandlerone,"lfs.setmode")
+ overload(lfs.readlink,filehandlerone,"lfs.readlink")
+ overload(lfs.shortname,filehandlerone,"lfs.shortname")
+ overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
end
if zip then
- zip.open=register(zip.open,filehandlerone,"zip.open")
+ zip.open=register(zip.open,filehandlerone,"zip.open")
end
if fontloader then
- fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
- fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
+ fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
+ fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
end
if epdf then
- epdf.open=register(epdf.open,filehandlerone,"epdf.open")
+ epdf.open=register(epdf.open,filehandlerone,"epdf.open")
end
sandbox.registerroot=registerroot
sandbox.registerbinary=registerbinary
@@ -14917,14 +14924,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-mrg"] = package.loaded["util-mrg"] or true
--- original size: 7757, stripped down to: 6015
+-- original size: 7819, stripped down to: 5881
if not modules then modules={} end modules ['util-mrg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local gsub,format=string.gsub,string.format
local concat=table.concat
@@ -14952,19 +14959,19 @@ local m_report=[[
]]
local m_preloaded=[[package.loaded[%q] = package.loaded[%q] or true]]
local function self_fake()
- return m_faked
+ return m_faked
end
local function self_nothing()
- return ""
+ return ""
end
local function self_load(name)
- local data=io.loaddata(name) or ""
- if data=="" then
- report("unknown file %a",name)
- else
- report("inserting file %a",name)
- end
- return data or ""
+ local data=io.loaddata(name) or ""
+ if data=="" then
+ report("unknown file %a",name)
+ else
+ report("inserting file %a",name)
+ end
+ return data or ""
end
local space=patterns.space
local eol=patterns.newline
@@ -14993,98 +15000,99 @@ local mandatespacing=(eol+space)^1/""
local pack=digit*space^1*operator4*optionalspacing+optionalspacing*operator1*optionalspacing+optionalspacing*operator2*optionalspaces+mandatespacing*operator3*mandatespaces+optionalspaces*separator*optionalspaces
local lines=emptyline^2/"\n"
local spaces=(space*space)/" "
+local spaces=(space*space*space*space)/" "
local compact=Cs ((
- ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
+ ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
)^1 )
local strip=Cs((emptyline^2/"\n"+1)^0)
local stripreturn=Cs((1-P("return")*space^1*P(1-space-eol)^1*(space+eol)^0*P(-1))^1)
function merger.compact(data)
- return lpegmatch(strip,lpegmatch(compact,data))
+ return lpegmatch(strip,lpegmatch(compact,data))
end
local function self_compact(data)
- local delta=0
- if merger.strip_comment then
- local before=#data
- data=lpegmatch(compact,data)
- data=lpegmatch(strip,data)
- local after=#data
- delta=before-after
- report("original size %s, compacted to %s, stripped %s",before,after,delta)
- data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
- end
- return lpegmatch(stripreturn,data) or data,delta
+ local delta=0
+ if merger.strip_comment then
+ local before=#data
+ data=lpegmatch(compact,data)
+ data=lpegmatch(strip,data)
+ local after=#data
+ delta=before-after
+ report("original size %s, compacted to %s, stripped %s",before,after,delta)
+ data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
+ end
+ return lpegmatch(stripreturn,data) or data,delta
end
local function self_save(name,data)
- if data~="" then
- io.savedata(name,data)
- report("saving %s with size %s",name,#data)
- end
+ if data~="" then
+ io.savedata(name,data)
+ report("saving %s with size %s",name,#data)
+ end
end
local function self_swap(data,code)
- return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
+ return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
end
local function self_libs(libs,list)
- local result,f,frozen,foundpath={},nil,false,nil
- result[#result+1]="\n"
- if type(libs)=='string' then libs={ libs } end
- if type(list)=='string' then list={ list } end
+ local result,f,frozen,foundpath={},nil,false,nil
+ result[#result+1]="\n"
+ if type(libs)=='string' then libs={ libs } end
+ if type(list)=='string' then list={ list } end
+ for i=1,#libs do
+ local lib=libs[i]
+ for j=1,#list do
+ local pth=gsub(list[j],"\\","/")
+ report("checking library path %a",pth)
+ local name=pth.."/"..lib
+ if lfs.isfile(name) then
+ foundpath=pth
+ end
+ end
+ if foundpath then break end
+ end
+ if foundpath then
+ report("using library path %a",foundpath)
+ local right,wrong,original,stripped={},{},0,0
for i=1,#libs do
- local lib=libs[i]
- for j=1,#list do
- local pth=gsub(list[j],"\\","/")
- report("checking library path %a",pth)
- local name=pth.."/"..lib
- if lfs.isfile(name) then
- foundpath=pth
- end
- end
- if foundpath then break end
- end
- if foundpath then
- report("using library path %a",foundpath)
- local right,wrong,original,stripped={},{},0,0
- for i=1,#libs do
- local lib=libs[i]
- local fullname=foundpath.."/"..lib
- if lfs.isfile(fullname) then
- report("using library %a",fullname)
- local preloaded=file.nameonly(lib)
- local data=io.loaddata(fullname,true)
- original=original+#data
- local data,delta=self_compact(data)
- right[#right+1]=lib
- result[#result+1]=m_begin_closure
- result[#result+1]=format(m_preloaded,preloaded,preloaded)
- result[#result+1]=data
- result[#result+1]=m_end_closure
- stripped=stripped+delta
- else
- report("skipping library %a",fullname)
- wrong[#wrong+1]=lib
- end
- end
- right=#right>0 and concat(right," ") or "-"
- wrong=#wrong>0 and concat(wrong," ") or "-"
- report("used libraries: %a",right)
- report("skipped libraries: %a",wrong)
- report("original bytes: %a",original)
- report("stripped bytes: %a",stripped)
- result[#result+1]=format(m_report,right,wrong,original,stripped)
- else
- report("no valid library path found")
+ local lib=libs[i]
+ local fullname=foundpath.."/"..lib
+ if lfs.isfile(fullname) then
+ report("using library %a",fullname)
+ local preloaded=file.nameonly(lib)
+ local data=io.loaddata(fullname,true)
+ original=original+#data
+ local data,delta=self_compact(data)
+ right[#right+1]=lib
+ result[#result+1]=m_begin_closure
+ result[#result+1]=format(m_preloaded,preloaded,preloaded)
+ result[#result+1]=data
+ result[#result+1]=m_end_closure
+ stripped=stripped+delta
+ else
+ report("skipping library %a",fullname)
+ wrong[#wrong+1]=lib
+ end
end
- return concat(result,"\n\n")
+ right=#right>0 and concat(right," ") or "-"
+ wrong=#wrong>0 and concat(wrong," ") or "-"
+ report("used libraries: %a",right)
+ report("skipped libraries: %a",wrong)
+ report("original bytes: %a",original)
+ report("stripped bytes: %a",stripped)
+ result[#result+1]=format(m_report,right,wrong,original,stripped)
+ else
+ report("no valid library path found")
+ end
+ return concat(result,"\n\n")
end
function merger.selfcreate(libs,list,target)
- if target then
- self_save(target,self_swap(self_fake(),self_libs(libs,list)))
- end
+ if target then
+ self_save(target,self_swap(self_fake(),self_libs(libs,list)))
+ end
end
function merger.selfmerge(name,libs,list,target)
- self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
+ self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
end
function merger.selfclean(name)
- self_save(name,self_swap(self_load(name),self_nothing()))
+ self_save(name,self_swap(self_load(name),self_nothing()))
end
@@ -15094,14 +15102,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-env"] = package.loaded["util-env"] or true
--- original size: 9634, stripped down to: 5673
+-- original size: 9634, stripped down to: 5360
if not modules then modules={} end modules ['util-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate,mark=utilities.storage.allocate,utilities.storage.mark
local format,sub,match,gsub,find=string.format,string.sub,string.match,string.gsub,string.find
@@ -15113,185 +15121,185 @@ local setlocale=os.setlocale
setlocale(nil,nil)
local report=logs.reporter("system")
function os.setlocale(a,b)
- if a or b then
- if report then
- report()
- report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
- report("now on are on your own and without support. Crashes or unexpected side effects")
- report("can happen but don't bother the luatex and context developer team with it.")
- report()
- report=nil
- end
- setlocale(a,b)
- end
+ if a or b then
+ if report then
+ report()
+ report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
+ report("now on are on your own and without support. Crashes or unexpected side effects")
+ report("can happen but don't bother the luatex and context developer team with it.")
+ report()
+ report=nil
+ end
+ setlocale(a,b)
+ end
end
local validengines=allocate {
- ["luatex"]=true,
- ["luajittex"]=true,
+ ["luatex"]=true,
+ ["luajittex"]=true,
}
local basicengines=allocate {
- ["luatex"]="luatex",
- ["texlua"]="luatex",
- ["texluac"]="luatex",
- ["luajittex"]="luajittex",
- ["texluajit"]="luajittex",
+ ["luatex"]="luatex",
+ ["texlua"]="luatex",
+ ["texluac"]="luatex",
+ ["luajittex"]="luajittex",
+ ["texluajit"]="luajittex",
}
local luaengines=allocate {
- ["lua"]=true,
- ["luajit"]=true,
+ ["lua"]=true,
+ ["luajit"]=true,
}
environment.validengines=validengines
environment.basicengines=basicengines
if not arg then
- environment.used_as_library=true
+ environment.used_as_library=true
elseif luaengines[file.removesuffix(arg[-1])] then
elseif validengines[file.removesuffix(arg[0])] then
- if arg[1]=="--luaonly" then
- arg[-1]=arg[0]
- arg[ 0]=arg[2]
- for k=3,#arg do
- arg[k-2]=arg[k]
- end
- remove(arg)
- remove(arg)
- else
- end
- local originalzero=file.basename(arg[0])
- local specialmapping={ luatools=="base" }
- if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
+ if arg[1]=="--luaonly" then
+ arg[-1]=arg[0]
+ arg[ 0]=arg[2]
+ for k=3,#arg do
+ arg[k-2]=arg[k]
+ end
+ remove(arg)
+ remove(arg)
+ else
+ end
+ local originalzero=file.basename(arg[0])
+ local specialmapping={ luatools=="base" }
+ if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
arg[0]=specialmapping[originalzero] or originalzero
insert(arg,0,"--script")
insert(arg,0,"mtxrun")
- end
+ end
end
environment.arguments=allocate()
environment.files=allocate()
environment.sortedflags=nil
function environment.initializearguments(arg)
- local arguments,files={},{}
- environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
- for index=1,#arg do
- local argument=arg[index]
- if index>0 then
- local flag,value=match(argument,"^%-+(.-)=(.-)$")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=unquoted(value or "")
- else
- flag=match(argument,"^%-+(.+)")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=true
- else
- files[#files+1]=argument
- end
- end
+ local arguments,files={},{}
+ environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
+ for index=1,#arg do
+ local argument=arg[index]
+ if index>0 then
+ local flag,value=match(argument,"^%-+(.-)=(.-)$")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=unquoted(value or "")
+ else
+ flag=match(argument,"^%-+(.+)")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=true
+ else
+ files[#files+1]=argument
end
+ end
end
- environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
+ end
+ environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
end
function environment.setargument(name,value)
- environment.arguments[name]=value
+ environment.arguments[name]=value
end
function environment.getargument(name,partial)
- local arguments,sortedflags=environment.arguments,environment.sortedflags
- if arguments[name] then
- return arguments[name]
- elseif partial then
- if not sortedflags then
- sortedflags=allocate(table.sortedkeys(arguments))
- for k=1,#sortedflags do
- sortedflags[k]="^"..sortedflags[k]
- end
- environment.sortedflags=sortedflags
- end
- for k=1,#sortedflags do
- local v=sortedflags[k]
- if find(name,v) then
- return arguments[sub(v,2,#v)]
- end
- end
+ local arguments,sortedflags=environment.arguments,environment.sortedflags
+ if arguments[name] then
+ return arguments[name]
+ elseif partial then
+ if not sortedflags then
+ sortedflags=allocate(table.sortedkeys(arguments))
+ for k=1,#sortedflags do
+ sortedflags[k]="^"..sortedflags[k]
+ end
+ environment.sortedflags=sortedflags
end
- return nil
+ for k=1,#sortedflags do
+ local v=sortedflags[k]
+ if find(name,v) then
+ return arguments[sub(v,2,#v)]
+ end
+ end
+ end
+ return nil
end
environment.argument=environment.getargument
function environment.splitarguments(separator)
- local done,before,after=false,{},{}
- local originalarguments=environment.originalarguments
- for k=1,#originalarguments do
- local v=originalarguments[k]
- if not done and v==separator then
- done=true
- elseif done then
- after[#after+1]=v
- else
- before[#before+1]=v
- end
+ local done,before,after=false,{},{}
+ local originalarguments=environment.originalarguments
+ for k=1,#originalarguments do
+ local v=originalarguments[k]
+ if not done and v==separator then
+ done=true
+ elseif done then
+ after[#after+1]=v
+ else
+ before[#before+1]=v
end
- return before,after
+ end
+ return before,after
end
function environment.reconstructcommandline(arg,noquote)
- local resolveprefix=resolvers.resolve
- arg=arg or environment.originalarguments
- if noquote and #arg==1 then
- return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
- elseif #arg>0 then
- local result={}
- for i=1,#arg do
- result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
- end
- return concat(result," ")
- else
- return ""
+ local resolveprefix=resolvers.resolve
+ arg=arg or environment.originalarguments
+ if noquote and #arg==1 then
+ return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
+ elseif #arg>0 then
+ local result={}
+ for i=1,#arg do
+ result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
end
+ return concat(result," ")
+ else
+ return ""
+ end
end
function environment.relativepath(path,root)
- if not path then
- path=""
+ if not path then
+ path=""
+ end
+ if not file.is_rootbased_path(path) then
+ if not root then
+ root=file.pathpart(environment.ownscript or environment.ownname or ".")
end
- if not file.is_rootbased_path(path) then
- if not root then
- root=file.pathpart(environment.ownscript or environment.ownname or ".")
- end
- if root=="" then
- root="."
- end
- path=root.."/"..path
+ if root=="" then
+ root="."
end
- return file.collapsepath(path,true)
+ path=root.."/"..path
+ end
+ return file.collapsepath(path,true)
end
if arg then
- local newarg,instring={},false
- for index=1,#arg do
- local argument=arg[index]
- if find(argument,"^\"") then
- if find(argument,"\"$") then
- newarg[#newarg+1]=gsub(argument,"^\"(.-)\"$","%1")
- instring=false
- else
- newarg[#newarg+1]=gsub(argument,"^\"","")
- instring=true
- end
- elseif find(argument,"\"$") then
- if instring then
- newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
- instring=false
- else
- newarg[#newarg+1]=argument
- end
- elseif instring then
- newarg[#newarg]=newarg[#newarg].." "..argument
- else
- newarg[#newarg+1]=argument
- end
- end
- for i=1,-5,-1 do
- newarg[i]=arg[i]
+ local newarg,instring={},false
+ for index=1,#arg do
+ local argument=arg[index]
+ if find(argument,"^\"") then
+ if find(argument,"\"$") then
+ newarg[#newarg+1]=gsub(argument,"^\"(.-)\"$","%1")
+ instring=false
+ else
+ newarg[#newarg+1]=gsub(argument,"^\"","")
+ instring=true
+ end
+ elseif find(argument,"\"$") then
+ if instring then
+ newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
+ instring=false
+ else
+ newarg[#newarg+1]=argument
+ end
+ elseif instring then
+ newarg[#newarg]=newarg[#newarg].." "..argument
+ else
+ newarg[#newarg+1]=argument
end
- environment.initializearguments(newarg)
- environment.originalarguments=mark(newarg)
- environment.rawarguments=mark(arg)
- arg={}
+ end
+ for i=1,-5,-1 do
+ newarg[i]=arg[i]
+ end
+ environment.initializearguments(newarg)
+ environment.originalarguments=mark(newarg)
+ environment.rawarguments=mark(arg)
+ arg={}
end
@@ -15301,18 +15309,18 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-env"] = package.loaded["luat-env"] or true
--- original size: 6134, stripped down to: 4402
+-- original size: 6134, stripped down to: 4118
if not modules then modules={} end modules ['luat-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local rawset,rawget,loadfile=rawset,rawget,loadfile
local gsub=string.gsub
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_lua=logs.reporter("resolvers","lua")
local luautilities=utilities.lua
local luasuffixes=luautilities.suffixes
@@ -15320,145 +15328,145 @@ local texgettoks=tex and tex.gettoks
environment=environment or {}
local environment=environment
local mt={
- __index=function(_,k)
- if k=="version" then
- local version=texgettoks and texgettoks("contextversiontoks")
- if version and version~="" then
- rawset(environment,"version",version)
- return version
- else
- return "unknown"
- end
- elseif k=="kind" then
- local kind=texgettoks and texgettoks("contextkindtoks")
- if kind and kind~="" then
- rawset(environment,"kind",kind)
- return kind
- else
- return "unknown"
- end
- elseif k=="jobname" or k=="formatname" then
- local name=tex and tex[k]
- if name or name=="" then
- rawset(environment,k,name)
- return name
- else
- return "unknown"
- end
- elseif k=="outputfilename" then
- local name=environment.jobname
- rawset(environment,k,name)
- return name
- end
+ __index=function(_,k)
+ if k=="version" then
+ local version=texgettoks and texgettoks("contextversiontoks")
+ if version and version~="" then
+ rawset(environment,"version",version)
+ return version
+ else
+ return "unknown"
+ end
+ elseif k=="kind" then
+ local kind=texgettoks and texgettoks("contextkindtoks")
+ if kind and kind~="" then
+ rawset(environment,"kind",kind)
+ return kind
+ else
+ return "unknown"
+ end
+ elseif k=="jobname" or k=="formatname" then
+ local name=tex and tex[k]
+ if name or name=="" then
+ rawset(environment,k,name)
+ return name
+ else
+ return "unknown"
+ end
+ elseif k=="outputfilename" then
+ local name=environment.jobname
+ rawset(environment,k,name)
+ return name
end
+ end
}
setmetatable(environment,mt)
function environment.texfile(filename)
- return resolvers.findfile(filename,'tex')
+ return resolvers.findfile(filename,'tex')
end
function environment.luafile(filename)
- local resolved=resolvers.findfile(filename,'tex') or ""
- if resolved~="" then
- return resolved
- end
- resolved=resolvers.findfile(filename,'texmfscripts') or ""
- if resolved~="" then
- return resolved
- end
- return resolvers.findfile(filename,'luatexlibs') or ""
-end
-local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
+ local resolved=resolvers.findfile(filename,'tex') or ""
+ if resolved~="" then
+ return resolved
+ end
+ resolved=resolvers.findfile(filename,'texmfscripts') or ""
+ if resolved~="" then
+ return resolved
+ end
+ return resolvers.findfile(filename,'luatexlibs') or ""
+end
+local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
local function strippable(filename)
- if stripindeed then
- local modu=modules[file.nameonly(filename)]
- return modu and modu.dataonly
- else
- return false
- end
+ if stripindeed then
+ local modu=modules[file.nameonly(filename)]
+ return modu and modu.dataonly
+ else
+ return false
+ end
end
function environment.luafilechunk(filename,silent,macros)
- filename=file.replacesuffix(filename,"lua")
- local fullname=environment.luafile(filename)
- if fullname and fullname~="" then
- local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
- if not silent then
- report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
- end
- return data
- else
- if not silent then
- report_lua("unknown file %a",filename)
- end
- return nil
+ filename=file.replacesuffix(filename,"lua")
+ local fullname=environment.luafile(filename)
+ if fullname and fullname~="" then
+ local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
+ if not silent then
+ report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
+ end
+ return data
+ else
+ if not silent then
+ report_lua("unknown file %a",filename)
end
+ return nil
+ end
end
function environment.loadluafile(filename,version)
- local lucname,luaname,chunk
- local basename=file.removesuffix(filename)
- if basename==filename then
- luaname=file.addsuffix(basename,luasuffixes.lua)
- lucname=file.addsuffix(basename,luasuffixes.luc)
- else
- luaname=filename
- lucname=nil
- end
- local fullname=(lucname and environment.luafile(lucname)) or ""
- if fullname~="" then
+ local lucname,luaname,chunk
+ local basename=file.removesuffix(filename)
+ if basename==filename then
+ luaname=file.addsuffix(basename,luasuffixes.lua)
+ lucname=file.addsuffix(basename,luasuffixes.luc)
+ else
+ luaname=filename
+ lucname=nil
+ end
+ local fullname=(lucname and environment.luafile(lucname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
+ end
+ chunk=loadfile(fullname)
+ end
+ if chunk then
+ chunk()
+ if version then
+ local v=version
+ if modules and modules[filename] then
+ v=modules[filename].version
+ elseif versions and versions[filename] then
+ v=versions[filename]
+ end
+ if v==version then
+ return true
+ else
if trace_locating then
- report_lua("loading %a",fullname)
+ report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
end
- chunk=loadfile(fullname)
+ environment.loadluafile(filename)
+ end
+ else
+ return true
end
- if chunk then
- chunk()
- if version then
- local v=version
- if modules and modules[filename] then
- v=modules[filename].version
- elseif versions and versions[filename] then
- v=versions[filename]
- end
- if v==version then
- return true
- else
- if trace_locating then
- report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
- end
- environment.loadluafile(filename)
- end
- else
- return true
- end
+ end
+ fullname=(luaname and environment.luafile(luaname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
end
- fullname=(luaname and environment.luafile(luaname)) or ""
- if fullname~="" then
- if trace_locating then
- report_lua("loading %a",fullname)
- end
- chunk=loadfile(fullname)
- if not chunk then
- if trace_locating then
- report_lua("unknown file %a",filename)
- end
- else
- chunk()
- return true
- end
+ chunk=loadfile(fullname)
+ if not chunk then
+ if trace_locating then
+ report_lua("unknown file %a",filename)
+ end
+ else
+ chunk()
+ return true
end
- return false
+ end
+ return false
end
environment.filenames=setmetatable({},{
- __index=function(t,k)
- local v=environment.files[k]
- if v then
- return (gsub(v,"%.+$",""))
- end
- end,
- __newindex=function(t,k)
- end,
- __len=function(t)
- return #environment.files
- end,
+ __index=function(t,k)
+ local v=environment.files[k]
+ if v then
+ return (gsub(v,"%.+$",""))
+ end
+ end,
+ __newindex=function(t,k)
+ end,
+ __len=function(t)
+ return #environment.files
+ end,
} )
@@ -15468,16 +15476,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true
--- original size: 60383, stripped down to: 38562
+-- original size: 60383, stripped down to: 35698
if not modules then modules={} end modules ['lxml-tab']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
+local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end
if lpeg.setmaxstack then lpeg.setmaxstack(1000) end
xml=xml or {}
@@ -15495,17 +15503,17 @@ xml.xmlns=xml.xmlns or {}
local check=P(false)
local parse=check
function xml.registerns(namespace,pattern)
- check=check+C(P(lower(pattern)))/namespace
- parse=P { P(check)+1*V(1) }
+ check=check+C(P(lower(pattern)))/namespace
+ parse=P { P(check)+1*V(1) }
end
function xml.checkns(namespace,url)
- local ns=lpegmatch(parse,lower(url))
- if ns and namespace~=ns then
- xml.xmlns[namespace]=ns
- end
+ local ns=lpegmatch(parse,lower(url))
+ if ns and namespace~=ns then
+ xml.xmlns[namespace]=ns
+ end
end
function xml.resolvens(url)
- return lpegmatch(parse,lower(url)) or ""
+ return lpegmatch(parse,lower(url)) or ""
end
end
local nsremap,resolvens=xml.xmlns,xml.resolvens
@@ -15523,661 +15531,661 @@ local handle_dec_entity
local handle_any_entity_dtd
local handle_any_entity_text
local function preparexmlstate(settings)
- if settings then
- linenumbers=settings.linenumbers
- stack={}
- level=0
- top={}
- at={}
- mt={}
- dt={}
- nt=0
- xmlns={}
- errorstr=nil
- strip=settings.strip_cm_and_dt
- utfize=settings.utfize_entities
- resolve=settings.resolve_entities
- resolve_predefined=settings.resolve_predefined_entities
- unify_predefined=settings.unify_predefined_entities
- cleanup=settings.text_cleanup
- entities=settings.entities or {}
- currentfilename=settings.currentresource
- currentline=1
- parameters={}
- reported_at_errors={}
- dcache={}
- hcache={}
- acache={}
- if utfize==nil then
- settings.utfize_entities=true
- utfize=true
- end
- if resolve_predefined==nil then
- settings.resolve_predefined_entities=true
- resolve_predefined=true
- end
- else
- linenumbers=false
- stack=nil
- level=nil
- top=nil
- at=nil
- mt=nil
- dt=nil
- nt=nil
- xmlns=nil
- errorstr=nil
- strip=nil
- utfize=nil
- resolve=nil
- resolve_predefined=nil
- unify_predefined=nil
- cleanup=nil
- entities=nil
- parameters=nil
- reported_at_errors=nil
- dcache=nil
- hcache=nil
- acache=nil
- currentfilename=nil
- currentline=1
- end
+ if settings then
+ linenumbers=settings.linenumbers
+ stack={}
+ level=0
+ top={}
+ at={}
+ mt={}
+ dt={}
+ nt=0
+ xmlns={}
+ errorstr=nil
+ strip=settings.strip_cm_and_dt
+ utfize=settings.utfize_entities
+ resolve=settings.resolve_entities
+ resolve_predefined=settings.resolve_predefined_entities
+ unify_predefined=settings.unify_predefined_entities
+ cleanup=settings.text_cleanup
+ entities=settings.entities or {}
+ currentfilename=settings.currentresource
+ currentline=1
+ parameters={}
+ reported_at_errors={}
+ dcache={}
+ hcache={}
+ acache={}
+ if utfize==nil then
+ settings.utfize_entities=true
+ utfize=true
+ end
+ if resolve_predefined==nil then
+ settings.resolve_predefined_entities=true
+ resolve_predefined=true
+ end
+ else
+ linenumbers=false
+ stack=nil
+ level=nil
+ top=nil
+ at=nil
+ mt=nil
+ dt=nil
+ nt=nil
+ xmlns=nil
+ errorstr=nil
+ strip=nil
+ utfize=nil
+ resolve=nil
+ resolve_predefined=nil
+ unify_predefined=nil
+ cleanup=nil
+ entities=nil
+ parameters=nil
+ reported_at_errors=nil
+ dcache=nil
+ hcache=nil
+ acache=nil
+ currentfilename=nil
+ currentline=1
+ end
end
local function initialize_mt(root)
- mt={ __index=root }
+ mt={ __index=root }
end
function xml.setproperty(root,k,v)
- getmetatable(root).__index[k]=v
+ getmetatable(root).__index[k]=v
end
function xml.checkerror(top,toclose)
- return ""
+ return ""
end
local checkns=xml.checkns
local function add_attribute(namespace,tag,value)
- if cleanup and value~="" then
- value=cleanup(value)
- end
- if tag=="xmlns" then
- xmlns[#xmlns+1]=resolvens(value)
- at[tag]=value
- elseif namespace=="" then
- at[tag]=value
- elseif namespace=="xmlns" then
- checkns(tag,value)
- at["xmlns:"..tag]=value
- else
- at[namespace..":"..tag]=value
- end
+ if cleanup and value~="" then
+ value=cleanup(value)
+ end
+ if tag=="xmlns" then
+ xmlns[#xmlns+1]=resolvens(value)
+ at[tag]=value
+ elseif namespace=="" then
+ at[tag]=value
+ elseif namespace=="xmlns" then
+ checkns(tag,value)
+ at["xmlns:"..tag]=value
+ else
+ at[namespace..":"..tag]=value
+ end
end
local function add_empty(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- top=stack[level]
- dt=top.dt
- nt=#dt+1
- local t=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- cf=currentfilename,
- cl=currentline,
- __p__=top,
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- __p__=top,
- }
- dt[nt]=t
- setmetatable(t,mt)
- if at.xmlns then
- remove(xmlns)
- end
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ top=stack[level]
+ dt=top.dt
+ nt=#dt+1
+ local t=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=top,
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ __p__=top,
+ }
+ dt[nt]=t
+ setmetatable(t,mt)
+ if at.xmlns then
+ remove(xmlns)
+ end
+ at={}
end
local function add_begin(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- dt={}
- top=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- cf=currentfilename,
- cl=currentline,
- __p__=stack[level],
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- __p__=stack[level],
- }
- setmetatable(top,mt)
- nt=0
- level=level+1
- stack[level]=top
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ dt={}
+ top=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=stack[level],
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ __p__=stack[level],
+ }
+ setmetatable(top,mt)
+ nt=0
+ level=level+1
+ stack[level]=top
+ at={}
end
local function add_end(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local toclose=stack[level]
- level=level-1
- top=stack[level]
- if level<1 then
- errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- elseif toclose.tg~=tag then
- errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- end
- dt=top.dt
- nt=#dt+1
- dt[nt]=toclose
- toclose.ni=nt
- if toclose.at.xmlns then
- remove(xmlns)
- end
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local toclose=stack[level]
+ level=level-1
+ top=stack[level]
+ if level<1 then
+ errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ elseif toclose.tg~=tag then
+ errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ end
+ dt=top.dt
+ nt=#dt+1
+ dt[nt]=toclose
+ toclose.ni=nt
+ if toclose.at.xmlns then
+ remove(xmlns)
+ end
end
local function add_text(text)
- if text=="" then
- return
- end
- if cleanup then
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..cleanup(text)
- else
- nt=nt+1
- dt[nt]=cleanup(text)
- end
- else
- nt=1
- dt[1]=cleanup(text)
- end
+ if text=="" then
+ return
+ end
+ if cleanup then
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..cleanup(text)
+ else
+ nt=nt+1
+ dt[nt]=cleanup(text)
+ end
else
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..text
- else
- nt=nt+1
- dt[nt]=text
- end
- else
- nt=1
- dt[1]=text
- end
+ nt=1
+ dt[1]=cleanup(text)
end
-end
-local function add_special(what,spacing,text)
- if spacing~="" then
+ else
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..text
+ else
nt=nt+1
- dt[nt]=spacing
- end
- if strip and (what=="@cm@" or what=="@dt@") then
+ dt[nt]=text
+ end
else
- nt=nt+1
- dt[nt]=linenumbers and {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- cf=currentfilename,
- cl=currentline,
- } or {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- }
+ nt=1
+ dt[1]=text
end
+ end
+end
+local function add_special(what,spacing,text)
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ if strip and (what=="@cm@" or what=="@dt@") then
+ else
+ nt=nt+1
+ dt[nt]=linenumbers and {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ cf=currentfilename,
+ cl=currentline,
+ } or {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ }
+ end
end
local function set_message(txt)
- errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
+ errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
end
local function attribute_value_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute value %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute value %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
local function attribute_specification_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute specification %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute specification %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
do
- local badentity="&"
- xml.placeholders={
- unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
- unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
- unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
- }
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return utfchar(n)
- else
- return formatters["h:%s"](s),true
+ local badentity="&"
+ xml.placeholders={
+ unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
+ unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
+ unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
+ }
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local p_rest=(1-P(";"))^0
+ local p_many=P(1)^0
+ local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
+ xml.parsedentitylpeg=parsedentity
+ local predefined_unified={
+ [38]="&amp;",
+ [42]="&quot;",
+ [47]="&apos;",
+ [74]="&lt;",
+ [76]="&gt;",
+ }
+ local predefined_simplified={
+ [38]="&",amp="&",
+ [42]='"',quot='"',
+ [47]="'",apos="'",
+ [74]="<",lt="<",
+ [76]=">",gt=">",
+ }
+ local nofprivates=0xF0000
+ local privates_u={
+ [ [[&]] ]="&amp;",
+ [ [["]] ]="&quot;",
+ [ [[']] ]="&apos;",
+ [ [[<]] ]="&lt;",
+ [ [[>]] ]="&gt;",
+ }
+ local privates_p={
+ }
+ local privates_s={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[&]] ]="&U+26;",
+ [ [[']] ]="&U+27;",
+ [ [[<]] ]="&U+3C;",
+ [ [[>]] ]="&U+3E;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_x={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[']] ]="&U+27;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_n={
+ }
+ local escaped=utf.remapper(privates_u,"dynamic")
+ local unprivatized=utf.remapper(privates_p,"dynamic")
+ local unspecialized=utf.remapper(privates_s,"dynamic")
+ local despecialized=utf.remapper(privates_x,"dynamic")
+ xml.unprivatized=unprivatized
+ xml.unspecialized=unspecialized
+ xml.despecialized=despecialized
+ xml.escaped=escaped
+ local function unescaped(s)
+ local p=privates_n[s]
+ if not p then
+ nofprivates=nofprivates+1
+ p=utfchar(nofprivates)
+ privates_n[s]=p
+ s="&"..s..";"
+ privates_u[p]=s
+ privates_p[p]=s
+ privates_s[p]=s
+ end
+ return p
+ end
+ xml.privatetoken=unescaped
+ xml.privatecodes=privates_n
+ xml.specialcodes=privates_s
+ function xml.addspecialcode(key,value)
+ privates_s[key]=value or "&"..s..";"
+ end
+ handle_hex_entity=function(str)
+ local h=hcache[str]
+ if not h then
+ local n=tonumber(str,16)
+ h=unify_predefined and predefined_unified[n]
+ if h then
+ if trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+ end
+ elseif utfize then
+ h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring hex entity &#x%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
end
+ else
+ if trace_entities then
+ report_xml("found entity &#x%s;",str)
+ end
+ h="&#x"..str..";"
+ end
+ hcache[str]=h
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return utfchar(n)
- else
- return formatters["d:%s"](s),true
- end
- end
- local p_rest=(1-P(";"))^0
- local p_many=P(1)^0
- local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
- xml.parsedentitylpeg=parsedentity
- local predefined_unified={
- [38]="&amp;",
- [42]="&quot;",
- [47]="&apos;",
- [74]="&lt;",
- [76]="&gt;",
- }
- local predefined_simplified={
- [38]="&",amp="&",
- [42]='"',quot='"',
- [47]="'",apos="'",
- [74]="<",lt="<",
- [76]=">",gt=">",
- }
- local nofprivates=0xF0000
- local privates_u={
- [ [[&]] ]="&amp;",
- [ [["]] ]="&quot;",
- [ [[']] ]="&apos;",
- [ [[<]] ]="&lt;",
- [ [[>]] ]="&gt;",
- }
- local privates_p={
- }
- local privates_s={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[&]] ]="&U+26;",
- [ [[']] ]="&U+27;",
- [ [[<]] ]="&U+3C;",
- [ [[>]] ]="&U+3E;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_x={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[']] ]="&U+27;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_n={
- }
- local escaped=utf.remapper(privates_u,"dynamic")
- local unprivatized=utf.remapper(privates_p,"dynamic")
- local unspecialized=utf.remapper(privates_s,"dynamic")
- local despecialized=utf.remapper(privates_x,"dynamic")
- xml.unprivatized=unprivatized
- xml.unspecialized=unspecialized
- xml.despecialized=despecialized
- xml.escaped=escaped
- local function unescaped(s)
- local p=privates_n[s]
- if not p then
- nofprivates=nofprivates+1
- p=utfchar(nofprivates)
- privates_n[s]=p
- s="&"..s..";"
- privates_u[p]=s
- privates_p[p]=s
- privates_s[p]=s
- end
- return p
- end
- xml.privatetoken=unescaped
- xml.privatecodes=privates_n
- xml.specialcodes=privates_s
- function xml.addspecialcode(key,value)
- privates_s[key]=value or "&"..s..";"
- end
- handle_hex_entity=function(str)
- local h=hcache[str]
- if not h then
- local n=tonumber(str,16)
- h=unify_predefined and predefined_unified[n]
- if h then
- if trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- elseif utfize then
- h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring hex entity &#x%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- else
- if trace_entities then
- report_xml("found entity &#x%s;",str)
- end
- h="&#x"..str..";"
- end
- hcache[str]=h
- end
- return h
- end
- handle_dec_entity=function(str)
- local d=dcache[str]
- if not d then
- local n=tonumber(str)
- d=unify_predefined and predefined_unified[n]
- if d then
- if trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- elseif utfize then
- d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring dec entity &#%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- else
- if trace_entities then
- report_xml("found entity &#%s;",str)
- end
- d="&#"..str..";"
- end
- dcache[str]=d
+ return h
+ end
+ handle_dec_entity=function(str)
+ local d=dcache[str]
+ if not d then
+ local n=tonumber(str)
+ d=unify_predefined and predefined_unified[n]
+ if d then
+ if trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ elseif utfize then
+ d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring dec entity &#%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ else
+ if trace_entities then
+ report_xml("found entity &#%s;",str)
end
- return d
+ d="&#"..str..";"
+ end
+ dcache[str]=d
end
- handle_any_entity_dtd=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
- end
- return a
+ return d
+ end
+ handle_any_entity_dtd=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
- end
- return a
+ a=entities[str]
end
- end
- handle_any_entity_text=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(grammar_parsed_text_two,a) or a
- if type(a)=="number" then
- return ""
- else
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- end
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
end
- return a
+ a=a(str) or ""
+ end
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
end
- return a
- end
- end
- local p_rest=(1-P(";"))^1
- local spec={
- [0x23]="\\Ux{23}",
- [0x24]="\\Ux{24}",
- [0x25]="\\Ux{25}",
- [0x5C]="\\Ux{5C}",
- [0x7B]="\\Ux{7B}",
- [0x7C]="\\Ux{7C}",
- [0x7D]="\\Ux{7D}",
- [0x7E]="\\Ux{7E}",
- }
- local hash=table.setmetatableindex(spec,function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
- else
- return formatters["u:%s"](s),true
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
- end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
+ end
+ return a
+ end
+ end
+ handle_any_entity_text=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- return formatters["d:%s"](s),true
+ a=entities[str]
end
- end
- local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- local hash=table.setmetatableindex(function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
+ end
+ a=a(str) or ""
+ end
+ a=lpegmatch(grammar_parsed_text_two,a) or a
+ if type(a)=="number" then
+ return ""
+ else
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
+ end
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- return formatters["u:%s"](s),true
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
+ end
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
+ end
+ return a
+ end
+ end
+ local p_rest=(1-P(";"))^1
+ local spec={
+ [0x23]="\\Ux{23}",
+ [0x24]="\\Ux{24}",
+ [0x25]="\\Ux{25}",
+ [0x5C]="\\Ux{5C}",
+ [0x7B]="\\Ux{7B}",
+ [0x7C]="\\Ux{7C}",
+ [0x7D]="\\Ux{7D}",
+ [0x7E]="\\Ux{7E}",
+ }
+ local hash=table.setmetatableindex(spec,function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
- else
- return formatters["d:%s"](s),true
- end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ local hash=table.setmetatableindex(function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
+ end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
end
- local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- xml.reparsedentitylpeg=reparsedentity
- xml.unescapedentitylpeg=unescapedentity
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ xml.reparsedentitylpeg=reparsedentity
+ xml.unescapedentitylpeg=unescapedentity
end
local escaped=xml.escaped
local unescaped=xml.unescaped
local placeholders=xml.placeholders
local function handle_end_entity(str)
- report_xml("error in entity, %a found without ending %a",str,";")
- return str
+ report_xml("error in entity, %a found without ending %a",str,";")
+ return str
end
local function handle_crap_error(chr)
- report_xml("error in parsing, unexpected %a found ",chr)
- add_text(chr)
- return chr
+ report_xml("error in parsing, unexpected %a found ",chr)
+ add_text(chr)
+ return chr
end
local function handlenewline()
- currentline=currentline+1
+ currentline=currentline+1
end
local spacetab=S(' \t')
local space=S(' \r\n\t')
@@ -16202,141 +16210,141 @@ local space_nl=spacetab+newline
local spacing_nl=Cs((space_nl)^0)
local anything_nl=newline+P(1)
local function weirdentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","weird",k,v)
- end
- parameters[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","weird",k,v)
+ end
+ parameters[k]=v
end
local function normalentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","normal",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","normal",k,v)
+ end
+ entities[k]=v
end
local function systementity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","system",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","system",k,v)
+ end
+ entities[k]=v
end
local function publicentity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","public",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","public",k,v)
+ end
+ entities[k]=v
end
local function entityfile(pattern,k,v,n)
- if n then
- local okay,data
- if resolvers then
- okay,data=resolvers.loadbinfile(n)
- else
- data=io.loaddata(n)
- okay=data and data~=""
- end
- if okay then
- if trace_entities then
- report_xml("loading public entities %a as %a from %a",k,v,n)
- end
- lpegmatch(pattern,data)
- return
- end
+ if n then
+ local okay,data
+ if resolvers then
+ okay,data=resolvers.loadbinfile(n)
+ else
+ data=io.loaddata(n)
+ okay=data and data~=""
end
- report_xml("ignoring public entities %a as %a from %a",k,v,n)
+ if okay then
+ if trace_entities then
+ report_xml("loading public entities %a as %a from %a",k,v,n)
+ end
+ lpegmatch(pattern,data)
+ return
+ end
+ end
+ report_xml("ignoring public entities %a as %a from %a",k,v,n)
end
local function install(spacenewline,spacing,anything)
- local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
- local hexentitycontent=R("AF","af","09")^1
- local decentitycontent=R("09")^1
- local parsedentity=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_dtd)
- local parsedentity_text=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_text)
- local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local text_unparsed=Cs((anything-open)^1)
- local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
- local somespace=(spacenewline)^1
- local optionalspace=(spacenewline)^0
- local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
- local endofattributes=slash*close+close
- local whatever=space*name*optionalspace*equal
- local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
- local attributevalue=value+wrongvalue
- local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
- local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
- local parsedtext=text_parsed
- local unparsedtext=text_unparsed/add_text
- local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
- local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
- local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
- local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
- local begincomment=open*P("!--")
- local endcomment=P("--")*close
- local begininstruction=open*P("?")
- local endinstruction=P("?")*close
- local begincdata=open*P("![CDATA[")
- local endcdata=P("]]")*close
- local someinstruction=C((anything-endinstruction)^0)
- local somecomment=C((anything-endcomment )^0)
- local somecdata=C((anything-endcdata )^0)
- local begindoctype=open*P("!DOCTYPE")
- local enddoctype=close
- local beginset=P("[")
- local endset=P("]")
- local wrdtypename=C((anything-somespace-P(";"))^1)
- local doctypename=C((anything-somespace-close)^0)
- local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
- local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
- local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
- local normalentitytype=(doctypename*somespace*value)/normalentity
- local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
- local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
- local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
- local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
- entityfile(entitydoctype,...)
- end
- local function weirdresolve(s)
- lpegmatch(entitydoctype,parameters[s])
- end
- local function normalresolve(s)
- lpegmatch(entitydoctype,entities[s])
- end
- local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
- entitydoctype=entitydoctype+entityresolve
- local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
- local definitiondoctype=doctypename*somespace*doctypeset
- local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
- local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
- local simpledoctype=(anything-close)^1
- local somedoctype=C((somespace*(
+ local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
+ local hexentitycontent=R("AF","af","09")^1
+ local decentitycontent=R("09")^1
+ local parsedentity=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_dtd)
+ local parsedentity_text=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_text)
+ local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local text_unparsed=Cs((anything-open)^1)
+ local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
+ local somespace=(spacenewline)^1
+ local optionalspace=(spacenewline)^0
+ local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
+ local endofattributes=slash*close+close
+ local whatever=space*name*optionalspace*equal
+ local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
+ local attributevalue=value+wrongvalue
+ local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
+ local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
+ local parsedtext=text_parsed
+ local unparsedtext=text_unparsed/add_text
+ local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
+ local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
+ local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
+ local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
+ local begincomment=open*P("!--")
+ local endcomment=P("--")*close
+ local begininstruction=open*P("?")
+ local endinstruction=P("?")*close
+ local begincdata=open*P("![CDATA[")
+ local endcdata=P("]]")*close
+ local someinstruction=C((anything-endinstruction)^0)
+ local somecomment=C((anything-endcomment )^0)
+ local somecdata=C((anything-endcdata )^0)
+ local begindoctype=open*P("!DOCTYPE")
+ local enddoctype=close
+ local beginset=P("[")
+ local endset=P("]")
+ local wrdtypename=C((anything-somespace-P(";"))^1)
+ local doctypename=C((anything-somespace-close)^0)
+ local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
+ local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
+ local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
+ local normalentitytype=(doctypename*somespace*value)/normalentity
+ local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
+ local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
+ local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
+ local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
+ entityfile(entitydoctype,...)
+ end
+ local function weirdresolve(s)
+ lpegmatch(entitydoctype,parameters[s])
+ end
+ local function normalresolve(s)
+ lpegmatch(entitydoctype,entities[s])
+ end
+ local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
+ entitydoctype=entitydoctype+entityresolve
+ local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
+ local definitiondoctype=doctypename*somespace*doctypeset
+ local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
+ local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
+ local simpledoctype=(anything-close)^1
+ local somedoctype=C((somespace*(
publicentityfile+publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0)
- local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
- local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
- local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
- local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
- local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
- local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
- local trailer=space^0*(text_unparsed/set_message)^0
- local grammar_parsed_text_one=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
- }
- local grammar_parsed_text_two=P { "followup",
- followup=V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
- }
- local grammar_unparsed_text=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
- }
- return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
+ local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
+ local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
+ local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
+ local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
+ local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
+ local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
+ local trailer=space^0*(text_unparsed/set_message)^0
+ local grammar_parsed_text_one=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
+ }
+ local grammar_parsed_text_two=P { "followup",
+ followup=V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
+ }
+ local grammar_unparsed_text=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
+ }
+ return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
end
grammar_parsed_text_one_nop,
grammar_parsed_text_two_nop,
@@ -16345,576 +16353,576 @@ grammar_parsed_text_one_yes,
grammar_parsed_text_two_yes,
grammar_unparsed_text_yes=install(space_nl,spacing_nl,anything_nl)
local function _xmlconvert_(data,settings,detail)
- settings=settings or {}
- preparexmlstate(settings)
- if settings.linenumbers then
- grammar_parsed_text_one=grammar_parsed_text_one_yes
- grammar_parsed_text_two=grammar_parsed_text_two_yes
- grammar_unparsed_text=grammar_unparsed_text_yes
- else
- grammar_parsed_text_one=grammar_parsed_text_one_nop
- grammar_parsed_text_two=grammar_parsed_text_two_nop
- grammar_unparsed_text=grammar_unparsed_text_nop
- end
- local preprocessor=settings.preprocessor
- if data and data~="" and type(preprocessor)=="function" then
- data=preprocessor(data,settings) or data
+ settings=settings or {}
+ preparexmlstate(settings)
+ if settings.linenumbers then
+ grammar_parsed_text_one=grammar_parsed_text_one_yes
+ grammar_parsed_text_two=grammar_parsed_text_two_yes
+ grammar_unparsed_text=grammar_unparsed_text_yes
+ else
+ grammar_parsed_text_one=grammar_parsed_text_one_nop
+ grammar_parsed_text_two=grammar_parsed_text_two_nop
+ grammar_unparsed_text=grammar_unparsed_text_nop
+ end
+ local preprocessor=settings.preprocessor
+ if data and data~="" and type(preprocessor)=="function" then
+ data=preprocessor(data,settings) or data
+ end
+ if settings.parent_root then
+ mt=getmetatable(settings.parent_root)
+ else
+ initialize_mt(top)
+ end
+ level=level+1
+ stack[level]=top
+ top.dt={}
+ dt=top.dt
+ nt=0
+ if not data or data=="" then
+ errorstr="empty xml file"
+ elseif data==true then
+ errorstr=detail or "problematic xml file"
+ elseif utfize or resolve then
+ local m=lpegmatch(grammar_parsed_text_one,data)
+ if m then
+ m=lpegmatch(grammar_parsed_text_two,data,m)
end
- if settings.parent_root then
- mt=getmetatable(settings.parent_root)
- else
- initialize_mt(top)
- end
- level=level+1
- stack[level]=top
- top.dt={}
- dt=top.dt
- nt=0
- if not data or data=="" then
- errorstr="empty xml file"
- elseif data==true then
- errorstr=detail or "problematic xml file"
- elseif utfize or resolve then
- local m=lpegmatch(grammar_parsed_text_one,data)
- if m then
- m=lpegmatch(grammar_parsed_text_two,data,m)
- end
- if m then
- else
- errorstr="invalid xml file - parsed text"
- end
- elseif type(data)=="string" then
- if lpegmatch(grammar_unparsed_text,data) then
- errorstr=""
- else
- errorstr="invalid xml file - unparsed text"
- end
+ if m then
else
- errorstr="invalid xml file - no text at all"
- end
- local result
- if errorstr and errorstr~="" then
- result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
- setmetatable(result,mt)
- setmetatable(result.dt[1],mt)
- setmetatable(stack,mt)
- local errorhandler=settings.error_handler
- if errorhandler==false then
+ errorstr="invalid xml file - parsed text"
+ end
+ elseif type(data)=="string" then
+ if lpegmatch(grammar_unparsed_text,data) then
+ errorstr=""
+ else
+ errorstr="invalid xml file - unparsed text"
+ end
+ else
+ errorstr="invalid xml file - no text at all"
+ end
+ local result
+ if errorstr and errorstr~="" then
+ result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
+ setmetatable(result,mt)
+ setmetatable(result.dt[1],mt)
+ setmetatable(stack,mt)
+ local errorhandler=settings.error_handler
+ if errorhandler==false then
+ else
+ errorhandler=errorhandler or xml.errorhandler
+ if errorhandler then
+ local currentresource=settings.currentresource
+ if currentresource and currentresource~="" then
+ xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
else
- errorhandler=errorhandler or xml.errorhandler
- if errorhandler then
- local currentresource=settings.currentresource
- if currentresource and currentresource~="" then
- xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
- else
- xml.errorhandler(formatters["load error: %s"](errorstr))
- end
- end
- end
- else
- result=stack[1]
- end
- if not settings.no_root then
- result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
- setmetatable(result,mt)
- local rdt=result.dt
- for k=1,#rdt do
- local v=rdt[k]
- if type(v)=="table" and not v.special then
- result.ri=k
- v.__p__=result
- break
- end
+ xml.errorhandler(formatters["load error: %s"](errorstr))
end
+ end
end
- if errorstr and errorstr~="" then
- result.error=true
- else
- errorstr=nil
- end
- result.statistics={
- errormessage=errorstr,
- entities={
- decimals=dcache,
- hexadecimals=hcache,
- names=acache,
- intermediates=parameters,
- }
+ else
+ result=stack[1]
+ end
+ if not settings.no_root then
+ result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
+ setmetatable(result,mt)
+ local rdt=result.dt
+ for k=1,#rdt do
+ local v=rdt[k]
+ if type(v)=="table" and not v.special then
+ result.ri=k
+ v.__p__=result
+ break
+ end
+ end
+ end
+ if errorstr and errorstr~="" then
+ result.error=true
+ else
+ errorstr=nil
+ end
+ result.statistics={
+ errormessage=errorstr,
+ entities={
+ decimals=dcache,
+ hexadecimals=hcache,
+ names=acache,
+ intermediates=parameters,
}
- preparexmlstate()
- return result
+ }
+ preparexmlstate()
+ return result
end
local function xmlconvert(data,settings)
- local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
- if ok then
- return result
- elseif type(result)=="string" then
- return _xmlconvert_(true,settings,result)
- else
- return _xmlconvert_(true,settings)
- end
+ local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
+ if ok then
+ return result
+ elseif type(result)=="string" then
+ return _xmlconvert_(true,settings,result)
+ else
+ return _xmlconvert_(true,settings)
+ end
end
xml.convert=xmlconvert
function xml.inheritedconvert(data,xmldata)
- local settings=xmldata.settings
- if settings then
- settings.parent_root=xmldata
- end
- local xc=xmlconvert(data,settings)
- return xc
+ local settings=xmldata.settings
+ if settings then
+ settings.parent_root=xmldata
+ end
+ local xc=xmlconvert(data,settings)
+ return xc
end
function xml.is_valid(root)
- return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
+ return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
end
function xml.package(tag,attributes,data)
- local ns,tg=match(tag,"^(.-):?([^:]+)$")
- local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
- setmetatable(t,mt)
- return t
+ local ns,tg=match(tag,"^(.-):?([^:]+)$")
+ local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
+ setmetatable(t,mt)
+ return t
end
function xml.is_valid(root)
- return root and not root.error
+ return root and not root.error
end
xml.errorhandler=report_xml
function xml.load(filename,settings)
- local data=""
- if type(filename)=="string" then
- local f=io.open(filename,'r')
- if f then
- data=f:read("*all")
- f:close()
- end
- elseif filename then
- data=filename:read("*all")
- end
- if settings then
- settings.currentresource=filename
- local result=xmlconvert(data,settings)
- settings.currentresource=nil
- return result
- else
- return xmlconvert(data,{ currentresource=filename })
- end
+ local data=""
+ if type(filename)=="string" then
+ local f=io.open(filename,'r')
+ if f then
+ data=f:read("*all")
+ f:close()
+ end
+ elseif filename then
+ data=filename:read("*all")
+ end
+ if settings then
+ settings.currentresource=filename
+ local result=xmlconvert(data,settings)
+ settings.currentresource=nil
+ return result
+ else
+ return xmlconvert(data,{ currentresource=filename })
+ end
end
local no_root={ no_root=true }
function xml.toxml(data)
- if type(data)=="string" then
- local root={ xmlconvert(data,no_root) }
- return (#root>1 and root) or root[1]
- else
- return data
- end
+ if type(data)=="string" then
+ local root={ xmlconvert(data,no_root) }
+ return (#root>1 and root) or root[1]
+ else
+ return data
+ end
end
local function copy(old,p)
- if old then
- local new={}
- for k,v in next,old do
- local t=type(v)=="table"
- if k=="at" then
- local t={}
- for k,v in next,v do
- t[k]=v
- end
- new[k]=t
- elseif k=="dt" then
- v.__p__=nil
- v=copy(v,new)
- new[k]=v
- v.__p__=p
- else
- new[k]=v
- end
- end
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ local t=type(v)=="table"
+ if k=="at" then
+ local t={}
+ for k,v in next,v do
+ t[k]=v
+ end
+ new[k]=t
+ elseif k=="dt" then
+ v.__p__=nil
+ v=copy(v,new)
+ new[k]=v
+ v.__p__=p
+ else
+ new[k]=v
+ end
+ end
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
end
+ return new
+ else
+ return {}
+ end
end
xml.copy=copy
function xml.checkbom(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@" and find(v.dt[1],"xml.*version=") then
- return
- end
- end
- insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
- insert(dt,2,"\n" )
+ 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@" and find(v.dt[1],"xml.*version=") then
+ return
+ end
end
+ insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
+ insert(dt,2,"\n" )
+ end
end
local f_attribute=formatters['%s=%q']
local function verbose_element(e,handlers,escape)
- local handle=handlers.handle
- local serialize=handlers.serialize
- local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
- local ats=eat and next(eat) and {}
- if ats then
- local n=0
- for k in next,eat do
- n=n+1
- ats[n]=k
- end
- if n==1 then
- local k=ats[1]
- ats=f_attribute(k,escaped(eat[k]))
- else
- sort(ats)
- for i=1,n do
- local k=ats[i]
- ats[i]=f_attribute(k,escaped(eat[k]))
- end
- ats=concat(ats," ")
- end
- end
- if ern and trace_entities and ern~=ens then
- ens=ern
+ local handle=handlers.handle
+ local serialize=handlers.serialize
+ local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
+ local ats=eat and next(eat) and {}
+ if ats then
+ local n=0
+ for k in next,eat do
+ n=n+1
+ ats[n]=k
end
- local n=edt and #edt
- if ens~="" then
- if n and n>0 then
- if ats then
- handle("<",ens,":",etg," ",ats,">")
- else
- handle("<",ens,":",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",ens,":",etg,">")
+ if n==1 then
+ local k=ats[1]
+ ats=f_attribute(k,escaped(eat[k]))
+ else
+ sort(ats)
+ for i=1,n do
+ local k=ats[i]
+ ats[i]=f_attribute(k,escaped(eat[k]))
+ end
+ ats=concat(ats," ")
+ end
+ end
+ if ern and trace_entities and ern~=ens then
+ ens=ern
+ end
+ local n=edt and #edt
+ if ens~="" then
+ if n and n>0 then
+ if ats then
+ handle("<",ens,":",etg," ",ats,">")
+ else
+ handle("<",ens,":",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",ens,":",etg," ",ats,"/>")
- else
- handle("<",ens,":",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",ens,":",etg,">")
else
- if n and n>0 then
- if ats then
- handle("<",etg," ",ats,">")
- else
- handle("<",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",etg,">")
+ if ats then
+ handle("<",ens,":",etg," ",ats,"/>")
+ else
+ handle("<",ens,":",etg,"/>")
+ end
+ end
+ else
+ if n and n>0 then
+ if ats then
+ handle("<",etg," ",ats,">")
+ else
+ handle("<",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",etg," ",ats,"/>")
- else
- handle("<",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",etg,">")
+ else
+ if ats then
+ handle("<",etg," ",ats,"/>")
+ else
+ handle("<",etg,"/>")
+ end
end
+ end
end
local function verbose_pi(e,handlers)
- handlers.handle("<?",e.dt[1],"?>")
+ handlers.handle("<?",e.dt[1],"?>")
end
local function verbose_comment(e,handlers)
- handlers.handle("<!--",e.dt[1],"-->")
+ handlers.handle("<!--",e.dt[1],"-->")
end
local function verbose_cdata(e,handlers)
- handlers.handle("<![CDATA[",e.dt[1],"]]>")
+ handlers.handle("<![CDATA[",e.dt[1],"]]>")
end
local function verbose_doctype(e,handlers)
- handlers.handle("<!DOCTYPE",e.dt[1],">")
+ handlers.handle("<!DOCTYPE",e.dt[1],">")
end
local function verbose_root(e,handlers)
- handlers.serialize(e.dt,handlers)
+ handlers.serialize(e.dt,handlers)
end
local function verbose_text(e,handlers)
- handlers.handle(escaped(e))
+ handlers.handle(escaped(e))
end
local function verbose_document(e,handlers)
- local serialize=handlers.serialize
- local functions=handlers.functions
- for i=1,#e do
- local ei=e[i]
- if type(ei)=="string" then
- functions["@tx@"](ei,handlers)
- else
- serialize(ei,handlers)
- end
+ local serialize=handlers.serialize
+ local functions=handlers.functions
+ for i=1,#e do
+ local ei=e[i]
+ if type(ei)=="string" then
+ functions["@tx@"](ei,handlers)
+ else
+ serialize(ei,handlers)
end
+ end
end
local function serialize(e,handlers,...)
- if e then
- local initialize=handlers.initialize
- local finalize=handlers.finalize
- local functions=handlers.functions
- if initialize then
- local state=initialize(...)
- if not state==true then
- return state
- end
- end
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
- if finalize then
- return finalize()
- end
+ if e then
+ local initialize=handlers.initialize
+ local finalize=handlers.finalize
+ local functions=handlers.functions
+ if initialize then
+ local state=initialize(...)
+ if not state==true then
+ return state
+ end
+ end
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
end
+ if finalize then
+ return finalize()
+ end
+ end
end
local function xserialize(e,handlers)
- if e then
- local functions=handlers.functions
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
+ if e then
+ local functions=handlers.functions
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
end
+ end
end
local handlers={}
local function newhandlers(settings)
- local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
- if settings then
- for k,v in next,settings do
- if type(v)=="table" then
- local tk=t[k] if not tk then tk={} t[k]=tk end
- for kk,vv in next,v do
- tk[kk]=vv
- end
- else
- t[k]=v
- end
- end
- if settings.name then
- handlers[settings.name]=t
- end
+ local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
+ if settings then
+ for k,v in next,settings do
+ if type(v)=="table" then
+ local tk=t[k] if not tk then tk={} t[k]=tk end
+ for kk,vv in next,v do
+ tk[kk]=vv
+ end
+ else
+ t[k]=v
+ end
end
- utilities.storage.mark(t)
- return t
+ if settings.name then
+ handlers[settings.name]=t
+ end
+ end
+ utilities.storage.mark(t)
+ return t
end
local nofunction=function() end
function xml.sethandlersfunction(handler,name,fnc)
- handler.functions[name]=fnc or nofunction
+ handler.functions[name]=fnc or nofunction
end
function xml.gethandlersfunction(handler,name)
- return handler.functions[name]
+ return handler.functions[name]
end
function xml.gethandlers(name)
- return handlers[name]
+ return handlers[name]
end
newhandlers {
- name="verbose",
- initialize=false,
- finalize=false,
- serialize=xserialize,
- handle=print,
- functions={
- ["@dc@"]=verbose_document,
- ["@dt@"]=verbose_doctype,
- ["@rt@"]=verbose_root,
- ["@el@"]=verbose_element,
- ["@pi@"]=verbose_pi,
- ["@cm@"]=verbose_comment,
- ["@cd@"]=verbose_cdata,
- ["@tx@"]=verbose_text,
- }
+ name="verbose",
+ initialize=false,
+ finalize=false,
+ serialize=xserialize,
+ handle=print,
+ functions={
+ ["@dc@"]=verbose_document,
+ ["@dt@"]=verbose_doctype,
+ ["@rt@"]=verbose_root,
+ ["@el@"]=verbose_element,
+ ["@pi@"]=verbose_pi,
+ ["@cm@"]=verbose_comment,
+ ["@cd@"]=verbose_cdata,
+ ["@tx@"]=verbose_text,
+ }
}
local result
local xmlfilehandler=newhandlers {
- name="file",
- initialize=function(name)
- result=io.open(name,"wb")
- return result
- end,
- finalize=function()
- result:close()
- return true
- end,
- handle=function(...)
- result:write(...)
- end,
+ name="file",
+ initialize=function(name)
+ result=io.open(name,"wb")
+ return result
+ end,
+ finalize=function()
+ result:close()
+ return true
+ end,
+ handle=function(...)
+ result:write(...)
+ end,
}
function xml.save(root,name)
- serialize(root,xmlfilehandler,name)
+ serialize(root,xmlfilehandler,name)
end
local result,r,threshold={},0,512
local xmlstringhandler=newhandlers {
- name="string",
- initialize=function()
- r=0
- return result
- end,
- finalize=function()
- local done=concat(result,"",1,r)
- r=0
- if r>threshold then
- result={}
- end
- return done
- end,
- handle=function(...)
- for i=1,select("#",...) do
- r=r+1
- result[r]=select(i,...)
- end
- end,
+ name="string",
+ initialize=function()
+ r=0
+ return result
+ end,
+ finalize=function()
+ local done=concat(result,"",1,r)
+ r=0
+ if r>threshold then
+ result={}
+ end
+ return done
+ end,
+ handle=function(...)
+ for i=1,select("#",...) do
+ r=r+1
+ result[r]=select(i,...)
+ end
+ end,
}
local function xmltostring(root)
- if not root then
- return ""
- elseif type(root)=="string" then
- return root
- else
- return serialize(root,xmlstringhandler) or ""
- end
+ if not root then
+ return ""
+ elseif type(root)=="string" then
+ return root
+ else
+ return serialize(root,xmlstringhandler) or ""
+ end
end
local function __tostring(root)
- return (root and xmltostring(root)) or ""
+ return (root and xmltostring(root)) or ""
end
initialize_mt=function(root)
- mt={ __tostring=__tostring,__index=root }
+ mt={ __tostring=__tostring,__index=root }
end
xml.defaulthandlers=handlers
xml.newhandlers=newhandlers
xml.serialize=serialize
xml.tostring=xmltostring
local function xmlstring(e,handle)
- if not handle or (e.special and e.tg~="@rt@") then
- elseif e.tg then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- xmlstring(edt[i],handle)
- end
- end
- else
- handle(e)
+ if not handle or (e.special and e.tg~="@rt@") then
+ elseif e.tg then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ xmlstring(edt[i],handle)
+ end
end
+ else
+ handle(e)
+ end
end
xml.string=xmlstring
function xml.settings(e)
- while e do
- local s=e.settings
- if s then
- return s
- else
- e=e.__p__
- end
+ while e do
+ local s=e.settings
+ if s then
+ return s
+ else
+ e=e.__p__
end
- return nil
+ end
+ return nil
end
function xml.root(e)
- local r=e
- while e do
- e=e.__p__
- if e then
- r=e
- end
+ local r=e
+ while e do
+ e=e.__p__
+ if e then
+ r=e
end
- return r
+ end
+ return r
end
function xml.parent(root)
- return root.__p__
+ return root.__p__
end
function xml.body(root)
- return root.ri and root.dt[root.ri] or root
+ return root.ri and root.dt[root.ri] or root
end
function xml.name(root)
- if not root then
- return ""
- end
- local ns=root.ns
- local tg=root.tg
- if ns=="" then
- return tg
- else
- return ns..":"..tg
- end
+ if not root then
+ return ""
+ end
+ local ns=root.ns
+ local tg=root.tg
+ if ns=="" then
+ return tg
+ else
+ return ns..":"..tg
+ end
end
function xml.erase(dt,k)
- if dt then
- if k then
- dt[k]=""
- else for k=1,#dt do
- dt[1]={ "" }
- end end
- end
+ if dt then
+ if k then
+ dt[k]=""
+ else for k=1,#dt do
+ dt[1]={ "" }
+ end end
+ end
end
function xml.assign(dt,k,root)
- if dt and k then
- dt[k]=type(root)=="table" and xml.body(root) or root
- return dt[k]
- else
- return xml.body(root)
- end
+ if dt and k then
+ dt[k]=type(root)=="table" and xml.body(root) or root
+ return dt[k]
+ else
+ return xml.body(root)
+ end
end
function xml.tocdata(e,wrapper)
- local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
- if wrapper then
- whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
- end
- local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
- setmetatable(t,getmetatable(e))
- e.dt={ t }
+ local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
+ if wrapper then
+ whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
+ end
+ local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
+ setmetatable(t,getmetatable(e))
+ 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
+ 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
- return root
+ end
+ return root
end
function xml.kind(e)
- local dt=e and e.dt
- if dt then
- local n=#dt
- if n==1 then
- local d=dt[1]
- if d.special then
- local tg=d.tg
- if tg=="@cd@" then
- return "cdata"
- elseif tg=="@cm" then
- return "comment"
- elseif tg=="@pi@" then
- return "instruction"
- elseif tg=="@dt@" then
- return "declaration"
- end
- elseif type(d)=="string" then
- return "text"
- end
- return "element"
- elseif n>0 then
- return "mixed"
- end
+ local dt=e and e.dt
+ if dt then
+ local n=#dt
+ if n==1 then
+ local d=dt[1]
+ if d.special then
+ local tg=d.tg
+ if tg=="@cd@" then
+ return "cdata"
+ elseif tg=="@cm" then
+ return "comment"
+ elseif tg=="@pi@" then
+ return "instruction"
+ elseif tg=="@dt@" then
+ return "declaration"
+ end
+ elseif type(d)=="string" then
+ return "text"
+ end
+ return "element"
+ elseif n>0 then
+ return "mixed"
end
- return "empty"
+ end
+ return "empty"
end
@@ -16924,14 +16932,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true
--- original size: 54551, stripped down to: 33353
+-- original size: 54551, stripped down to: 30745
if not modules then modules={} end modules ['lxml-lpt']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local concat,remove,insert=table.concat,table.remove,table.insert
local type,next,tonumber,tostring,setmetatable,load,select=type,next,tonumber,tostring,setmetatable,load,select
@@ -16944,21 +16952,21 @@ local trace_lparse=false
local trace_lprofile=false
local report_lpath=logs.reporter("xml","lpath")
if trackers then
- trackers.register("xml.path",function(v)
- trace_lpath=v
- end)
- trackers.register("xml.parse",function(v)
- trace_lparse=v
- end)
- trackers.register("xml.profile",function(v)
- trace_lpath=v
- trace_lparse=v
- trace_lprofile=v
- end)
+ trackers.register("xml.path",function(v)
+ trace_lpath=v
+ end)
+ trackers.register("xml.parse",function(v)
+ trace_lparse=v
+ end)
+ trackers.register("xml.profile",function(v)
+ trace_lpath=v
+ trace_lparse=v
+ trace_lprofile=v
+ end)
end
local xml=xml
-local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
-local lpathcached=0 function xml.lpathcached() return lpathcached end
+local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
+local lpathcached=0 function xml.lpathcached() return lpathcached end
xml.functions=xml.functions or {}
local functions=xml.functions
xml.expressions=xml.expressions or {}
@@ -16972,262 +16980,262 @@ local xmlpatterns=lpegpatterns.xml
finalizers.xml=finalizers.xml or {}
finalizers.tex=finalizers.tex or {}
local function fallback (t,name)
- local fn=finalizers[name]
- if fn then
- t[name]=fn
- else
- report_lpath("unknown sub finalizer %a",name)
- fn=function() end
- end
- return fn
+ local fn=finalizers[name]
+ if fn then
+ t[name]=fn
+ else
+ report_lpath("unknown sub finalizer %a",name)
+ fn=function() end
+ end
+ return fn
end
setmetatableindex(finalizers.xml,fallback)
setmetatableindex(finalizers.tex,fallback)
xml.defaultprotocol="xml"
local apply_axis={}
apply_axis['root']=function(list)
- local collected={}
- for l=1,#list do
- local ll=list[l]
- local rt=ll
- while ll do
- ll=ll.__p__
- if ll then
- rt=ll
- end
- end
- collected[l]=rt
+ local collected={}
+ for l=1,#list do
+ local ll=list[l]
+ local rt=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
+ rt=ll
+ end
end
- return collected
+ collected[l]=rt
+ end
+ return collected
end
apply_axis['self']=function(list)
- return list
+ return list
end
apply_axis['child']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local dt=ll.dt
- if dt then
- local n=#dt
- if n==0 then
- ll.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- ll.en=1
- end
- else
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- end
- end
- ll.en=en
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local dt=ll.dt
+ if dt then
+ local n=#dt
+ if n==0 then
+ ll.en=0
+ elseif n==1 then
+ local dk=dt[1]
+ if dk.tg then
+ c=c+1
+ collected[c]=dk
+ dk.ni=1
+ dk.ei=1
+ ll.en=1
+ end
+ else
+ local en=0
+ for k=1,#dt do
+ local dk=dt[k]
+ if dk.tg then
+ c=c+1
+ en=en+1
+ collected[c]=dk
+ dk.ni=k
+ dk.ei=en
+ end
end
+ ll.en=en
+ end
end
- return collected
+ end
+ return collected
end
local function collect(list,collected,c)
- local dt=list.dt
- if dt then
- local n=#dt
- if n==0 then
- list.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- c=collect(dk,collected,c)
- list.en=1
- else
- list.en=0
- end
- else
- local en=0
- for k=1,n do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- c=collect(dk,collected,c)
- end
- end
- list.en=en
+ local dt=list.dt
+ if dt then
+ local n=#dt
+ if n==0 then
+ list.en=0
+ elseif n==1 then
+ local dk=dt[1]
+ if dk.tg then
+ c=c+1
+ collected[c]=dk
+ dk.ni=1
+ dk.ei=1
+ c=collect(dk,collected,c)
+ list.en=1
+ else
+ list.en=0
+ end
+ else
+ local en=0
+ for k=1,n do
+ local dk=dt[k]
+ if dk.tg then
+ c=c+1
+ en=en+1
+ collected[c]=dk
+ dk.ni=k
+ dk.ei=en
+ c=collect(dk,collected,c)
end
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant']=function(list)
- local collected,c={},0
- for l=1,#list do
- c=collect(list[l],collected,c)
- end
- return collected
+ local collected,c={},0
+ for l=1,#list do
+ c=collect(list[l],collected,c)
+ end
+ return collected
end
local function collect(list,collected,c)
- local dt=list.dt
- if dt then
- local n=#dt
- if n==0 then
- list.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- c=collect(dk,collected,c)
- list.en=1
- end
- else
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- c=collect(dk,collected,c)
- end
- end
- list.en=en
+ local dt=list.dt
+ if dt then
+ local n=#dt
+ if n==0 then
+ list.en=0
+ elseif n==1 then
+ local dk=dt[1]
+ if dk.tg then
+ c=c+1
+ collected[c]=dk
+ dk.ni=1
+ dk.ei=1
+ c=collect(dk,collected,c)
+ list.en=1
+ end
+ else
+ local en=0
+ for k=1,#dt do
+ local dk=dt[k]
+ if dk.tg then
+ c=c+1
+ en=en+1
+ collected[c]=dk
+ dk.ni=k
+ dk.ei=en
+ c=collect(dk,collected,c)
end
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- if ll.special~=true then
- c=c+1
- collected[c]=ll
- end
- c=collect(ll,collected,c)
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ if ll.special~=true then
+ c=c+1
+ collected[c]=ll
end
- return collected
+ c=collect(ll,collected,c)
+ end
+ return collected
end
apply_axis['ancestor']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ while ll do
+ ll=ll.__p__
+ if ll then
+ c=c+1
+ collected[c]=ll
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['ancestor-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ c=c+1
+ collected[c]=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
c=c+1
collected[c]=ll
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['parent']=function(list)
- local collected,c={},0
- for l=1,#list do
- local pl=list[l].__p__
- if pl then
- c=c+1
- collected[c]=pl
- end
+ local collected,c={},0
+ for l=1,#list do
+ local pl=list[l].__p__
+ if pl then
+ c=c+1
+ collected[c]=pl
end
- return collected
+ end
+ return collected
end
apply_axis['attribute']=function(list)
- return {}
+ return {}
end
apply_axis['namespace']=function(list)
- return {}
+ return {}
end
apply_axis['following']=function(list)
- return {}
+ return {}
end
apply_axis['preceding']=function(list)
- return {}
+ return {}
end
apply_axis['following-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=ll.ni+1,#d do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=ll.ni+1,#d do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['preceding-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=1,ll.ni-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=1,ll.ni-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['reverse-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=ll.ni-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=ll.ni-1,1,-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['auto-descendant-or-self']=apply_axis['descendant-or-self']
apply_axis['auto-descendant']=apply_axis['descendant']
@@ -17235,130 +17243,130 @@ apply_axis['auto-child']=apply_axis['child']
apply_axis['auto-self']=apply_axis['self']
apply_axis['initial-child']=apply_axis['child']
local function apply_nodes(list,directive,nodes)
- local maxn=#nodes
- if maxn==3 then
- local nns,ntg=nodes[2],nodes[3]
- if not nns and not ntg then
+ local maxn=#nodes
+ if maxn==3 then
+ local nns,ntg=nodes[2],nodes[3]
+ if not nns and not ntg then
+ if directive then
+ return list
+ else
+ return {}
+ end
+ else
+ local collected,c,m,p={},0,0,nil
+ if not nns then
+ for l=1,#list do
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
if directive then
- return list
- else
- return {}
+ if ntg==ltg then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif ntg~=ltg then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
end
- else
- local collected,c,m,p={},0,0,nil
- if not nns then
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- if directive then
- if ntg==ltg then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif ntg~=ltg then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- elseif not ntg then
- for l=1,#list do
- local ll=list[l]
- local lns=ll.rn or ll.ns
- if lns then
- if directive then
- if lns==nns then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif lns~=nns then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- else
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=ltg==ntg and lns==nns
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
+ end
+ end
+ elseif not ntg then
+ for l=1,#list do
+ local ll=list[l]
+ local lns=ll.rn or ll.ns
+ if lns then
+ if directive then
+ if lns==nns then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif lns~=nns then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
end
- return collected
+ end
end
- else
- local collected,c,m,p={},0,0,nil
+ else
for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=false
- for n=1,maxn,3 do
- local nns,ntg=nodes[n+1],nodes[n+2]
- ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
- if ok then
- break
- end
- end
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=ltg==ntg and lns==nns
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
end
+ end
end
- return collected
+ end
+ return collected
end
-end
-local quit_expression=false
-local function apply_expression(list,expression,order)
- local collected,c={},0
- quit_expression=false
+ else
+ local collected,c,m,p={},0,0,nil
for l=1,#list do
- local ll=list[l]
- if expression(list,ll,l,order) then
- c=c+1
- collected[c]=ll
- end
- if quit_expression then
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=false
+ for n=1,maxn,3 do
+ local nns,ntg=nodes[n+1],nodes[n+2]
+ ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
+ if ok then
break
+ end
end
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ end
end
return collected
+ end
end
-local function apply_selector(list,specification)
- if xml.applyselector then
- apply_selector=xml.applyselector
- return apply_selector(list,specification)
- else
- return list
+local quit_expression=false
+local function apply_expression(list,expression,order)
+ local collected,c={},0
+ quit_expression=false
+ for l=1,#list do
+ local ll=list[l]
+ if expression(list,ll,l,order) then
+ c=c+1
+ collected[c]=ll
+ end
+ if quit_expression then
+ break
end
+ end
+ return collected
+end
+local function apply_selector(list,specification)
+ if xml.applyselector then
+ apply_selector=xml.applyselector
+ return apply_selector(list,specification)
+ else
+ return list
+ end
end
local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb
local spaces=S(" \n\r\t\f")^0
@@ -17369,24 +17377,24 @@ local lp_doequal=P("=")/"=="
local lp_or=P("|")/" or "
local lp_and=P("&")/" and "
local builtin={
- text="(ll.dt[1] or '')",
- content="ll.dt",
- name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
- tag="ll.tg",
- position="l",
- firstindex="1",
- firstelement="1",
- first="1",
- lastindex="(#ll.__p__.dt or 1)",
- lastelement="(ll.__p__.en or 1)",
- last="#list",
- rootposition="order",
- order="order",
- element="(ll.ei or 1)",
- index="(ll.ni or 1)",
- match="(ll.mi or 1)",
- namespace="ll.ns",
- ns="ll.ns",
+ text="(ll.dt[1] or '')",
+ content="ll.dt",
+ name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
+ tag="ll.tg",
+ position="l",
+ firstindex="1",
+ firstelement="1",
+ first="1",
+ lastindex="(#ll.__p__.dt or 1)",
+ lastelement="(ll.__p__.en or 1)",
+ last="#list",
+ rootposition="order",
+ order="order",
+ element="(ll.ei or 1)",
+ index="(ll.ni or 1)",
+ match="(ll.mi or 1)",
+ namespace="ll.ns",
+ ns="ll.ns",
}
local lp_builtin=lpeg.utfchartabletopattern(builtin)/builtin*((spaces*P("(")*spaces*P(")"))/"")
local lp_attribute=(P("@")+P("attribute::"))/""*Cc("(ll.at and ll.at['")*((R("az","AZ")+S("-_:"))^1)*Cc("'])")
@@ -17396,11 +17404,11 @@ local lp_fastpos=lp_fastpos_n+lp_fastpos_p
local lp_reserved=C("and")+C("or")+C("not")+C("div")+C("mod")+C("true")+C("false")
local lp_lua_function=Cs((R("az","AZ","__")^1*(P(".")*R("az","AZ","__")^1)^1)*("("))/"%0"
local lp_function=C(R("az","AZ","__")^1)*P("(")/function(t)
- if expressions[t] then
- return "expr."..t.."("
- else
- return "expr.error("
- end
+ if expressions[t] then
+ return "expr."..t.."("
+ else
+ return "expr.error("
+ end
end
local lparent=P("(")
local rparent=P(")")
@@ -17413,24 +17421,24 @@ local lp_string=Cc("'")*R("az","AZ","--","__")^1*Cc("'")
local lp_content=(P("'")*(1-P("'"))^0*P("'")+P('"')*(1-P('"'))^0*P('"'))
local cleaner
local lp_special=(C(P("name")+P("text")+P("tag")+P("count")+P("child")))*value/function(t,s)
- if expressions[t] then
- s=s and s~="" and lpegmatch(cleaner,s)
- if s and s~="" then
- return "expr."..t.."(ll,"..s..")"
- else
- return "expr."..t.."(ll)"
- end
+ if expressions[t] then
+ s=s and s~="" and lpegmatch(cleaner,s)
+ if s and s~="" then
+ return "expr."..t.."(ll,"..s..")"
else
- return "expr.error("..t..")"
+ return "expr."..t.."(ll)"
end
+ else
+ return "expr.error("..t..")"
+ end
end
local content=lp_builtin+lp_attribute+lp_special+lp_noequal+lp_doequal+lp_or+lp_and+lp_reserved+lp_lua_function+lp_function+lp_content+
- lp_child+lp_any
+ lp_child+lp_any
local converter=Cs (
- lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
+ lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
)
cleaner=Cs ((
- lp_reserved+lp_number+lp_string+1 )^1 )
+ lp_reserved+lp_number+lp_string+1 )^1 )
local template_e=[[
local expr = xml.expressions
return function(list,ll,l,order)
@@ -17446,75 +17454,75 @@ local template_f_y=[[
local template_f_n=[[
return xml.finalizers['%s']['%s']
]]
-local register_last_match={ kind="axis",axis="last-match" }
-local register_self={ kind="axis",axis="self" }
-local register_parent={ kind="axis",axis="parent" }
-local register_descendant={ kind="axis",axis="descendant" }
-local register_child={ kind="axis",axis="child" }
+local register_last_match={ kind="axis",axis="last-match" }
+local register_self={ kind="axis",axis="self" }
+local register_parent={ kind="axis",axis="parent" }
+local register_descendant={ kind="axis",axis="descendant" }
+local register_child={ kind="axis",axis="child" }
local register_descendant_or_self={ kind="axis",axis="descendant-or-self" }
-local register_root={ kind="axis",axis="root" }
-local register_ancestor={ kind="axis",axis="ancestor" }
-local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
-local register_attribute={ kind="axis",axis="attribute" }
-local register_namespace={ kind="axis",axis="namespace" }
-local register_following={ kind="axis",axis="following" }
+local register_root={ kind="axis",axis="root" }
+local register_ancestor={ kind="axis",axis="ancestor" }
+local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
+local register_attribute={ kind="axis",axis="attribute" }
+local register_namespace={ kind="axis",axis="namespace" }
+local register_following={ kind="axis",axis="following" }
local register_following_sibling={ kind="axis",axis="following-sibling" }
-local register_preceding={ kind="axis",axis="preceding" }
+local register_preceding={ kind="axis",axis="preceding" }
local register_preceding_sibling={ kind="axis",axis="preceding-sibling" }
-local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
+local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
local register_auto_descendant_or_self={ kind="axis",axis="auto-descendant-or-self" }
-local register_auto_descendant={ kind="axis",axis="auto-descendant" }
-local register_auto_self={ kind="axis",axis="auto-self" }
-local register_auto_child={ kind="axis",axis="auto-child" }
-local register_initial_child={ kind="axis",axis="initial-child" }
+local register_auto_descendant={ kind="axis",axis="auto-descendant" }
+local register_auto_self={ kind="axis",axis="auto-self" }
+local register_auto_child={ kind="axis",axis="auto-child" }
+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)
- if not skip[str] then
- report_lpath("error in expression: %s => %s",str,cnv)
- skip[str]=cnv or str
- end
- return false
+ if not skip[str] then
+ report_lpath("error in expression: %s => %s",str,cnv)
+ skip[str]=cnv or str
+ end
+ return false
end
local function errorrunner_f(str,arg)
- report_lpath("error in finalizer: %s(%s)",str,arg or "")
- return false
+ report_lpath("error in finalizer: %s(%s)",str,arg or "")
+ return false
end
local function register_nodes(nodetest,nodes)
- return { kind="nodes",nodetest=nodetest,nodes=nodes }
+ return { kind="nodes",nodetest=nodetest,nodes=nodes }
end
local function register_selector(specification)
- return { kind="selector",specification=specification }
+ return { kind="selector",specification=specification }
end
local function register_expression(expression)
- local converted=lpegmatch(converter,expression)
- local runner=load(format(template_e,converted))
- runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
- return { kind="expression",expression=expression,converted=converted,evaluator=runner }
+ local converted=lpegmatch(converter,expression)
+ local runner=load(format(template_e,converted))
+ runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
+ return { kind="expression",expression=expression,converted=converted,evaluator=runner }
end
local function register_finalizer(protocol,name,arguments)
- local runner
- if arguments and arguments~="" then
- runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
- else
- runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
- end
- runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
- return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
+ local runner
+ if arguments and arguments~="" then
+ runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
+ else
+ runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
+ end
+ runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
+ return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
end
local expression=P { "ex",
- ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
- sq="'"*(1-S("'"))^0*"'",
- dq='"'*(1-S('"'))^0*'"',
+ ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
+ sq="'"*(1-S("'"))^0*"'",
+ dq='"'*(1-S('"'))^0*'"',
}
local arguments=P { "ar",
- ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
- nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
- sq=P("'")*(1-P("'"))^0*P("'"),
- dq=P('"')*(1-P('"'))^0*P('"'),
+ ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
+ nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
+ sq=P("'")*(1-P("'"))^0*P("'"),
+ dq=P('"')*(1-P('"'))^0*P('"'),
}
local function register_error(str)
- return { kind="error",error=format("unparsed: %s",str) }
+ return { kind="error",error=format("unparsed: %s",str) }
end
local special_1=P("*")*Cc(register_auto_descendant)*Cc(register_all_nodes)
local special_2=P("/")*Cc(register_auto_self)
@@ -17522,367 +17530,367 @@ local special_3=P("")*Cc(register_auto_self)
local no_nextcolon=P(-1)+#(1-P(":"))
local no_nextlparent=P(-1)+#(1-P("("))
local pathparser=Ct { "patterns",
- patterns=spaces*V("protocol")*spaces*(
- (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
- ),
- protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
- step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
- axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
- special=special_1+special_2+special_3,
- initial=(P("/")*spaces*Cc(register_initial_child))^-1,
- error=(P(1)^1)/register_error,
- shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
- shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
- s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
- s_descendant=P("**")*Cc(register_descendant),
- s_child=P("*")*no_nextcolon*Cc(register_child),
- s_parent=P("..")*Cc(register_parent),
- s_self=P("." )*Cc(register_self),
- s_root=P("^^")*Cc(register_root),
- s_ancestor=P("^")*Cc(register_ancestor),
- s_lastmatch=P("=")*Cc(register_last_match),
- descendant=P("descendant::")*Cc(register_descendant),
- child=P("child::")*Cc(register_child),
- parent=P("parent::")*Cc(register_parent),
- self=P("self::")*Cc(register_self),
- root=P('root::')*Cc(register_root),
- ancestor=P('ancestor::')*Cc(register_ancestor),
- descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
- ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
- following=P('following::')*Cc(register_following),
- following_sibling=P('following-sibling::')*Cc(register_following_sibling),
- preceding=P('preceding::')*Cc(register_preceding),
- preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
- reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
- last_match=P('last-match::')*Cc(register_last_match),
- selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
- nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
- expressions=expression/register_expression,
- letters=R("az")^1,
- name=(1-S("/[]()|:*!"))^1,
- negate=P("!")*Cc(false),
- nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
- nodetest=V("negate")+Cc(true),
- nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
- wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
- nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
- finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
+ patterns=spaces*V("protocol")*spaces*(
+ (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
+ ),
+ protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
+ step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
+ axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
+ special=special_1+special_2+special_3,
+ initial=(P("/")*spaces*Cc(register_initial_child))^-1,
+ error=(P(1)^1)/register_error,
+ shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
+ shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
+ s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
+ s_descendant=P("**")*Cc(register_descendant),
+ s_child=P("*")*no_nextcolon*Cc(register_child),
+ s_parent=P("..")*Cc(register_parent),
+ s_self=P("." )*Cc(register_self),
+ s_root=P("^^")*Cc(register_root),
+ s_ancestor=P("^")*Cc(register_ancestor),
+ s_lastmatch=P("=")*Cc(register_last_match),
+ descendant=P("descendant::")*Cc(register_descendant),
+ child=P("child::")*Cc(register_child),
+ parent=P("parent::")*Cc(register_parent),
+ self=P("self::")*Cc(register_self),
+ root=P('root::')*Cc(register_root),
+ ancestor=P('ancestor::')*Cc(register_ancestor),
+ descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
+ ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
+ following=P('following::')*Cc(register_following),
+ following_sibling=P('following-sibling::')*Cc(register_following_sibling),
+ preceding=P('preceding::')*Cc(register_preceding),
+ preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
+ reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
+ last_match=P('last-match::')*Cc(register_last_match),
+ selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
+ nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
+ expressions=expression/register_expression,
+ letters=R("az")^1,
+ name=(1-S("/[]()|:*!"))^1,
+ negate=P("!")*Cc(false),
+ nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
+ nodetest=V("negate")+Cc(true),
+ nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
+ wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
+ nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
+ finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
}
xmlpatterns.pathparser=pathparser
local cache={}
local function nodesettostring(set,nodetest)
- local t={}
- for i=1,#set,3 do
- local directive,ns,tg=set[i],set[i+1],set[i+2]
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- t[#t+1]=(directive and tg) or format("not(%s)",tg)
- end
- if nodetest==false then
- return format("not(%s)",concat(t,"|"))
- else
- return concat(t,"|")
- end
+ local t={}
+ for i=1,#set,3 do
+ local directive,ns,tg=set[i],set[i+1],set[i+2]
+ if not ns or ns=="" then ns="*" end
+ if not tg or tg=="" then tg="*" end
+ tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
+ t[#t+1]=(directive and tg) or format("not(%s)",tg)
+ end
+ if nodetest==false then
+ return format("not(%s)",concat(t,"|"))
+ else
+ return concat(t,"|")
+ end
end
local function tagstostring(list)
- if #list==0 then
- return "no elements"
- else
- local t={}
- for i=1,#list do
- local li=list[i]
- local ns,tg=li.ns,li.tg
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- t[i]=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- end
- return concat(t," ")
+ if #list==0 then
+ return "no elements"
+ else
+ local t={}
+ for i=1,#list do
+ local li=list[i]
+ local ns,tg=li.ns,li.tg
+ if not ns or ns=="" then ns="*" end
+ if not tg or tg=="" then tg="*" end
+ t[i]=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
end
+ return concat(t," ")
+ end
end
xml.nodesettostring=nodesettostring
local lpath
local function lshow(parsed)
- if type(parsed)=="string" then
- parsed=lpath(parsed)
- end
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
- table.serialize(parsed,false))
+ if type(parsed)=="string" then
+ parsed=lpath(parsed)
+ end
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
+ table.serialize(parsed,false))
end
xml.lshow=lshow
local function add_comment(p,str)
- local pc=p.comment
- if not pc then
- p.comment={ str }
- else
- pc[#pc+1]=str
- end
+ local pc=p.comment
+ if not pc then
+ p.comment={ str }
+ else
+ pc[#pc+1]=str
+ end
end
lpath=function (pattern)
- lpathcalls=lpathcalls+1
- if type(pattern)=="table" then
- return pattern
- else
- local parsed=cache[pattern]
- if parsed then
- lpathcached=lpathcached+1
+ lpathcalls=lpathcalls+1
+ if type(pattern)=="table" then
+ return pattern
+ else
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcached=lpathcached+1
+ else
+ parsed=lpegmatch(pathparser,pattern)
+ if parsed then
+ parsed.pattern=pattern
+ local np=#parsed
+ if np==0 then
+ parsed={ pattern=pattern,register_self,state="parsing error" }
+ report_lpath("parsing error in pattern: %s",pattern)
+ lshow(parsed)
else
- parsed=lpegmatch(pathparser,pattern)
- if parsed then
- parsed.pattern=pattern
- local np=#parsed
- if np==0 then
- parsed={ pattern=pattern,register_self,state="parsing error" }
- report_lpath("parsing error in pattern: %s",pattern)
- lshow(parsed)
- else
- local pi=parsed[1]
- if pi.axis=="auto-child" then
- if false then
- add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
- parsed[1]=register_auto_descendant_or_self
- else
- add_comment(parsed,"auto-child replaced by auto-descendant")
- parsed[1]=register_auto_descendant
- end
- elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
- add_comment(parsed,"initial-child removed")
- remove(parsed,1)
- end
- local np=#parsed
- if np>1 then
- local pnp=parsed[np]
- if pnp.kind=="nodes" and pnp.nodetest==true then
- local nodes=pnp.nodes
- if nodes[1]==true and nodes[2]==false and nodes[3]==false then
- add_comment(parsed,"redundant final wildcard filter removed")
- remove(parsed,np)
- end
- end
- end
- end
+ local pi=parsed[1]
+ if pi.axis=="auto-child" then
+ if false then
+ add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
+ parsed[1]=register_auto_descendant_or_self
else
- parsed={ pattern=pattern }
+ add_comment(parsed,"auto-child replaced by auto-descendant")
+ parsed[1]=register_auto_descendant
end
- cache[pattern]=parsed
- if trace_lparse and not trace_lprofile then
- lshow(parsed)
+ elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
+ add_comment(parsed,"initial-child removed")
+ remove(parsed,1)
+ end
+ local np=#parsed
+ if np>1 then
+ local pnp=parsed[np]
+ if pnp.kind=="nodes" and pnp.nodetest==true then
+ local nodes=pnp.nodes
+ if nodes[1]==true and nodes[2]==false and nodes[3]==false then
+ add_comment(parsed,"redundant final wildcard filter removed")
+ remove(parsed,np)
+ end
end
+ end
end
- return parsed
+ else
+ parsed={ pattern=pattern }
+ end
+ cache[pattern]=parsed
+ if trace_lparse and not trace_lprofile then
+ lshow(parsed)
+ end
end
+ return parsed
+ end
end
xml.lpath=lpath
do
- local profiled={}
- xml.profiled=profiled
- local lastmatch=nil
- local keepmatch=nil
- if directives then
- directives.register("xml.path.keeplastmatch",function(v)
- keepmatch=v
- lastmatch=nil
- end)
- end
- apply_axis["last-match"]=function()
- return lastmatch or {}
- end
- local function profiled_apply(list,parsed,nofparsed,order)
- local p=profiled[parsed.pattern]
- if p then
- p.tested=p.tested+1
- else
- p={ tested=1,matched=0,finalized=0 }
- profiled[parsed.pattern]=p
- end
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- p.matched=p.matched+1
- p.finalized=p.finalized+1
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- p.finalized=p.finalized+1
- return collected
- end
- return nil
- end
- end
- if collected then
- p.matched=p.matched+1
- end
- return collected
- end
- local function traced_apply(list,parsed,nofparsed,order)
- if trace_lparse then
- lshow(parsed)
- end
- report_lpath("collecting: %s",parsed.pattern)
- report_lpath("root tags : %s",tagstostring(list))
- report_lpath("order : %s",order or "unset")
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
- return collected
- end
- return nil
- end
- end
+ local profiled={}
+ xml.profiled=profiled
+ local lastmatch=nil
+ local keepmatch=nil
+ if directives then
+ directives.register("xml.path.keeplastmatch",function(v)
+ keepmatch=v
+ lastmatch=nil
+ end)
+ end
+ apply_axis["last-match"]=function()
+ return lastmatch or {}
+ end
+ local function profiled_apply(list,parsed,nofparsed,order)
+ local p=profiled[parsed.pattern]
+ if p then
+ p.tested=p.tested+1
+ else
+ p={ tested=1,matched=0,finalized=0 }
+ profiled[parsed.pattern]=p
+ end
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ p.matched=p.matched+1
+ p.finalized=p.finalized+1
return collected
- end
- local function normal_apply(list,parsed,nofparsed,order)
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- local axis=pi.axis
- if axis~="self" then
- collected=apply_axis[axis](collected)
- end
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- return pi.finalizer(collected)
- end
- if not collected or #collected==0 then
- local pf=i<nofparsed and parsed[nofparsed].finalizer
- if pf then
- return pf(collected)
- end
- return nil
- end
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ p.finalized=p.finalized+1
+ return collected
end
- return collected
+ return nil
+ end
end
- local apply=normal_apply
- if trackers then
- trackers.register("xml.path,xml.parse,xml.profile",function()
- if trace_lprofile then
- apply=profiled_apply
- elseif trace_lpath then
- apply=traced_apply
- else
- apply=normal_apply
- end
- end)
+ if collected then
+ p.matched=p.matched+1
end
- function xml.applylpath(list,pattern)
- if not list then
- lastmatch=nil
- return
- end
- local parsed=cache[pattern]
- if parsed then
- lpathcalls=lpathcalls+1
- lpathcached=lpathcached+1
- elseif type(pattern)=="table" then
- lpathcalls=lpathcalls+1
- parsed=pattern
- else
- parsed=lpath(pattern) or pattern
- end
- if not parsed then
- lastmatch=nil
- return
- end
- local nofparsed=#parsed
- if nofparsed==0 then
- lastmatch=nil
- return
- end
- local collected=apply({ list },parsed,nofparsed,list.mi)
- lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ local function traced_apply(list,parsed,nofparsed,order)
+ if trace_lparse then
+ lshow(parsed)
+ end
+ report_lpath("collecting: %s",parsed.pattern)
+ report_lpath("root tags : %s",tagstostring(list))
+ report_lpath("order : %s",order or "unset")
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
return collected
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
+ return collected
+ end
+ return nil
+ end
end
- function xml.lastmatch()
- return lastmatch
- end
- local stack={}
- function xml.pushmatch()
- insert(stack,lastmatch)
- end
- function xml.popmatch()
- lastmatch=remove(stack)
+ return collected
+ end
+ local function normal_apply(list,parsed,nofparsed,order)
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ local axis=pi.axis
+ if axis~="self" then
+ collected=apply_axis[axis](collected)
+ end
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ return pi.finalizer(collected)
+ end
+ if not collected or #collected==0 then
+ local pf=i<nofparsed and parsed[nofparsed].finalizer
+ if pf then
+ return pf(collected)
+ end
+ return nil
+ end
end
+ return collected
+ end
+ local apply=normal_apply
+ if trackers then
+ trackers.register("xml.path,xml.parse,xml.profile",function()
+ if trace_lprofile then
+ apply=profiled_apply
+ elseif trace_lpath then
+ apply=traced_apply
+ else
+ apply=normal_apply
+ end
+ end)
+ end
+ function xml.applylpath(list,pattern)
+ if not list then
+ lastmatch=nil
+ return
+ end
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcalls=lpathcalls+1
+ lpathcached=lpathcached+1
+ elseif type(pattern)=="table" then
+ lpathcalls=lpathcalls+1
+ parsed=pattern
+ else
+ parsed=lpath(pattern) or pattern
+ end
+ if not parsed then
+ lastmatch=nil
+ return
+ end
+ local nofparsed=#parsed
+ if nofparsed==0 then
+ lastmatch=nil
+ return
+ end
+ local collected=apply({ list },parsed,nofparsed,list.mi)
+ lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ function xml.lastmatch()
+ return lastmatch
+ end
+ local stack={}
+ function xml.pushmatch()
+ insert(stack,lastmatch)
+ end
+ function xml.popmatch()
+ lastmatch=remove(stack)
+ end
end
local applylpath=xml.applylpath
function xml.filter(root,pattern)
- return applylpath(root,pattern)
+ return applylpath(root,pattern)
end
expressions.child=function(e,pattern)
- return applylpath(e,pattern)
+ return applylpath(e,pattern)
end
expressions.count=function(e,pattern)
- local collected=applylpath(e,pattern)
- return pattern and (collected and #collected) or 0
+ local collected=applylpath(e,pattern)
+ return pattern and (collected and #collected) or 0
end
expressions.oneof=function(s,...)
- for i=1,select("#",...) do
- if s==select(i,...) then
- return true
- end
+ for i=1,select("#",...) do
+ if s==select(i,...) then
+ return true
end
- return false
+ end
+ return false
end
expressions.error=function(str)
- xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
- return false
+ xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
+ return false
end
expressions.undefined=function(s)
- return s==nil
+ return s==nil
end
expressions.quit=function(s)
- if s or s==nil then
- quit_expression=true
- end
- return true
+ if s or s==nil then
+ quit_expression=true
+ end
+ return true
end
expressions.print=function(...)
- print(...)
- return true
+ print(...)
+ return true
end
expressions.find=find
expressions.upper=upper
@@ -17890,233 +17898,233 @@ expressions.lower=lower
expressions.number=tonumber
expressions.boolean=toboolean
function expressions.contains(str,pattern)
- local t=type(str)
- if t=="string" then
- if find(str,pattern) then
- return true
- end
- elseif t=="table" then
- for i=1,#str do
- local d=str[i]
- if type(d)=="string" and find(d,pattern) then
- return true
- end
- end
+ local t=type(str)
+ if t=="string" then
+ if find(str,pattern) then
+ return true
end
- return false
+ elseif t=="table" then
+ for i=1,#str do
+ local d=str[i]
+ if type(d)=="string" and find(d,pattern) then
+ return true
+ end
+ end
+ end
+ return false
end
function xml.expressions.idstring(str)
- return type(str)=="string" and gsub(str,"^#","") or ""
+ return type(str)=="string" and gsub(str,"^#","") or ""
end
local function traverse(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local r=e.__p__
- handle(r,r.dt,e.ni)
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local r=e.__p__
+ handle(r,r.dt,e.ni)
end
+ end
end
local function selection(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- if handle then
- for c=1,#collected do
- handle(collected[c])
- end
- else
- return collected
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ if handle then
+ for c=1,#collected do
+ handle(collected[c])
+ end
+ else
+ return collected
end
+ end
end
-xml.traverse=traverse
+xml.traverse=traverse
xml.selection=selection
local function dofunction(collected,fnc,...)
- if collected then
- local f=functions[fnc]
- if f then
- for c=1,#collected do
- f(collected[c],...)
- end
- else
- report_lpath("unknown function %a",fnc)
- end
+ if collected then
+ local f=functions[fnc]
+ if f then
+ for c=1,#collected do
+ f(collected[c],...)
+ end
+ else
+ report_lpath("unknown function %a",fnc)
end
+ end
end
finalizers.xml["function"]=dofunction
finalizers.tex["function"]=dofunction
expressions.text=function(e,n)
- local rdt=e.__p__.dt
- return rdt and rdt[n] or ""
+ local rdt=e.__p__.dt
+ return rdt and rdt[n] or ""
end
expressions.name=function(e,n)
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=type(e)=="table" and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=type(e)=="table" and e
+ elseif n<0 then
+ local d,k=e.__p__.dt,e.ni
+ for i=k-1,1,-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
end
+ end
end
- if found then
- local ns,tg=found.rn or found.ns or "",found.tg
- if ns~="" then
- return ns..":"..tg
+ else
+ local d,k=e.__p__.dt,e.ni
+ for i=k+1,#d,1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==1 then
+ found=di
+ break
else
- return tg
+ n=n-1
end
+ end
+ end
+ end
+ if found then
+ local ns,tg=found.rn or found.ns or "",found.tg
+ if ns~="" then
+ return ns..":"..tg
else
- return ""
+ return tg
end
+ else
+ return ""
+ end
end
expressions.tag=function(e,n)
- if not e then
- return ""
+ if not e then
+ return ""
+ else
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=(type(e)=="table") and e
+ elseif n<0 then
+ local d,k=e.__p__.dt,e.ni
+ for i=k-1,1,-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
+ end
+ end
+ end
else
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=(type(e)=="table") and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
- end
+ local d,k=e.__p__.dt,e.ni
+ for i=k+1,#d,1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==1 then
+ found=di
+ break
+ else
+ n=n-1
+ end
end
- return (found and found.tg) or ""
+ end
end
+ return (found and found.tg) or ""
+ end
end
local dummy=function() end
function xml.elements(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
+ end
end
function xml.collected(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ return collected[c]
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- return collected[c]
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- return collected[c]
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ return collected[c]
+ end
end
+ end
end
function xml.inspect(collection,pattern)
- pattern=pattern or "."
- for e in xml.collected(collection,pattern or ".") do
- report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
- end
+ pattern=pattern or "."
+ for e in xml.collected(collection,pattern or ".") do
+ report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
+ end
end
local function split(e)
- local dt=e.dt
- if dt then
- for i=1,#dt do
- local dti=dt[i]
- if type(dti)=="string" then
- dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
- dti=gsub(dti,"[\n\r]+","\n\n")
- dt[i]=dti
- else
- split(dti)
- end
- end
+ local dt=e.dt
+ if dt then
+ for i=1,#dt do
+ local dti=dt[i]
+ if type(dti)=="string" then
+ dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
+ dti=gsub(dti,"[\n\r]+","\n\n")
+ dt[i]=dti
+ else
+ split(dti)
+ end
end
- return e
+ end
+ return e
end
function xml.finalizers.paragraphs(c)
- for i=1,#c do
- split(c[i])
- end
- return c
+ for i=1,#c do
+ split(c[i])
+ end
+ return c
end
@@ -18126,14 +18134,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-mis"] = package.loaded["lxml-mis"] or true
--- original size: 3574, stripped down to: 1863
+-- original size: 3574, stripped down to: 1808
if not modules then modules={} end modules ['lxml-mis']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local xml,lpeg,string=xml,lpeg,string
local type=type
@@ -18144,26 +18152,26 @@ local P,S,R,C,V,Cc,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.Cc,lpeg.Cs
lpegpatterns.xml=lpegpatterns.xml or {}
local xmlpatterns=lpegpatterns.xml
local function xmlgsub(t,old,new)
- local dt=t.dt
- if dt then
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="string" then
- dt[k]=gsub(v,old,new)
- else
- xmlgsub(v,old,new)
- end
- end
+ local dt=t.dt
+ if dt then
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="string" then
+ dt[k]=gsub(v,old,new)
+ else
+ xmlgsub(v,old,new)
+ end
end
+ end
end
function xml.stripleadingspaces(dk,d,k)
- if d and k then
- local dkm=d[k-1]
- if dkm and type(dkm)=="string" then
- local s=match(dkm,"\n(%s+)")
- xmlgsub(dk,"\n"..rep(" ",#s),"\n")
- end
+ if d and k then
+ local dkm=d[k-1]
+ if dkm and type(dkm)=="string" then
+ local s=match(dkm,"\n(%s+)")
+ xmlgsub(dk,"\n"..rep(" ",#s),"\n")
end
+ end
end
local normal=(1-S("<&>"))^0
local special=P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"
@@ -18175,17 +18183,17 @@ local cleansed=Cs(((P("<")*(1-P(">"))^0*P(">"))/""+1)^0)
xmlpatterns.escaped=escaped
xmlpatterns.unescaped=unescaped
xmlpatterns.cleansed=cleansed
-function xml.escaped (str) return lpegmatch(escaped,str) end
+function xml.escaped (str) return lpegmatch(escaped,str) end
function xml.unescaped(str) return lpegmatch(unescaped,str) end
-function xml.cleansed (str) return lpegmatch(cleansed,str) end
+function xml.cleansed (str) return lpegmatch(cleansed,str) end
function xml.fillin(root,pattern,str,check)
- local e=xml.first(root,pattern)
- if e then
- local n=#e.dt
- if not check or n==0 or (n==1 and e.dt[1]=="") then
- e.dt={ str }
- end
+ local e=xml.first(root,pattern)
+ if e then
+ local n=#e.dt
+ if not check or n==0 or (n==1 and e.dt[1]=="") then
+ e.dt={ str }
end
+ end
end
@@ -18195,17 +18203,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-aux"] = package.loaded["lxml-aux"] or true
--- original size: 30650, stripped down to: 21793
+-- original size: 30650, stripped down to: 19621
if not modules then modules={} end modules ['lxml-aux']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
-local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
+local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
+local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
local report_xml=logs.reporter("xml")
local xml=xml
local xmlcopy,xmlname=xml.copy,xml.name
@@ -18218,308 +18226,308 @@ local utfbyte=utf.byte
local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
local striplinepatterns=utilities.strings.striplinepatterns
local function report(what,pattern,c,e)
- report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
+ report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
end
local function withelements(e,handle,depth)
- if e and handle then
- local edt=e.dt
- if edt then
- depth=depth or 0
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- handle(e,depth)
- withelements(e,handle,depth+1)
- end
- end
+ if e and handle then
+ local edt=e.dt
+ if edt then
+ depth=depth or 0
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ handle(e,depth)
+ withelements(e,handle,depth+1)
end
+ end
end
+ end
end
xml.withelements=withelements
function xml.withelement(e,n,handle)
- if e and n~=0 and handle then
- local edt=e.dt
- if edt then
- if n>0 then
- for i=1,#edt do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==1 then
- handle(ei)
- return
- else
- n=n-1
- end
- end
- end
- elseif n<0 then
- for i=#edt,1,-1 do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==-1 then
- handle(ei)
- return
- else
- n=n+1
- end
- end
- end
+ if e and n~=0 and handle then
+ local edt=e.dt
+ if edt then
+ if n>0 then
+ for i=1,#edt do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==1 then
+ handle(ei)
+ return
+ else
+ n=n-1
end
+ end
end
- end
-end
-function xml.each(root,pattern,handle,reverse)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- if handle then
- if reverse then
- for c=#collected,1,-1 do
- handle(collected[c])
- end
+ elseif n<0 then
+ for i=#edt,1,-1 do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==-1 then
+ handle(ei)
+ return
else
- for c=1,#collected do
- handle(collected[c])
- end
+ n=n+1
end
+ end
end
- return collected
+ end
end
+ end
end
-function xml.processattributes(root,pattern,handle)
- local collected=xmlapplylpath(root,pattern)
- if collected and handle then
+function xml.each(root,pattern,handle,reverse)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ if handle then
+ if reverse then
+ for c=#collected,1,-1 do
+ handle(collected[c])
+ end
+ else
for c=1,#collected do
- handle(collected[c].at)
+ handle(collected[c])
end
+ end
end
return collected
+ end
+end
+function xml.processattributes(root,pattern,handle)
+ local collected=xmlapplylpath(root,pattern)
+ if collected and handle then
+ for c=1,#collected do
+ handle(collected[c].at)
+ end
+ end
+ return collected
end
function xml.collect(root,pattern)
- return xmlapplylpath(root,pattern)
+ return xmlapplylpath(root,pattern)
end
function xml.collecttexts(root,pattern,flatten)
- local collected=xmlapplylpath(root,pattern)
- if collected and flatten then
- local xmltostring=xml.tostring
- for c=1,#collected do
- collected[c]=xmltostring(collected[c].dt)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected and flatten then
+ local xmltostring=xml.tostring
+ for c=1,#collected do
+ collected[c]=xmltostring(collected[c].dt)
end
- return collected or {}
+ end
+ return collected or {}
end
function xml.collect_tags(root,pattern,nonamespace)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- local t,n={},0
- for c=1,#collected do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace then
- t[n]=tg
- elseif ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
- end
- return t
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ local t,n={},0
+ for c=1,#collected do
+ local e=collected[c]
+ local ns,tg=e.ns,e.tg
+ n=n+1
+ if nonamespace then
+ t[n]=tg
+ elseif ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
+ end
end
+ return t
+ end
end
local no_root={ no_root=true }
local function redo_ni(d)
- for k=1,#d do
- local dk=d[k]
- if type(dk)=="table" then
- dk.ni=k
- end
+ for k=1,#d do
+ local dk=d[k]
+ if type(dk)=="table" then
+ dk.ni=k
end
+ end
end
xml.reindex=redo_ni
local function xmltoelement(whatever,root)
- if not whatever then
- return nil
- end
- local element
- if type(whatever)=="string" then
- element=xmlinheritedconvert(whatever,root)
- else
- element=whatever
- end
- if element.error then
- return whatever
- end
- if element then
- end
- return element
+ if not whatever then
+ return nil
+ end
+ local element
+ if type(whatever)=="string" then
+ element=xmlinheritedconvert(whatever,root)
+ else
+ element=whatever
+ end
+ if element.error then
+ return whatever
+ end
+ if element then
+ end
+ return element
end
xml.toelement=xmltoelement
local function copiedelement(element,newparent)
- if type(element)=="string" then
- return element
- else
- element=xmlcopy(element).dt
- if newparent and type(element)=="table" then
- element.__p__=newparent
- end
- return element
+ if type(element)=="string" then
+ return element
+ else
+ element=xmlcopy(element).dt
+ if newparent and type(element)=="table" then
+ element.__p__=newparent
end
+ return element
+ end
end
function xml.delete(root,pattern)
- if not pattern or pattern=="" then
- local p=root.__p__
+ if not pattern or pattern=="" then
+ local p=root.__p__
+ if p then
+ if trace_manipulations then
+ report('deleting',"--",c,root)
+ end
+ local d=p.dt
+ remove(d,root.ni)
+ redo_ni(d)
+ end
+ else
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
if p then
- if trace_manipulations then
- report('deleting',"--",c,root)
- end
- local d=p.dt
- remove(d,root.ni)
- redo_ni(d)
- end
- else
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('deleting',pattern,c,e)
- end
- local d=p.dt
- local ni=e.ni
- if ni<=#d then
- if false then
- p.dt[ni]=""
- else
- remove(d,ni)
- redo_ni(d)
- end
- else
- end
- end
+ if trace_manipulations then
+ report('deleting',pattern,c,e)
+ end
+ local d=p.dt
+ local ni=e.ni
+ if ni<=#d then
+ if false then
+ p.dt[ni]=""
+ else
+ remove(d,ni)
+ redo_ni(d)
end
+ else
+ end
end
+ end
end
+ end
end
function xml.replace(root,pattern,whatever)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('replacing',pattern,c,e)
- end
- local d=p.dt
- local n=e.ni
- local t=copiedelement(element,p)
- if type(t)=="table" then
- d[n]=t[1]
- for i=2,#t do
- n=n+1
- insert(d,n,t[i])
- end
- else
- d[n]=t
- end
- redo_ni(d)
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
+ if p then
+ if trace_manipulations then
+ report('replacing',pattern,c,e)
end
+ local d=p.dt
+ local n=e.ni
+ local t=copiedelement(element,p)
+ if type(t)=="table" then
+ d[n]=t[1]
+ for i=2,#t do
+ n=n+1
+ insert(d,n,t[i])
+ end
+ else
+ d[n]=t
+ end
+ redo_ni(d)
+ end
end
+ end
end
local function wrap(e,wrapper)
- local t={
- rn=e.rn,
- tg=e.tg,
- ns=e.ns,
- at=e.at,
- dt=e.dt,
- __p__=e,
- }
- setmetatable(t,getmetatable(e))
- e.rn=wrapper.rn or e.rn or ""
- e.tg=wrapper.tg or e.tg or ""
- e.ns=wrapper.ns or e.ns or ""
- e.at=fastcopy(wrapper.at)
- e.dt={ t }
+ local t={
+ rn=e.rn,
+ tg=e.tg,
+ ns=e.ns,
+ at=e.at,
+ dt=e.dt,
+ __p__=e,
+ }
+ setmetatable(t,getmetatable(e))
+ e.rn=wrapper.rn or e.rn or ""
+ e.tg=wrapper.tg or e.tg or ""
+ e.ns=wrapper.ns or e.ns or ""
+ e.at=fastcopy(wrapper.at)
+ e.dt={ t }
end
function xml.wrap(root,pattern,whatever)
- if whatever then
- local wrapper=xmltoelement(whatever,root)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if trace_manipulations then
- report('wrapping',pattern,c,e)
- end
- wrap(e,wrapper)
- end
+ if whatever then
+ local wrapper=xmltoelement(whatever,root)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if trace_manipulations then
+ report('wrapping',pattern,c,e)
end
- else
- wrap(root,xmltoelement(pattern))
+ wrap(e,wrapper)
+ end
end
+ else
+ wrap(root,xmltoelement(pattern))
+ end
end
local function inject_element(root,pattern,whatever,prepend)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function inject_e(e)
- local r=e.__p__
- local d,k,rri=r.dt,e.ni,r.ri
- local edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
- if edt then
- local be,af
- local cp=copiedelement(element,e)
- if prepend then
- be,af=cp,edt
- else
- be,af=edt,cp
- end
- local bn=#be
- for i=1,#af do
- bn=bn+1
- be[bn]=af[i]
- end
- if rri then
- r.dt[rri].dt=be
- else
- d[k].dt=be
- end
- redo_ni(d)
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ local function inject_e(e)
+ local r=e.__p__
+ local d,k,rri=r.dt,e.ni,r.ri
+ local edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
+ if edt then
+ local be,af
+ local cp=copiedelement(element,e)
+ if prepend then
+ be,af=cp,edt
+ else
+ be,af=edt,cp
+ end
+ local bn=#be
+ for i=1,#af do
+ bn=bn+1
+ be[bn]=af[i]
+ end
+ if rri then
+ r.dt[rri].dt=be
+ else
+ d[k].dt=be
+ end
+ redo_ni(d)
end
- if not collected then
- elseif collected.tg then
- inject_e(collected)
- else
- for c=1,#collected do
- inject_e(collected[c])
- end
+ end
+ if not collected then
+ elseif collected.tg then
+ inject_e(collected)
+ else
+ for c=1,#collected do
+ inject_e(collected[c])
end
+ end
end
local function insert_element(root,pattern,whatever,before)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function insert_e(e)
- local r=e.__p__
- local d,k=r.dt,e.ni
- if not before then
- k=k+1
- end
- insert(d,k,copiedelement(element,r))
- redo_ni(d)
- end
- if not collected then
- elseif collected.tg then
- insert_e(collected)
- else
- for c=1,#collected do
- insert_e(collected[c])
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ local function insert_e(e)
+ local r=e.__p__
+ local d,k=r.dt,e.ni
+ if not before then
+ k=k+1
+ end
+ insert(d,k,copiedelement(element,r))
+ redo_ni(d)
+ end
+ if not collected then
+ elseif collected.tg then
+ insert_e(collected)
+ else
+ for c=1,#collected do
+ insert_e(collected[c])
end
+ end
end
xml.insert_element=insert_element
xml.insertafter=insert_element
@@ -18527,124 +18535,124 @@ xml.insertbefore=function(r,p,e) insert_element(r,p,e,true) end
xml.injectafter=inject_element
xml.injectbefore=function(r,p,e) inject_element(r,p,e,true) end
local function include(xmldata,pattern,attribute,recursive,loaddata,level)
- pattern=pattern or 'include'
- loaddata=loaddata or io.loaddata
- local collected=xmlapplylpath(xmldata,pattern)
- if collected then
- if not level then
- level=1
- end
- for c=1,#collected do
- local ek=collected[c]
- local name=nil
- local ekdt=ek.dt
- if ekdt then
- local ekat=ek.at
- local ekrt=ek.__p__
- if ekrt then
- local epdt=ekrt.dt
- if not attribute or attribute=="" then
- name=(type(ekdt)=="table" and ekdt[1]) or ekdt
- end
- if not name then
- for a in gmatch(attribute or "href","([^|]+)") do
- name=ekat[a]
- if name then
- break
- end
- end
- end
- local data=nil
- if name and name~="" then
- local d,n=loaddata(name)
- data=d or ""
- name=n or name
- if trace_inclusions then
- report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
- end
- end
- if not data or data=="" then
- epdt[ek.ni]=""
- elseif ekat["parse"]=="text" then
- epdt[ek.ni]=xml.escaped(data)
- else
+ pattern=pattern or 'include'
+ loaddata=loaddata or io.loaddata
+ local collected=xmlapplylpath(xmldata,pattern)
+ if collected then
+ if not level then
+ level=1
+ end
+ for c=1,#collected do
+ local ek=collected[c]
+ local name=nil
+ local ekdt=ek.dt
+ if ekdt then
+ local ekat=ek.at
+ local ekrt=ek.__p__
+ if ekrt then
+ local epdt=ekrt.dt
+ if not attribute or attribute=="" then
+ name=(type(ekdt)=="table" and ekdt[1]) or ekdt
+ end
+ if not name then
+ for a in gmatch(attribute or "href","([^|]+)") do
+ name=ekat[a]
+ if name then
+ break
+ end
+ end
+ end
+ local data=nil
+ if name and name~="" then
+ local d,n=loaddata(name)
+ data=d or ""
+ name=n or name
+ if trace_inclusions then
+ report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
+ end
+ end
+ if not data or data=="" then
+ epdt[ek.ni]=""
+ elseif ekat["parse"]=="text" then
+ epdt[ek.ni]=xml.escaped(data)
+ else
local settings=xmldata.settings
local savedresource=settings.currentresource
settings.currentresource=name
- local xi=xmlinheritedconvert(data,xmldata)
- if not xi then
- epdt[ek.ni]=""
- else
- if recursive then
- include(xi,pattern,attribute,recursive,loaddata,level+1)
- end
- local child=xml.body(xi)
- child.__p__=ekrt
- child.__f__=name
+ local xi=xmlinheritedconvert(data,xmldata)
+ if not xi then
+ epdt[ek.ni]=""
+ else
+ if recursive then
+ include(xi,pattern,attribute,recursive,loaddata,level+1)
+ end
+ local child=xml.body(xi)
+ child.__p__=ekrt
+ child.__f__=name
child.cf=name
- epdt[ek.ni]=child
- local settings=xmldata.settings
- local inclusions=settings and settings.inclusions
- if inclusions then
- inclusions[#inclusions+1]=name
- elseif settings then
- settings.inclusions={ name }
- else
- settings={ inclusions={ name } }
- xmldata.settings=settings
- end
- if child.er then
- local badinclusions=settings.badinclusions
- if badinclusions then
- badinclusions[#badinclusions+1]=name
- else
- settings.badinclusions={ name }
- end
- end
- end
-settings.currentresource=savedresource
- end
+ epdt[ek.ni]=child
+ local settings=xmldata.settings
+ local inclusions=settings and settings.inclusions
+ if inclusions then
+ inclusions[#inclusions+1]=name
+ elseif settings then
+ settings.inclusions={ name }
+ else
+ settings={ inclusions={ name } }
+ xmldata.settings=settings
+ end
+ if child.er then
+ local badinclusions=settings.badinclusions
+ if badinclusions then
+ badinclusions[#badinclusions+1]=name
+ else
+ settings.badinclusions={ name }
end
+ end
end
+settings.currentresource=savedresource
+ end
end
+ end
end
+ end
end
xml.include=include
function xml.inclusion(e,default)
- while e do
- local f=e.__f__
- if f then
- return f
- else
- e=e.__p__
- end
+ while e do
+ local f=e.__f__
+ if f then
+ return f
+ else
+ e=e.__p__
end
- return default
+ end
+ return default
end
local function getinclusions(key,e,sorted)
- while e do
- local settings=e.settings
- if settings then
- local inclusions=settings[key]
- if inclusions then
- inclusions=table.unique(inclusions)
- if sorted then
- table.sort(inclusions)
- end
- return inclusions
- else
- e=e.__p__
- end
- else
- e=e.__p__
- end
+ while e do
+ local settings=e.settings
+ if settings then
+ local inclusions=settings[key]
+ if inclusions then
+ inclusions=table.unique(inclusions)
+ if sorted then
+ table.sort(inclusions)
+ end
+ return inclusions
+ else
+ e=e.__p__
+ end
+ else
+ e=e.__p__
end
+ end
end
function xml.inclusions(e,sorted)
- return getinclusions("inclusions",e,sorted)
+ return getinclusions("inclusions",e,sorted)
end
function xml.badinclusions(e,sorted)
- return getinclusions("badinclusions",e,sorted)
+ return getinclusions("badinclusions",e,sorted)
end
local b_collapser=lpegpatterns.b_collapser
local m_collapser=lpegpatterns.m_collapser
@@ -18653,194 +18661,194 @@ local b_stripper=lpegpatterns.b_stripper
local m_stripper=lpegpatterns.m_stripper
local e_stripper=lpegpatterns.e_stripper
local function stripelement(e,nolines,anywhere)
- local edt=e.dt
- if edt then
- local n=#edt
- if n==0 then
- return e
- elseif anywhere then
- local t={}
- local m=0
- for e=1,n do
- local str=edt[e]
- if type(str)~="string" then
- m=m+1
- t[m]=str
- elseif str~="" then
- if nolines then
- str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
- else
- str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
- end
- if str~="" then
- m=m+1
- t[m]=str
- end
- end
- end
- e.dt=t
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==0 then
+ return e
+ elseif anywhere then
+ local t={}
+ local m=0
+ for e=1,n do
+ local str=edt[e]
+ if type(str)~="string" then
+ m=m+1
+ t[m]=str
+ elseif str~="" then
+ if nolines then
+ str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
+ else
+ str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
+ end
+ if str~="" then
+ m=m+1
+ t[m]=str
+ end
+ end
+ end
+ e.dt=t
+ else
+ local str=edt[1]
+ if type(str)=="string" then
+ if str~="" then
+ str=lpegmatch(nolines and b_collapser or b_stripper,str)
+ end
+ if str=="" then
+ remove(edt,1)
+ n=n-1
else
- local str=edt[1]
- if type(str)=="string" then
- if str~="" then
- str=lpegmatch(nolines and b_collapser or b_stripper,str)
- end
- if str=="" then
- remove(edt,1)
- n=n-1
- else
- edt[1]=str
- end
- end
- if n>0 then
- str=edt[n]
- if type(str)=="string" then
- if str=="" then
- remove(edt)
- else
- str=lpegmatch(nolines and e_collapser or e_stripper,str)
- if str=="" then
- remove(edt)
- else
- edt[n]=str
- end
- end
- end
+ edt[1]=str
+ end
+ end
+ if n>0 then
+ str=edt[n]
+ if type(str)=="string" then
+ if str=="" then
+ remove(edt)
+ else
+ str=lpegmatch(nolines and e_collapser or e_stripper,str)
+ if str=="" then
+ remove(edt)
+ else
+ edt[n]=str
end
+ end
end
+ end
end
- return e
+ end
+ return e
end
xml.stripelement=stripelement
function xml.strip(root,pattern,nolines,anywhere)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for i=1,#collected do
- stripelement(collected[i],nolines,anywhere)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for i=1,#collected do
+ stripelement(collected[i],nolines,anywhere)
end
+ end
end
local function renamespace(root,oldspace,newspace)
- local ndt=#root.dt
- for i=1,ndt or 0 do
- local e=root[i]
- if type(e)=="table" then
- if e.ns==oldspace then
- e.ns=newspace
- if e.rn then
- e.rn=newspace
- end
- end
- local edt=e.dt
- if edt then
- renamespace(edt,oldspace,newspace)
- end
+ local ndt=#root.dt
+ for i=1,ndt or 0 do
+ local e=root[i]
+ if type(e)=="table" then
+ if e.ns==oldspace then
+ e.ns=newspace
+ if e.rn then
+ e.rn=newspace
end
+ end
+ local edt=e.dt
+ if edt then
+ renamespace(edt,oldspace,newspace)
+ end
end
+ end
end
xml.renamespace=renamespace
function xml.remaptag(root,pattern,newtg)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].tg=newtg
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].tg=newtg
end
+ end
end
function xml.remapnamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].ns=newns
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].ns=newns
end
+ end
end
function xml.checknamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if (not e.rn or e.rn=="") and e.ns=="" then
- e.rn=newns
- end
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if (not e.rn or e.rn=="") and e.ns=="" then
+ e.rn=newns
+ end
end
+ end
end
function xml.remapname(root,pattern,newtg,newns,newrn)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- e.tg,e.ns,e.rn=newtg,newns,newrn
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ e.tg,e.ns,e.rn=newtg,newns,newrn
end
+ end
end
function xml.cdatatotext(e)
- local dt=e.dt
- if #dt==1 then
- local first=dt[1]
- if first.tg=="@cd@" then
- e.dt=first.dt
- end
- else
+ local dt=e.dt
+ if #dt==1 then
+ local first=dt[1]
+ if first.tg=="@cd@" then
+ e.dt=first.dt
end
+ else
+ end
end
function xml.texttocdata(e)
- local dt=e.dt
- local s=xml.tostring(dt)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(dt)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
function xml.elementtocdata(e)
- local dt=e.dt
- local s=xml.tostring(e)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(e)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
xml.builtinentities=table.tohash { "amp","quot","apos","lt","gt" }
local entities=characters and characters.entities or nil
local builtinentities=xml.builtinentities
function xml.addentitiesdoctype(root,option)
- if not entities then
- require("char-ent")
- entities=characters.entities
- end
- if entities and root and root.tg=="@rt@" and root.statistics then
- local list={}
- local hexify=option=="hexadecimal"
- for k,v in table.sortedhash(root.statistics.entities.names) do
- if not builtinentities[k] then
- local e=entities[k]
- if not e then
- e=format("[%s]",k)
- elseif hexify then
- e=format("&#%05X;",utfbyte(k))
- end
- list[#list+1]=format(" <!ENTITY %s %q >",k,e)
- end
- end
- local dt=root.dt
- local n=dt[1].tg=="@pi@" and 2 or 1
- if #list>0 then
- insert(dt,n,{ "\n" })
- insert(dt,n,{
- tg="@dt@",
- dt={ format("Something [\n%s\n] ",concat(list)) },
- ns="",
- special=true,
- })
- insert(dt,n,{ "\n\n" })
- else
- end
+ if not entities then
+ require("char-ent")
+ entities=characters.entities
+ end
+ if entities and root and root.tg=="@rt@" and root.statistics then
+ local list={}
+ local hexify=option=="hexadecimal"
+ for k,v in table.sortedhash(root.statistics.entities.names) do
+ if not builtinentities[k] then
+ local e=entities[k]
+ if not e then
+ e=format("[%s]",k)
+ elseif hexify then
+ e=format("&#%05X;",utfbyte(k))
+ end
+ list[#list+1]=format(" <!ENTITY %s %q >",k,e)
+ end
end
+ local dt=root.dt
+ local n=dt[1].tg=="@pi@" and 2 or 1
+ if #list>0 then
+ insert(dt,n,{ "\n" })
+ insert(dt,n,{
+ tg="@dt@",
+ dt={ format("Something [\n%s\n] ",concat(list)) },
+ ns="",
+ special=true,
+ })
+ insert(dt,n,{ "\n\n" })
+ else
+ end
+ end
end
xml.all=xml.each
xml.insert=xml.insertafter
@@ -18850,239 +18858,239 @@ xml.before=xml.insertbefore
xml.process=xml.each
xml.obsolete=xml.obsolete or {}
local obsolete=xml.obsolete
-xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
-xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
-xml.delete_element=xml.delete obsolete.delete_element=xml.delete
-xml.replace_element=xml.replace obsolete.replace_element=xml.replace
-xml.each_element=xml.each obsolete.each_element=xml.each
-xml.process_elements=xml.process obsolete.process_elements=xml.process
-xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
-xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
-xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
-xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
-xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
-xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
-xml.inject_element=xml.inject obsolete.inject_element=xml.inject
-xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
-xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
-xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
+xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
+xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
+xml.delete_element=xml.delete obsolete.delete_element=xml.delete
+xml.replace_element=xml.replace obsolete.replace_element=xml.replace
+xml.each_element=xml.each obsolete.each_element=xml.each
+xml.process_elements=xml.process obsolete.process_elements=xml.process
+xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
+xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
+xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
+xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
+xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
+xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
+xml.inject_element=xml.inject obsolete.inject_element=xml.inject
+xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
+xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
+xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
function xml.cdata(e)
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
end
- return ""
+ end
+ return ""
end
function xml.finalizers.xml.cdata(collected)
- if collected then
- local e=collected[1]
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
- end
+ if collected then
+ local e=collected[1]
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
+ end
end
- return ""
+ end
+ return ""
end
function xml.insertcomment(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.insertcdata(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.setcomment(e,str,n)
- e.dt={ {
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.setcdata(e,str)
- e.dt={ {
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.separate(x,pattern)
- local collected=xmlapplylpath(x,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local d=e.dt
- if d==x then
- report_xml("warning: xml.separate changes root")
- x=d
- end
- local t,n={ "\n" },1
- local i,nd=1,#d
- while i<=nd do
- while i<=nd do
- local di=d[i]
- if type(di)=="string" then
- if di=="\n" or find(di,"^%s+$") then
- i=i+1
- else
- d[i]=strip(di)
- break
- end
- else
- break
- end
- end
- if i>nd then
- break
- end
- t[n+1]="\n"
- t[n+2]=d[i]
- t[n+3]="\n"
- n=n+3
- i=i+1
+ local collected=xmlapplylpath(x,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local d=e.dt
+ if d==x then
+ report_xml("warning: xml.separate changes root")
+ x=d
+ end
+ local t,n={ "\n" },1
+ local i,nd=1,#d
+ while i<=nd do
+ while i<=nd do
+ local di=d[i]
+ if type(di)=="string" then
+ if di=="\n" or find(di,"^%s+$") then
+ i=i+1
+ else
+ d[i]=strip(di)
+ break
end
- t[n+1]="\n"
- setmetatable(t,getmetatable(d))
- e.dt=t
+ else
+ break
+ end
end
+ if i>nd then
+ break
+ end
+ t[n+1]="\n"
+ t[n+2]=d[i]
+ t[n+3]="\n"
+ n=n+3
+ i=i+1
+ end
+ t[n+1]="\n"
+ setmetatable(t,getmetatable(d))
+ e.dt=t
end
- return x
+ end
+ return x
end
local helpers=xml.helpers or {}
xml.helpers=helpers
local function normal(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)=="string" and str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)=="string" and str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
local function recurse(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)~="string" then
- recurse(str,action)
- elseif str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)~="string" then
+ recurse(str,action)
+ elseif str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
function helpers.recursetext(collected,action,recursive)
- if recursive then
- for i=1,#collected do
- recurse(collected[i],action)
- end
- else
- for i=1,#collected do
- normal(collected[i],action)
- end
+ if recursive then
+ for i=1,#collected do
+ recurse(collected[i],action)
+ end
+ else
+ for i=1,#collected do
+ normal(collected[i],action)
end
+ end
end
local specials={
- ["@rt@"]="root",
- ["@pi@"]="instruction",
- ["@cm@"]="comment",
- ["@dt@"]="declaration",
- ["@cd@"]="cdata",
+ ["@rt@"]="root",
+ ["@pi@"]="instruction",
+ ["@cm@"]="comment",
+ ["@dt@"]="declaration",
+ ["@cd@"]="cdata",
}
local function convert(x,strip,flat)
- local ns=x.ns
- local tg=x.tg
- local at=x.at
- local dt=x.dt
- local node=flat and {
- [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
- } or {
- _namespace=ns~="" and ns or nil,
- _tag=not x.special and tg or nil,
- _type=specials[tg] or "_element",
- }
- if at then
- for k,v in next,at do
- node[k]=v
+ local ns=x.ns
+ local tg=x.tg
+ local at=x.at
+ local dt=x.dt
+ local node=flat and {
+ [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
+ } or {
+ _namespace=ns~="" and ns or nil,
+ _tag=not x.special and tg or nil,
+ _type=specials[tg] or "_element",
+ }
+ if at then
+ for k,v in next,at do
+ node[k]=v
+ end
+ end
+ local n=0
+ for i=1,#dt do
+ local di=dt[i]
+ if type(di)=="table" then
+ if flat and di.special then
+ else
+ di=convert(di,strip,flat)
+ if di then
+ n=n+1
+ node[n]=di
end
+ end
+ elseif strip then
+ di=lpegmatch(strip,di)
+ if di~="" then
+ n=n+1
+ node[n]=di
+ end
+ else
+ n=n+1
+ node[n]=di
end
- local n=0
- for i=1,#dt do
- local di=dt[i]
- if type(di)=="table" then
- if flat and di.special then
- else
- di=convert(di,strip,flat)
- if di then
- n=n+1
- node[n]=di
- end
- end
- elseif strip then
- di=lpegmatch(strip,di)
- if di~="" then
- n=n+1
- node[n]=di
- end
- else
- n=n+1
- node[n]=di
- end
- end
- if next(node) then
- return node
- end
+ end
+ if next(node) then
+ return node
+ end
end
function xml.totable(x,strip,flat)
- if type(x)=="table" then
- if strip then
- strip=striplinepatterns[strip]
- end
- return convert(x,strip,flat)
+ if type(x)=="table" then
+ if strip then
+ strip=striplinepatterns[strip]
end
+ return convert(x,strip,flat)
+ end
end
function xml.rename(e,namespace,name,attributes)
- if type(e)~="table" or not e.tg then
- return
- end
- if type(name)=="table" then
- attributes=name
- name=namespace
- namespace=""
- elseif type(name)~="string" then
- attributes={}
- name=namespace
- namespace=""
- end
- if type(attributes)~="table" then
- attributes={}
- end
- e.ns=namespace
- e.rn=namespace
- e.tg=name
- e.at=attributes
+ if type(e)~="table" or not e.tg then
+ return
+ end
+ if type(name)=="table" then
+ attributes=name
+ name=namespace
+ namespace=""
+ elseif type(name)~="string" then
+ attributes={}
+ name=namespace
+ namespace=""
+ end
+ if type(attributes)~="table" then
+ attributes={}
+ end
+ e.ns=namespace
+ e.rn=namespace
+ e.tg=name
+ e.at=attributes
end
@@ -19092,14 +19100,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
--- original size: 11096, stripped down to: 8243
+-- original size: 11096, stripped down to: 7702
if not modules then modules={} end modules ['lxml-xml']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber,next=tonumber,next
local concat=table.concat
@@ -19111,241 +19119,241 @@ local xmltostring=xml.tostring
local xmlserialize=xml.serialize
local xmlcollected=xml.collected
local xmlnewhandlers=xml.newhandlers
-local reparsedentity=xml.reparsedentitylpeg
+local reparsedentity=xml.reparsedentitylpeg
local unescapedentity=xml.unescapedentitylpeg
local parsedentity=reparsedentity
local function first(collected)
- return collected and collected[1]
+ return collected and collected[1]
end
local function last(collected)
- return collected and collected[#collected]
+ return collected and collected[#collected]
end
local function all(collected)
- return collected
+ return collected
end
local reverse=table.reversed
local function attribute(collected,name)
- if collected and #collected>0 then
- local at=collected[1].at
- return at and at[name]
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ return at and at[name]
+ end
end
local function att(id,name)
- local at=id.at
- return at and at[name]
+ local at=id.at
+ return at and at[name]
end
local function count(collected)
- return collected and #collected or 0
+ return collected and #collected or 0
end
local function position(collected,n)
- if not collected then
- return 0
- end
- local nc=#collected
- if nc==0 then
- return 0
- end
- n=tonumber(n) or 0
- if n<0 then
- return collected[nc+n+1]
- elseif n>0 then
- return collected[n]
- else
- return collected[1].mi or 0
- end
+ if not collected then
+ return 0
+ end
+ local nc=#collected
+ if nc==0 then
+ return 0
+ end
+ n=tonumber(n) or 0
+ if n<0 then
+ return collected[nc+n+1]
+ elseif n>0 then
+ return collected[n]
+ else
+ return collected[1].mi or 0
+ end
end
local function match(collected)
- return collected and #collected>0 and collected[1].mi or 0
+ return collected and #collected>0 and collected[1].mi or 0
end
local function index(collected)
- return collected and #collected>0 and collected[1].ni or 0
+ return collected and #collected>0 and collected[1].ni or 0
end
local function attributes(collected,arguments)
- if collected and #collected>0 then
- local at=collected[1].at
- if arguments then
- return at[arguments]
- elseif next(at) then
- return at
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ if arguments then
+ return at[arguments]
+ elseif next(at) then
+ return at
end
+ end
end
local function chainattribute(collected,arguments)
- if collected and #collected>0 then
- local e=collected[1]
- while e do
- local at=e.at
- if at then
- local a=at[arguments]
- if a then
- return a
- end
- else
- break
- end
- e=e.__p__
+ if collected and #collected>0 then
+ local e=collected[1]
+ while e do
+ local at=e.at
+ if at then
+ local a=at[arguments]
+ if a then
+ return a
end
+ else
+ break
+ end
+ e=e.__p__
end
- return ""
+ end
+ return ""
end
local function raw(collected)
- if collected and #collected>0 then
- local e=collected[1] or collected
- return e and xmltostring(e) or ""
- else
- return ""
- end
+ if collected and #collected>0 then
+ local e=collected[1] or collected
+ return e and xmltostring(e) or ""
+ else
+ return ""
+ end
end
local xmltexthandler=xmlnewhandlers {
- name="string",
- initialize=function()
- result={}
- return result
- end,
- finalize=function()
- return concat(result)
- end,
- handle=function(...)
- result[#result+1]=concat {... }
- end,
- escape=false,
+ name="string",
+ initialize=function()
+ result={}
+ return result
+ end,
+ finalize=function()
+ return concat(result)
+ end,
+ handle=function(...)
+ result[#result+1]=concat {... }
+ end,
+ escape=false,
}
local function xmltotext(root)
- local dt=root.dt
- if not dt then
- return ""
- end
- local nt=#dt
- if nt==0 then
- return ""
- elseif nt==1 and type(dt[1])=="string" then
- return dt[1]
- else
- return xmlserialize(root,xmltexthandler) or ""
- end
+ local dt=root.dt
+ if not dt then
+ return ""
+ end
+ local nt=#dt
+ if nt==0 then
+ return ""
+ elseif nt==1 and type(dt[1])=="string" then
+ return dt[1]
+ else
+ return xmlserialize(root,xmltexthandler) or ""
+ end
end
function xml.serializetotext(root)
- return root and xmlserialize(root,xmltexthandler) or ""
+ return root and xmlserialize(root,xmltexthandler) or ""
end
local function text(collected)
- if collected then
- local e=collected[1] or collected
- return e and xmltotext(e) or ""
- else
- return ""
- end
+ if collected then
+ local e=collected[1] or collected
+ return e and xmltotext(e) or ""
+ else
+ return ""
+ end
end
local function texts(collected)
- if not collected then
- return {}
- end
- local nc=#collected
- if nc==0 then
- return {}
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- if e and e.dt then
- n=n+1
- t[n]=e.dt
- end
- end
- return t
+ if not collected then
+ return {}
+ end
+ local nc=#collected
+ if nc==0 then
+ return {}
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ if e and e.dt then
+ n=n+1
+ t[n]=e.dt
+ end
+ end
+ return t
end
local function tag(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- return c and c.tg
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ return c and c.tg
end
local function name(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- if not c then
- elseif c.ns=="" then
- return c.tg
- else
- return c.ns..":"..c.tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ if not c then
+ elseif c.ns=="" then
+ return c.tg
+ else
+ return c.ns..":"..c.tg
+ end
end
local function tags(collected,nonamespace)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace or ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ local ns,tg=e.ns,e.tg
+ n=n+1
+ if nonamespace or ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
end
- return t
+ end
+ return t
end
local function empty(collected,spacesonly)
- if not collected then
- return true
- end
- local nc=#collected
- if nc==0 then
- return true
- end
- for c=1,nc do
- local e=collected[c]
- if e then
- local edt=e.dt
- if edt then
- local n=#edt
- if n==1 then
- local edk=edt[1]
- local typ=type(edk)
- if typ=="table" then
- return false
- elseif edk~="" then
- return false
- elseif spacesonly and not find(edk,"%S") then
- return false
- end
- elseif n>1 then
- return false
- end
- end
+ if not collected then
+ return true
+ end
+ local nc=#collected
+ if nc==0 then
+ return true
+ end
+ for c=1,nc do
+ local e=collected[c]
+ if e then
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==1 then
+ local edk=edt[1]
+ local typ=type(edk)
+ if typ=="table" then
+ return false
+ elseif edk~="" then
+ return false
+ elseif spacesonly and not find(edk,"%S") then
+ return false
+ end
+ elseif n>1 then
+ return false
end
+ end
end
- return true
+ end
+ return true
end
finalizers.first=first
finalizers.last=last
@@ -19368,124 +19376,124 @@ finalizers.name=name
finalizers.tags=tags
finalizers.empty=empty
function xml.first(id,pattern)
- return first(xmlfilter(id,pattern))
+ return first(xmlfilter(id,pattern))
end
function xml.last(id,pattern)
- return last(xmlfilter(id,pattern))
+ return last(xmlfilter(id,pattern))
end
function xml.count(id,pattern)
- return count(xmlfilter(id,pattern))
+ return count(xmlfilter(id,pattern))
end
function xml.attribute(id,pattern,a,default)
- return attribute(xmlfilter(id,pattern),a,default)
+ return attribute(xmlfilter(id,pattern),a,default)
end
function xml.raw(id,pattern)
- if pattern then
- return raw(xmlfilter(id,pattern))
- else
- return raw(id)
- end
+ if pattern then
+ return raw(xmlfilter(id,pattern))
+ else
+ return raw(id)
+ end
end
function xml.text(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- return collected and #collected>0 and xmltotext(collected[1]) or ""
- elseif id then
- return xmltotext(id) or ""
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ return collected and #collected>0 and xmltotext(collected[1]) or ""
+ elseif id then
+ return xmltotext(id) or ""
+ else
+ return ""
+ end
end
function xml.pure(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- if collected and #collected>0 then
- parsedentity=unescapedentity
- local s=collected and #collected>0 and xmltotext(collected[1]) or ""
- parsedentity=reparsedentity
- return s
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ if collected and #collected>0 then
+ parsedentity=unescapedentity
+ local s=collected and #collected>0 and xmltotext(collected[1]) or ""
+ parsedentity=reparsedentity
+ return s
else
- parsedentity=unescapedentity
- local s=xmltotext(id) or ""
- parsedentity=reparsedentity
- return s
+ return ""
end
+ else
+ parsedentity=unescapedentity
+ local s=xmltotext(id) or ""
+ parsedentity=reparsedentity
+ return s
+ end
end
xml.content=text
function xml.position(id,pattern,n)
- return position(xmlfilter(id,pattern),n)
+ return position(xmlfilter(id,pattern),n)
end
function xml.match(id,pattern)
- return match(xmlfilter(id,pattern))
+ return match(xmlfilter(id,pattern))
end
function xml.empty(id,pattern,spacesonly)
- return empty(xmlfilter(id,pattern),spacesonly)
+ return empty(xmlfilter(id,pattern),spacesonly)
end
xml.all=xml.filter
xml.index=xml.position
xml.found=xml.filter
local function totable(x)
- local t={}
- for e in xmlcollected(x[1] or x,"/*") do
- t[e.tg]=xmltostring(e.dt) or ""
- end
- return next(t) and t or nil
+ local t={}
+ for e in xmlcollected(x[1] or x,"/*") do
+ t[e.tg]=xmltostring(e.dt) or ""
+ end
+ return next(t) and t or nil
end
xml.table=totable
finalizers.table=totable
local function textonly(e,t)
- if e then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- textonly(e,t)
- else
- t[#t+1]=e
- end
- end
+ if e then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ textonly(e,t)
+ else
+ t[#t+1]=e
end
+ end
end
- return t
+ end
+ return t
end
function xml.textonly(e)
- return concat(textonly(e,{}))
+ return concat(textonly(e,{}))
end
function finalizers.lowerall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=lower(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[lower(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=lower(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[lower(k)]=v
end
+ e.at=t
+ end
end
+ end
end
function finalizers.upperall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=upper(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[upper(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=upper(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[upper(k)]=v
end
+ e.at=t
+ end
end
+ end
end
@@ -19495,14 +19503,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-xml"] = package.loaded["trac-xml"] or true
--- original size: 6407, stripped down to: 4965
+-- original size: 6407, stripped down to: 4640
if not modules then modules={} end modules ['trac-xml']={
- version=1.001,
- comment="companion to trac-log.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local formatters=string.formatters
local reporters=logs.reporters
@@ -19511,152 +19519,152 @@ local xmlcollected=xml.collected
local xmltext=xml.text
local xmlfirst=xml.first
local function showhelp(specification,...)
- local root=xml.convert(specification.helpinfo or "")
- if not root then
- return
- end
- local xs=xml.gethandlers("string")
- xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
- xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
- local wantedcategories=select("#",...)==0 and true or table.tohash {... }
- local nofcategories=xml.count(root,"/application/flags/category")
- local report=specification.report
- for category in xmlcollected(root,"/application/flags/category") do
- local categoryname=category.at.name or ""
- if wantedcategories==true or wantedcategories[categoryname] then
- if nofcategories>1 then
- report("%s options:",categoryname)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for flag in xmlcollected(subcategory,"/flag") do
- local name=flag.at.name
- local value=flag.at.value
- local short=xmltext(xmlfirst(flag,"/short"))
- if value then
- report("--%-20s %s",formatters["%s=%s"](name,value),short)
- else
- report("--%-20s %s",name,short)
- end
- end
- report()
- end
- end
- end
- for category in xmlcollected(root,"/application/examples/category") do
- local title=xmltext(xmlfirst(category,"/title"))
- if title and title~="" then
- report()
- report(title)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for example in xmlcollected(subcategory,"/example") do
- local command=xmltext(xmlfirst(example,"/command"))
- local comment=xmltext(xmlfirst(example,"/comment"))
- report(command)
- end
- report()
- end
- end
- for comment in xmlcollected(root,"/application/comments/comment") do
- local comment=xmltext(comment)
+ local root=xml.convert(specification.helpinfo or "")
+ if not root then
+ return
+ end
+ local xs=xml.gethandlers("string")
+ xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
+ xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
+ local wantedcategories=select("#",...)==0 and true or table.tohash {... }
+ local nofcategories=xml.count(root,"/application/flags/category")
+ local report=specification.report
+ for category in xmlcollected(root,"/application/flags/category") do
+ local categoryname=category.at.name or ""
+ if wantedcategories==true or wantedcategories[categoryname] then
+ if nofcategories>1 then
+ report("%s options:",categoryname)
report()
- report(comment)
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for flag in xmlcollected(subcategory,"/flag") do
+ local name=flag.at.name
+ local value=flag.at.value
+ local short=xmltext(xmlfirst(flag,"/short"))
+ if value then
+ report("--%-20s %s",formatters["%s=%s"](name,value),short)
+ else
+ report("--%-20s %s",name,short)
+ end
+ end
report()
+ end
+ end
+ end
+ for category in xmlcollected(root,"/application/examples/category") do
+ local title=xmltext(xmlfirst(category,"/title"))
+ if title and title~="" then
+ report()
+ report(title)
+ report()
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for example in xmlcollected(subcategory,"/example") do
+ local command=xmltext(xmlfirst(example,"/command"))
+ local comment=xmltext(xmlfirst(example,"/comment"))
+ report(command)
+ end
+ report()
end
+ end
+ for comment in xmlcollected(root,"/application/comments/comment") do
+ local comment=xmltext(comment)
+ report()
+ report(comment)
+ report()
+ end
end
local reporthelp=reporters.help
local exporthelp=reporters.export
local function xmlfound(t)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="table" then
- return false
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="table" then
+ return false
+ end
+ if type(helpinfo)~="string" then
+ helpinfo="Warning: no helpinfo found."
+ t.helpinfo=helpinfo
+ return false
+ end
+ if string.find(helpinfo,".xml$") then
+ local ownscript=environment.ownscript
+ local helpdata=false
+ if ownscript then
+ local helpfile=file.join(file.pathpart(ownscript),helpinfo)
+ helpdata=io.loaddata(helpfile)
+ if helpdata=="" then
+ helpdata=false
+ end
end
- if type(helpinfo)~="string" then
- helpinfo="Warning: no helpinfo found."
- t.helpinfo=helpinfo
- return false
+ if not helpdata then
+ local helpfile=resolvers.findfile(helpinfo,"tex")
+ helpdata=helpfile and io.loaddata(helpfile)
end
- if string.find(helpinfo,".xml$") then
- local ownscript=environment.ownscript
- local helpdata=false
- if ownscript then
- local helpfile=file.join(file.pathpart(ownscript),helpinfo)
- helpdata=io.loaddata(helpfile)
- if helpdata=="" then
- helpdata=false
- end
- end
- if not helpdata then
- local helpfile=resolvers.findfile(helpinfo,"tex")
- helpdata=helpfile and io.loaddata(helpfile)
- end
- if helpdata and helpdata~="" then
- helpinfo=helpdata
- else
- helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
- end
+ if helpdata and helpdata~="" then
+ helpinfo=helpdata
+ else
+ helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
end
- t.helpinfo=helpinfo
- return string.find(t.helpinfo,"^<%?xml") and true or false
+ end
+ t.helpinfo=helpinfo
+ return string.find(t.helpinfo,"^<%?xml") and true or false
end
function reporters.help(t,...)
- if xmlfound(t) then
- showhelp(t,...)
- else
- reporthelp(t,...)
- end
+ if xmlfound(t) then
+ showhelp(t,...)
+ else
+ reporthelp(t,...)
+ end
end
function reporters.export(t,methods,filename)
- if not xmlfound(t) then
- return exporthelp(t)
- end
- if not methods or methods=="" then
- methods=environment.arguments["exporthelp"]
- end
- if not filename or filename=="" then
- filename=environment.files[1]
- end
- dofile(resolvers.findfile("trac-exp.lua","tex"))
- local exporters=logs.exporters
- if not exporters or not methods then
- return exporthelp(t)
- end
- if methods=="all" then
- methods=table.keys(exporters)
- elseif type(methods)=="string" then
- methods=utilities.parsers.settings_to_array(methods)
- else
- return exporthelp(t)
- end
- if type(filename)~="string" or filename=="" then
- filename=false
- elseif file.pathpart(filename)=="" then
- t.report("export file %a will not be saved on the current path (safeguard)",filename)
- return
- end
- for i=1,#methods do
- local method=methods[i]
- local exporter=exporters[method]
- if exporter then
- local result=exporter(t,method)
- if result and result~="" then
- if filename then
- local fullname=file.replacesuffix(filename,method)
- t.report("saving export in %a",fullname)
- dir.mkdirs(file.pathpart(fullname))
- io.savedata(fullname,result)
- else
- reporters.lines(t,result)
- end
- else
- t.report("no output from exporter %a",method)
- end
+ if not xmlfound(t) then
+ return exporthelp(t)
+ end
+ if not methods or methods=="" then
+ methods=environment.arguments["exporthelp"]
+ end
+ if not filename or filename=="" then
+ filename=environment.files[1]
+ end
+ dofile(resolvers.findfile("trac-exp.lua","tex"))
+ local exporters=logs.exporters
+ if not exporters or not methods then
+ return exporthelp(t)
+ end
+ if methods=="all" then
+ methods=table.keys(exporters)
+ elseif type(methods)=="string" then
+ methods=utilities.parsers.settings_to_array(methods)
+ else
+ return exporthelp(t)
+ end
+ if type(filename)~="string" or filename=="" then
+ filename=false
+ elseif file.pathpart(filename)=="" then
+ t.report("export file %a will not be saved on the current path (safeguard)",filename)
+ return
+ end
+ for i=1,#methods do
+ local method=methods[i]
+ local exporter=exporters[method]
+ if exporter then
+ local result=exporter(t,method)
+ if result and result~="" then
+ if filename then
+ local fullname=file.replacesuffix(filename,method)
+ t.report("saving export in %a",fullname)
+ dir.mkdirs(file.pathpart(fullname))
+ io.savedata(fullname,result)
else
- t.report("unknown exporter %a",method)
+ reporters.lines(t,result)
end
+ else
+ t.report("no output from exporter %a",method)
+ end
+ else
+ t.report("unknown exporter %a",method)
end
+ end
end
@@ -19666,149 +19674,149 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-ini"] = package.loaded["data-ini"] or true
--- original size: 11099, stripped down to: 7516
+-- original size: 11099, stripped down to: 7152
if not modules then modules={} end modules ['data-ini']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local next,type,getmetatable,rawset=next,type,getmetatable,rawset
local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char
local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join
local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv
local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
local report_initialization=logs.reporter("resolvers","initialization")
resolvers=resolvers or {}
local resolvers=resolvers
texconfig.kpse_init=false
texconfig.shell_escape='t'
if not (environment and environment.default_texmfcnf) and kpse and kpse.default_texmfcnf then
- local default_texmfcnf=kpse.default_texmfcnf()
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
- default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
- environment.default_texmfcnf=default_texmfcnf
+ local default_texmfcnf=kpse.default_texmfcnf()
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
+ default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
+ environment.default_texmfcnf=default_texmfcnf
end
kpse={ original=kpse }
setmetatable(kpse,{
- __index=function(kp,name)
- report_initialization("fatal error: kpse library is accessed (key: %s)",name)
- os.exit()
- end
+ __index=function(kp,name)
+ report_initialization("fatal error: kpse library is accessed (key: %s)",name)
+ os.exit()
+ end
} )
do
- local osfontdir=osgetenv("OSFONTDIR")
- if osfontdir and osfontdir~="" then
- elseif osname=="windows" then
- ossetenv("OSFONTDIR","c:/windows/fonts//")
- elseif osname=="macosx" then
- ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
- end
+ local osfontdir=osgetenv("OSFONTDIR")
+ if osfontdir and osfontdir~="" then
+ elseif osname=="windows" then
+ ossetenv("OSFONTDIR","c:/windows/fonts//")
+ elseif osname=="macosx" then
+ ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
+ end
end
do
- local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
- if not homedir or homedir=="" then
- homedir=char(127)
- end
- homedir=file.collapsepath(homedir)
- ossetenv("HOME",homedir)
- ossetenv("USERPROFILE",homedir)
- environment.homedir=homedir
+ local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
+ if not homedir or homedir=="" then
+ homedir=char(127)
+ end
+ homedir=file.collapsepath(homedir)
+ ossetenv("HOME",homedir)
+ ossetenv("USERPROFILE",homedir)
+ environment.homedir=homedir
end
do
- local args=environment.originalarguments or arg
- if not environment.ownmain then
- environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
- end
- local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
- local ownpath=environment.ownpath or os.selfdir
- ownbin=file.collapsepath(ownbin)
- ownpath=file.collapsepath(ownpath)
- if not ownpath or ownpath=="" or ownpath=="unset" then
- ownpath=args[-1] or arg[-1]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- if not ownpath or ownpath=="" then
- ownpath=args[-0] or arg[-0]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- end
- local binary=ownbin
- if not ownpath or ownpath=="" then
- ownpath=ownpath and filedirname(binary)
- end
- if not ownpath or ownpath=="" then
- if os.binsuffix~="" then
- binary=file.replacesuffix(binary,os.binsuffix)
- end
- local path=osgetenv("PATH")
- if path then
- for p in gmatch(path,"[^"..io.pathseparator.."]+") do
- local b=filejoin(p,binary)
- if lfs.isfile(b) then
- local olddir=lfs.currentdir()
- if lfs.chdir(p) then
- local pp=lfs.currentdir()
- if trace_locating and p~=pp then
- report_initialization("following symlink %a to %a",p,pp)
- end
- ownpath=pp
- lfs.chdir(olddir)
- else
- if trace_locating then
- report_initialization("unable to check path %a",p)
- end
- ownpath=p
- end
- break
- end
- end
+ local args=environment.originalarguments or arg
+ if not environment.ownmain then
+ environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
+ end
+ local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
+ local ownpath=environment.ownpath or os.selfdir
+ ownbin=file.collapsepath(ownbin)
+ ownpath=file.collapsepath(ownpath)
+ if not ownpath or ownpath=="" or ownpath=="unset" then
+ ownpath=args[-1] or arg[-1]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ if not ownpath or ownpath=="" then
+ ownpath=args[-0] or arg[-0]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ end
+ local binary=ownbin
+ if not ownpath or ownpath=="" then
+ ownpath=ownpath and filedirname(binary)
+ end
+ if not ownpath or ownpath=="" then
+ if os.binsuffix~="" then
+ binary=file.replacesuffix(binary,os.binsuffix)
+ end
+ local path=osgetenv("PATH")
+ if path then
+ for p in gmatch(path,"[^"..io.pathseparator.."]+") do
+ local b=filejoin(p,binary)
+ if lfs.isfile(b) then
+ local olddir=lfs.currentdir()
+ if lfs.chdir(p) then
+ local pp=lfs.currentdir()
+ if trace_locating and p~=pp then
+ report_initialization("following symlink %a to %a",p,pp)
+ end
+ ownpath=pp
+ lfs.chdir(olddir)
+ else
+ if trace_locating then
+ report_initialization("unable to check path %a",p)
+ end
+ ownpath=p
end
+ break
+ end
end
- if not ownpath or ownpath=="" then
- ownpath="."
- report_initialization("forcing fallback to ownpath %a",ownpath)
- elseif trace_locating then
- report_initialization("using ownpath %a",ownpath)
- end
+ end
end
- environment.ownbin=ownbin
- environment.ownpath=ownpath
+ if not ownpath or ownpath=="" then
+ ownpath="."
+ report_initialization("forcing fallback to ownpath %a",ownpath)
+ elseif trace_locating then
+ report_initialization("using ownpath %a",ownpath)
+ end
+ end
+ environment.ownbin=ownbin
+ environment.ownpath=ownpath
end
resolvers.ownpath=environment.ownpath
function resolvers.getownpath()
- return environment.ownpath
+ return environment.ownpath
end
do
- local ownpath=environment.ownpath or dir.current()
- if ownpath then
- ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
- ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
- ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
- else
- report_initialization("error: unable to locate ownpath")
- os.exit()
- end
-end
-local texos=environment.texos or osgetenv("TEXOS")
+ local ownpath=environment.ownpath or dir.current()
+ if ownpath then
+ ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
+ ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
+ ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
+ else
+ report_initialization("error: unable to locate ownpath")
+ os.exit()
+ end
+end
+local texos=environment.texos or osgetenv("TEXOS")
local texmfos=environment.texmfos or osgetenv('SELFAUTODIR')
if not texos or texos=="" then
- texos=file.basename(texmfos)
+ texos=file.basename(texmfos)
end
ossetenv('TEXMFOS',texmfos)
-ossetenv('TEXOS',texos)
-ossetenv('SELFAUTOSYSTEM',os.platform)
+ossetenv('TEXOS',texos)
+ossetenv('SELFAUTOSYSTEM',os.platform)
environment.texos=texos
environment.texmfos=texmfos
local texroot=environment.texroot or osgetenv("TEXROOT")
if not texroot or texroot=="" then
- texroot=osgetenv('SELFAUTOPARENT')
- ossetenv('TEXROOT',texroot)
+ texroot=osgetenv('SELFAUTOPARENT')
+ ossetenv('TEXROOT',texroot)
end
environment.texroot=file.collapsepath(texroot)
local prefixes=utilities.storage.allocate()
@@ -19817,30 +19825,30 @@ local resolved={}
local abstract={}
local dynamic={}
function resolvers.resetresolve(str)
- resolved,abstract={},{}
+ resolved,abstract={},{}
end
function resolvers.allprefixes(separator)
- local all=table.sortedkeys(prefixes)
- if separator then
- for i=1,#all do
- all[i]=all[i]..":"
- end
+ local all=table.sortedkeys(prefixes)
+ if separator then
+ for i=1,#all do
+ all[i]=all[i]..":"
end
- return all
+ end
+ return all
end
local function _resolve_(method,target)
- local action=prefixes[method]
- if action then
- return action(target)
- else
- return method..":"..target
- end
+ local action=prefixes[method]
+ if action then
+ return action(target)
+ else
+ return method..":"..target
+ end
end
function resolvers.unresolve(str)
- return abstract[str] or str
+ return abstract[str] or str
end
function resolvers.setdynamic(str)
- dynamic[str]=true
+ dynamic[str]=true
end
local pattern=Cs((C(R("az")^2)*P(":")*C((1-S(" \"\';,"))^1)/_resolve_+P(1))^0)
local prefix=C(R("az")^2)*P(":")
@@ -19849,65 +19857,65 @@ local notarget=(#S(";,")+P(-1))*Cc("")
local p_resolve=Cs(((prefix*(target+notarget))/_resolve_+P(1))^0)
local p_simple=prefix*P(-1)
local function resolve(str)
- if type(str)=="table" then
- local res={}
- for i=1,#str do
- res[i]=resolve(str[i])
- end
- return res
- end
- local res=resolved[str]
- if res then
- return res
+ if type(str)=="table" then
+ local res={}
+ for i=1,#str do
+ res[i]=resolve(str[i])
end
- local simple=lpegmatch(p_simple,str)
- local action=prefixes[simple]
- if action then
- local res=action(res)
- if not dynamic[simple] then
- resolved[simple]=res
- abstract[res]=simple
- end
- return res
+ return res
+ end
+ local res=resolved[str]
+ if res then
+ return res
+ end
+ local simple=lpegmatch(p_simple,str)
+ local action=prefixes[simple]
+ if action then
+ local res=action(res)
+ if not dynamic[simple] then
+ resolved[simple]=res
+ abstract[res]=simple
end
- res=lpegmatch(p_resolve,str)
- resolved[str]=res
- abstract[res]=str
return res
+ end
+ res=lpegmatch(p_resolve,str)
+ resolved[str]=res
+ abstract[res]=str
+ return res
end
resolvers.resolve=resolve
if type(osuname)=="function" then
- for k,v in next,osuname() do
- if not prefixes[k] then
- prefixes[k]=function() return v end
- end
+ for k,v in next,osuname() do
+ if not prefixes[k] then
+ prefixes[k]=function() return v end
end
+ end
end
if ostype=="unix" then
- local pattern
- local function makepattern(t,k,v)
- if t then
- rawset(t,k,v)
- end
- local colon=P(":")
- for k,v in table.sortedpairs(prefixes) do
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- pattern=Cs((p*colon+colon/";"+P(1))^0)
- end
- makepattern()
- table.setmetatablenewindex(prefixes,makepattern)
- function resolvers.repath(str)
- return lpegmatch(pattern,str)
+ local pattern
+ local function makepattern(t,k,v)
+ if t then
+ rawset(t,k,v)
+ end
+ local colon=P(":")
+ for k,v in table.sortedpairs(prefixes) do
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
end
+ pattern=Cs((p*colon+colon/";"+P(1))^0)
+ end
+ makepattern()
+ table.setmetatablenewindex(prefixes,makepattern)
+ function resolvers.repath(str)
+ return lpegmatch(pattern,str)
+ end
else
- function resolvers.repath(str)
- return str
- end
+ function resolvers.repath(str)
+ return str
+ end
end
@@ -19917,14 +19925,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-exp"] = package.loaded["data-exp"] or true
--- original size: 18105, stripped down to: 11207
+-- original size: 18105, stripped down to: 10389
if not modules then modules={} end modules ['data-exp']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub
local concat,sort=table.concat,table.sort
@@ -19934,21 +19942,21 @@ local Ct,Cs,Cc,Carg,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.P,lpeg.C,lpeg.S
local type,next=type,next
local isdir=lfs.isdir
local collapsepath,joinpath,basename=file.collapsepath,file.join,file.basename
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
local report_expansions=logs.reporter("resolvers","expansions")
local report_globbing=logs.reporter("resolvers","globbing")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
local function f_both(a,b)
- local t,n={},0
- for sb in gmatch(b,"[^,]+") do
- for sa in gmatch(a,"[^,]+") do
- n=n+1;t[n]=sa..sb
- end
+ local t,n={},0
+ for sb in gmatch(b,"[^,]+") do
+ for sa in gmatch(a,"[^,]+") do
+ n=n+1;t[n]=sa..sb
end
- return concat(t,",")
+ end
+ return concat(t,",")
end
local comma=P(",")
local nocomma=(1-comma)^1
@@ -19958,7 +19966,7 @@ local after=Cs((Carg(1)*nocomma+docomma)^0)
local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0)
local function f_first (a,b) return lpegmatch(after,b,1,a) end
local function f_second(a,b) return lpegmatch(before,a,1,b) end
-local function f_both (a,b) return lpegmatch(both,b,1,a) end
+local function f_both (a,b) return lpegmatch(both,b,1,a) end
local left=P("{")
local right=P("}")
local var=P((1-S("{}" ))^0)
@@ -19971,141 +19979,141 @@ local l_rest=Cs((left*var*(left/"")*var*(right/"")*var*right+other )^0 )
local stripper_1=lpeg.stripper ("{}@")
local replacer_1=lpeg.replacer { { ",}",",@}" },{ "{,","{@," },}
local function splitpathexpr(str,newlist,validate)
- if trace_expansions then
- report_expansions("expanding variable %a",str)
- end
- local t,ok,done=newlist or {},false,false
- local n=#t
- str=lpegmatch(replacer_1,str)
+ if trace_expansions then
+ report_expansions("expanding variable %a",str)
+ end
+ local t,ok,done=newlist or {},false,false
+ local n=#t
+ str=lpegmatch(replacer_1,str)
+ repeat
+ local old=str
repeat
- local old=str
- repeat
- local old=str
- str=lpegmatch(l_first,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_second,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_both,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_rest,str)
- until old==str
- until old==str
- str=lpegmatch(stripper_1,str)
- if validate then
- for s in gmatch(str,"[^,]+") do
- s=validate(s)
- if s then
- n=n+1
- t[n]=s
- end
- end
- else
- for s in gmatch(str,"[^,]+") do
- n=n+1
- t[n]=s
- end
+ local old=str
+ str=lpegmatch(l_first,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_second,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_both,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_rest,str)
+ until old==str
+ until old==str
+ str=lpegmatch(stripper_1,str)
+ if validate then
+ for s in gmatch(str,"[^,]+") do
+ s=validate(s)
+ if s then
+ n=n+1
+ t[n]=s
+ end
end
- if trace_expansions then
- for k=1,#t do
- report_expansions("% 4i: %s",k,t[k])
- end
+ else
+ for s in gmatch(str,"[^,]+") do
+ n=n+1
+ t[n]=s
end
- return t
+ end
+ if trace_expansions then
+ for k=1,#t do
+ report_expansions("% 4i: %s",k,t[k])
+ end
+ end
+ return t
end
local function validate(s)
- s=collapsepath(s)
- return s~="" and not find(s,"^!*unset/*$") and s
+ s=collapsepath(s)
+ return s~="" and not find(s,"^!*unset/*$") and s
end
resolvers.validatedpath=validate
function resolvers.expandedpathfromlist(pathlist)
- local newlist={}
- for k=1,#pathlist do
- splitpathexpr(pathlist[k],newlist,validate)
- end
- return newlist
+ local newlist={}
+ for k=1,#pathlist do
+ splitpathexpr(pathlist[k],newlist,validate)
+ end
+ return newlist
end
local usedhomedir=nil
-local donegation=(P("!")/"" )^0
+local donegation=(P("!")/"" )^0
local doslashes=(P("\\")/"/"+1)^0
local function expandedhome()
- if not usedhomedir then
- usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
- if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
- if trace_expansions then
- report_expansions("no home dir set, ignoring dependent path using current path")
- end
- usedhomedir="."
- end
+ if not usedhomedir then
+ usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
+ if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
+ if trace_expansions then
+ report_expansions("no home dir set, ignoring dependent path using current path")
+ end
+ usedhomedir="."
end
- return usedhomedir
+ end
+ return usedhomedir
end
local dohome=((P("~")+P("$HOME")+P("%HOME%"))/expandedhome)^0
local cleanup=Cs(donegation*dohome*doslashes)
resolvers.cleanpath=function(str)
- return str and lpegmatch(cleanup,str) or ""
+ return str and lpegmatch(cleanup,str) or ""
end
local expandhome=P("~")/"$HOME"
local dodouble=P('"')/""*(expandhome+(1-P('"')))^0*P('"')/""
local dosingle=P("'")/""*(expandhome+(1-P("'")))^0*P("'")/""
-local dostring=(expandhome+1 )^0
+local dostring=(expandhome+1 )^0
local stripper=Cs(
- lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
+ lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
)
function resolvers.checkedvariable(str)
- return type(str)=="string" and lpegmatch(stripper,str) or str
+ return type(str)=="string" and lpegmatch(stripper,str) or str
end
local cache={}
local splitter=lpeg.tsplitat(";")
local backslashswapper=lpeg.replacer("\\","/")
local function splitconfigurationpath(str)
- if str then
- local found=cache[str]
- if not found then
- if str=="" then
- found={}
- else
- local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
- found={}
- local noffound=0
- for i=1,#split do
- local s=split[i]
- if not find(s,"^{*unset}*") then
- noffound=noffound+1
- found[noffound]=s
- end
- end
- if trace_expansions then
- report_expansions("splitting path specification %a",str)
- for k=1,noffound do
- report_expansions("% 4i: %s",k,found[k])
- end
- end
- cache[str]=found
- end
+ if str then
+ local found=cache[str]
+ if not found then
+ if str=="" then
+ found={}
+ else
+ local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
+ found={}
+ local noffound=0
+ for i=1,#split do
+ local s=split[i]
+ if not find(s,"^{*unset}*") then
+ noffound=noffound+1
+ found[noffound]=s
+ end
end
- return found
+ if trace_expansions then
+ report_expansions("splitting path specification %a",str)
+ for k=1,noffound do
+ report_expansions("% 4i: %s",k,found[k])
+ end
+ end
+ cache[str]=found
+ end
end
+ return found
+ end
end
resolvers.splitconfigurationpath=splitconfigurationpath
function resolvers.splitpath(str)
- if type(str)=='table' then
- return str
- else
- return splitconfigurationpath(str)
- end
+ if type(str)=='table' then
+ return str
+ else
+ return splitconfigurationpath(str)
+ end
end
function resolvers.joinpath(str)
- if type(str)=='table' then
- return joinpath(str)
- else
- return str
- end
+ if type(str)=='table' then
+ return joinpath(str)
+ else
+ return str
+ end
end
local attributes,directory=lfs.attributes,lfs.dir
local weird=P(".")^1+lpeg.anywhere(S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t"))
@@ -20118,201 +20126,201 @@ local fullcache={}
local nofsharedscans=0
local addcasecraptoo=true
local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant)
- local full=path=="" and spec or (spec..path..'/')
- local dirlist={}
- local nofdirs=0
- local pattern=tolerant and lessweird or weird
- local filelist={}
- local noffiles=0
- for name in directory(full) do
- if not lpegmatch(pattern,name) then
- local mode=attributes(full..name,"mode")
- if mode=="file" then
- n=n+1
- noffiles=noffiles+1
- filelist[noffiles]=name
- elseif mode=="directory" then
- m=m+1
- nofdirs=nofdirs+1
- if path~="" then
- dirlist[nofdirs]=path.."/"..name
- else
- dirlist[nofdirs]=name
- end
- end
+ local full=path=="" and spec or (spec..path..'/')
+ local dirlist={}
+ local nofdirs=0
+ local pattern=tolerant and lessweird or weird
+ local filelist={}
+ local noffiles=0
+ for name in directory(full) do
+ if not lpegmatch(pattern,name) then
+ local mode=attributes(full..name,"mode")
+ if mode=="file" then
+ n=n+1
+ noffiles=noffiles+1
+ filelist[noffiles]=name
+ elseif mode=="directory" then
+ m=m+1
+ nofdirs=nofdirs+1
+ if path~="" then
+ dirlist[nofdirs]=path.."/"..name
+ else
+ dirlist[nofdirs]=name
end
+ end
end
- if noffiles>0 then
- sort(filelist)
- for i=1,noffiles do
- local name=filelist[i]
- local lower=lower(name)
- local paths=files[lower]
- if paths then
- if onlyone then
- else
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- if addcasecraptoo then
- local paths=files[name]
- if not paths then
- files[name]=path
- elseif type(paths)=="string" then
- files[name]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- end
- if type(paths)=="string" then
- files[lower]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- else
- files[lower]=path
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- end
+ end
+ if noffiles>0 then
+ sort(filelist)
+ for i=1,noffiles do
+ local name=filelist[i]
+ local lower=lower(name)
+ local paths=files[lower]
+ if paths then
+ if onlyone then
+ else
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
+ if addcasecraptoo then
+ local paths=files[name]
+ if not paths then
+ files[name]=path
+ elseif type(paths)=="string" then
+ files[name]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
+ end
+ if type(paths)=="string" then
+ files[lower]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
- end
- if nofdirs>0 then
- sort(dirlist)
- for i=1,nofdirs do
- files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
+ else
+ files[lower]=path
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
end
+ end
+ end
+ end
+ if nofdirs>0 then
+ sort(dirlist)
+ for i=1,nofdirs do
+ files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
end
- scancache[sub(full,1,-2)]=files
- return files,remap,n,m,r
+ end
+ scancache[sub(full,1,-2)]=files
+ return files,remap,n,m,r
end
function resolvers.scanfiles(path,branch,usecache,onlyonce,tolerant)
- local realpath=resolveprefix(path)
- if usecache then
- local content=fullcache[realpath]
- if content then
- if trace_locating then
- report_expansions("using cached scan of path %a, branch %a",path,branch or path)
- end
- nofsharedscans=nofsharedscans+1
- return content
- end
- end
- statistics.starttiming(timer)
+ local realpath=resolveprefix(path)
+ if usecache then
+ local content=fullcache[realpath]
+ if content then
+ if trace_locating then
+ report_expansions("using cached scan of path %a, branch %a",path,branch or path)
+ end
+ nofsharedscans=nofsharedscans+1
+ return content
+ end
+ end
+ statistics.starttiming(timer)
+ if trace_locating then
+ report_expansions("scanning path %a, branch %a",path,branch or path)
+ end
+ local content
+ if isdir(realpath) then
+ local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
+ content={
+ metadata={
+ path=path,
+ files=n,
+ directories=m,
+ remappings=r,
+ },
+ files=files,
+ remap=remap,
+ }
if trace_locating then
- report_expansions("scanning path %a, branch %a",path,branch or path)
+ report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
end
- local content
- if isdir(realpath) then
- local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
- content={
- metadata={
- path=path,
- files=n,
- directories=m,
- remappings=r,
- },
- files=files,
- remap=remap,
- }
- if trace_locating then
- report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
- end
- else
- content={
- metadata={
- path=path,
- files=0,
- directories=0,
- remappings=0,
- },
- files={},
- remap={},
- }
- if trace_locating then
- report_expansions("invalid path %a",realpath)
- end
- end
- if usecache then
- scanned[#scanned+1]=realpath
- fullcache[realpath]=content
+ else
+ content={
+ metadata={
+ path=path,
+ files=0,
+ directories=0,
+ remappings=0,
+ },
+ files={},
+ remap={},
+ }
+ if trace_locating then
+ report_expansions("invalid path %a",realpath)
end
- nofscans=nofscans+1
- statistics.stoptiming(timer)
- return content
+ end
+ if usecache then
+ scanned[#scanned+1]=realpath
+ fullcache[realpath]=content
+ end
+ nofscans=nofscans+1
+ statistics.stoptiming(timer)
+ return content
end
function resolvers.simplescanfiles(path,branch,usecache)
- return resolvers.scanfiles(path,branch,usecache,true,true)
+ return resolvers.scanfiles(path,branch,usecache,true,true)
end
function resolvers.scandata()
- table.sort(scanned)
- return {
- n=nofscans,
- shared=nofsharedscans,
- time=statistics.elapsedtime(timer),
- paths=scanned,
- }
+ table.sort(scanned)
+ return {
+ n=nofscans,
+ shared=nofsharedscans,
+ time=statistics.elapsedtime(timer),
+ paths=scanned,
+ }
end
function resolvers.get_from_content(content,path,name)
- if not content then
- return
- end
- local files=content.files
- if not files then
- return
- end
- local remap=content.remap
- if not remap then
- return
- end
- if name then
- local used=lower(name)
- return path,remap[used] or used
- else
- local name=path
- local used=lower(name)
- local path=files[used]
- if path then
- return path,remap[used] or used
- end
- end
+ if not content then
+ return
+ end
+ local files=content.files
+ if not files then
+ return
+ end
+ local remap=content.remap
+ if not remap then
+ return
+ end
+ if name then
+ local used=lower(name)
+ return path,remap[used] or used
+ else
+ local name=path
+ local used=lower(name)
+ local path=files[used]
+ if path then
+ return path,remap[used] or used
+ end
+ end
end
local nothing=function() end
function resolvers.filtered_from_content(content,pattern)
- if content and type(pattern)=="string" then
- local pattern=lower(pattern)
- local files=content.files
- local remap=content.remap
- if files and remap then
- local f=sortedkeys(files)
- local n=#f
- local i=0
- local function iterator()
- while i<n do
- i=i+1
- local k=f[i]
- if find(k,pattern) then
- return files[k],remap and remap[k] or k
- end
- end
- end
- return iterator
+ if content and type(pattern)=="string" then
+ local pattern=lower(pattern)
+ local files=content.files
+ local remap=content.remap
+ if files and remap then
+ local f=sortedkeys(files)
+ local n=#f
+ local i=0
+ local function iterator()
+ while i<n do
+ i=i+1
+ local k=f[i]
+ if find(k,pattern) then
+ return files[k],remap and remap[k] or k
+ end
end
+ end
+ return iterator
end
- return nothing
+ end
+ return nothing
end
@@ -20322,14 +20330,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-env"] = package.loaded["data-env"] or true
--- original size: 9360, stripped down to: 6903
+-- original size: 9360, stripped down to: 6312
if not modules then modules={} end modules ['data-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local lower,gsub=string.lower,string.gsub
local next=next
@@ -20349,255 +20357,255 @@ resolvers.suffixmap=suffixmap
resolvers.usertypes=usertypes
local luasuffixes=utilities.lua.suffixes
local relations=allocate {
- core={
- ofm={
- names={ "ofm","omega font metric","omega font metrics" },
- variable='OFMFONTS',
- suffixes={ 'ofm','tfm' },
- },
- ovf={
- names={ "ovf","omega virtual font","omega virtual fonts" },
- variable='OVFFONTS',
- suffixes={ 'ovf','vf' },
- },
- tfm={
- names={ "tfm","tex font metric","tex font metrics" },
- variable='TFMFONTS',
- suffixes={ 'tfm' },
- },
- vf={
- names={ "vf","virtual font","virtual fonts" },
- variable='VFFONTS',
- suffixes={ 'vf' },
- },
- otf={
- names={ "otf","opentype","opentype font","opentype fonts"},
- variable='OPENTYPEFONTS',
- suffixes={ 'otf' },
- },
- ttf={
- names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
- variable='TTFONTS',
- suffixes={ 'ttf','ttc','dfont' },
- },
- afm={
- names={ "afm","adobe font metric","adobe font metrics" },
- variable="AFMFONTS",
- suffixes={ "afm" },
- },
- pfb={
- names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
- variable='T1FONTS',
- suffixes={ 'pfb','pfa' },
- },
- fea={
- names={ "fea","font feature","font features","font feature file","font feature files" },
- variable='FONTFEATURES',
- suffixes={ 'fea' },
- },
- cid={
- names={ "cid","cid map","cid maps","cid file","cid files" },
- variable='FONTCIDMAPS',
- suffixes={ 'cid','cidmap' },
- },
- fmt={
- names={ "fmt","format","tex format" },
- variable='TEXFORMATS',
- suffixes={ 'fmt' },
- },
- mem={
- names={ 'mem',"metapost format" },
- variable='MPMEMS',
- suffixes={ 'mem' },
- },
- mp={
- names={ "mp" },
- variable='MPINPUTS',
- suffixes={ 'mp','mpvi','mpiv','mpii' },
- usertype=true,
- },
- tex={
- names={ "tex" },
- variable='TEXINPUTS',
- suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
- usertype=true,
- },
- icc={
- names={ "icc","icc profile","icc profiles" },
- variable='ICCPROFILES',
- suffixes={ 'icc' },
- },
- texmfscripts={
- names={ "texmfscript","texmfscripts","script","scripts" },
- variable='TEXMFSCRIPTS',
- suffixes={ 'lua','rb','pl','py' },
- },
- lua={
- names={ "lua" },
- variable='LUAINPUTS',
- suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
- usertype=true,
- },
- lib={
- names={ "lib" },
- variable='CLUAINPUTS',
- suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
- },
- bib={
- names={ 'bib' },
- variable='BIBINPUTS',
- suffixes={ 'bib' },
- usertype=true,
- },
- bst={
- names={ 'bst' },
- variable='BSTINPUTS',
- suffixes={ 'bst' },
- usertype=true,
- },
- fontconfig={
- names={ 'fontconfig','fontconfig file','fontconfig files' },
- variable='FONTCONFIG_PATH',
- },
- pk={
- names={ "pk" },
- variable='PKFONTS',
- suffixes={ 'pk' },
- },
+ core={
+ ofm={
+ names={ "ofm","omega font metric","omega font metrics" },
+ variable='OFMFONTS',
+ suffixes={ 'ofm','tfm' },
+ },
+ ovf={
+ names={ "ovf","omega virtual font","omega virtual fonts" },
+ variable='OVFFONTS',
+ suffixes={ 'ovf','vf' },
+ },
+ tfm={
+ names={ "tfm","tex font metric","tex font metrics" },
+ variable='TFMFONTS',
+ suffixes={ 'tfm' },
},
- obsolete={
- enc={
- names={ "enc","enc files","enc file","encoding files","encoding file" },
- variable='ENCFONTS',
- suffixes={ 'enc' },
- },
- map={
- names={ "map","map files","map file" },
- variable='TEXFONTMAPS',
- suffixes={ 'map' },
- },
- lig={
- names={ "lig files","lig file","ligature file","ligature files" },
- variable='LIGFONTS',
- suffixes={ 'lig' },
- },
- opl={
- names={ "opl" },
- variable='OPLFONTS',
- suffixes={ 'opl' },
- },
- ovp={
- names={ "ovp" },
- variable='OVPFONTS',
- suffixes={ 'ovp' },
- },
+ vf={
+ names={ "vf","virtual font","virtual fonts" },
+ variable='VFFONTS',
+ suffixes={ 'vf' },
},
- kpse={
- base={
- names={ 'base',"metafont format" },
- variable='MFBASES',
- suffixes={ 'base','bas' },
- },
- cmap={
- names={ 'cmap','cmap files','cmap file' },
- variable='CMAPFONTS',
- suffixes={ 'cmap' },
- },
- cnf={
- names={ 'cnf' },
- suffixes={ 'cnf' },
- },
- web={
- names={ 'web' },
- suffixes={ 'web','ch' }
- },
- cweb={
- names={ 'cweb' },
- suffixes={ 'w','web','ch' },
- },
- gf={
- names={ 'gf' },
- suffixes={ '<resolution>gf' },
- },
- mf={
- names={ 'mf' },
- variable='MFINPUTS',
- suffixes={ 'mf' },
- },
- mft={
- names={ 'mft' },
- suffixes={ 'mft' },
- },
- pk={
- names={ 'pk' },
- suffixes={ '<resolution>pk' },
- },
+ otf={
+ names={ "otf","opentype","opentype font","opentype fonts"},
+ variable='OPENTYPEFONTS',
+ suffixes={ 'otf' },
},
+ ttf={
+ names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
+ variable='TTFONTS',
+ suffixes={ 'ttf','ttc','dfont' },
+ },
+ afm={
+ names={ "afm","adobe font metric","adobe font metrics" },
+ variable="AFMFONTS",
+ suffixes={ "afm" },
+ },
+ pfb={
+ names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
+ variable='T1FONTS',
+ suffixes={ 'pfb','pfa' },
+ },
+ fea={
+ names={ "fea","font feature","font features","font feature file","font feature files" },
+ variable='FONTFEATURES',
+ suffixes={ 'fea' },
+ },
+ cid={
+ names={ "cid","cid map","cid maps","cid file","cid files" },
+ variable='FONTCIDMAPS',
+ suffixes={ 'cid','cidmap' },
+ },
+ fmt={
+ names={ "fmt","format","tex format" },
+ variable='TEXFORMATS',
+ suffixes={ 'fmt' },
+ },
+ mem={
+ names={ 'mem',"metapost format" },
+ variable='MPMEMS',
+ suffixes={ 'mem' },
+ },
+ mp={
+ names={ "mp" },
+ variable='MPINPUTS',
+ suffixes={ 'mp','mpvi','mpiv','mpii' },
+ usertype=true,
+ },
+ tex={
+ names={ "tex" },
+ variable='TEXINPUTS',
+ suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
+ usertype=true,
+ },
+ icc={
+ names={ "icc","icc profile","icc profiles" },
+ variable='ICCPROFILES',
+ suffixes={ 'icc' },
+ },
+ texmfscripts={
+ names={ "texmfscript","texmfscripts","script","scripts" },
+ variable='TEXMFSCRIPTS',
+ suffixes={ 'lua','rb','pl','py' },
+ },
+ lua={
+ names={ "lua" },
+ variable='LUAINPUTS',
+ suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
+ usertype=true,
+ },
+ lib={
+ names={ "lib" },
+ variable='CLUAINPUTS',
+ suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
+ },
+ bib={
+ names={ 'bib' },
+ variable='BIBINPUTS',
+ suffixes={ 'bib' },
+ usertype=true,
+ },
+ bst={
+ names={ 'bst' },
+ variable='BSTINPUTS',
+ suffixes={ 'bst' },
+ usertype=true,
+ },
+ fontconfig={
+ names={ 'fontconfig','fontconfig file','fontconfig files' },
+ variable='FONTCONFIG_PATH',
+ },
+ pk={
+ names={ "pk" },
+ variable='PKFONTS',
+ suffixes={ 'pk' },
+ },
+ },
+ obsolete={
+ enc={
+ names={ "enc","enc files","enc file","encoding files","encoding file" },
+ variable='ENCFONTS',
+ suffixes={ 'enc' },
+ },
+ map={
+ names={ "map","map files","map file" },
+ variable='TEXFONTMAPS',
+ suffixes={ 'map' },
+ },
+ lig={
+ names={ "lig files","lig file","ligature file","ligature files" },
+ variable='LIGFONTS',
+ suffixes={ 'lig' },
+ },
+ opl={
+ names={ "opl" },
+ variable='OPLFONTS',
+ suffixes={ 'opl' },
+ },
+ ovp={
+ names={ "ovp" },
+ variable='OVPFONTS',
+ suffixes={ 'ovp' },
+ },
+ },
+ kpse={
+ base={
+ names={ 'base',"metafont format" },
+ variable='MFBASES',
+ suffixes={ 'base','bas' },
+ },
+ cmap={
+ names={ 'cmap','cmap files','cmap file' },
+ variable='CMAPFONTS',
+ suffixes={ 'cmap' },
+ },
+ cnf={
+ names={ 'cnf' },
+ suffixes={ 'cnf' },
+ },
+ web={
+ names={ 'web' },
+ suffixes={ 'web','ch' }
+ },
+ cweb={
+ names={ 'cweb' },
+ suffixes={ 'w','web','ch' },
+ },
+ gf={
+ names={ 'gf' },
+ suffixes={ '<resolution>gf' },
+ },
+ mf={
+ names={ 'mf' },
+ variable='MFINPUTS',
+ suffixes={ 'mf' },
+ },
+ mft={
+ names={ 'mft' },
+ suffixes={ 'mft' },
+ },
+ pk={
+ names={ 'pk' },
+ suffixes={ '<resolution>pk' },
+ },
+ },
}
resolvers.relations=relations
function resolvers.updaterelations()
- for category,categories in next,relations do
- for name,relation in next,categories do
- local rn=relation.names
- local rv=relation.variable
- if rn and rv then
- local rs=relation.suffixes
- local ru=relation.usertype
- for i=1,#rn do
- local rni=lower(gsub(rn[i]," ",""))
- formats[rni]=rv
- if rs then
- suffixes[rni]=rs
- for i=1,#rs do
- local rsi=rs[i]
- suffixmap[rsi]=rni
- end
- end
- end
- if ru then
- usertypes[name]=true
- end
+ for category,categories in next,relations do
+ for name,relation in next,categories do
+ local rn=relation.names
+ local rv=relation.variable
+ if rn and rv then
+ local rs=relation.suffixes
+ local ru=relation.usertype
+ for i=1,#rn do
+ local rni=lower(gsub(rn[i]," ",""))
+ formats[rni]=rv
+ if rs then
+ suffixes[rni]=rs
+ for i=1,#rs do
+ local rsi=rs[i]
+ suffixmap[rsi]=rni
end
+ end
+ end
+ if ru then
+ usertypes[name]=true
end
+ end
end
+ end
end
resolvers.updaterelations()
local function simplified(t,k)
- return k and rawget(t,lower(gsub(k," ",""))) or nil
+ return k and rawget(t,lower(gsub(k," ",""))) or nil
end
setmetatableindex(formats,simplified)
setmetatableindex(suffixes,simplified)
setmetatableindex(suffixmap,simplified)
function resolvers.suffixofformat(str)
- local s=suffixes[str]
- return s and s[1] or ""
+ local s=suffixes[str]
+ return s and s[1] or ""
end
function resolvers.suffixofformat(str)
- return suffixes[str] or {}
+ return suffixes[str] or {}
end
for name,format in next,formats do
- dangerous[name]=true
+ dangerous[name]=true
end
dangerous.tex=nil
function resolvers.formatofvariable(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.formatofsuffix(str)
- return suffixmap[suffixonly(str)] or 'tex'
+ return suffixmap[suffixonly(str)] or 'tex'
end
function resolvers.variableofformat(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.variableofformatorsuffix(str)
- local v=formats[str]
- if v then
- return v
- end
- v=suffixmap[suffixonly(str)]
- if v then
- return formats[v]
- end
- return ''
+ local v=formats[str]
+ if v then
+ return v
+ end
+ v=suffixmap[suffixonly(str)]
+ if v then
+ return formats[v]
+ end
+ return ''
end
@@ -20607,14 +20615,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16116, stripped down to: 11459
+-- original size: 16116, stripped down to: 10782
if not modules then modules={} end modules ['data-tmp']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub,concat=string.format,string.lower,string.gsub,table.concat
local concat=table.concat
@@ -20622,19 +20630,19 @@ local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile
local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
local formatters=string.formatters
local next,type=next,type
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
local report_caches=logs.reporter("resolvers","caches")
local report_resolvers=logs.reporter("resolvers","caching")
local resolvers=resolvers
local cleanpath=resolvers.cleanpath
-local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
-local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
+local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
+local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
local compile=utilities.lua.compile
function utilities.lua.compile(luafile,lucfile,cleanup,strip)
- if cleanup==nil then cleanup=directive_cleanup end
- if strip==nil then strip=directive_strip end
- return compile(luafile,lucfile,cleanup,strip)
+ if cleanup==nil then cleanup=directive_cleanup end
+ if strip==nil then strip=directive_strip end
+ return compile(luafile,lucfile,cleanup,strip)
end
caches=caches or {}
local caches=caches
@@ -20649,324 +20657,324 @@ caches.relocate=false
caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
local writable,readables,usedreadables=nil,{},{}
local function identify()
- local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- cachepath=file.collapsepath(cachepath)
- local valid=isdir(cachepath)
- if valid then
- if is_readable(cachepath) then
- readables[#readables+1]=cachepath
- if not writable and is_writable(cachepath) then
- writable=cachepath
- end
- end
- elseif not writable and caches.force then
- local cacheparent=file.dirname(cachepath)
- if is_writable(cacheparent) and true then
- if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
- mkdirs(cachepath)
- if isdir(cachepath) and is_writable(cachepath) then
- report_caches("path %a created",cachepath)
- writable=cachepath
- readables[#readables+1]=cachepath
- end
- end
- end
- end
+ local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ cachepath=file.collapsepath(cachepath)
+ local valid=isdir(cachepath)
+ if valid then
+ if is_readable(cachepath) then
+ readables[#readables+1]=cachepath
+ if not writable and is_writable(cachepath) then
+ writable=cachepath
end
- end
- end
- local texmfcaches=caches.defaults
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- cachepath=resolvers.expansion(cachepath)
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- local valid=isdir(cachepath)
- if valid and is_readable(cachepath) then
- if not writable and is_writable(cachepath) then
- readables[#readables+1]=cachepath
- writable=cachepath
- break
- end
- end
+ end
+ elseif not writable and caches.force then
+ local cacheparent=file.dirname(cachepath)
+ if is_writable(cacheparent) and true then
+ if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
+ mkdirs(cachepath)
+ if isdir(cachepath) and is_writable(cachepath) then
+ report_caches("path %a created",cachepath)
+ writable=cachepath
+ readables[#readables+1]=cachepath
+ end
end
+ end
end
+ end
end
- if not writable then
- report_caches("fatal error: there is no valid writable cache path defined")
- os.exit()
- elseif #readables==0 then
- report_caches("fatal error: there is no valid readable cache path defined")
- os.exit()
- end
- writable=dir.expandname(resolvers.cleanpath(writable))
- local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
- if tree then
- caches.tree=tree
- writable=mkdirs(writable,base,more,tree)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more,tree)
- end
- else
- writable=mkdirs(writable,base,more)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more)
+ end
+ local texmfcaches=caches.defaults
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ cachepath=resolvers.expansion(cachepath)
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ local valid=isdir(cachepath)
+ if valid and is_readable(cachepath) then
+ if not writable and is_writable(cachepath) then
+ readables[#readables+1]=cachepath
+ writable=cachepath
+ break
+ end
end
+ end
end
- if trace_cache then
- for i=1,#readables do
- report_caches("using readable path %a (order %s)",readables[i],i)
- end
- report_caches("using writable path %a",writable)
+ end
+ if not writable then
+ report_caches("fatal error: there is no valid writable cache path defined")
+ os.exit()
+ elseif #readables==0 then
+ report_caches("fatal error: there is no valid readable cache path defined")
+ os.exit()
+ end
+ writable=dir.expandname(resolvers.cleanpath(writable))
+ local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
+ if tree then
+ caches.tree=tree
+ writable=mkdirs(writable,base,more,tree)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more,tree)
end
- identify=function()
- return writable,readables
+ else
+ writable=mkdirs(writable,base,more)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more)
+ end
+ end
+ if trace_cache then
+ for i=1,#readables do
+ report_caches("using readable path %a (order %s)",readables[i],i)
end
+ report_caches("using writable path %a",writable)
+ end
+ identify=function()
return writable,readables
+ end
+ return writable,readables
end
function caches.usedpaths(separator)
- local writable,readables=identify()
- if #readables>1 then
- local result={}
- local done={}
- for i=1,#readables do
- local readable=readables[i]
- if readable==writable then
- done[readable]=true
- result[#result+1]=formatters["readable+writable: %a"](readable)
- elseif usedreadables[i] then
- done[readable]=true
- result[#result+1]=formatters["readable: %a"](readable)
- end
- end
- if not done[writable] then
- result[#result+1]=formatters["writable: %a"](writable)
- end
- return concat(result,separator or " | ")
- else
- return writable or "?"
+ local writable,readables=identify()
+ if #readables>1 then
+ local result={}
+ local done={}
+ for i=1,#readables do
+ local readable=readables[i]
+ if readable==writable then
+ done[readable]=true
+ result[#result+1]=formatters["readable+writable: %a"](readable)
+ elseif usedreadables[i] then
+ done[readable]=true
+ result[#result+1]=formatters["readable: %a"](readable)
+ end
+ end
+ if not done[writable] then
+ result[#result+1]=formatters["writable: %a"](writable)
end
+ return concat(result,separator or " | ")
+ else
+ return writable or "?"
+ end
end
function caches.configfiles()
- return concat(resolvers.configurationfiles(),";")
+ return concat(resolvers.configurationfiles(),";")
end
function caches.hashed(tree)
- tree=gsub(tree,"[\\/]+$","")
- tree=lower(tree)
- local hash=md5.hex(tree)
- if trace_cache or trace_locating then
- report_caches("hashing tree %a, hash %a",tree,hash)
- end
- return hash
+ tree=gsub(tree,"[\\/]+$","")
+ tree=lower(tree)
+ local hash=md5.hex(tree)
+ if trace_cache or trace_locating then
+ report_caches("hashing tree %a, hash %a",tree,hash)
+ end
+ return hash
end
function caches.treehash()
- local tree=caches.configfiles()
- if not tree or tree=="" then
- return false
- else
- return caches.hashed(tree)
- end
+ local tree=caches.configfiles()
+ if not tree or tree=="" then
+ return false
+ else
+ return caches.hashed(tree)
+ end
end
local r_cache,w_cache={},{}
local function getreadablepaths(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=r_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done={}
- for i=1,#readables do
- done[i]=file.join(readables[i],...)
- end
- else
- done=readables
- end
- r_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=r_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done={}
+ for i=1,#readables do
+ done[i]=file.join(readables[i],...)
+ end
+ else
+ done=readables
end
- return done
+ r_cache[hash]=done
+ end
+ return done
end
local function getwritablepath(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=w_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done=mkdirs(writable,...)
- else
- done=writable
- end
- w_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=w_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done=mkdirs(writable,...)
+ else
+ done=writable
end
- return done
+ w_cache[hash]=done
+ end
+ return done
end
caches.getreadablepaths=getreadablepaths
caches.getwritablepath=getwritablepath
function caches.getfirstreadablefile(filename,...)
- local fullname,path=caches.setfirstwritablefile(filename,...)
+ local fullname,path=caches.setfirstwritablefile(filename,...)
+ if is_readable(fullname) then
+ return fullname,path
+ end
+ local rd=getreadablepaths(...)
+ for i=1,#rd do
+ local path=rd[i]
+ local fullname=file.join(path,filename)
if is_readable(fullname) then
- return fullname,path
- end
- local rd=getreadablepaths(...)
- for i=1,#rd do
- local path=rd[i]
- local fullname=file.join(path,filename)
- if is_readable(fullname) then
- usedreadables[i]=true
- return fullname,path
- end
+ usedreadables[i]=true
+ return fullname,path
end
- return fullname,path
+ end
+ return fullname,path
end
function caches.setfirstwritablefile(filename,...)
- local wr=getwritablepath(...)
- local fullname=file.join(wr,filename)
- return fullname,wr
+ local wr=getwritablepath(...)
+ local fullname=file.join(wr,filename)
+ return fullname,wr
end
function caches.define(category,subcategory)
- return function()
- return getwritablepath(category,subcategory)
- end
+ return function()
+ return getwritablepath(category,subcategory)
+ end
end
function caches.setluanames(path,name)
- return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
+ return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
end
function caches.loaddata(readables,name,writable)
- if type(readables)=="string" then
- readables={ readables }
+ if type(readables)=="string" then
+ readables={ readables }
+ end
+ for i=1,#readables do
+ local path=readables[i]
+ local loader=false
+ local tmaname,tmcname=caches.setluanames(path,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader and isfile(tmaname) then
+ local tmacrap,tmcname=caches.setluanames(writable,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ utilities.lua.compile(tmaname,tmcname)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader then
+ loader=loadfile(tmaname)
+ end
end
- for i=1,#readables do
- local path=readables[i]
- local loader=false
- local tmaname,tmcname=caches.setluanames(path,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader and isfile(tmaname) then
- local tmacrap,tmcname=caches.setluanames(writable,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- utilities.lua.compile(tmaname,tmcname)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader then
- loader=loadfile(tmaname)
- end
- end
- if loader then
- loader=loader()
- collectgarbage("step")
- return loader
- end
+ if loader then
+ loader=loader()
+ collectgarbage("step")
+ return loader
end
- return false
+ end
+ return false
end
function caches.is_writable(filepath,filename)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- return is_writable(tmaname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ return is_writable(tmaname)
end
local saveoptions={ compact=true }
function caches.savedata(filepath,filename,data,raw)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- data.cache_uuid=os.uuid()
- if caches.direct then
- file.savedata(tmaname,table.serialize(data,true,saveoptions))
- else
- table.tofile(tmaname,data,true,saveoptions)
- end
- utilities.lua.compile(tmaname,tmcname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ data.cache_uuid=os.uuid()
+ if caches.direct then
+ file.savedata(tmaname,table.serialize(data,true,saveoptions))
+ else
+ table.tofile(tmaname,data,true,saveoptions)
+ end
+ utilities.lua.compile(tmaname,tmcname)
end
local content_state={}
function caches.contentstate()
- return content_state or {}
+ return content_state or {}
end
function caches.loadcontent(cachename,dataname,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
- if blob then
- local data=blob()
- if data and data.content then
- if data.type==dataname then
- if data.version==resolvers.cacheversion then
- content_state[#content_state+1]=data.uuid
- if trace_locating then
- report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
- end
- return data.content
- else
- report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
- end
- else
- report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
- end
- elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
+ if blob then
+ local data=blob()
+ if data and data.content then
+ if data.type==dataname then
+ if data.version==resolvers.cacheversion then
+ content_state[#content_state+1]=data.uuid
+ if trace_locating then
+ report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
+ end
+ return data.content
+ else
+ report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
end
+ else
+ report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
+ end
elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
end
+ elseif trace_locating then
+ report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ end
end
function caches.collapsecontent(content)
- for k,v in next,content do
- if type(v)=="table" and #v==1 then
- content[k]=v[1]
- end
+ for k,v in next,content do
+ if type(v)=="table" and #v==1 then
+ content[k]=v[1]
end
+ end
end
function caches.savecontent(cachename,dataname,content,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local luaname=addsuffix(filename,luasuffixes.lua)
- local lucname=addsuffix(filename,luasuffixes.luc)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local luaname=addsuffix(filename,luasuffixes.lua)
+ local lucname=addsuffix(filename,luasuffixes.luc)
+ if trace_locating then
+ report_resolvers("preparing %a for %a",dataname,cachename)
+ end
+ local data={
+ type=dataname,
+ root=cachename,
+ version=resolvers.cacheversion,
+ date=os.date("%Y-%m-%d"),
+ time=os.date("%H:%M:%S"),
+ content=content,
+ uuid=os.uuid(),
+ }
+ local ok=io.savedata(luaname,table.serialize(data,true))
+ if ok then
if trace_locating then
- report_resolvers("preparing %a for %a",dataname,cachename)
- end
- local data={
- type=dataname,
- root=cachename,
- version=resolvers.cacheversion,
- date=os.date("%Y-%m-%d"),
- time=os.date("%H:%M:%S"),
- content=content,
- uuid=os.uuid(),
- }
- local ok=io.savedata(luaname,table.serialize(data,true))
- if ok then
- if trace_locating then
- report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
- end
- if utilities.lua.compile(luaname,lucname) then
- if trace_locating then
- report_resolvers("%a compiled to %a",dataname,lucname)
- end
- return true
- else
- if trace_locating then
- report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
- end
- os.remove(lucname)
- end
- elseif trace_locating then
- report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
end
+ if utilities.lua.compile(luaname,lucname) then
+ if trace_locating then
+ report_resolvers("%a compiled to %a",dataname,lucname)
+ end
+ return true
+ else
+ if trace_locating then
+ report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
+ end
+ os.remove(lucname)
+ end
+ elseif trace_locating then
+ report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ end
end
@@ -20976,14 +20984,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-met"] = package.loaded["data-met"] or true
--- original size: 5310, stripped down to: 3980
+-- original size: 5310, stripped down to: 3784
if not modules then modules={} end modules ['data-met']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local find,format=string.find,string.format
local sequenced=table.sequenced
@@ -20997,86 +21005,86 @@ local allocate=utilities.storage.allocate
local resolvers=resolvers
local registered={}
local function splitmethod(filename)
- if not filename then
- return { scheme="unknown",original=filename }
- end
- if type(filename)=="table" then
- return filename
- end
- filename=file.collapsepath(filename,".")
- if not find(filename,"://",1,true) then
- return { scheme="file",path=filename,original=filename,filename=filename }
- end
- local specification=url.hashed(filename)
- if not specification.scheme or specification.scheme=="" then
- return { scheme="file",path=filename,original=filename,filename=filename }
- else
- return specification
- end
+ if not filename then
+ return { scheme="unknown",original=filename }
+ end
+ if type(filename)=="table" then
+ return filename
+ end
+ filename=file.collapsepath(filename,".")
+ if not find(filename,"://",1,true) then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ end
+ local specification=url.hashed(filename)
+ if not specification.scheme or specification.scheme=="" then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ else
+ return specification
+ end
end
resolvers.splitmethod=splitmethod
local function methodhandler(what,first,...)
- local method=registered[what]
- if method then
- local how,namespace=method.how,method.namespace
- if how=="uri" or how=="url" then
- local specification=splitmethod(first)
- local scheme=specification.scheme
- local resolver=namespace and namespace[scheme]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
- end
- return resolver(specification,...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
- end
- return resolver(specification,...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
- end
- end
- elseif how=="tag" then
- local resolver=namespace and namespace[first]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,first)
- end
- return resolver(...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
- end
- return resolver(...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
- end
- end
+ local method=registered[what]
+ if method then
+ local how,namespace=method.how,method.namespace
+ if how=="uri" or how=="url" then
+ local specification=splitmethod(first)
+ local scheme=specification.scheme
+ local resolver=namespace and namespace[scheme]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
+ end
+ return resolver(specification,...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
+ end
+ return resolver(specification,...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
end
- else
- report_methods("resolving, invalid method %a")
+ end
+ elseif how=="tag" then
+ local resolver=namespace and namespace[first]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,first)
+ end
+ return resolver(...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
+ end
+ return resolver(...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
+ end
+ end
end
+ else
+ report_methods("resolving, invalid method %a")
+ end
end
resolvers.methodhandler=methodhandler
function resolvers.registermethod(name,namespace,how)
- registered[name]={ how=how or "tag",namespace=namespace }
- namespace["byscheme"]=function(scheme,filename,...)
- if scheme=="file" then
- return methodhandler(name,filename,...)
- else
- return methodhandler(name,addurlscheme(filename,scheme),...)
- end
+ registered[name]={ how=how or "tag",namespace=namespace }
+ namespace["byscheme"]=function(scheme,filename,...)
+ if scheme=="file" then
+ return methodhandler(name,filename,...)
+ else
+ return methodhandler(name,addurlscheme(filename,scheme),...)
end
+ end
end
-local concatinators=allocate { notfound=file.join }
-local locators=allocate { notfound=function() end }
-local hashers=allocate { notfound=function() end }
-local generators=allocate { notfound=function() end }
+local concatinators=allocate { notfound=file.join }
+local locators=allocate { notfound=function() end }
+local hashers=allocate { notfound=function() end }
+local generators=allocate { notfound=function() end }
resolvers.concatinators=concatinators
resolvers.locators=locators
resolvers.hashers=hashers
@@ -21094,14 +21102,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-res"] = package.loaded["data-res"] or true
--- original size: 68195, stripped down to: 47727
+-- original size: 68195, stripped down to: 43680
if not modules then modules={} end modules ['data-res']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local gsub,find,lower,upper,match,gmatch=string.gsub,string.find,string.lower,string.upper,string.match,string.gmatch
local concat,insert,remove=table.concat,table.insert,table.remove
@@ -21126,11 +21134,11 @@ local isfile=lfs.isfile
local isdir=lfs.isdir
local setmetatableindex=table.setmetatableindex
local luasuffixes=utilities.lua.suffixes
-local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
-local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
+local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
+local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
local report_resolving=logs.reporter("resolvers","resolving")
local resolvers=resolvers
local expandedpathfromlist=resolvers.expandedpathfromlist
@@ -21151,15 +21159,15 @@ resolvers.luacnfname="texmfcnf.lua"
resolvers.luacnffallback="contextcnf.lua"
resolvers.luacnfstate="unknown"
if environment.default_texmfcnf then
- resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
+ resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
else
- resolvers.luacnfspec=concat ({
- "home:texmf/web2c",
- "selfautoparent:/texmf-local/web2c",
- "selfautoparent:/texmf-context/web2c",
- "selfautoparent:/texmf-dist/web2c",
- "selfautoparent:/texmf/web2c",
- },";")
+ resolvers.luacnfspec=concat ({
+ "home:texmf/web2c",
+ "selfautoparent:/texmf-local/web2c",
+ "selfautoparent:/texmf-context/web2c",
+ "selfautoparent:/texmf-dist/web2c",
+ "selfautoparent:/texmf/web2c",
+ },";")
end
local unset_variable="unset"
local formats=resolvers.formats
@@ -21170,24 +21178,24 @@ local suffixmap=resolvers.suffixmap
resolvers.defaultsuffixes={ "tex" }
local instance=nil
function resolvers.setenv(key,value,raw)
- if instance then
- instance.environment[key]=value
- ossetenv(key,raw and value or resolveprefix(value))
- end
+ if instance then
+ instance.environment[key]=value
+ ossetenv(key,raw and value or resolveprefix(value))
+ end
end
local function getenv(key)
- local value=rawget(instance.environment,key)
- if value and value~="" then
- return value
- else
- local e=osgetenv(key)
- return e~=nil and e~="" and checkedvariable(e) or ""
- end
+ local value=rawget(instance.environment,key)
+ if value and value~="" then
+ return value
+ else
+ local e=osgetenv(key)
+ return e~=nil and e~="" and checkedvariable(e) or ""
+ end
end
resolvers.getenv=getenv
resolvers.env=getenv
local function resolvevariable(k)
- return instance.expansions[k]
+ return instance.expansions[k]
end
local dollarstripper=lpeg.stripper("$")
local inhibitstripper=P("!")^0*Cs(P(1)^0)
@@ -21201,1506 +21209,1506 @@ local somevariable=R("az","AZ","09","__","--")^1/resolvevariable
local variable=(P("$")/"")*(somevariable+(P("{")/"")*somevariable*(P("}")/""))
local variableresolver=Cs((variable+P(1))^0)
local function expandedvariable(var)
- return lpegmatch(variableexpander,var) or var
+ return lpegmatch(variableexpander,var) or var
end
function resolvers.reset()
- if trace_locating then
- report_resolving("creating instance")
- end
- local environment={}
- local variables={}
- local expansions={}
- local order={}
- instance={
- environment=environment,
- variables=variables,
- expansions=expansions,
- order=order,
- files={},
- setups={},
- found={},
- foundintrees={},
- hashes={},
- hashed={},
- pathlists=false,
- specification={},
- lists={},
- data={},
- fakepaths={},
- remember=true,
- diskcache=true,
- renewcache=false,
- renewtree=false,
- loaderror=false,
- savelists=true,
- pattern=nil,
- force_suffixes=true,
- pathstack={},
- }
- setmetatableindex(variables,function(t,k)
- local v
- for i=1,#order do
- v=order[i][k]
- if v~=nil then
- t[k]=v
- return v
- end
- end
- if v==nil then
- v=""
- end
+ if trace_locating then
+ report_resolving("creating instance")
+ end
+ local environment={}
+ local variables={}
+ local expansions={}
+ local order={}
+ instance={
+ environment=environment,
+ variables=variables,
+ expansions=expansions,
+ order=order,
+ files={},
+ setups={},
+ found={},
+ foundintrees={},
+ hashes={},
+ hashed={},
+ pathlists=false,
+ specification={},
+ lists={},
+ data={},
+ fakepaths={},
+ remember=true,
+ diskcache=true,
+ renewcache=false,
+ renewtree=false,
+ loaderror=false,
+ savelists=true,
+ pattern=nil,
+ force_suffixes=true,
+ pathstack={},
+ }
+ setmetatableindex(variables,function(t,k)
+ local v
+ for i=1,#order do
+ v=order[i][k]
+ if v~=nil then
t[k]=v
return v
- end)
- setmetatableindex(environment,function(t,k)
- local v=osgetenv(k)
- if v==nil then
- v=variables[k]
- end
- if v~=nil then
- v=checkedvariable(v) or ""
- end
- v=resolvers.repath(v)
- t[k]=v
- return v
- end)
- setmetatableindex(expansions,function(t,k)
- local v=environment[k]
- if type(v)=="string" then
- v=lpegmatch(variableresolver,v)
- v=lpegmatch(variablecleaner,v)
- end
- t[k]=v
- return v
- end)
+ end
+ end
+ if v==nil then
+ v=""
+ end
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(environment,function(t,k)
+ local v=osgetenv(k)
+ if v==nil then
+ v=variables[k]
+ end
+ if v~=nil then
+ v=checkedvariable(v) or ""
+ end
+ v=resolvers.repath(v)
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(expansions,function(t,k)
+ local v=environment[k]
+ if type(v)=="string" then
+ v=lpegmatch(variableresolver,v)
+ v=lpegmatch(variablecleaner,v)
+ end
+ t[k]=v
+ return v
+ end)
end
function resolvers.initialized()
- return instance~=nil
+ return instance~=nil
end
local function reset_hashes()
- instance.lists={}
- instance.pathlists=false
- instance.found={}
+ instance.lists={}
+ instance.pathlists=false
+ instance.found={}
end
local function reset_caches()
- instance.lists={}
- instance.pathlists=false
+ instance.lists={}
+ instance.pathlists=false
end
local slash=P("/")
local pathexpressionpattern=Cs (
- Cc("^")*(
- Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+ Cc("^")*(
+ Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+slash^2/"/"+(1-slash)*P(-1)*Cc("/")+P(1)
- )^1*Cc("$")
+ )^1*Cc("$")
)
local cache={}
local function makepathexpression(str)
- if str=="." then
- return "^%./$"
- else
- local c=cache[str]
- if not c then
- c=lpegmatch(pathexpressionpattern,str)
- cache[str]=c
- end
- return c
+ if str=="." then
+ return "^%./$"
+ else
+ local c=cache[str]
+ if not c then
+ c=lpegmatch(pathexpressionpattern,str)
+ cache[str]=c
end
+ return c
+ end
end
local function reportcriticalvariables(cnfspec)
- if trace_locating then
- for i=1,#resolvers.criticalvars do
- local k=resolvers.criticalvars[i]
- local v=resolvers.getenv(k) or "unknown"
- report_resolving("variable %a set to %a",k,v)
- end
- report_resolving()
- if cnfspec then
- report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
- end
- report_resolving()
+ if trace_locating then
+ for i=1,#resolvers.criticalvars do
+ local k=resolvers.criticalvars[i]
+ local v=resolvers.getenv(k) or "unknown"
+ report_resolving("variable %a set to %a",k,v)
+ end
+ report_resolving()
+ if cnfspec then
+ report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
end
- reportcriticalvariables=function() end
+ report_resolving()
+ end
+ reportcriticalvariables=function() end
end
local function identify_configuration_files()
- local specification=instance.specification
- if #specification==0 then
- local cnfspec=getenv("TEXMFCNF")
- if cnfspec=="" then
- cnfspec=resolvers.luacnfspec
- resolvers.luacnfstate="default"
- else
- resolvers.luacnfstate="environment"
- end
- reportcriticalvariables(cnfspec)
- local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
- local function locatecnf(luacnfname,kind)
- for i=1,#cnfpaths do
- local filepath=cnfpaths[i]
- local filename=collapsepath(filejoin(filepath,luacnfname))
- local realname=resolveprefix(filename)
- if trace_locating then
- local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
- local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
- report_resolving("looking for %s %a on %s path %a from specification %a",
- kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
- end
- if isfile(realname) then
- specification[#specification+1]=filename
- if trace_locating then
- report_resolving("found %s configuration file %a",kind,realname)
- end
- end
- end
- end
- locatecnf(resolvers.luacnfname,"regular")
- if #specification==0 then
- locatecnf(resolvers.luacnffallback,"fallback")
- end
+ local specification=instance.specification
+ if #specification==0 then
+ local cnfspec=getenv("TEXMFCNF")
+ if cnfspec=="" then
+ cnfspec=resolvers.luacnfspec
+ resolvers.luacnfstate="default"
+ else
+ resolvers.luacnfstate="environment"
+ end
+ reportcriticalvariables(cnfspec)
+ local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
+ local function locatecnf(luacnfname,kind)
+ for i=1,#cnfpaths do
+ local filepath=cnfpaths[i]
+ local filename=collapsepath(filejoin(filepath,luacnfname))
+ local realname=resolveprefix(filename)
if trace_locating then
- report_resolving()
+ local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
+ local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
+ report_resolving("looking for %s %a on %s path %a from specification %a",
+ kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
+ end
+ if isfile(realname) then
+ specification[#specification+1]=filename
+ if trace_locating then
+ report_resolving("found %s configuration file %a",kind,realname)
+ end
end
- elseif trace_locating then
- report_resolving("configuration files already identified")
+ end
end
+ locatecnf(resolvers.luacnfname,"regular")
+ if #specification==0 then
+ locatecnf(resolvers.luacnffallback,"fallback")
+ end
+ if trace_locating then
+ report_resolving()
+ end
+ elseif trace_locating then
+ report_resolving("configuration files already identified")
+ end
end
local function load_configuration_files()
- local specification=instance.specification
- if #specification>0 then
- local luacnfname=resolvers.luacnfname
- for i=1,#specification do
- local filename=specification[i]
- local pathname=filedirname(filename)
- local filename=filejoin(pathname,luacnfname)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local setups=instance.setups
- local data=blob()
- local parent=data and data.parent
- if parent then
- local filename=filejoin(pathname,parent)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local parentdata=blob()
- if parentdata then
- report_resolving("loading configuration file %a",filename)
- data=table.merged(parentdata,data)
- end
- end
- end
- data=data and data.content
- if data then
- if trace_locating then
- report_resolving("loading configuration file %a",filename)
- report_resolving()
- end
- local variables=data.variables or {}
- local warning=false
- for k,v in next,data do
- local variant=type(v)
- if variant=="table" then
- initializesetter(filename,k,v)
- elseif variables[k]==nil then
- if trace_locating and not warning then
- report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
- k,resolveprefix(filename))
- warning=true
- end
- variables[k]=v
- end
- end
- setups[pathname]=variables
- if resolvers.luacnfstate=="default" then
- local cnfspec=variables["TEXMFCNF"]
- if cnfspec then
- if trace_locating then
- report_resolving("reloading configuration due to TEXMF redefinition")
- end
- resolvers.setenv("TEXMFCNF",cnfspec)
- instance.specification={}
- identify_configuration_files()
- load_configuration_files()
- resolvers.luacnfstate="configuration"
- break
- end
- end
- else
- if trace_locating then
- report_resolving("skipping configuration file %a (no content)",filename)
- end
- setups[pathname]={}
- instance.loaderror=true
- end
- elseif trace_locating then
- report_resolving("skipping configuration file %a (no valid format)",filename)
+ local specification=instance.specification
+ if #specification>0 then
+ local luacnfname=resolvers.luacnfname
+ for i=1,#specification do
+ local filename=specification[i]
+ local pathname=filedirname(filename)
+ local filename=filejoin(pathname,luacnfname)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local setups=instance.setups
+ local data=blob()
+ local parent=data and data.parent
+ if parent then
+ local filename=filejoin(pathname,parent)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local parentdata=blob()
+ if parentdata then
+ report_resolving("loading configuration file %a",filename)
+ data=table.merged(parentdata,data)
end
- instance.order[#instance.order+1]=instance.setups[pathname]
- if instance.loaderror then
- break
+ end
+ end
+ data=data and data.content
+ if data then
+ if trace_locating then
+ report_resolving("loading configuration file %a",filename)
+ report_resolving()
+ end
+ local variables=data.variables or {}
+ local warning=false
+ for k,v in next,data do
+ local variant=type(v)
+ if variant=="table" then
+ initializesetter(filename,k,v)
+ elseif variables[k]==nil then
+ if trace_locating and not warning then
+ report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
+ k,resolveprefix(filename))
+ warning=true
+ end
+ variables[k]=v
+ end
+ end
+ setups[pathname]=variables
+ if resolvers.luacnfstate=="default" then
+ local cnfspec=variables["TEXMFCNF"]
+ if cnfspec then
+ if trace_locating then
+ report_resolving("reloading configuration due to TEXMF redefinition")
+ end
+ resolvers.setenv("TEXMFCNF",cnfspec)
+ instance.specification={}
+ identify_configuration_files()
+ load_configuration_files()
+ resolvers.luacnfstate="configuration"
+ break
end
+ end
+ else
+ if trace_locating then
+ report_resolving("skipping configuration file %a (no content)",filename)
+ end
+ setups[pathname]={}
+ instance.loaderror=true
end
- elseif trace_locating then
- report_resolving("warning: no lua configuration files found")
+ elseif trace_locating then
+ report_resolving("skipping configuration file %a (no valid format)",filename)
+ end
+ instance.order[#instance.order+1]=instance.setups[pathname]
+ if instance.loaderror then
+ break
+ end
end
+ elseif trace_locating then
+ report_resolving("warning: no lua configuration files found")
+ end
end
function resolvers.configurationfiles()
- return instance.specification or {}
+ return instance.specification or {}
end
local function load_file_databases()
- instance.loaderror=false
- instance.files={}
- if not instance.renewcache then
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- resolvers.hashers.byscheme(hash.type,hash.name)
- if instance.loaderror then break end
- end
+ instance.loaderror=false
+ instance.files={}
+ if not instance.renewcache then
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ resolvers.hashers.byscheme(hash.type,hash.name)
+ if instance.loaderror then break end
end
+ end
end
local function locate_file_databases()
- local texmfpaths=resolvers.expandedpathlist("TEXMF")
- if #texmfpaths>0 then
- for i=1,#texmfpaths do
- local path=collapsepath(texmfpaths[i])
- path=gsub(path,"/+$","")
- local stripped=lpegmatch(inhibitstripper,path)
- if stripped~="" then
- local runtime=stripped==path
- path=cleanpath(path)
- local spec=resolvers.splitmethod(stripped)
- if runtime and (spec.noscheme or spec.scheme=="file") then
- stripped="tree:///"..stripped
- elseif spec.scheme=="cache" or spec.scheme=="file" then
- stripped=spec.path
- end
- if trace_locating then
- if runtime then
- report_resolving("locating list of %a (runtime) (%s)",path,stripped)
- else
- report_resolving("locating list of %a (cached)",path)
- end
- end
- methodhandler('locators',stripped)
- end
+ local texmfpaths=resolvers.expandedpathlist("TEXMF")
+ if #texmfpaths>0 then
+ for i=1,#texmfpaths do
+ local path=collapsepath(texmfpaths[i])
+ path=gsub(path,"/+$","")
+ local stripped=lpegmatch(inhibitstripper,path)
+ if stripped~="" then
+ local runtime=stripped==path
+ path=cleanpath(path)
+ local spec=resolvers.splitmethod(stripped)
+ if runtime and (spec.noscheme or spec.scheme=="file") then
+ stripped="tree:///"..stripped
+ elseif spec.scheme=="cache" or spec.scheme=="file" then
+ stripped=spec.path
end
if trace_locating then
- report_resolving()
+ if runtime then
+ report_resolving("locating list of %a (runtime) (%s)",path,stripped)
+ else
+ report_resolving("locating list of %a (cached)",path)
+ end
end
- elseif trace_locating then
- report_resolving("no texmf paths are defined (using TEXMF)")
- end
-end
-local function generate_file_databases()
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- methodhandler('generators',hash.name)
+ methodhandler('locators',stripped)
+ end
end
if trace_locating then
- report_resolving()
+ report_resolving()
end
+ elseif trace_locating then
+ report_resolving("no texmf paths are defined (using TEXMF)")
+ end
+end
+local function generate_file_databases()
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ methodhandler('generators',hash.name)
+ end
+ if trace_locating then
+ report_resolving()
+ end
end
local function save_file_databases()
- for i=1,#instance.hashes do
- local hash=instance.hashes[i]
- local cachename=hash.name
- if hash.cache then
- local content=instance.files[cachename]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",cachename)
- end
- caches.savecontent(cachename,"files",content)
- elseif trace_locating then
- report_resolving("not saving runtime tree %a",cachename)
- end
+ for i=1,#instance.hashes do
+ local hash=instance.hashes[i]
+ local cachename=hash.name
+ if hash.cache then
+ local content=instance.files[cachename]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",cachename)
+ end
+ caches.savecontent(cachename,"files",content)
+ elseif trace_locating then
+ report_resolving("not saving runtime tree %a",cachename)
end
+ end
end
function resolvers.renew(hashname)
- if hashname and hashname~="" then
- local expanded=resolvers.expansion(hashname) or ""
- if expanded~="" then
- if trace_locating then
- report_resolving("identifying tree %a from %a",expanded,hashname)
- end
- hashname=expanded
- else
- if trace_locating then
- report_resolving("identifying tree %a",hashname)
- end
- end
- local realpath=resolveprefix(hashname)
- if isdir(realpath) then
- if trace_locating then
- report_resolving("using path %a",realpath)
- end
- methodhandler('generators',hashname)
- local content=instance.files[hashname]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",hashname)
- end
- caches.savecontent(hashname,"files",content)
- else
- report_resolving("invalid path %a",realpath)
- end
+ if hashname and hashname~="" then
+ local expanded=resolvers.expansion(hashname) or ""
+ if expanded~="" then
+ if trace_locating then
+ report_resolving("identifying tree %a from %a",expanded,hashname)
+ end
+ hashname=expanded
+ else
+ if trace_locating then
+ report_resolving("identifying tree %a",hashname)
+ end
end
+ local realpath=resolveprefix(hashname)
+ if isdir(realpath) then
+ if trace_locating then
+ report_resolving("using path %a",realpath)
+ end
+ methodhandler('generators',hashname)
+ local content=instance.files[hashname]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",hashname)
+ end
+ caches.savecontent(hashname,"files",content)
+ else
+ report_resolving("invalid path %a",realpath)
+ end
+ end
end
local function load_databases()
- locate_file_databases()
- if instance.diskcache and not instance.renewcache then
- load_file_databases()
- if instance.loaderror then
- generate_file_databases()
- save_file_databases()
- end
- else
- generate_file_databases()
- if instance.renewcache then
- save_file_databases()
- end
+ locate_file_databases()
+ if instance.diskcache and not instance.renewcache then
+ load_file_databases()
+ if instance.loaderror then
+ generate_file_databases()
+ save_file_databases()
+ end
+ else
+ generate_file_databases()
+ if instance.renewcache then
+ save_file_databases()
end
+ end
end
function resolvers.appendhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a appended",name)
- end
- insert(instance.hashes,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a appended",name)
end
+ insert(instance.hashes,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.prependhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a prepended",name)
- end
- insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a prepended",name)
end
+ insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.extendtexmfvariable(specification)
- local t=resolvers.splitpath(getenv("TEXMF"))
- insert(t,1,specification)
- local newspec=concat(t,",")
- if instance.environment["TEXMF"] then
- instance.environment["TEXMF"]=newspec
- elseif instance.variables["TEXMF"] then
- instance.variables["TEXMF"]=newspec
- else
- end
- reset_hashes()
+ local t=resolvers.splitpath(getenv("TEXMF"))
+ insert(t,1,specification)
+ local newspec=concat(t,",")
+ if instance.environment["TEXMF"] then
+ instance.environment["TEXMF"]=newspec
+ elseif instance.variables["TEXMF"] then
+ instance.variables["TEXMF"]=newspec
+ else
+ end
+ reset_hashes()
end
function resolvers.splitexpansions()
- local ie=instance.expansions
- for k,v in next,ie do
- local t,tn,h,p={},0,{},splitconfigurationpath(v)
- for kk=1,#p do
- local vv=p[kk]
- if vv~="" and not h[vv] then
- tn=tn+1
- t[tn]=vv
- h[vv]=true
- end
- end
- if #t>1 then
- ie[k]=t
- else
- ie[k]=t[1]
- end
+ local ie=instance.expansions
+ for k,v in next,ie do
+ local t,tn,h,p={},0,{},splitconfigurationpath(v)
+ for kk=1,#p do
+ local vv=p[kk]
+ if vv~="" and not h[vv] then
+ tn=tn+1
+ t[tn]=vv
+ h[vv]=true
+ end
end
+ if #t>1 then
+ ie[k]=t
+ else
+ ie[k]=t[1]
+ end
+ end
end
function resolvers.datastate()
- return caches.contentstate()
+ return caches.contentstate()
end
function resolvers.variable(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.variables[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.variables[name]
+ return result~=nil and result or ""
end
function resolvers.expansion(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.expansions[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.expansions[name]
+ return result~=nil and result or ""
end
function resolvers.unexpandedpathlist(str)
- local pth=resolvers.variable(str)
- local lst=resolvers.splitpath(pth)
- return expandedpathfromlist(lst)
+ local pth=resolvers.variable(str)
+ local lst=resolvers.splitpath(pth)
+ return expandedpathfromlist(lst)
end
function resolvers.unexpandedpath(str)
- return joinpath(resolvers.unexpandedpathlist(str))
+ return joinpath(resolvers.unexpandedpathlist(str))
end
function resolvers.pushpath(name)
- local pathstack=instance.pathstack
- local lastpath=pathstack[#pathstack]
- local pluspath=filedirname(name)
- if lastpath then
- lastpath=collapsepath(filejoin(lastpath,pluspath))
- else
- lastpath=collapsepath(pluspath)
- end
- insert(pathstack,lastpath)
- if trace_paths then
- report_resolving("pushing path %a",lastpath)
- end
+ local pathstack=instance.pathstack
+ local lastpath=pathstack[#pathstack]
+ local pluspath=filedirname(name)
+ if lastpath then
+ lastpath=collapsepath(filejoin(lastpath,pluspath))
+ else
+ lastpath=collapsepath(pluspath)
+ end
+ insert(pathstack,lastpath)
+ if trace_paths then
+ report_resolving("pushing path %a",lastpath)
+ end
end
function resolvers.poppath()
- local pathstack=instance.pathstack
- if trace_paths and #pathstack>0 then
- report_resolving("popping path %a",pathstack[#pathstack])
- end
- remove(pathstack)
+ local pathstack=instance.pathstack
+ if trace_paths and #pathstack>0 then
+ report_resolving("popping path %a",pathstack[#pathstack])
+ end
+ remove(pathstack)
end
function resolvers.stackpath()
- local pathstack=instance.pathstack
- local currentpath=pathstack[#pathstack]
- return currentpath~="" and currentpath or nil
+ local pathstack=instance.pathstack
+ local currentpath=pathstack[#pathstack]
+ return currentpath~="" and currentpath or nil
end
local done={}
function resolvers.resetextrapaths()
- local ep=instance.extra_paths
- if not ep then
- done={}
- instance.extra_paths={}
- elseif #ep>0 then
- done={}
- reset_caches()
- end
+ local ep=instance.extra_paths
+ if not ep then
+ done={}
+ instance.extra_paths={}
+ elseif #ep>0 then
+ done={}
+ reset_caches()
+ end
end
function resolvers.getextrapaths()
- return instance.extra_paths or {}
+ return instance.extra_paths or {}
end
function resolvers.registerextrapath(paths,subpaths)
- if not subpaths or subpaths=="" then
- if not paths or path=="" then
- return
- elseif done[paths] then
- return
- end
- end
- local paths=settings_to_array(paths)
- local subpaths=settings_to_array(subpaths)
- local ep=instance.extra_paths or {}
- local oldn=#ep
- local newn=oldn
- local nofpaths=#paths
- local nofsubpaths=#subpaths
- if nofpaths>0 then
- if nofsubpaths>0 then
- for i=1,nofpaths do
- local p=paths[i]
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=p.."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
- end
- else
- for i=1,nofpaths do
- local p=paths[i]
- if not done[p] then
- newn=newn+1
- ep[newn]=cleanpath(p)
- done[p]=true
- end
- end
+ if not subpaths or subpaths=="" then
+ if not paths or path=="" then
+ return
+ elseif done[paths] then
+ return
+ end
+ end
+ local paths=settings_to_array(paths)
+ local subpaths=settings_to_array(subpaths)
+ local ep=instance.extra_paths or {}
+ local oldn=#ep
+ local newn=oldn
+ local nofpaths=#paths
+ local nofsubpaths=#subpaths
+ if nofpaths>0 then
+ if nofsubpaths>0 then
+ for i=1,nofpaths do
+ local p=paths[i]
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=p.."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
end
- elseif nofsubpaths>0 then
- for i=1,oldn do
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=ep[i].."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
+ end
+ else
+ for i=1,nofpaths do
+ local p=paths[i]
+ if not done[p] then
+ newn=newn+1
+ ep[newn]=cleanpath(p)
+ done[p]=true
end
+ end
end
- if newn>0 then
- instance.extra_paths=ep
- end
- if newn~=oldn then
- reset_caches()
+ elseif nofsubpaths>0 then
+ for i=1,oldn do
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=ep[i].."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
+ end
end
+ end
+ if newn>0 then
+ instance.extra_paths=ep
+ end
+ if newn~=oldn then
+ reset_caches()
+ end
end
function resolvers.pushextrapath(path)
- local paths=settings_to_array(path)
- if instance.extra_stack then
- insert(instance.extra_stack,1,paths)
- else
- instance.extra_stack={ paths }
- end
- reset_caches()
+ local paths=settings_to_array(path)
+ if instance.extra_stack then
+ insert(instance.extra_stack,1,paths)
+ else
+ instance.extra_stack={ paths }
+ end
+ reset_caches()
end
function resolvers.popextrapath()
- if instance.extra_stack then
- reset_caches()
- return remove(instance.extra_stack,1)
- end
+ if instance.extra_stack then
+ reset_caches()
+ return remove(instance.extra_stack,1)
+ end
end
local function made_list(instance,list,extra_too)
- local done={}
- local new={}
- local newn=0
- local function add(p)
- for k=1,#p do
- local v=p[k]
- if not done[v] then
- done[v]=true
- newn=newn+1
- new[newn]=v
- end
- end
+ local done={}
+ local new={}
+ local newn=0
+ local function add(p)
+ for k=1,#p do
+ local v=p[k]
+ if not done[v] then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ end
end
- for k=1,#list do
- local v=list[k]
- if done[v] then
- elseif find(v,"^[%.%/]$") then
- done[v]=true
- newn=newn+1
- new[newn]=v
- else
- break
- end
+ end
+ for k=1,#list do
+ local v=list[k]
+ if done[v] then
+ elseif find(v,"^[%.%/]$") then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ else
+ break
+ end
+ end
+ if extra_too then
+ local es=instance.extra_stack
+ if es and #es>0 then
+ for k=1,#es do
+ add(es[k])
+ end
end
- if extra_too then
- local es=instance.extra_stack
- if es and #es>0 then
- for k=1,#es do
- add(es[k])
- end
- end
- local ep=instance.extra_paths
- if ep and #ep>0 then
- add(ep)
- end
+ local ep=instance.extra_paths
+ if ep and #ep>0 then
+ add(ep)
end
- add(list)
- return new
+ end
+ add(list)
+ return new
end
function resolvers.cleanpathlist(str)
- local t=resolvers.expandedpathlist(str)
- if t then
- for i=1,#t do
- t[i]=collapsepath(cleanpath(t[i]))
- end
+ local t=resolvers.expandedpathlist(str)
+ if t then
+ for i=1,#t do
+ t[i]=collapsepath(cleanpath(t[i]))
end
- return t
+ end
+ return t
end
function resolvers.expandpath(str)
- return joinpath(resolvers.expandedpathlist(str))
+ return joinpath(resolvers.expandedpathlist(str))
end
function resolvers.expandedpathlist(str,extra_too)
- if not str then
- return {}
- elseif instance.savelists then
- str=lpegmatch(dollarstripper,str)
- local lists=instance.lists
- local lst=lists[str]
- if not lst then
- local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
- lst=expandedpathfromlist(l)
- lists[str]=lst
- end
- return lst
- else
- local lst=resolvers.splitpath(resolvers.expansion(str))
- return made_list(instance,expandedpathfromlist(lst),extra_too)
+ if not str then
+ return {}
+ elseif instance.savelists then
+ str=lpegmatch(dollarstripper,str)
+ local lists=instance.lists
+ local lst=lists[str]
+ if not lst then
+ local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
+ lst=expandedpathfromlist(l)
+ lists[str]=lst
end
+ return lst
+ else
+ local lst=resolvers.splitpath(resolvers.expansion(str))
+ return made_list(instance,expandedpathfromlist(lst),extra_too)
+ end
end
function resolvers.expandedpathlistfromvariable(str)
- str=lpegmatch(dollarstripper,str)
- local tmp=resolvers.variableofformatorsuffix(str)
- return resolvers.expandedpathlist(tmp~="" and tmp or str)
+ str=lpegmatch(dollarstripper,str)
+ local tmp=resolvers.variableofformatorsuffix(str)
+ return resolvers.expandedpathlist(tmp~="" and tmp or str)
end
function resolvers.expandpathfromvariable(str)
- return joinpath(resolvers.expandedpathlistfromvariable(str))
+ return joinpath(resolvers.expandedpathlistfromvariable(str))
end
function resolvers.cleanedpathlist(v)
- local t=resolvers.expandedpathlist(v)
- for i=1,#t do
- t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
- end
- return t
+ local t=resolvers.expandedpathlist(v)
+ for i=1,#t do
+ t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
+ end
+ return t
end
function resolvers.expandbraces(str)
- local pth=expandedpathfromlist(resolvers.splitpath(str))
- return joinpath(pth)
+ local pth=expandedpathfromlist(resolvers.splitpath(str))
+ return joinpath(pth)
end
function resolvers.registerfilehash(name,content,someerror)
- if content then
- instance.files[name]=content
- else
- instance.files[name]={}
- if somerror==true then
- instance.loaderror=someerror
- end
+ if content then
+ instance.files[name]=content
+ else
+ instance.files[name]={}
+ if somerror==true then
+ instance.loaderror=someerror
end
+ end
end
function resolvers.getfilehashes()
- return instance and instance.files or {}
+ return instance and instance.files or {}
end
function resolvers.gethashes()
- return instance and instance.hashes or {}
+ return instance and instance.hashes or {}
end
function resolvers.renewcache()
- if instance then
- instance.renewcache=true
- end
+ if instance then
+ instance.renewcache=true
+ end
end
local function isreadable(name)
- local readable=isfile(name)
- if trace_detail then
- if readable then
- report_resolving("file %a is readable",name)
- else
- report_resolving("file %a is not readable",name)
- end
+ local readable=isfile(name)
+ if trace_detail then
+ if readable then
+ report_resolving("file %a is readable",name)
+ else
+ report_resolving("file %a is not readable",name)
end
- return readable
+ end
+ return readable
end
local function collect_files(names)
- local filelist={}
- local noffiles=0
- local function check(hash,root,pathname,path,basename,name)
- if not pathname or find(path,pathname) then
- local variant=hash.type
- local search=filejoin(root,path,name)
- local result=methodhandler('concatinators',variant,root,path,name)
- if trace_detail then
- report_resolving("match: variant %a, search %a, result %a",variant,search,result)
- end
- noffiles=noffiles+1
- filelist[noffiles]={ variant,search,result }
- end
+ local filelist={}
+ local noffiles=0
+ local function check(hash,root,pathname,path,basename,name)
+ if not pathname or find(path,pathname) then
+ local variant=hash.type
+ local search=filejoin(root,path,name)
+ local result=methodhandler('concatinators',variant,root,path,name)
+ if trace_detail then
+ report_resolving("match: variant %a, search %a, result %a",variant,search,result)
+ end
+ noffiles=noffiles+1
+ filelist[noffiles]={ variant,search,result }
end
- for k=1,#names do
- local filename=names[k]
+ end
+ for k=1,#names do
+ local filename=names[k]
+ if trace_detail then
+ report_resolving("checking name %a",filename)
+ end
+ local basename=filebasename(filename)
+ local pathname=filedirname(filename)
+ if pathname=="" or find(pathname,"^%.") then
+ pathname=false
+ else
+ pathname=gsub(pathname,"%*",".*")
+ pathname="/"..pathname.."$"
+ end
+ local hashes=instance.hashes
+ for h=1,#hashes do
+ local hash=hashes[h]
+ local hashname=hash.name
+ local content=hashname and instance.files[hashname]
+ if content then
if trace_detail then
- report_resolving("checking name %a",filename)
+ report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
end
- local basename=filebasename(filename)
- local pathname=filedirname(filename)
- if pathname=="" or find(pathname,"^%.") then
- pathname=false
- else
- pathname=gsub(pathname,"%*",".*")
- pathname="/"..pathname.."$"
- end
- local hashes=instance.hashes
- for h=1,#hashes do
- local hash=hashes[h]
- local hashname=hash.name
- local content=hashname and instance.files[hashname]
- if content then
- if trace_detail then
- report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
- end
- local path,name=lookup(content,basename)
- if path then
- local metadata=content.metadata
- local realroot=metadata and metadata.path or hashname
- if type(path)=="string" then
- check(hash,realroot,pathname,path,basename,name)
- else
- for i=1,#path do
- check(hash,realroot,pathname,path[i],basename,name)
- end
- end
- end
- elseif trace_locating then
- report_resolving("no match in %a (%s)",hashname,basename)
+ local path,name=lookup(content,basename)
+ if path then
+ local metadata=content.metadata
+ local realroot=metadata and metadata.path or hashname
+ if type(path)=="string" then
+ check(hash,realroot,pathname,path,basename,name)
+ else
+ for i=1,#path do
+ check(hash,realroot,pathname,path[i],basename,name)
end
+ end
end
+ elseif trace_locating then
+ report_resolving("no match in %a (%s)",hashname,basename)
+ end
end
- return noffiles>0 and filelist or nil
+ end
+ return noffiles>0 and filelist or nil
end
local fit={}
function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname)
- local foundintrees=instance.foundintrees
- if usedmethod=="direct" and filename==foundname and fit[foundname] then
- else
- local collapsed=collapsepath(foundname,true)
- local t={
- filename=filename,
- format=format~="" and format or nil,
- filetype=filetype~="" and filetype or nil,
- usedmethod=usedmethod,
- foundname=foundname,
- fullname=collapsed,
- }
- fit[foundname]=t
- foundintrees[#foundintrees+1]=t
- end
+ local foundintrees=instance.foundintrees
+ if usedmethod=="direct" and filename==foundname and fit[foundname] then
+ else
+ local collapsed=collapsepath(foundname,true)
+ local t={
+ filename=filename,
+ format=format~="" and format or nil,
+ filetype=filetype~="" and filetype or nil,
+ usedmethod=usedmethod,
+ foundname=foundname,
+ fullname=collapsed,
+ }
+ fit[foundname]=t
+ foundintrees[#foundintrees+1]=t
+ end
end
function resolvers.foundintrees()
- return instance.foundintrees or {}
+ return instance.foundintrees or {}
end
function resolvers.foundintree(fullname)
- local f=fit[fullname]
- return f and f.usedmethod=="database"
+ local f=fit[fullname]
+ return f and f.usedmethod=="database"
end
local function can_be_dir(name)
- local fakepaths=instance.fakepaths
- if not fakepaths[name] then
- if isdir(name) then
- fakepaths[name]=1
- else
- fakepaths[name]=2
- end
+ local fakepaths=instance.fakepaths
+ if not fakepaths[name] then
+ if isdir(name) then
+ fakepaths[name]=1
+ else
+ fakepaths[name]=2
end
- return fakepaths[name]==1
+ end
+ return fakepaths[name]==1
end
local preparetreepattern=Cs((P(".")/"%%."+P("-")/"%%-"+P(1))^0*Cc("$"))
local collect_instance_files
local function find_analyze(filename,askedformat,allresults)
- local filetype=''
- local filesuffix=suffixonly(filename)
- local wantedfiles={}
- wantedfiles[#wantedfiles+1]=filename
- if askedformat=="" then
- if filesuffix=="" or not suffixmap[filesuffix] then
- local defaultsuffixes=resolvers.defaultsuffixes
- local formatofsuffix=resolvers.formatofsuffix
- for i=1,#defaultsuffixes do
- local forcedname=filename..'.'..defaultsuffixes[i]
- wantedfiles[#wantedfiles+1]=forcedname
- filetype=formatofsuffix(forcedname)
- if trace_locating then
- report_resolving("forcing filetype %a",filetype)
- end
- end
- else
- filetype=resolvers.formatofsuffix(filename)
- if trace_locating then
- report_resolving("using suffix based filetype %a",filetype)
- end
+ local filetype=''
+ local filesuffix=suffixonly(filename)
+ local wantedfiles={}
+ wantedfiles[#wantedfiles+1]=filename
+ if askedformat=="" then
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local defaultsuffixes=resolvers.defaultsuffixes
+ local formatofsuffix=resolvers.formatofsuffix
+ for i=1,#defaultsuffixes do
+ local forcedname=filename..'.'..defaultsuffixes[i]
+ wantedfiles[#wantedfiles+1]=forcedname
+ filetype=formatofsuffix(forcedname)
+ if trace_locating then
+ report_resolving("forcing filetype %a",filetype)
end
+ end
else
- if filesuffix=="" or not suffixmap[filesuffix] then
- local format_suffixes=suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
- end
- end
- end
- filetype=askedformat
- if trace_locating then
- report_resolving("using given filetype %a",filetype)
+ filetype=resolvers.formatofsuffix(filename)
+ if trace_locating then
+ report_resolving("using suffix based filetype %a",filetype)
+ end
+ end
+ else
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local format_suffixes=suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
end
+ end
end
- return filetype,wantedfiles
+ filetype=askedformat
+ if trace_locating then
+ report_resolving("using given filetype %a",filetype)
+ end
+ end
+ return filetype,wantedfiles
end
local function find_direct(filename,allresults)
- if not dangerous[askedformat] and isreadable(filename) then
- if trace_detail then
- report_resolving("file %a found directly",filename)
- end
- return "direct",{ filename }
+ if not dangerous[askedformat] and isreadable(filename) then
+ if trace_detail then
+ report_resolving("file %a found directly",filename)
end
+ return "direct",{ filename }
+ end
end
local function find_wildcard(filename,allresults)
- if find(filename,'*',1,true) then
- if trace_locating then
- report_resolving("checking wildcard %a",filename)
- end
- local result=resolvers.findwildcardfiles(filename)
- if result then
- return "wildcard",result
- end
- end
-end
-local function find_qualified(filename,allresults,askedformat,alsostripped)
- if not is_qualified_path(filename) then
- return
- end
+ if find(filename,'*',1,true) then
if trace_locating then
- report_resolving("checking qualified name %a",filename)
+ report_resolving("checking wildcard %a",filename)
end
- if isreadable(filename) then
- if trace_detail then
- report_resolving("qualified file %a found",filename)
- end
- return "qualified",{ filename }
+ local result=resolvers.findwildcardfiles(filename)
+ if result then
+ return "wildcard",result
end
+ end
+end
+local function find_qualified(filename,allresults,askedformat,alsostripped)
+ if not is_qualified_path(filename) then
+ return
+ end
+ if trace_locating then
+ report_resolving("checking qualified name %a",filename)
+ end
+ if isreadable(filename) then
if trace_detail then
- report_resolving("locating qualified file %a",filename)
- end
- local forcedname,suffix="",suffixonly(filename)
- if suffix=="" then
- local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- local s=format_suffixes[i]
- forcedname=filename.."."..s
- if isreadable(forcedname) then
- if trace_locating then
- report_resolving("no suffix, forcing format filetype %a",s)
- end
- return "qualified",{ forcedname }
- end
- end
+ report_resolving("qualified file %a found",filename)
+ end
+ return "qualified",{ filename }
+ end
+ if trace_detail then
+ report_resolving("locating qualified file %a",filename)
+ end
+ local forcedname,suffix="",suffixonly(filename)
+ if suffix=="" then
+ local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ local s=format_suffixes[i]
+ forcedname=filename.."."..s
+ if isreadable(forcedname) then
+ if trace_locating then
+ report_resolving("no suffix, forcing format filetype %a",s)
+ end
+ return "qualified",{ forcedname }
end
+ end
end
- if alsostripped and suffix and suffix~="" then
- local basename=filebasename(filename)
- local pattern=lpegmatch(preparetreepattern,filename)
- local savedformat=askedformat
- local format=savedformat or ""
- if format=="" then
- askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if alsostripped and suffix and suffix~="" then
+ local basename=filebasename(filename)
+ local pattern=lpegmatch(preparetreepattern,filename)
+ local savedformat=askedformat
+ local format=savedformat or ""
+ if format=="" then
+ askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if not format then
+ askedformat="othertextfiles"
+ end
+ if basename~=filename then
+ local resolved=collect_instance_files(basename,askedformat,allresults)
+ if #resolved==0 then
+ local lowered=lower(basename)
+ if filename~=lowered then
+ resolved=collect_instance_files(lowered,askedformat,allresults)
end
- if not format then
- askedformat="othertextfiles"
+ end
+ resolvers.format=savedformat
+ if #resolved>0 then
+ local result={}
+ for r=1,#resolved do
+ local rr=resolved[r]
+ if find(rr,pattern) then
+ result[#result+1]=rr
+ end
end
- if basename~=filename then
- local resolved=collect_instance_files(basename,askedformat,allresults)
- if #resolved==0 then
- local lowered=lower(basename)
- if filename~=lowered then
- resolved=collect_instance_files(lowered,askedformat,allresults)
- end
- end
- resolvers.format=savedformat
- if #resolved>0 then
- local result={}
- for r=1,#resolved do
- local rr=resolved[r]
- if find(rr,pattern) then
- result[#result+1]=rr
- end
- end
- if #result>0 then
- return "qualified",result
- end
- end
+ if #result>0 then
+ return "qualified",result
end
+ end
end
+ end
end
local function check_subpath(fname)
- if isreadable(fname) then
- if trace_detail then
- report_resolving("found %a by deep scanning",fname)
- end
- return fname
+ if isreadable(fname) then
+ if trace_detail then
+ report_resolving("found %a by deep scanning",fname)
end
+ return fname
+ end
end
local function makepathlist(list,filetype)
- local typespec=resolvers.variableofformat(filetype)
- local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
- local entry={}
- if pathlist and #pathlist>0 then
- for k=1,#pathlist do
- local path=pathlist[k]
- local prescanned=find(path,'^!!')
- local resursive=find(path,'//$')
- local pathname=lpegmatch(inhibitstripper,path)
- local expression=makepathexpression(pathname)
- local barename=gsub(pathname,"/+$","")
- barename=resolveprefix(barename)
- local scheme=url.hasscheme(barename)
- local schemename=gsub(barename,"%.%*$",'')
- entry[k]={
- path=path,
- pathname=pathname,
- prescanned=prescanned,
- recursive=recursive,
- expression=expression,
- barename=barename,
- scheme=scheme,
- schemename=schemename,
- }
- end
- entry.typespec=typespec
- list[filetype]=entry
- else
- list[filetype]=false
- end
- return entry
+ local typespec=resolvers.variableofformat(filetype)
+ local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
+ local entry={}
+ if pathlist and #pathlist>0 then
+ for k=1,#pathlist do
+ local path=pathlist[k]
+ local prescanned=find(path,'^!!')
+ local resursive=find(path,'//$')
+ local pathname=lpegmatch(inhibitstripper,path)
+ local expression=makepathexpression(pathname)
+ local barename=gsub(pathname,"/+$","")
+ barename=resolveprefix(barename)
+ local scheme=url.hasscheme(barename)
+ local schemename=gsub(barename,"%.%*$",'')
+ entry[k]={
+ path=path,
+ pathname=pathname,
+ prescanned=prescanned,
+ recursive=recursive,
+ expression=expression,
+ barename=barename,
+ scheme=scheme,
+ schemename=schemename,
+ }
+ end
+ entry.typespec=typespec
+ list[filetype]=entry
+ else
+ list[filetype]=false
+ end
+ return entry
end
local function find_intree(filename,filetype,wantedfiles,allresults)
- local pathlists=instance.pathlists
- if not pathlists then
- pathlists=setmetatableindex({},makepathlist)
- instance.pathlists=pathlists
- end
- local pathlist=pathlists[filetype]
- if pathlist then
- local method="intree"
- local filelist=collect_files(wantedfiles)
- local dirlist={}
- local result={}
- if filelist then
- for i=1,#filelist do
- dirlist[i]=filedirname(filelist[i][3]).."/"
+ local pathlists=instance.pathlists
+ if not pathlists then
+ pathlists=setmetatableindex({},makepathlist)
+ instance.pathlists=pathlists
+ end
+ local pathlist=pathlists[filetype]
+ if pathlist then
+ local method="intree"
+ local filelist=collect_files(wantedfiles)
+ local dirlist={}
+ local result={}
+ if filelist then
+ for i=1,#filelist do
+ dirlist[i]=filedirname(filelist[i][3]).."/"
+ end
+ end
+ if trace_detail then
+ report_resolving("checking filename %a in tree",filename)
+ end
+ for k=1,#pathlist do
+ local entry=pathlist[k]
+ local path=entry.path
+ local pathname=entry.pathname
+ local done=false
+ if filelist then
+ local expression=entry.expression
+ if trace_detail then
+ report_resolving("using pattern %a for path %a",expression,pathname)
+ end
+ for k=1,#filelist do
+ local fl=filelist[k]
+ local f=fl[2]
+ local d=dirlist[k]
+ if find(d,expression) or find(resolveprefix(d),expression) then
+ result[#result+1]=resolveprefix(fl[3])
+ done=true
+ if allresults then
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
+ end
+ else
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
+ end
+ break
end
+ elseif trace_detail then
+ report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ end
end
- if trace_detail then
- report_resolving("checking filename %a in tree",filename)
- end
- for k=1,#pathlist do
- local entry=pathlist[k]
- local path=entry.path
- local pathname=entry.pathname
- local done=false
- if filelist then
- local expression=entry.expression
+ end
+ if done then
+ method="database"
+ else
+ method="filesystem"
+ local scheme=entry.scheme
+ if not scheme or scheme=="file" then
+ local pname=entry.schemename
+ if not find(pname,"*",1,true) then
+ if can_be_dir(pname) then
+ if not done and not entry.prescanned then
if trace_detail then
- report_resolving("using pattern %a for path %a",expression,pathname)
+ report_resolving("quick root scan for %a",pname)
end
- for k=1,#filelist do
- local fl=filelist[k]
- local f=fl[2]
- local d=dirlist[k]
- if find(d,expression) or find(resolveprefix(d),expression) then
- result[#result+1]=resolveprefix(fl[3])
- done=true
- if allresults then
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
- end
- else
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
- end
- break
- end
- elseif trace_detail then
- report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local fname=check_subpath(filejoin(pname,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
- end
- end
- if done then
- method="database"
- else
- method="filesystem"
- local scheme=entry.scheme
- if not scheme or scheme=="file" then
- local pname=entry.schemename
- if not find(pname,"*",1,true) then
- if can_be_dir(pname) then
- if not done and not entry.prescanned then
- if trace_detail then
- report_resolving("quick root scan for %a",pname)
- end
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local fname=check_subpath(filejoin(pname,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- if not done and entry.recursive then
- if trace_detail then
- report_resolving("scanning filesystem for %a",pname)
- end
- local files=resolvers.simplescanfiles(pname,false,true)
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local subpath=files[w]
- if not subpath or subpath=="" then
- elseif type(subpath)=="string" then
- local fname=check_subpath(filejoin(pname,subpath,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- else
- for i=1,#subpath do
- local sp=subpath[i]
- if sp=="" then
- else
- local fname=check_subpath(filejoin(pname,sp,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- end
- if done and not allresults then
- break
- end
- end
- end
- end
- end
+ end
+ end
+ if not done and entry.recursive then
+ if trace_detail then
+ report_resolving("scanning filesystem for %a",pname)
+ end
+ local files=resolvers.simplescanfiles(pname,false,true)
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local subpath=files[w]
+ if not subpath or subpath=="" then
+ elseif type(subpath)=="string" then
+ local fname=check_subpath(filejoin(pname,subpath,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
+ end
else
- end
- else
- for k=1,#wantedfiles do
- local pname=entry.barename
- local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
- if fname then
+ for i=1,#subpath do
+ local sp=subpath[i]
+ if sp=="" then
+ else
+ local fname=check_subpath(filejoin(pname,sp,w))
+ if fname then
result[#result+1]=fname
done=true
if not allresults then
- break
+ break
end
+ end
end
+ end
+ if done and not allresults then
+ break
+ end
end
+ end
end
+ end
end
- if done and not allresults then
+ else
+ end
+ else
+ for k=1,#wantedfiles do
+ local pname=entry.barename
+ local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
break
+ end
end
+ end
end
- if #result>0 then
- return method,result
- end
+ end
+ if done and not allresults then
+ break
+ end
end
+ if #result>0 then
+ return method,result
+ end
+ end
end
local function find_onpath(filename,filetype,wantedfiles,allresults)
- if trace_detail then
- report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
- end
- local result={}
- for k=1,#wantedfiles do
- local fname=wantedfiles[k]
- if fname and isreadable(fname) then
- filename=fname
- result[#result+1]=filejoin('.',fname)
- if not allresults then
- break
- end
- end
- end
- if #result>0 then
- return "onpath",result
+ if trace_detail then
+ report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
+ end
+ local result={}
+ for k=1,#wantedfiles do
+ local fname=wantedfiles[k]
+ if fname and isreadable(fname) then
+ filename=fname
+ result[#result+1]=filejoin('.',fname)
+ if not allresults then
+ break
+ end
end
+ end
+ if #result>0 then
+ return "onpath",result
+ end
end
local function find_otherwise(filename,filetype,wantedfiles,allresults)
- local filelist=collect_files(wantedfiles)
- local fl=filelist and filelist[1]
- if fl then
- return "otherwise",{ resolveprefix(fl[3]) }
- end
+ local filelist=collect_files(wantedfiles)
+ local fl=filelist and filelist[1]
+ if fl then
+ return "otherwise",{ resolveprefix(fl[3]) }
+ end
end
collect_instance_files=function(filename,askedformat,allresults)
- if not filename or filename=="" then
- return {}
- end
- askedformat=askedformat or ""
- filename=collapsepath(filename,".")
- filename=gsub(filename,"^%./",getcurrentdir().."/")
- if allresults then
- local filetype,wantedfiles=find_analyze(filename,askedformat)
- local results={
- { find_direct (filename,true) },
- { find_wildcard (filename,true) },
- { find_qualified(filename,true,askedformat) },
- { find_intree (filename,filetype,wantedfiles,true) },
- { find_onpath (filename,filetype,wantedfiles,true) },
- { find_otherwise(filename,filetype,wantedfiles,true) },
- }
- local result,status,done={},{},{}
- for k,r in next,results do
- local method,list=r[1],r[2]
- if method and list then
- for i=1,#list do
- local c=collapsepath(list[i])
- if not done[c] then
- result[#result+1]=c
- done[c]=true
- end
- status[#status+1]=formatters["%-10s: %s"](method,c)
- end
- end
- end
- if trace_detail then
- report_resolving("lookup status: %s",table.serialize(status,filename))
+ if not filename or filename=="" then
+ return {}
+ end
+ askedformat=askedformat or ""
+ filename=collapsepath(filename,".")
+ filename=gsub(filename,"^%./",getcurrentdir().."/")
+ if allresults then
+ local filetype,wantedfiles=find_analyze(filename,askedformat)
+ local results={
+ { find_direct (filename,true) },
+ { find_wildcard (filename,true) },
+ { find_qualified(filename,true,askedformat) },
+ { find_intree (filename,filetype,wantedfiles,true) },
+ { find_onpath (filename,filetype,wantedfiles,true) },
+ { find_otherwise(filename,filetype,wantedfiles,true) },
+ }
+ local result,status,done={},{},{}
+ for k,r in next,results do
+ local method,list=r[1],r[2]
+ if method and list then
+ for i=1,#list do
+ local c=collapsepath(list[i])
+ if not done[c] then
+ result[#result+1]=c
+ done[c]=true
+ end
+ status[#status+1]=formatters["%-10s: %s"](method,c)
end
- return result,status
- else
- local method,result,stamp,filetype,wantedfiles
- if instance.remember then
- if askedformat=="" then
- stamp=formatters["%s::%s"](suffixonly(filename),filename)
- else
- stamp=formatters["%s::%s"](askedformat,filename)
- end
- result=stamp and instance.found[stamp]
- if result then
- if trace_locating then
- report_resolving("remembered file %a",filename)
- end
- return result
- end
+ end
+ end
+ if trace_detail then
+ report_resolving("lookup status: %s",table.serialize(status,filename))
+ end
+ return result,status
+ else
+ local method,result,stamp,filetype,wantedfiles
+ if instance.remember then
+ if askedformat=="" then
+ stamp=formatters["%s::%s"](suffixonly(filename),filename)
+ else
+ stamp=formatters["%s::%s"](askedformat,filename)
+ end
+ result=stamp and instance.found[stamp]
+ if result then
+ if trace_locating then
+ report_resolving("remembered file %a",filename)
end
- method,result=find_direct(filename)
+ return result
+ end
+ end
+ method,result=find_direct(filename)
+ if not result then
+ method,result=find_wildcard(filename)
+ if not result then
+ method,result=find_qualified(filename,false,askedformat)
if not result then
- method,result=find_wildcard(filename)
- if not result then
- method,result=find_qualified(filename,false,askedformat)
- if not result then
- filetype,wantedfiles=find_analyze(filename,askedformat)
- method,result=find_intree(filename,filetype,wantedfiles)
- if not result then
- method,result=find_onpath(filename,filetype,wantedfiles)
- if resolve_otherwise and not result then
- method,result=find_otherwise(filename,filetype,wantedfiles)
- end
- end
- end
- end
- end
- if result and #result>0 then
- local foundname=collapsepath(result[1])
- resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
- result={ foundname }
- else
- result={}
- end
- if stamp then
- if trace_locating then
- report_resolving("remembering file %a using hash %a",filename,stamp)
+ filetype,wantedfiles=find_analyze(filename,askedformat)
+ method,result=find_intree(filename,filetype,wantedfiles)
+ if not result then
+ method,result=find_onpath(filename,filetype,wantedfiles)
+ if resolve_otherwise and not result then
+ method,result=find_otherwise(filename,filetype,wantedfiles)
end
- instance.found[stamp]=result
+ end
end
- return result
+ end
+ end
+ if result and #result>0 then
+ local foundname=collapsepath(result[1])
+ resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
+ result={ foundname }
+ else
+ result={}
end
+ if stamp then
+ if trace_locating then
+ report_resolving("remembering file %a using hash %a",filename,stamp)
+ end
+ instance.found[stamp]=result
+ end
+ return result
+ end
end
local function findfiles(filename,filetype,allresults)
- if not filename or filename=="" then
- return {}
- end
- local result,status=collect_instance_files(filename,filetype or "",allresults)
- if not result or #result==0 then
- local lowered=lower(filename)
- if filename~=lowered then
- result,status=collect_instance_files(lowered,filetype or "",allresults)
- end
+ if not filename or filename=="" then
+ return {}
+ end
+ local result,status=collect_instance_files(filename,filetype or "",allresults)
+ if not result or #result==0 then
+ local lowered=lower(filename)
+ if filename~=lowered then
+ result,status=collect_instance_files(lowered,filetype or "",allresults)
end
- return result or {},status
+ end
+ return result or {},status
end
function resolvers.findfiles(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,true)
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,true)
+ end
end
function resolvers.findfile(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,false)[1] or ""
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,false)[1] or ""
+ end
end
function resolvers.findpath(filename,filetype)
- return filedirname(findfiles(filename,filetype,false)[1] or "")
+ return filedirname(findfiles(filename,filetype,false)[1] or "")
end
local function findgivenfiles(filename,allresults)
- local base=filebasename(filename)
- local result={}
- local hashes=instance.hashes
- local function okay(hash,path,name)
- local found=methodhandler('concatinators',hash.type,hash.name,path,name)
- if found and found~="" then
- result[#result+1]=resolveprefix(found)
- return not allresults
- end
- end
- for k=1,#hashes do
- local hash=hashes[k]
- local content=instance.files[hash.name]
- if content then
- local path,name=lookup(content,base)
- if not path then
- elseif type(path)=="string" then
- if okay(hash,path,name) then
- return result
- end
- else
- for i=1,#path do
- if okay(hash,path[i],name) then
- return result
- end
- end
- end
+ local base=filebasename(filename)
+ local result={}
+ local hashes=instance.hashes
+ local function okay(hash,path,name)
+ local found=methodhandler('concatinators',hash.type,hash.name,path,name)
+ if found and found~="" then
+ result[#result+1]=resolveprefix(found)
+ return not allresults
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local content=instance.files[hash.name]
+ if content then
+ local path,name=lookup(content,base)
+ if not path then
+ elseif type(path)=="string" then
+ if okay(hash,path,name) then
+ return result
+ end
+ else
+ for i=1,#path do
+ if okay(hash,path[i],name) then
+ return result
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findgivenfiles(filename)
- return findgivenfiles(filename,true)
+ return findgivenfiles(filename,true)
end
function resolvers.findgivenfile(filename)
- return findgivenfiles(filename,false)[1] or ""
+ return findgivenfiles(filename,false)[1] or ""
end
local makewildcard=Cs(
- (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
+ (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
)
function resolvers.wildcardpattern(pattern)
- return lpegmatch(makewildcard,pattern) or pattern
+ return lpegmatch(makewildcard,pattern) or pattern
end
local function findwildcardfiles(filename,allresults,result)
- local result=result or {}
- local base=filebasename(filename)
- local dirn=filedirname(filename)
- local path=lower(lpegmatch(makewildcard,dirn) or dirn)
- local name=lower(lpegmatch(makewildcard,base) or base)
- local files=instance.files
- if find(name,"*",1,true) then
- local hashes=instance.hashes
- local function okay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
- end
+ local result=result or {}
+ local base=filebasename(filename)
+ local dirn=filedirname(filename)
+ local path=lower(lpegmatch(makewildcard,dirn) or dirn)
+ local name=lower(lpegmatch(makewildcard,base) or base)
+ local files=instance.files
+ if find(name,"*",1,true) then
+ local hashes=instance.hashes
+ local function okay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
end
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- for found,base in filtered(files[hashname],name) do
- if type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
- end
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ for found,base in filtered(files[hashname],name) do
+ if type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
end
- end
- else
- local function okayokay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
+ end
end
+ end
end
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- local found,base=lookup(content,base)
- if not found then
- elseif type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
+ end
+ end
+ else
+ local function okayokay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
+ end
+ end
+ end
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ local found,base=lookup(content,base)
+ if not found then
+ elseif type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
+ end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
end
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findwildcardfiles(filename,result)
- return findwildcardfiles(filename,true,result)
+ return findwildcardfiles(filename,true,result)
end
function resolvers.findwildcardfile(filename)
- return findwildcardfiles(filename,false)[1] or ""
+ return findwildcardfiles(filename,false)[1] or ""
end
function resolvers.automount()
end
function resolvers.starttiming()
- statistics.starttiming(instance)
+ statistics.starttiming(instance)
end
function resolvers.stoptiming()
- statistics.stoptiming(instance)
+ statistics.stoptiming(instance)
end
function resolvers.load(option)
- resolvers.starttiming()
- identify_configuration_files()
- load_configuration_files()
- if option~="nofiles" then
- load_databases()
- resolvers.automount()
- end
- resolvers.stoptiming()
- local files=instance.files
- return files and next(files) and true
+ resolvers.starttiming()
+ identify_configuration_files()
+ load_configuration_files()
+ if option~="nofiles" then
+ load_databases()
+ resolvers.automount()
+ end
+ resolvers.stoptiming()
+ local files=instance.files
+ return files and next(files) and true
end
function resolvers.loadtime()
- return statistics.elapsedtime(instance)
+ return statistics.elapsedtime(instance)
end
local function report(str)
- if trace_locating then
- report_resolving(str)
- else
- print(str)
- end
+ if trace_locating then
+ report_resolving(str)
+ else
+ print(str)
+ end
end
function resolvers.dowithfilesandreport(command,files,...)
- if files and #files>0 then
- if trace_locating then
- report('')
- end
- if type(files)=="string" then
- files={ files }
- end
- for f=1,#files do
- local file=files[f]
- local result=command(file,...)
- if type(result)=='string' then
- report(result)
- else
- for i=1,#result do
- report(result[i])
- end
- end
+ if files and #files>0 then
+ if trace_locating then
+ report('')
+ end
+ if type(files)=="string" then
+ files={ files }
+ end
+ for f=1,#files do
+ local file=files[f]
+ local result=command(file,...)
+ if type(result)=='string' then
+ report(result)
+ else
+ for i=1,#result do
+ report(result[i])
end
+ end
end
+ end
end
-function resolvers.showpath(str)
- return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
+function resolvers.showpath(str)
+ return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
end
function resolvers.registerfile(files,name,path)
- if files[name] then
- if type(files[name])=='string' then
- files[name]={ files[name],path }
- else
- files[name]=path
- end
+ if files[name] then
+ if type(files[name])=='string' then
+ files[name]={ files[name],path }
else
- files[name]=path
+ files[name]=path
end
+ else
+ files[name]=path
+ end
end
function resolvers.dowithpath(name,func)
- local pathlist=resolvers.expandedpathlist(name)
- for i=1,#pathlist do
- func("^"..cleanpath(pathlist[i]))
- end
+ local pathlist=resolvers.expandedpathlist(name)
+ for i=1,#pathlist do
+ func("^"..cleanpath(pathlist[i]))
+ end
end
function resolvers.dowithvariable(name,func)
- func(expandedvariable(name))
+ func(expandedvariable(name))
end
function resolvers.locateformat(name)
- local engine=environment.ownmain or "luatex"
- local barename=removesuffix(name)
- local fullname=addsuffix(barename,"fmt")
- local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
- if fmtname=="" then
- fmtname=resolvers.findfile(fullname)
- fmtname=cleanpath(fmtname)
- end
- if fmtname~="" then
- local barename=removesuffix(fmtname)
- local luaname=addsuffix(barename,luasuffixes.lua)
- local lucname=addsuffix(barename,luasuffixes.luc)
- local luiname=addsuffix(barename,luasuffixes.lui)
- if isfile(luiname) then
- return barename,luiname
- elseif isfile(lucname) then
- return barename,lucname
- elseif isfile(luaname) then
- return barename,luaname
- end
- end
- return nil,nil
+ local engine=environment.ownmain or "luatex"
+ local barename=removesuffix(name)
+ local fullname=addsuffix(barename,"fmt")
+ local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
+ if fmtname=="" then
+ fmtname=resolvers.findfile(fullname)
+ fmtname=cleanpath(fmtname)
+ end
+ if fmtname~="" then
+ local barename=removesuffix(fmtname)
+ local luaname=addsuffix(barename,luasuffixes.lua)
+ local lucname=addsuffix(barename,luasuffixes.luc)
+ local luiname=addsuffix(barename,luasuffixes.lui)
+ if isfile(luiname) then
+ return barename,luiname
+ elseif isfile(lucname) then
+ return barename,lucname
+ elseif isfile(luaname) then
+ return barename,luaname
+ end
+ end
+ return nil,nil
end
function resolvers.booleanvariable(str,default)
- local b=resolvers.expansion(str)
- if b=="" then
- return default
- else
- b=toboolean(b)
- return (b==nil and default) or b
- end
+ local b=resolvers.expansion(str)
+ if b=="" then
+ return default
+ else
+ b=toboolean(b)
+ return (b==nil and default) or b
+ end
end
function resolvers.dowithfilesintree(pattern,handle,before,after)
- local hashes=instance.hashes
- for i=1,#hashes do
- local hash=hashes[i]
- local blobtype=hash.type
- local blobpath=hash.name
- if blobtype and blobpath then
- local total=0
- local checked=0
- local done=0
- if before then
- before(blobtype,blobpath,pattern)
- end
- for path,name in filtered(instance.files[blobpath],pattern) do
- if type(path)=="string" then
- checked=checked+1
- if handle(blobtype,blobpath,path,name) then
- done=done+1
- end
- else
- checked=checked+#path
- for i=1,#path do
- if handle(blobtype,blobpath,path[i],name) then
- done=done+1
- end
- end
- end
- end
- if after then
- after(blobtype,blobpath,pattern,checked,done)
+ local hashes=instance.hashes
+ for i=1,#hashes do
+ local hash=hashes[i]
+ local blobtype=hash.type
+ local blobpath=hash.name
+ if blobtype and blobpath then
+ local total=0
+ local checked=0
+ local done=0
+ if before then
+ before(blobtype,blobpath,pattern)
+ end
+ for path,name in filtered(instance.files[blobpath],pattern) do
+ if type(path)=="string" then
+ checked=checked+1
+ if handle(blobtype,blobpath,path,name) then
+ done=done+1
+ end
+ else
+ checked=checked+#path
+ for i=1,#path do
+ if handle(blobtype,blobpath,path[i],name) then
+ done=done+1
end
+ end
end
+ end
+ if after then
+ after(blobtype,blobpath,pattern,checked,done)
+ end
end
+ end
end
local obsolete=resolvers.obsolete or {}
resolvers.obsolete=obsolete
-resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
-resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
+resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
+resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
function resolvers.knownvariables(pattern)
- if instance then
- local environment=instance.environment
- local variables=instance.variables
- local expansions=instance.expansions
- local order=instance.order
- local pattern=upper(pattern or "")
- local result={}
- for i=1,#order do
- for key in next,order[i] do
- if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
- result[key]={
- environment=rawget(environment,key),
- variable=key,
- expansion=expansions[key],
- resolved=resolveprefix(expansions[key]),
- }
- end
- end
+ if instance then
+ local environment=instance.environment
+ local variables=instance.variables
+ local expansions=instance.expansions
+ local order=instance.order
+ local pattern=upper(pattern or "")
+ local result={}
+ for i=1,#order do
+ for key in next,order[i] do
+ if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
+ result[key]={
+ environment=rawget(environment,key),
+ variable=key,
+ expansion=expansions[key],
+ resolved=resolveprefix(expansions[key]),
+ }
end
- return result
- else
- return {}
+ end
end
+ return result
+ else
+ return {}
+ end
end
@@ -22710,14 +22718,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-pre"] = package.loaded["data-pre"] or true
--- original size: 4854, stripped down to: 2993
+-- original size: 4854, stripped down to: 2889
if not modules then modules={} end modules ['data-pre']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local resolvers=resolvers
local prefixes=resolvers.prefixes
@@ -22730,64 +22738,64 @@ local dirname=file.dirname
local joinpath=file.join
local isfile=lfs.isfile
prefixes.environment=function(str)
- return cleanpath(expansion(str))
+ return cleanpath(expansion(str))
end
local function relative(str,n)
- if not isfile(str) then
- local pstr="./"..str
+ if not isfile(str) then
+ local pstr="./"..str
+ if isfile(pstr) then
+ str=pstr
+ else
+ local p="../"
+ for i=1,n or 2 do
+ local pstr=p..str
if isfile(pstr) then
- str=pstr
+ str=pstr
+ break
else
- local p="../"
- for i=1,n or 2 do
- local pstr=p..str
- if isfile(pstr) then
- str=pstr
- break
- else
- p=p.."../"
- end
- end
+ p=p.."../"
end
+ end
end
- return cleanpath(str)
+ end
+ return cleanpath(str)
end
local function locate(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(fullname~="" and fullname or str)
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(fullname~="" and fullname or str)
end
prefixes.relative=relative
prefixes.locate=locate
prefixes.auto=function(str)
- local fullname=relative(str)
- if not isfile(fullname) then
- fullname=locate(str)
- end
- return fullname
+ local fullname=relative(str)
+ if not isfile(fullname) then
+ fullname=locate(str)
+ end
+ return fullname
end
prefixes.filename=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(basename((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(basename((fullname~="" and fullname) or str))
end
prefixes.pathname=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(dirname((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(dirname((fullname~="" and fullname) or str))
end
prefixes.selfautoloc=function(str)
- local pth=getenv('SELFAUTOLOC')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOLOC')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautoparent=function(str)
- local pth=getenv('SELFAUTOPARENT')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOPARENT')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautodir=function(str)
- local pth=getenv('SELFAUTODIR')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTODIR')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.home=function(str)
- local pth=getenv('HOME')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('HOME')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.env=prefixes.environment
prefixes.rel=prefixes.relative
@@ -22797,24 +22805,24 @@ prefixes.full=prefixes.locate
prefixes.file=prefixes.filename
prefixes.path=prefixes.pathname
local function toppath()
- local inputstack=resolvers.inputstack
- if not inputstack then
- return "."
- end
- local pathname=dirname(inputstack[#inputstack] or "")
- if pathname=="" then
- return "."
- else
- return pathname
- end
+ local inputstack=resolvers.inputstack
+ if not inputstack then
+ return "."
+ end
+ local pathname=dirname(inputstack[#inputstack] or "")
+ if pathname=="" then
+ return "."
+ else
+ return pathname
+ end
end
local function jobpath()
- local path=resolvers.stackpath()
- if not path or path=="" then
- return "."
- else
- return path
- end
+ local path=resolvers.stackpath()
+ if not path or path=="" then
+ return "."
+ else
+ return path
+ end
end
resolvers.toppath=toppath
resolvers.jobpath=jobpath
@@ -22830,14 +22838,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-inp"] = package.loaded["data-inp"] or true
--- original size: 910, stripped down to: 823
+-- original size: 910, stripped down to: 818
if not modules then modules={} end modules ['data-inp']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -22860,14 +22868,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-out"] = package.loaded["data-out"] or true
--- original size: 530, stripped down to: 475
+-- original size: 530, stripped down to: 470
if not modules then modules={} end modules ['data-out']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -22883,16 +22891,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-fil"] = package.loaded["data-fil"] or true
--- original size: 3863, stripped down to: 3310
+-- original size: 3863, stripped down to: 3170
if not modules then modules={} end modules ['data-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_files=logs.reporter("resolvers","files")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -22900,88 +22908,88 @@ local finders,openers,loaders,savers=resolvers.finders,resolvers.openers,resolve
local locators,hashers,generators,concatinators=resolvers.locators,resolvers.hashers,resolvers.generators,resolvers.concatinators
local checkgarbage=utilities.garbagecollector and utilities.garbagecollector.check
function locators.file(specification)
- local filename=specification.filename
- local realname=resolveprefix(filename)
- if realname and realname~='' and lfs.isdir(realname) then
- if trace_locating then
- report_files("file locator %a found as %a",filename,realname)
- end
- resolvers.appendhash('file',filename,true)
- elseif trace_locating then
- report_files("file locator %a not found",filename)
+ local filename=specification.filename
+ local realname=resolveprefix(filename)
+ if realname and realname~='' and lfs.isdir(realname) then
+ if trace_locating then
+ report_files("file locator %a found as %a",filename,realname)
end
+ resolvers.appendhash('file',filename,true)
+ elseif trace_locating then
+ report_files("file locator %a not found",filename)
+ end
end
function hashers.file(specification)
- local pathname=specification.filename
- local content=caches.loadcontent(pathname,'files')
- resolvers.registerfilehash(pathname,content,content==nil)
+ local pathname=specification.filename
+ local content=caches.loadcontent(pathname,'files')
+ resolvers.registerfilehash(pathname,content,content==nil)
end
function generators.file(specification)
- local pathname=specification.filename
- local content=resolvers.scanfiles(pathname,false,true)
- resolvers.registerfilehash(pathname,content,true)
+ local pathname=specification.filename
+ local content=resolvers.scanfiles(pathname,false,true)
+ resolvers.registerfilehash(pathname,content,true)
end
concatinators.file=file.join
function finders.file(specification,filetype)
- local filename=specification.filename
- local foundname=resolvers.findfile(filename,filetype)
- if foundname and foundname~="" then
- if trace_locating then
- report_files("file finder: %a found",filename)
- end
- return foundname
- else
- if trace_locating then
- report_files("file finder: %a not found",filename)
- end
- return finders.notfound()
+ local filename=specification.filename
+ local foundname=resolvers.findfile(filename,filetype)
+ if foundname and foundname~="" then
+ if trace_locating then
+ report_files("file finder: %a found",filename)
+ end
+ return foundname
+ else
+ if trace_locating then
+ report_files("file finder: %a not found",filename)
end
+ return finders.notfound()
+ end
end
function openers.helpers.textopener(tag,filename,f)
- return {
- reader=function() return f:read () end,
- close=function() logs.show_close(filename) return f:close() end,
- }
+ return {
+ reader=function() return f:read () end,
+ close=function() logs.show_close(filename) return f:close() end,
+ }
end
function openers.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"r")
- if f then
- if trace_locating then
- report_files("file opener: %a opened",filename)
- end
- return openers.helpers.textopener("file",filename,f)
- end
- end
- if trace_locating then
- report_files("file opener: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"r")
+ if f then
+ if trace_locating then
+ report_files("file opener: %a opened",filename)
+ end
+ return openers.helpers.textopener("file",filename,f)
end
- return openers.notfound()
+ end
+ if trace_locating then
+ report_files("file opener: %a not found",filename)
+ end
+ return openers.notfound()
end
function loaders.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"rb")
- if f then
- logs.show_load(filename)
- if trace_locating then
- report_files("file loader: %a loaded",filename)
- end
- local s=f:read("*a")
- if checkgarbage then
- checkgarbage(#s)
- end
- f:close()
- if s then
- return true,s,#s
- end
- end
- end
- if trace_locating then
- report_files("file loader: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"rb")
+ if f then
+ logs.show_load(filename)
+ if trace_locating then
+ report_files("file loader: %a loaded",filename)
+ end
+ local s=f:read("*a")
+ if checkgarbage then
+ checkgarbage(#s)
+ end
+ f:close()
+ if s then
+ return true,s,#s
+ end
end
- return loaders.notfound()
+ end
+ if trace_locating then
+ report_files("file loader: %a not found",filename)
+ end
+ return loaders.notfound()
end
@@ -22991,116 +22999,116 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-con"] = package.loaded["data-con"] or true
--- original size: 5029, stripped down to: 3607
+-- original size: 5029, stripped down to: 3432
if not modules then modules={} end modules ['data-con']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub=string.format,string.lower,string.gsub
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
-local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
-local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
+local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
containers=containers or {}
local containers=containers
containers.usecache=true
local report_containers=logs.reporter("resolvers","containers")
local allocated={}
local mt={
- __index=function(t,k)
- if k=="writable" then
- local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
- t.writable=writable
- return writable
- elseif k=="readables" then
- local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
- t.readables=readables
- return readables
- end
- end,
- __storage__=true
+ __index=function(t,k)
+ if k=="writable" then
+ local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
+ t.writable=writable
+ return writable
+ elseif k=="readables" then
+ local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
+ t.readables=readables
+ return readables
+ end
+ end,
+ __storage__=true
}
function containers.define(category,subcategory,version,enabled)
- if category and subcategory then
- local c=allocated[category]
- if not c then
- c={}
- allocated[category]=c
- end
- local s=c[subcategory]
- if not s then
- s={
- category=category,
- subcategory=subcategory,
- storage={},
- enabled=enabled,
- version=version or math.pi,
- trace=false,
- }
- setmetatable(s,mt)
- c[subcategory]=s
- end
- return s
+ if category and subcategory then
+ local c=allocated[category]
+ if not c then
+ c={}
+ allocated[category]=c
+ end
+ local s=c[subcategory]
+ if not s then
+ s={
+ category=category,
+ subcategory=subcategory,
+ storage={},
+ enabled=enabled,
+ version=version or math.pi,
+ trace=false,
+ }
+ setmetatable(s,mt)
+ c[subcategory]=s
end
+ return s
+ end
end
function containers.is_usable(container,name)
- return container.enabled and caches and caches.is_writable(container.writable,name)
+ return container.enabled and caches and caches.is_writable(container.writable,name)
end
function containers.is_valid(container,name)
- if name and name~="" then
- local storage=container.storage[name]
- return storage and storage.cache_version==container.version
- else
- return false
- end
+ if name and name~="" then
+ local storage=container.storage[name]
+ return storage and storage.cache_version==container.version
+ else
+ return false
+ end
end
function containers.read(container,name)
- local storage=container.storage
- local stored=storage[name]
- if not stored and container.enabled and caches and containers.usecache then
- stored=caches.loaddata(container.readables,name,container.writable)
- if stored and stored.cache_version==container.version then
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","load",container.subcategory,name)
- end
- else
- stored=nil
- end
- storage[name]=stored
- elseif stored then
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
- end
+ local storage=container.storage
+ local stored=storage[name]
+ if not stored and container.enabled and caches and containers.usecache then
+ stored=caches.loaddata(container.readables,name,container.writable)
+ if stored and stored.cache_version==container.version then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","load",container.subcategory,name)
+ end
+ else
+ stored=nil
end
- return stored
+ storage[name]=stored
+ elseif stored then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
+ end
+ end
+ return stored
end
function containers.write(container,name,data)
- if data then
- data.cache_version=container.version
- if container.enabled and caches then
- local unique,shared=data.unique,data.shared
- data.unique,data.shared=nil,nil
- caches.savedata(container.writable,name,data)
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","save",container.subcategory,name)
- end
- data.unique,data.shared=unique,shared
- end
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","store",container.subcategory,name)
- end
- container.storage[name]=data
+ if data then
+ data.cache_version=container.version
+ if container.enabled and caches then
+ local unique,shared=data.unique,data.shared
+ data.unique,data.shared=nil,nil
+ caches.savedata(container.writable,name,data)
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","save",container.subcategory,name)
+ end
+ data.unique,data.shared=unique,shared
end
- return data
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","store",container.subcategory,name)
+ end
+ container.storage[name]=data
+ end
+ return data
end
function containers.content(container,name)
- return container.storage[name]
+ return container.storage[name]
end
function containers.cleanname(name)
- return (gsub(lower(name),"[^%w\128-\255]+","-"))
+ return (gsub(lower(name),"[^%w\128-\255]+","-"))
end
@@ -23110,97 +23118,97 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-use"] = package.loaded["data-use"] or true
--- original size: 4272, stripped down to: 3289
+-- original size: 4272, stripped down to: 3060
if not modules then modules={} end modules ['data-use']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub,find=string.format,string.lower,string.gsub,string.find
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_mounts=logs.reporter("resolvers","mounts")
local resolvers=resolvers
resolvers.automounted=resolvers.automounted or {}
function resolvers.automount(usecache)
- local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
- if (not mountpaths or #mountpaths==0) and usecache then
- mountpaths=caches.getreadablepaths("mount")
- end
- if mountpaths and #mountpaths>0 then
- resolvers.starttiming()
- for k=1,#mountpaths do
- local root=mountpaths[k]
- local f=io.open(root.."/url.tmi")
- if f then
- for line in f:lines() do
- if line then
- if find(line,"^[%%#%-]") then
- elseif find(line,"^zip://") then
- if trace_locating then
- report_mounts("mounting %a",line)
- end
- table.insert(resolvers.automounted,line)
- resolvers.usezipfile(line)
- end
- end
- end
- f:close()
+ local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
+ if (not mountpaths or #mountpaths==0) and usecache then
+ mountpaths=caches.getreadablepaths("mount")
+ end
+ if mountpaths and #mountpaths>0 then
+ resolvers.starttiming()
+ for k=1,#mountpaths do
+ local root=mountpaths[k]
+ local f=io.open(root.."/url.tmi")
+ if f then
+ for line in f:lines() do
+ if line then
+ if find(line,"^[%%#%-]") then
+ elseif find(line,"^zip://") then
+ if trace_locating then
+ report_mounts("mounting %a",line)
+ end
+ table.insert(resolvers.automounted,line)
+ resolvers.usezipfile(line)
end
+ end
end
- resolvers.stoptiming()
+ f:close()
+ end
end
+ resolvers.stoptiming()
+ end
end
statistics.register("used config file",function() return caches.configfiles() end)
statistics.register("used cache path",function() return caches.usedpaths() end)
function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner)
- local enginebanner=status.banner
- if formatbanner and enginebanner and sourcefile then
- local luvname=file.replacesuffix(texname,"luv")
- local luvdata={
- enginebanner=enginebanner,
- formatbanner=formatbanner,
- sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
- sourcefile=sourcefile,
- luaversion=LUAVERSION,
- }
- io.savedata(luvname,table.serialize(luvdata,true))
- lua.registerfinalizer(function()
- logs.report("format banner","%s",banner)
- logs.newline()
- end)
- end
+ local enginebanner=status.banner
+ if formatbanner and enginebanner and sourcefile then
+ local luvname=file.replacesuffix(texname,"luv")
+ local luvdata={
+ enginebanner=enginebanner,
+ formatbanner=formatbanner,
+ sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
+ sourcefile=sourcefile,
+ luaversion=LUAVERSION,
+ }
+ io.savedata(luvname,table.serialize(luvdata,true))
+ lua.registerfinalizer(function()
+ logs.report("format banner","%s",banner)
+ logs.newline()
+ end)
+ end
end
function statistics.checkfmtstatus(texname)
- local enginebanner=status.banner
- if enginebanner and texname then
- local luvname=file.replacesuffix(texname,"luv")
- if lfs.isfile(luvname) then
- local luv=dofile(luvname)
- if luv and luv.sourcefile then
- local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
- local luvbanner=luv.enginebanner or "?"
- if luvbanner~=enginebanner then
- return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
- end
- local luvhash=luv.sourcehash or "?"
- if luvhash~=sourcehash then
- return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
- end
- local luvluaversion=luv.luaversion or 0
- if luvluaversion~=LUAVERSION then
- return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
- end
- else
- return "invalid status file"
- end
- else
- return "missing status file"
- end
+ local enginebanner=status.banner
+ if enginebanner and texname then
+ local luvname=file.replacesuffix(texname,"luv")
+ if lfs.isfile(luvname) then
+ local luv=dofile(luvname)
+ if luv and luv.sourcefile then
+ local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
+ local luvbanner=luv.enginebanner or "?"
+ if luvbanner~=enginebanner then
+ return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
+ end
+ local luvhash=luv.sourcehash or "?"
+ if luvhash~=sourcehash then
+ return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
+ end
+ local luvluaversion=luv.luaversion or 0
+ if luvluaversion~=LUAVERSION then
+ return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
+ end
+ else
+ return "invalid status file"
+ end
+ else
+ return "missing status file"
end
- return true
+ end
+ return true
end
@@ -23210,17 +23218,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-zip"] = package.loaded["data-zip"] or true
--- original size: 8700, stripped down to: 6781
+-- original size: 8700, stripped down to: 6313
if not modules then modules={} end modules ['data-zip']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,find,match=string.format,string.find,string.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_zip=logs.reporter("resolvers","zip")
local resolvers=resolvers
zip=zip or {}
@@ -23230,213 +23238,213 @@ zip.archives=archives
local registeredfiles=zip.registeredfiles or {}
zip.registeredfiles=registeredfiles
local function validzip(str)
- if not find(str,"^zip://") then
- return "zip:///"..str
- else
- return str
- end
+ if not find(str,"^zip://") then
+ return "zip:///"..str
+ else
+ return str
+ end
end
function zip.openarchive(name)
- if not name or name=="" then
- return nil
- else
- local arch=archives[name]
- if not arch then
- local full=resolvers.findfile(name) or ""
- arch=full~="" and zip.open(full) or false
- archives[name]=arch
- end
- return arch
+ if not name or name=="" then
+ return nil
+ else
+ local arch=archives[name]
+ if not arch then
+ local full=resolvers.findfile(name) or ""
+ arch=full~="" and zip.open(full) or false
+ archives[name]=arch
end
+ return arch
+ end
end
function zip.closearchive(name)
- if not name or (name=="" and archives[name]) then
- zip.close(archives[name])
- archives[name]=nil
- end
+ if not name or (name=="" and archives[name]) then
+ zip.close(archives[name])
+ archives[name]=nil
+ end
end
function resolvers.locators.zip(specification)
- local archive=specification.filename
- local zipfile=archive and archive~="" and zip.openarchive(archive)
- if trace_locating then
- if zipfile then
- report_zip("locator: archive %a found",archive)
- else
- report_zip("locator: archive %a not found",archive)
- end
+ local archive=specification.filename
+ local zipfile=archive and archive~="" and zip.openarchive(archive)
+ if trace_locating then
+ if zipfile then
+ report_zip("locator: archive %a found",archive)
+ else
+ report_zip("locator: archive %a not found",archive)
end
+ end
end
function resolvers.hashers.zip(specification)
- local archive=specification.filename
- if trace_locating then
- report_zip("loading file %a",archive)
- end
- resolvers.usezipfile(specification.original)
+ local archive=specification.filename
+ if trace_locating then
+ report_zip("loading file %a",archive)
+ end
+ resolvers.usezipfile(specification.original)
end
function resolvers.concatinators.zip(zipfile,path,name)
- if not path or path=="" then
- return format('%s?name=%s',zipfile,name)
- else
- return format('%s?name=%s/%s',zipfile,path,name)
- end
+ if not path or path=="" then
+ return format('%s?name=%s',zipfile,name)
+ else
+ return format('%s?name=%s/%s',zipfile,path,name)
+ end
end
function resolvers.finders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("finder: archive %a found",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- dfile:close()
- if trace_locating then
- report_zip("finder: file %a found",queryname)
- end
- return specification.original
- elseif trace_locating then
- report_zip("finder: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("finder: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("finder: archive %a found",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ dfile:close()
+ if trace_locating then
+ report_zip("finder: file %a found",queryname)
+ end
+ return specification.original
+ elseif trace_locating then
+ report_zip("finder: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("finder: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("finder: %a not found",original)
- end
- return resolvers.finders.notfound()
+ end
+ if trace_locating then
+ report_zip("finder: %a not found",original)
+ end
+ return resolvers.finders.notfound()
end
function resolvers.openers.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("opener; archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- if trace_locating then
- report_zip("opener: file %a found",queryname)
- end
- return resolvers.openers.helpers.textopener('zip',original,dfile)
- elseif trace_locating then
- report_zip("opener: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("opener: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("opener; archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ if trace_locating then
+ report_zip("opener: file %a found",queryname)
+ end
+ return resolvers.openers.helpers.textopener('zip',original,dfile)
+ elseif trace_locating then
+ report_zip("opener: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("opener: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("opener: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("opener: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.loaders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("loader: archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- logs.show_load(original)
- if trace_locating then
- report_zip("loader; file %a loaded",original)
- end
- local s=dfile:read("*all")
- dfile:close()
- return true,s,#s
- elseif trace_locating then
- report_zip("loader: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("loader; unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("loader: archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ logs.show_load(original)
+ if trace_locating then
+ report_zip("loader; file %a loaded",original)
+ end
+ local s=dfile:read("*all")
+ dfile:close()
+ return true,s,#s
+ elseif trace_locating then
+ report_zip("loader: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("loader; unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("loader: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("loader: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.usezipfile(archive)
- local specification=resolvers.splitmethod(archive)
- local archive=specification.filename
- if archive and not registeredfiles[archive] then
- local z=zip.openarchive(archive)
- if z then
- local tree=url.query(specification.query).tree or ""
- if trace_locating then
- report_zip("registering: archive %a",archive)
- end
- resolvers.starttiming()
- resolvers.prependhash('zip',archive)
- resolvers.extendtexmfvariable(archive)
- registeredfiles[archive]=z
- resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
- resolvers.stoptiming()
- elseif trace_locating then
- report_zip("registering: unknown archive %a",archive)
- end
+ local specification=resolvers.splitmethod(archive)
+ local archive=specification.filename
+ if archive and not registeredfiles[archive] then
+ local z=zip.openarchive(archive)
+ if z then
+ local tree=url.query(specification.query).tree or ""
+ if trace_locating then
+ report_zip("registering: archive %a",archive)
+ end
+ resolvers.starttiming()
+ resolvers.prependhash('zip',archive)
+ resolvers.extendtexmfvariable(archive)
+ registeredfiles[archive]=z
+ resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
+ resolvers.stoptiming()
elseif trace_locating then
- report_zip("registering: archive %a not found",archive)
+ report_zip("registering: unknown archive %a",archive)
end
+ elseif trace_locating then
+ report_zip("registering: archive %a not found",archive)
+ end
end
function resolvers.registerzipfile(z,tree)
- local names={}
- local files={}
- local remap={}
- local n=0
- local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
- local register=resolvers.registerfile
- if trace_locating then
- report_zip("registering: using filter %a",filter)
- end
- for i in z:files() do
- local filename=i.filename
- local path,name=match(filename,filter)
- if not path then
- n=n+1
- register(names,filename,"")
- local usedname=lower(filename)
- files[usedname]=""
- if usedname~=filename then
- remap[usedname]=filename
- end
- elseif name and name~="" then
- n=n+1
- register(names,name,path)
- local usedname=lower(name)
- files[usedname]=path
- if usedname~=name then
- remap[usedname]=name
- end
- else
- end
+ local names={}
+ local files={}
+ local remap={}
+ local n=0
+ local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
+ local register=resolvers.registerfile
+ if trace_locating then
+ report_zip("registering: using filter %a",filter)
+ end
+ for i in z:files() do
+ local filename=i.filename
+ local path,name=match(filename,filter)
+ if not path then
+ n=n+1
+ register(names,filename,"")
+ local usedname=lower(filename)
+ files[usedname]=""
+ if usedname~=filename then
+ remap[usedname]=filename
+ end
+ elseif name and name~="" then
+ n=n+1
+ register(names,name,path)
+ local usedname=lower(name)
+ files[usedname]=path
+ if usedname~=name then
+ remap[usedname]=name
+ end
+ else
end
- report_zip("registering: %s files registered",n)
- return {
- files=files,
- remap=remap,
- }
+ end
+ report_zip("registering: %s files registered",n)
+ return {
+ files=files,
+ remap=remap,
+ }
end
@@ -23446,20 +23454,20 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tre"] = package.loaded["data-tre"] or true
--- original size: 8478, stripped down to: 5611
+-- original size: 8478, stripped down to: 5223
if not modules then modules={} end modules ['data-tre']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local find,gsub,lower=string.find,string.gsub,string.lower
-local basename,dirname,joinname=file.basename,file.dirname,file .join
+local basename,dirname,joinname=file.basename,file.dirname,file .join
local globdir,isdir,isfile=dir.glob,lfs.isdir,lfs.isfile
local P,lpegmatch=lpeg.P,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_trees=logs.reporter("resolvers","trees")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -23468,167 +23476,167 @@ local lookup=resolvers.get_from_content
local collectors={}
local found={}
function resolvers.finders.tree(specification)
- local spec=specification.filename
- local okay=found[spec]
- if okay==nil then
- if spec~="" then
- local path=dirname(spec)
- local name=basename(spec)
- if path=="" then
- path="."
- end
- local names=collectors[path]
- if not names then
- local pattern=find(path,"/%*+$") and path or (path.."/*")
- names=globdir(pattern)
- collectors[path]=names
- end
- local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
- for i=1,#names do
- local fullname=names[i]
- if find(fullname,pattern) then
- found[spec]=fullname
- return fullname
- end
- end
- local pattern=lower(pattern)
- for i=1,#names do
- local fullname=lower(names[i])
- if find(fullname,pattern) then
- if isfile(fullname) then
- found[spec]=fullname
- return fullname
- else
- break
- end
- end
- end
+ local spec=specification.filename
+ local okay=found[spec]
+ if okay==nil then
+ if spec~="" then
+ local path=dirname(spec)
+ local name=basename(spec)
+ if path=="" then
+ path="."
+ end
+ local names=collectors[path]
+ if not names then
+ local pattern=find(path,"/%*+$") and path or (path.."/*")
+ names=globdir(pattern)
+ collectors[path]=names
+ end
+ local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
+ for i=1,#names do
+ local fullname=names[i]
+ if find(fullname,pattern) then
+ found[spec]=fullname
+ return fullname
+ end
+ end
+ local pattern=lower(pattern)
+ for i=1,#names do
+ local fullname=lower(names[i])
+ if find(fullname,pattern) then
+ if isfile(fullname) then
+ found[spec]=fullname
+ return fullname
+ else
+ break
+ end
end
- okay=notfound()
- found[spec]=okay
+ end
end
- return okay
+ okay=notfound()
+ found[spec]=okay
+ end
+ return okay
end
function resolvers.locators.tree(specification)
- local name=specification.filename
- local realname=resolveprefix(name)
- if realname and realname~='' and isdir(realname) then
- if trace_locating then
- report_trees("locator %a found",realname)
- end
- resolvers.appendhash('tree',name,false)
- elseif trace_locating then
- report_trees("locator %a not found",name)
+ local name=specification.filename
+ local realname=resolveprefix(name)
+ if realname and realname~='' and isdir(realname) then
+ if trace_locating then
+ report_trees("locator %a found",realname)
end
+ resolvers.appendhash('tree',name,false)
+ elseif trace_locating then
+ report_trees("locator %a not found",name)
+ end
end
function resolvers.hashers.tree(specification)
- local name=specification.filename
- if trace_locating then
- report_trees("analyzing %a",name)
- end
- resolvers.methodhandler("hashers",name)
- resolvers.generators.file(specification)
+ local name=specification.filename
+ if trace_locating then
+ report_trees("analyzing %a",name)
+ end
+ resolvers.methodhandler("hashers",name)
+ resolvers.generators.file(specification)
end
local collectors={}
local splitter=lpeg.splitat("/**/")
local stripper=lpeg.replacer { [P("/")*P("*")^1*P(-1)]="" }
table.setmetatableindex(collectors,function(t,k)
- local rootname=lpegmatch(stripper,k)
- local dataname=joinname(rootname,"dirlist")
- local content=caches.loadcontent(dataname,"files",dataname)
- if not content then
- content=resolvers.scanfiles(rootname,nil,nil,false,true)
- caches.savecontent(dataname,"files",content,dataname)
- end
- t[k]=content
- return content
+ local rootname=lpegmatch(stripper,k)
+ local dataname=joinname(rootname,"dirlist")
+ local content=caches.loadcontent(dataname,"files",dataname)
+ if not content then
+ content=resolvers.scanfiles(rootname,nil,nil,false,true)
+ caches.savecontent(dataname,"files",content,dataname)
+ end
+ t[k]=content
+ return content
end)
local function checked(root,p,n)
- if p then
- if type(p)=="table" then
- for i=1,#p do
- local fullname=joinname(root,p[i],n)
- if isfile(fullname) then
- return fullname
- end
- end
- else
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
+ if p then
+ if type(p)=="table" then
+ for i=1,#p do
+ local fullname=joinname(root,p[i],n)
+ if isfile(fullname) then
+ return fullname
end
+ end
+ else
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- return notfound()
+ end
+ return notfound()
end
local function resolve(specification)
- local filename=specification.filename
- if filename~="" then
- local root,rest=lpegmatch(splitter,filename)
- if root and rest then
- local path,name=dirname(rest),basename(rest)
- if name~=rest then
- local content=collectors[root]
- local p,n=lookup(content,name)
- if not p then
- return notfound()
- end
- local pattern=".*/"..path.."$"
- local istable=type(p)=="table"
- if istable then
- for i=1,#p do
- local pi=p[i]
- if pi==path or find(pi,pattern) then
- local fullname=joinname(root,pi,n)
- if isfile(fullname) then
- return fullname
- end
- end
- end
- elseif p==path or find(p,pattern) then
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
- end
- local queries=specification.queries
- if queries and queries.option=="fileonly" then
- return checked(root,p,n)
- else
- return notfound()
- end
+ local filename=specification.filename
+ if filename~="" then
+ local root,rest=lpegmatch(splitter,filename)
+ if root and rest then
+ local path,name=dirname(rest),basename(rest)
+ if name~=rest then
+ local content=collectors[root]
+ local p,n=lookup(content,name)
+ if not p then
+ return notfound()
+ end
+ local pattern=".*/"..path.."$"
+ local istable=type(p)=="table"
+ if istable then
+ for i=1,#p do
+ local pi=p[i]
+ if pi==path or find(pi,pattern) then
+ local fullname=joinname(root,pi,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
+ end
+ elseif p==path or find(p,pattern) then
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- local path,name=dirname(filename),basename(filename)
- local root=lpegmatch(stripper,path)
- local content=collectors[path]
- local p,n=lookup(content,name)
- if p then
- return checked(root,p,n)
+ local queries=specification.queries
+ if queries and queries.option=="fileonly" then
+ return checked(root,p,n)
+ else
+ return notfound()
end
+ end
+ end
+ local path,name=dirname(filename),basename(filename)
+ local root=lpegmatch(stripper,path)
+ local content=collectors[path]
+ local p,n=lookup(content,name)
+ if p then
+ return checked(root,p,n)
end
- return notfound()
+ end
+ return notfound()
end
-resolvers.finders .dirlist=resolve
-resolvers.locators .dirlist=resolvers.locators .tree
-resolvers.hashers .dirlist=resolvers.hashers .tree
+resolvers.finders .dirlist=resolve
+resolvers.locators .dirlist=resolvers.locators .tree
+resolvers.hashers .dirlist=resolvers.hashers .tree
resolvers.generators.dirlist=resolvers.generators.file
-resolvers.openers .dirlist=resolvers.openers .file
-resolvers.loaders .dirlist=resolvers.loaders .file
+resolvers.openers .dirlist=resolvers.openers .file
+resolvers.loaders .dirlist=resolvers.loaders .file
function resolvers.finders.dirfile(specification)
- local queries=specification.queries
- if queries then
- queries.option="fileonly"
- else
- specification.queries={ option="fileonly" }
- end
- return resolve(specification)
-end
-resolvers.locators .dirfile=resolvers.locators .dirlist
-resolvers.hashers .dirfile=resolvers.hashers .dirlist
+ local queries=specification.queries
+ if queries then
+ queries.option="fileonly"
+ else
+ specification.queries={ option="fileonly" }
+ end
+ return resolve(specification)
+end
+resolvers.locators .dirfile=resolvers.locators .dirlist
+resolvers.hashers .dirfile=resolvers.hashers .dirlist
resolvers.generators.dirfile=resolvers.generators.dirlist
-resolvers.openers .dirfile=resolvers.openers .dirlist
-resolvers.loaders .dirfile=resolvers.loaders .dirlist
+resolvers.openers .dirfile=resolvers.openers .dirlist
+resolvers.loaders .dirfile=resolvers.loaders .dirlist
end -- of closure
@@ -23637,19 +23645,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-sch"] = package.loaded["data-sch"] or true
--- original size: 6753, stripped down to: 5511
+-- original size: 6753, stripped down to: 5268
if not modules then modules={} end modules ['data-sch']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local load,tonumber=load,tonumber
local gsub,concat,format=string.gsub,table.concat,string.format
local finders,openers,loaders=resolvers.finders,resolvers.openers,resolvers.loaders
-local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
+local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
local report_schemes=logs.reporter("resolvers","schemes")
local http=require("socket.http")
local ltn12=require("ltn12")
@@ -23662,27 +23670,27 @@ schemes.cleaners=cleaners
local threshold=24*60*60
directives.register("schemes.threshold",function(v) threshold=tonumber(v) or threshold end)
function cleaners.none(specification)
- return specification.original
+ return specification.original
end
function cleaners.strip(specification)
- local path,name=file.splitbase(specification.original)
- if path=="" then
- return (gsub(name,"[^%a%d%.]+","-"))
- else
- return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
- end
+ local path,name=file.splitbase(specification.original)
+ if path=="" then
+ return (gsub(name,"[^%a%d%.]+","-"))
+ else
+ return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
+ end
end
function cleaners.md5(specification)
- return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
+ return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
end
local cleaner=cleaners.strip
directives.register("schemes.cleanmethod",function(v) cleaner=cleaners[v] or cleaners.strip end)
function resolvers.schemes.cleanname(specification)
- local hash=cleaner(specification)
- if trace_schemes then
- report_schemes("hashing %a to %a",specification.original,hash)
- end
- return hash
+ local hash=cleaner(specification)
+ if trace_schemes then
+ report_schemes("hashing %a to %a",specification.original,hash)
+ end
+ return hash
end
local cached={}
local loaded={}
@@ -23690,139 +23698,139 @@ local reused={}
local thresholds={}
local handlers={}
local runner=sandbox.registerrunner {
- name="curl resolver",
- method="execute",
- program="curl",
- template="--silent --insecure --create-dirs --output %cachename% %original%",
- checkers={
- cachename="cache",
- original="url",
- }
+ name="curl resolver",
+ method="execute",
+ program="curl",
+ template="--silent --insecure --create-dirs --output %cachename% %original%",
+ checkers={
+ cachename="cache",
+ original="url",
+ }
}
local function fetch(specification)
- local original=specification.original
- local scheme=specification.scheme
- local cleanname=schemes.cleanname(specification)
- local cachename=caches.setfirstwritablefile(cleanname,"schemes")
- if not cached[original] then
- statistics.starttiming(schemes)
- if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
- cached[original]=cachename
- local handler=handlers[scheme]
- if handler then
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
- end
- logs.flush()
- handler(specification,cachename)
- else
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
- end
- logs.flush()
- runner {
- original=original,
- cachename=cachename,
- }
- end
- end
- if io.exists(cachename) then
- cached[original]=cachename
- if trace_schemes then
- report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
- end
- else
- cached[original]=""
- if trace_schemes then
- report_schemes("using missing %a, protocol %a",original,scheme)
- end
+ local original=specification.original
+ local scheme=specification.scheme
+ local cleanname=schemes.cleanname(specification)
+ local cachename=caches.setfirstwritablefile(cleanname,"schemes")
+ if not cached[original] then
+ statistics.starttiming(schemes)
+ if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
+ cached[original]=cachename
+ local handler=handlers[scheme]
+ if handler then
+ if trace_schemes then
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
end
- loaded[scheme]=loaded[scheme]+1
- statistics.stoptiming(schemes)
- else
+ logs.flush()
+ handler(specification,cachename)
+ else
if trace_schemes then
- report_schemes("reusing %a, protocol %a",original,scheme)
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
end
- reused[scheme]=reused[scheme]+1
+ logs.flush()
+ runner {
+ original=original,
+ cachename=cachename,
+ }
+ end
end
- return cached[original]
+ if io.exists(cachename) then
+ cached[original]=cachename
+ if trace_schemes then
+ report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
+ end
+ else
+ cached[original]=""
+ if trace_schemes then
+ report_schemes("using missing %a, protocol %a",original,scheme)
+ end
+ end
+ loaded[scheme]=loaded[scheme]+1
+ statistics.stoptiming(schemes)
+ else
+ if trace_schemes then
+ report_schemes("reusing %a, protocol %a",original,scheme)
+ end
+ reused[scheme]=reused[scheme]+1
+ end
+ return cached[original]
end
local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
+ return resolvers.methodhandler("finders",fetch(specification),filetype)
end
local opener=openers.file
local loader=loaders.file
local function install(scheme,handler,newthreshold)
- handlers [scheme]=handler
- loaded [scheme]=0
- reused [scheme]=0
- finders [scheme]=finder
- openers [scheme]=opener
- loaders [scheme]=loader
- thresholds[scheme]=newthreshold or threshold
+ handlers [scheme]=handler
+ loaded [scheme]=0
+ reused [scheme]=0
+ finders [scheme]=finder
+ openers [scheme]=opener
+ loaders [scheme]=loader
+ thresholds[scheme]=newthreshold or threshold
end
schemes.install=install
local function http_handler(specification,cachename)
- local tempname=cachename..".tmp"
- local f=io.open(tempname,"wb")
- local status,message=http.request {
- url=specification.original,
- sink=ltn12.sink.file(f)
- }
- if not status then
- os.remove(tempname)
- else
- os.remove(cachename)
- os.rename(tempname,cachename)
- end
- return cachename
+ local tempname=cachename..".tmp"
+ local f=io.open(tempname,"wb")
+ local status,message=http.request {
+ url=specification.original,
+ sink=ltn12.sink.file(f)
+ }
+ if not status then
+ os.remove(tempname)
+ else
+ os.remove(cachename)
+ os.rename(tempname,cachename)
+ end
+ return cachename
end
install('http',http_handler)
install('https')
install('ftp')
statistics.register("scheme handling time",function()
- local l,r,nl,nr={},{},0,0
- for k,v in table.sortedhash(loaded) do
- if v>0 then
- nl=nl+1
- l[nl]=k..":"..v
- end
- end
- for k,v in table.sortedhash(reused) do
- if v>0 then
- nr=nr+1
- r[nr]=k..":"..v
- end
- end
- local n=nl+nr
- if n>0 then
- l=nl>0 and concat(l) or "none"
- r=nr>0 and concat(r) or "none"
- return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
- statistics.elapsedtime(schemes),n,threshold,l,r)
- else
- return nil
- end
+ local l,r,nl,nr={},{},0,0
+ for k,v in table.sortedhash(loaded) do
+ if v>0 then
+ nl=nl+1
+ l[nl]=k..":"..v
+ end
+ end
+ for k,v in table.sortedhash(reused) do
+ if v>0 then
+ nr=nr+1
+ r[nr]=k..":"..v
+ end
+ end
+ local n=nl+nr
+ if n>0 then
+ l=nl>0 and concat(l) or "none"
+ r=nr>0 and concat(r) or "none"
+ return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
+ statistics.elapsedtime(schemes),n,threshold,l,r)
+ else
+ return nil
+ end
end)
local httprequest=http.request
local toquery=url.toquery
local function fetchstring(url,data)
- local q=data and toquery(data)
- if q then
- url=url.."?"..q
- end
- local reply=httprequest(url)
- return reply
+ local q=data and toquery(data)
+ if q then
+ url=url.."?"..q
+ end
+ local reply=httprequest(url)
+ return reply
end
schemes.fetchstring=fetchstring
function schemes.fetchtable(url,data)
- local reply=fetchstring(url,data)
- if reply then
- local s=load("return "..reply)
- if s then
- return s()
- end
+ local reply=fetchstring(url,data)
+ if reply then
+ local s=load("return "..reply)
+ if s then
+ return s()
end
+ end
end
@@ -23832,14 +23840,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lua"] = package.loaded["data-lua"] or true
--- original size: 4207, stripped down to: 3137
+-- original size: 4207, stripped down to: 3041
if not modules then modules={} end modules ['data-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local package,lpeg=package,lpeg
local gsub=string.gsub
@@ -23858,20 +23866,20 @@ helpers.report=logs.reporter("resolvers","libraries")
trackers.register("resolvers.libraries",function(v) helpers.trace=v end)
trackers.register("resolvers.locating",function(v) helpers.trace=v end)
helpers.sequence={
- "already loaded",
- "preload table",
- "lua variable format",
- "lib variable format",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
+ "already loaded",
+ "preload table",
+ "lua variable format",
+ "lib variable format",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
}
local pattern=Cs(P("!")^0/""*(P("/")*P(-1)/"/"+P("/")^1/"/"+1)^0)
function helpers.cleanpath(path)
- return resolveprefix(lpegmatch(pattern,path))
+ return resolveprefix(lpegmatch(pattern,path))
end
local loadedaslib=helpers.loadedaslib
local registerpath=helpers.registerpath
@@ -23879,56 +23887,56 @@ local lualibfile=helpers.lualibfile
local luaformatpaths
local libformatpaths
local function getluaformatpaths()
- if not luaformatpaths then
- luaformatpaths={}
- for i=1,#luaformats do
- registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
- end
+ if not luaformatpaths then
+ luaformatpaths={}
+ for i=1,#luaformats do
+ registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
end
- return luaformatpaths
+ end
+ return luaformatpaths
end
local function getlibformatpaths()
- if not libformatpaths then
- libformatpaths={}
- for i=1,#libformats do
- registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
- end
+ if not libformatpaths then
+ libformatpaths={}
+ for i=1,#libformats do
+ registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
end
- return libformatpaths
+ end
+ return libformatpaths
end
local function loadedbyformat(name,rawname,suffixes,islib,what)
- local trace=helpers.trace
- local report=helpers.report
- for i=1,#suffixes do
- local format=suffixes[i]
- local resolved=resolvers.findfile(name,format) or ""
- if trace then
- report("%s format, identifying %a using format %a",what,name,format)
- end
- if resolved~="" then
- if trace then
- report("%s format, %a found on %a",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ local report=helpers.report
+ for i=1,#suffixes do
+ local format=suffixes[i]
+ local resolved=resolvers.findfile(name,format) or ""
+ if trace then
+ report("%s format, identifying %a using format %a",what,name,format)
end
+ if resolved~="" then
+ if trace then
+ report("%s format, %a found on %a",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
+ end
+ end
end
helpers.loadedbyformat=loadedbyformat
methods["lua variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
end
methods["lib variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
end
resolvers.loadlualib=require
@@ -23939,64 +23947,64 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-aux"] = package.loaded["data-aux"] or true
--- original size: 2438, stripped down to: 2003
+-- original size: 2438, stripped down to: 1863
if not modules then modules={} end modules ['data-aux']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local find=string.find
local type,next=type,next
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local resolvers=resolvers
local report_scripts=logs.reporter("resolvers","scripts")
function resolvers.updatescript(oldname,newname)
- local scriptpath="context/lua"
- newname=file.addsuffix(newname,"lua")
- local oldscript=resolvers.cleanpath(oldname)
+ local scriptpath="context/lua"
+ newname=file.addsuffix(newname,"lua")
+ local oldscript=resolvers.cleanpath(oldname)
+ if trace_locating then
+ report_scripts("to be replaced old script %a",oldscript)
+ end
+ local newscripts=resolvers.findfiles(newname) or {}
+ if #newscripts==0 then
if trace_locating then
- report_scripts("to be replaced old script %a",oldscript)
+ report_scripts("unable to locate new script")
end
- local newscripts=resolvers.findfiles(newname) or {}
- if #newscripts==0 then
+ else
+ for i=1,#newscripts do
+ local newscript=resolvers.cleanpath(newscripts[i])
+ if trace_locating then
+ report_scripts("checking new script %a",newscript)
+ end
+ if oldscript==newscript then
if trace_locating then
- report_scripts("unable to locate new script")
+ report_scripts("old and new script are the same")
end
- else
- for i=1,#newscripts do
- local newscript=resolvers.cleanpath(newscripts[i])
- if trace_locating then
- report_scripts("checking new script %a",newscript)
- end
- if oldscript==newscript then
- if trace_locating then
- report_scripts("old and new script are the same")
- end
- elseif not find(newscript,scriptpath,1,true) then
- if trace_locating then
- report_scripts("new script should come from %a",scriptpath)
- end
- elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
- if trace_locating then
- report_scripts("invalid new script name")
- end
- else
- local newdata=io.loaddata(newscript)
- if newdata then
- if trace_locating then
- report_scripts("old script content replaced by new content")
- end
- io.savedata(oldscript,newdata)
- break
- elseif trace_locating then
- report_scripts("unable to load new script")
- end
- end
+ elseif not find(newscript,scriptpath,1,true) then
+ if trace_locating then
+ report_scripts("new script should come from %a",scriptpath)
+ end
+ elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
+ if trace_locating then
+ report_scripts("invalid new script name")
end
+ else
+ local newdata=io.loaddata(newscript)
+ if newdata then
+ if trace_locating then
+ report_scripts("old script content replaced by new content")
+ end
+ io.savedata(oldscript,newdata)
+ break
+ elseif trace_locating then
+ report_scripts("unable to load new script")
+ end
+ end
end
+ end
end
@@ -24006,53 +24014,53 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmf"] = package.loaded["data-tmf"] or true
--- original size: 2601, stripped down to: 1627
+-- original size: 2601, stripped down to: 1549
if not modules then modules={} end modules ['data-tmf']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local resolvers=resolvers
local report_tds=logs.reporter("resolvers","tds")
function resolvers.load_tree(tree,resolve)
- if type(tree)=="string" and tree~="" then
- local getenv,setenv=resolvers.getenv,resolvers.setenv
- local texos="texmf-"..os.platform
- local oldroot=environment.texroot
- local newroot=file.collapsepath(tree)
- local newtree=file.join(newroot,texos)
- local newpath=file.join(newtree,"bin")
- if not lfs.isdir(newtree) then
- report_tds("no %a under tree %a",texos,tree)
- os.exit()
- end
- if not lfs.isdir(newpath) then
- report_tds("no '%s/bin' under tree %a",texos,tree)
- os.exit()
- end
- local texmfos=newtree
- environment.texroot=newroot
- environment.texos=texos
- environment.texmfos=texmfos
- if resolve then
- resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
- end
- setenv('SELFAUTOPARENT',newroot)
- setenv('SELFAUTODIR',newtree)
- setenv('SELFAUTOLOC',newpath)
- setenv('TEXROOT',newroot)
- setenv('TEXOS',texos)
- setenv('TEXMFOS',texmfos)
- setenv('TEXMFCNF',resolvers.luacnfspec,true)
- setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
- report_tds("changing from root %a to %a",oldroot,newroot)
- report_tds("prepending %a to PATH",newpath)
- report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
- report_tds()
- end
+ if type(tree)=="string" and tree~="" then
+ local getenv,setenv=resolvers.getenv,resolvers.setenv
+ local texos="texmf-"..os.platform
+ local oldroot=environment.texroot
+ local newroot=file.collapsepath(tree)
+ local newtree=file.join(newroot,texos)
+ local newpath=file.join(newtree,"bin")
+ if not lfs.isdir(newtree) then
+ report_tds("no %a under tree %a",texos,tree)
+ os.exit()
+ end
+ if not lfs.isdir(newpath) then
+ report_tds("no '%s/bin' under tree %a",texos,tree)
+ os.exit()
+ end
+ local texmfos=newtree
+ environment.texroot=newroot
+ environment.texos=texos
+ environment.texmfos=texmfos
+ if resolve then
+ resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
+ end
+ setenv('SELFAUTOPARENT',newroot)
+ setenv('SELFAUTODIR',newtree)
+ setenv('SELFAUTOLOC',newpath)
+ setenv('TEXROOT',newroot)
+ setenv('TEXOS',texos)
+ setenv('TEXMFOS',texmfos)
+ setenv('TEXMFCNF',resolvers.luacnfspec,true)
+ setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
+ report_tds("changing from root %a to %a",oldroot,newroot)
+ report_tds("prepending %a to PATH",newpath)
+ report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
+ report_tds()
+ end
end
@@ -24062,14 +24070,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lst"] = package.loaded["data-lst"] or true
--- original size: 1823, stripped down to: 1591
+-- original size: 1823, stripped down to: 1542
if not modules then modules={} end modules ['data-lst']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type=type
local concat,sortedhash=table.concat,table.sortedhash
@@ -24080,37 +24088,37 @@ local resolveprefix=resolvers.resolve
local report_lists=logs.reporter("resolvers","lists")
local report_resolved=logs.reporter("system","resolved")
local function tabstr(str)
- if type(str)=='table' then
- return concat(str," | ")
- else
- return str
- end
+ if type(str)=='table' then
+ return concat(str," | ")
+ else
+ return str
+ end
end
function listers.variables(pattern)
- local result=resolvers.knownvariables(pattern)
- for key,value in sortedhash(result) do
- report_lists(key)
- report_lists(" env: %s",tabstr(value.environment or "unset"))
- report_lists(" var: %s",tabstr(value.variable or "unset"))
- report_lists(" exp: %s",tabstr(value.expansion or "unset"))
- report_lists(" res: %s",tabstr(value.resolved or "unset"))
- end
+ local result=resolvers.knownvariables(pattern)
+ for key,value in sortedhash(result) do
+ report_lists(key)
+ report_lists(" env: %s",tabstr(value.environment or "unset"))
+ report_lists(" var: %s",tabstr(value.variable or "unset"))
+ report_lists(" exp: %s",tabstr(value.expansion or "unset"))
+ report_lists(" res: %s",tabstr(value.resolved or "unset"))
+ end
end
function listers.configurations()
- local configurations=resolvers.configurationfiles()
- for i=1,#configurations do
- report_resolved("file : %s",resolveprefix(configurations[i]))
- end
- report_resolved("")
- local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
- for i=1,#list do
- local li=resolveprefix(list[i])
- if lfs.isdir(li) then
- report_resolved("path - %s",li)
- else
- report_resolved("path + %s",li)
- end
+ local configurations=resolvers.configurationfiles()
+ for i=1,#configurations do
+ report_resolved("file : %s",resolveprefix(configurations[i]))
+ end
+ report_resolved("")
+ local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
+ for i=1,#list do
+ local li=resolveprefix(list[i])
+ if lfs.isdir(li) then
+ report_resolved("path - %s",li)
+ else
+ report_resolved("path + %s",li)
end
+ end
end
@@ -24120,14 +24128,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lib"] = package.loaded["util-lib"] or true
--- original size: 16094, stripped down to: 9206
+-- original size: 16094, stripped down to: 8443
if not modules then modules={} end modules ['util-lib']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local type=type
local next=next
@@ -24147,291 +24155,291 @@ local qualifiedpath=file.is_qualified_path
local isfile=lfs.isfile
local done=false
local function locate(required,version,trace,report,action)
- if type(required)~="string" then
- report("provide a proper library name")
- return
- end
- if trace then
- report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/")
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
- if isfile(addsuffix(required,os.libsuffix)) then
- if trace then
- report("qualified name %a found",required)
- end
- found_library=required
- else
- if trace then
- report("qualified name %a not found",required)
- end
- end
+ if type(required)~="string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library=nil
+ local required_full=gsub(required,"%.","/")
+ local required_path=pathpart(required_full)
+ local required_base=nameonly(required_full)
+ if qualifiedpath(required) then
+ if isfile(addsuffix(required,os.libsuffix)) then
+ if trace then
+ report("qualified name %a found",required)
+ end
+ found_library=required
else
- local required_name=required_base.."."..os.libsuffix
- local version=type(version)=="string" and version~="" and version or false
- local engine="luatex"
- if trace and not done then
- local list=expandpaths("lib")
- for i=1,#list do
- report("tds path %i: %s",i,list[i])
- end
+ if trace then
+ report("qualified name %a not found",required)
+ end
+ end
+ else
+ local required_name=required_base.."."..os.libsuffix
+ local version=type(version)=="string" and version~="" and version or false
+ local engine="luatex"
+ if trace and not done then
+ local list=expandpaths("lib")
+ for i=1,#list do
+ report("tds path %i: %s",i,list[i])
+ end
+ end
+ local function found(locate,asked_library,how,...)
+ if trace then
+ report("checking %s: %a",how,asked_library)
+ end
+ return locate(asked_library,...)
+ end
+ local function check(locate,...)
+ local found=nil
+ if version then
+ local asked_library=joinfile(required_path,version,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function found(locate,asked_library,how,...)
- if trace then
- report("checking %s: %a",how,asked_library)
- end
- return locate(asked_library,...)
- end
- local function check(locate,...)
- local found=nil
- if version then
- local asked_library=joinfile(required_path,version,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- if not found or found=="" then
- local asked_library=joinfile(required_path,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- return found and found~="" and found or false
+ found=locate(asked_library,...)
+ end
+ if not found or found=="" then
+ local asked_library=joinfile(required_path,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function attempt(checkpattern)
- if trace then
- report("checking tds lib paths strictly")
- end
- local found=findfile and check(findfile,"lib")
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- if trace then
- report("checking tds lib paths with wildcard")
- end
- local asked_library=joinfile(required_path,".*",required_name)
- if trace then
- report("checking %s: %a","latest version",asked_library)
- end
- local list=findfiles(asked_library,"lib",true)
- if list and #list>0 then
- sort(list)
- local found=list[#list]
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- if trace then
- report("checking lib paths")
- end
- package.extralibpath(environment.ownpath)
- local paths=package.libpaths()
- local pattern="/[^/]+%."..os.libsuffix.."$"
- for i=1,#paths do
- required_path=gsub(paths[i],pattern,"")
- local found=check(lfs.isfound)
- if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- return false
+ found=locate(asked_library,...)
+ end
+ return found and found~="" and found or false
+ end
+ local function attempt(checkpattern)
+ if trace then
+ report("checking tds lib paths strictly")
+ end
+ local found=findfile and check(findfile,"lib")
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
+ end
+ if trace then
+ report("checking tds lib paths with wildcard")
+ end
+ local asked_library=joinfile(required_path,".*",required_name)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
+ end
+ local list=findfiles(asked_library,"lib",true)
+ if list and #list>0 then
+ sort(list)
+ local found=list[#list]
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
end
- if engine then
- if trace then
- report("attemp 1, engine %a",engine)
- end
- found_library=attempt("/"..engine.."/")
- if not found_library then
- if trace then
- report("attemp 2, no engine",asked_library)
- end
- found_library=attempt()
- end
- else
- found_library=attempt()
+ end
+ if trace then
+ report("checking lib paths")
+ end
+ package.extralibpath(environment.ownpath)
+ local paths=package.libpaths()
+ local pattern="/[^/]+%."..os.libsuffix.."$"
+ for i=1,#paths do
+ required_path=gsub(paths[i],pattern,"")
+ local found=check(lfs.isfound)
+ if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
+ return found
end
+ end
+ return false
end
- if not found_library then
+ if engine then
+ if trace then
+ report("attemp 1, engine %a",engine)
+ end
+ found_library=attempt("/"..engine.."/")
+ if not found_library then
if trace then
- report("not found: %a",required)
+ report("attemp 2, no engine",asked_library)
end
- library=false
+ found_library=attempt()
+ end
else
- if trace then
- report("found: %a",found_library)
- end
- local result,message=action(found_library,required_base)
- if result then
- library=result
- else
- library=false
- report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
- end
+ found_library=attempt()
end
+ end
+ if not found_library then
if trace then
- if not library then
- report("unknown library: %a",required)
- else
- report("stored library: %a",required)
- end
+ report("not found: %a",required)
+ end
+ library=false
+ else
+ if trace then
+ report("found: %a",found_library)
+ end
+ local result,message=action(found_library,required_base)
+ if result then
+ library=result
+ else
+ library=false
+ report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
end
- return library or nil
+ end
+ if trace then
+ if not library then
+ report("unknown library: %a",required)
+ else
+ report("stored library: %a",required)
+ end
+ end
+ return library or nil
end
do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
- local library=loadedlibs[library]
- if library==nil then
- local trace_swiglib=trace_swiglib or package.helpers.trace
- library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
- pushdir(pathpart(name))
- local opener="luaopen_"..base
- if trace_swiglib then
- report_swiglib("opening: %a with %a",name,opener)
- end
- local library,message=loadlib(name,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
- else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
- end
- popdir()
- return library
- end)
- loadedlibs[required]=library or false
- end
- return library
- end
- function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
+ local report_swiglib=logs.reporter("swiglib")
+ local trace_swiglib=false
+ local savedrequire=require
+ local loadedlibs={}
+ local loadlib=package.loadlib
+ local pushdir=dir.push
+ local popdir=dir.pop
+ trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+ function requireswiglib(required,version)
+ local library=loadedlibs[library]
+ if library==nil then
+ local trace_swiglib=trace_swiglib or package.helpers.trace
+ library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ pushdir(pathpart(name))
+ local opener="luaopen_"..base
+ if trace_swiglib then
+ report_swiglib("opening: %a with %a",name,opener)
+ end
+ local library,message=loadlib(name,opener)
+ local libtype=type(library)
+ if libtype=="function" then
+ library=library()
else
- return savedrequire(name)
- end
- end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
- else
- fullname="swiglib."..name
- end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library=false
end
+ popdir()
return library
+ end)
+ loadedlibs[required]=library or false
+ end
+ return library
+ end
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
+ else
+ return savedrequire(name)
+ end
+ end
+ local swiglibs={}
+ local initializer="core"
+ function swiglib(name,version)
+ local library=swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
+ if trace_swiglib then
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%."..initializer.."$") then
+ fullname="swiglib."..name.."."..initializer
+ else
+ fullname="swiglib."..name
+ end
+ library=requireswiglib(fullname,version)
+ swiglibs[name]=library
+ statistics.stoptiming(swiglibs)
end
- statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
- end)
+ return library
+ end
+ statistics.register("used swiglibs",function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
+ end
+ end)
end
if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
- name=removesuffix(name)
- local l=loaded[name]
- if l==nil then
- local state,library=pcall(savedffiload,name)
- if type(library)=="userdata" then
- l=library
- elseif type(state)=="userdata" then
- l=state
- else
- l=false
- end
- loaded[name]=l
- elseif trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
+ local report_ffilib=logs.reporter("ffilib")
+ local trace_ffilib=false
+ local savedffiload=ffi.load
+ trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+ local loaded={}
+ local function locateindeed(name)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l==nil then
+ local state,library=pcall(savedffiload,name)
+ if type(library)=="userdata" then
+ l=library
+ elseif type(state)=="userdata" then
+ l=state
+ else
+ l=false
+ end
+ loaded[name]=l
+ elseif trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
end
- local function getlist(required)
- local list=directives.value("system.librarynames" )
- if type(list)=="table" then
- list=list[required]
- if type(list)=="table" then
- if trace then
- report("using lookup list for library %a: % | t",required,list)
- end
- return list
- end
+ return l
+ end
+ local function getlist(required)
+ local list=directives.value("system.librarynames" )
+ if type(list)=="table" then
+ list=list[required]
+ if type(list)=="table" then
+ if trace then
+ report("using lookup list for library %a: % | t",required,list)
end
- return { required }
+ return list
+ end
end
- function ffilib(name,version)
- name=removesuffix(name)
- local l=loaded[name]
- if l~=nil then
- if trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- end
- local list=getlist(name)
- if version=="system" then
- for i=1,#list do
- local library=locateindeed(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- else
- for i=1,#list do
- local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
- if type(library)=="userdata" then
- return library
- end
- end
- end
+ return { required }
+ end
+ function ffilib(name,version)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l~=nil then
+ if trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
+ end
+ return l
end
- function ffi.load(name)
- local list=getlist(name)
- for i=1,#list do
- local library=ffilib(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- if trace_ffilib then
- report_ffilib("trying to load %a using normal loader",name)
+ local list=getlist(name)
+ if version=="system" then
+ for i=1,#list do
+ local library=locateindeed(list[i])
+ if type(library)=="userdata" then
+ return library
end
- for i=1,#list do
- local state,library=pcall(savedffiload,list[i])
- if type(library)=="userdata" then
- return library
- elseif type(state)=="userdata" then
- return library
- end
+ end
+ else
+ for i=1,#list do
+ local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
+ if type(library)=="userdata" then
+ return library
end
+ end
+ end
+ end
+ function ffi.load(name)
+ local list=getlist(name)
+ for i=1,#list do
+ local library=ffilib(list[i])
+ if type(library)=="userdata" then
+ return library
+ end
+ end
+ if trace_ffilib then
+ report_ffilib("trying to load %a using normal loader",name)
+ end
+ for i=1,#list do
+ local state,library=pcall(savedffiload,list[i])
+ if type(library)=="userdata" then
+ return library
+ elseif type(state)=="userdata" then
+ return library
+ end
end
+ end
end
@@ -24441,13 +24449,13 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-sta"] = package.loaded["luat-sta"] or true
--- original size: 5703, stripped down to: 2507
+-- original size: 5703, stripped down to: 2321
if not modules then modules={} end modules ['luat-sta']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local gmatch,match=string.gmatch,string.match
local type=type
@@ -24460,81 +24468,81 @@ local hash=states.hash
states.tag=states.tag or ""
states.filename=states.filename or ""
function states.save(filename,tag)
- tag=tag or states.tag
- filename=file.addsuffix(filename or states.filename,'lus')
- io.savedata(filename,
- "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
- )
+ tag=tag or states.tag
+ filename=file.addsuffix(filename or states.filename,'lus')
+ io.savedata(filename,
+ "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
+ )
end
function states.load(filename,tag)
- states.filename=filename
- states.tag=tag or "whatever"
- states.filename=file.addsuffix(states.filename,'lus')
- data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
+ states.filename=filename
+ states.tag=tag or "whatever"
+ states.filename=file.addsuffix(states.filename,'lus')
+ data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
end
local function set_by_tag(tag,key,value,default,persistent)
- local d,h=data[tag],hash[tag]
- if d then
- if type(d)=="table" then
- local dkey,hkey=key,key
- local pre,post=match(key,"(.+)%.([^%.]+)$")
- if pre and post then
- for k in gmatch(pre,"[^%.]+") do
- local dk=d[k]
- if not dk then
- dk={}
- d[k]=dk
- elseif type(dk)=="string" then
- break
- end
- d=dk
- end
- dkey,hkey=post,key
- end
- if value==nil then
- value=default
- elseif value==false then
- elseif persistent then
- value=value or d[dkey] or default
- else
- value=value or default
- end
- d[dkey],h[hkey]=value,value
- elseif type(d)=="string" then
- data[tag],hash[tag]=value,value
+ local d,h=data[tag],hash[tag]
+ if d then
+ if type(d)=="table" then
+ local dkey,hkey=key,key
+ local pre,post=match(key,"(.+)%.([^%.]+)$")
+ if pre and post then
+ for k in gmatch(pre,"[^%.]+") do
+ local dk=d[k]
+ if not dk then
+ dk={}
+ d[k]=dk
+ elseif type(dk)=="string" then
+ break
+ end
+ d=dk
end
+ dkey,hkey=post,key
+ end
+ if value==nil then
+ value=default
+ elseif value==false then
+ elseif persistent then
+ value=value or d[dkey] or default
+ else
+ value=value or default
+ end
+ d[dkey],h[hkey]=value,value
+ elseif type(d)=="string" then
+ data[tag],hash[tag]=value,value
end
+ end
end
local function get_by_tag(tag,key,default)
- local h=hash[tag]
- if h and h[key] then
- return h[key]
- else
- local d=data[tag]
- if d then
- for k in gmatch(key,"[^%.]+") do
- local dk=d[k]
- if dk~=nil then
- d=dk
- else
- return default
- end
- end
- if d==false then
- return false
- else
- return d or default
- end
+ local h=hash[tag]
+ if h and h[key] then
+ return h[key]
+ else
+ local d=data[tag]
+ if d then
+ for k in gmatch(key,"[^%.]+") do
+ local dk=d[k]
+ if dk~=nil then
+ d=dk
+ else
+ return default
end
+ end
+ if d==false then
+ return false
+ else
+ return d or default
+ end
end
+ end
end
states.set_by_tag=set_by_tag
states.get_by_tag=get_by_tag
function states.set(key,value,default,persistent)
- set_by_tag(states.tag,key,value,default,persistent)
+ set_by_tag(states.tag,key,value,default,persistent)
end
function states.get(key,default)
- return get_by_tag(states.tag,key,default)
+ return get_by_tag(states.tag,key,default)
end
@@ -24544,14 +24552,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
--- original size: 9346, stripped down to: 7465
+-- original size: 9346, stripped down to: 7085
if not modules then modules={} end modules ['luat-fmt']={
- version=1.001,
- comment="companion to mtxrun",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to mtxrun",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format=string.format
local concat=table.concat
@@ -24559,223 +24567,223 @@ local quoted=string.quoted
local luasuffixes=utilities.lua.suffixes
local report_format=logs.reporter("resolvers","formats")
local function primaryflags()
- local arguments=environment.arguments
- local flags={}
- if arguments.silent then
- flags[#flags+1]="--interaction=batchmode"
- end
- if arguments.jit then
- flags[#flags+1]="--jiton"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local flags={}
+ if arguments.silent then
+ flags[#flags+1]="--interaction=batchmode"
+ end
+ if arguments.jit then
+ flags[#flags+1]="--jiton"
+ end
+ return concat(flags," ")
end
local function secondaryflags()
- local arguments=environment.arguments
- local trackers=arguments.trackers
- local directives=arguments.directives
- local flags={}
- if trackers and trackers~="" then
- flags[#flags+1]="--c:trackers="..quoted(trackers)
- end
- if directives and directives~="" then
- flags[#flags+1]="--c:directives="..quoted(directives)
- end
- if arguments.silent then
- flags[#flags+1]="--c:silent"
- end
- if arguments.errors then
- flags[#flags+1]="--c:errors"
- end
- if arguments.jit then
- flags[#flags+1]="--c:jiton"
- end
- if arguments.ansi then
- flags[#flags+1]="--c:ansi"
- end
- if arguments.strip then
- flags[#flags+1]="--c:strip"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local trackers=arguments.trackers
+ local directives=arguments.directives
+ local flags={}
+ if trackers and trackers~="" then
+ flags[#flags+1]="--c:trackers="..quoted(trackers)
+ end
+ if directives and directives~="" then
+ flags[#flags+1]="--c:directives="..quoted(directives)
+ end
+ if arguments.silent then
+ flags[#flags+1]="--c:silent"
+ end
+ if arguments.errors then
+ flags[#flags+1]="--c:errors"
+ end
+ if arguments.jit then
+ flags[#flags+1]="--c:jiton"
+ end
+ if arguments.ansi then
+ flags[#flags+1]="--c:ansi"
+ end
+ if arguments.strip then
+ flags[#flags+1]="--c:strip"
+ end
+ return concat(flags," ")
end
local template=[[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]]
local checkers={
- primaryflags="string",
- secondaryflags="string",
- luafile="readable",
- texfile="readable",
- redirect="string",
- dump="string",
+ primaryflags="string",
+ secondaryflags="string",
+ luafile="readable",
+ texfile="readable",
+ redirect="string",
+ dump="string",
}
local runners={
- luatex=sandbox.registerrunner {
- name="make luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="make luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="make luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="make luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.make_format(name,arguments)
- local engine=environment.ownmain or "luatex"
- local silent=environment.arguments.silent
- local errors=environment.arguments.errors
- local olddir=dir.current()
- local path=caches.getwritablepath("formats",engine) or ""
- if path~="" then
- lfs.chdir(path)
- end
- report_format("using format path %a",dir.current())
- local texsourcename=file.addsuffix(name,"mkiv")
- local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- if fulltexsourcename=="" then
- texsourcename=file.addsuffix(name,"tex")
- fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- end
- if fulltexsourcename=="" then
- report_format("no tex source file with name %a (mkiv or tex)",name)
- lfs.chdir(olddir)
- return
- else
- report_format("using tex source file %a",fulltexsourcename)
- end
- local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
- local specificationname=file.replacesuffix(fulltexsourcename,"lus")
- local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- if fullspecificationname=="" then
- specificationname=file.join(texsourcepath,"context.lus")
- fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- end
- if fullspecificationname=="" then
- report_format("unknown stub specification %a",specificationname)
- lfs.chdir(olddir)
- return
- end
- local specificationpath=file.dirname(fullspecificationname)
- local usedluastub=nil
- local usedlualibs=dofile(fullspecificationname)
- if type(usedlualibs)=="string" then
- usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
- elseif type(usedlualibs)=="table" then
- report_format("using stub specification %a",fullspecificationname)
- local texbasename=file.basename(name)
- local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
- local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
- report_format("creating initialization file %a",luastubname)
- utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
- if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
- report_format("using compiled initialization file %a",lucstubname)
- usedluastub=lucstubname
- else
- report_format("using uncompiled initialization file %a",luastubname)
- usedluastub=luastubname
- end
- else
- report_format("invalid stub specification %a",fullspecificationname)
- lfs.chdir(olddir)
- return
- end
- local specification={
- primaryflags=primaryflags(),
- secondaryflags=secondaryflags(),
- luafile=quoted(usedluastub),
- texfile=quoted(fulltexsourcename),
- dump=os.platform=="unix" and "\\\\dump" or "\\dump",
- }
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
- elseif silent then
- statistics.starttiming()
- specification.redirect="> temp.log"
- local result=runner(specification)
- local runtime=statistics.stoptiming()
- if result~=0 then
- print(format("%s silent make > fatal error when making format %q",engine,name))
- else
- print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
- end
- os.remove("temp.log")
- else
- runner(specification)
- end
- local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
- local mp=dir.glob(pattern)
- if mp then
- for i=1,#mp do
- local name=mp[i]
- report_format("removing related mplib format %a",file.basename(name))
- os.remove(name)
- end
- end
+ local engine=environment.ownmain or "luatex"
+ local silent=environment.arguments.silent
+ local errors=environment.arguments.errors
+ local olddir=dir.current()
+ local path=caches.getwritablepath("formats",engine) or ""
+ if path~="" then
+ lfs.chdir(path)
+ end
+ report_format("using format path %a",dir.current())
+ local texsourcename=file.addsuffix(name,"mkiv")
+ local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ if fulltexsourcename=="" then
+ texsourcename=file.addsuffix(name,"tex")
+ fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ end
+ if fulltexsourcename=="" then
+ report_format("no tex source file with name %a (mkiv or tex)",name)
lfs.chdir(olddir)
+ return
+ else
+ report_format("using tex source file %a",fulltexsourcename)
+ end
+ local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
+ local specificationname=file.replacesuffix(fulltexsourcename,"lus")
+ local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ if fullspecificationname=="" then
+ specificationname=file.join(texsourcepath,"context.lus")
+ fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ end
+ if fullspecificationname=="" then
+ report_format("unknown stub specification %a",specificationname)
+ lfs.chdir(olddir)
+ return
+ end
+ local specificationpath=file.dirname(fullspecificationname)
+ local usedluastub=nil
+ local usedlualibs=dofile(fullspecificationname)
+ if type(usedlualibs)=="string" then
+ usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
+ elseif type(usedlualibs)=="table" then
+ report_format("using stub specification %a",fullspecificationname)
+ local texbasename=file.basename(name)
+ local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
+ local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
+ report_format("creating initialization file %a",luastubname)
+ utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
+ if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
+ report_format("using compiled initialization file %a",lucstubname)
+ usedluastub=lucstubname
+ else
+ report_format("using uncompiled initialization file %a",luastubname)
+ usedluastub=luastubname
+ end
+ else
+ report_format("invalid stub specification %a",fullspecificationname)
+ lfs.chdir(olddir)
+ return
+ end
+ local specification={
+ primaryflags=primaryflags(),
+ secondaryflags=secondaryflags(),
+ luafile=quoted(usedluastub),
+ texfile=quoted(fulltexsourcename),
+ dump=os.platform=="unix" and "\\\\dump" or "\\dump",
+ }
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
+ elseif silent then
+ statistics.starttiming()
+ specification.redirect="> temp.log"
+ local result=runner(specification)
+ local runtime=statistics.stoptiming()
+ if result~=0 then
+ print(format("%s silent make > fatal error when making format %q",engine,name))
+ else
+ print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
+ end
+ os.remove("temp.log")
+ else
+ runner(specification)
+ end
+ local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
+ local mp=dir.glob(pattern)
+ if mp then
+ for i=1,#mp do
+ local name=mp[i]
+ report_format("removing related mplib format %a",file.basename(name))
+ os.remove(name)
+ end
+ end
+ lfs.chdir(olddir)
end
local template=[[%flags% --fmt=%fmtfile% --lua=%luafile% %texfile% %more%]]
local checkers={
- flags="string",
- more="string",
- fmtfile="readable",
- luafile="readable",
- texfile="readable",
+ flags="string",
+ more="string",
+ fmtfile="readable",
+ luafile="readable",
+ texfile="readable",
}
local runners={
- luatex=sandbox.registerrunner {
- name="run luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="run luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="run luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="run luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.run_format(name,data,more)
- if name and name~="" then
- local engine=environment.ownmain or "luatex"
- local barename=file.removesuffix(name)
- local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
- if fmtname=="" then
- fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
- end
- fmtname=resolvers.cleanpath(fmtname)
- if fmtname=="" then
- report_format("no format with name %a",name)
+ if name and name~="" then
+ local engine=environment.ownmain or "luatex"
+ local barename=file.removesuffix(name)
+ local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
+ if fmtname=="" then
+ fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
+ end
+ fmtname=resolvers.cleanpath(fmtname)
+ if fmtname=="" then
+ report_format("no format with name %a",name)
+ else
+ local barename=file.removesuffix(name)
+ local luaname=file.addsuffix(barename,"luc")
+ if not lfs.isfile(luaname) then
+ luaname=file.addsuffix(barename,"lua")
+ end
+ if not lfs.isfile(luaname) then
+ report_format("using format name %a",fmtname)
+ report_format("no luc/lua file with name %a",barename)
+ else
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be run, no runner available for engine %a",name,engine)
else
- local barename=file.removesuffix(name)
- local luaname=file.addsuffix(barename,"luc")
- if not lfs.isfile(luaname) then
- luaname=file.addsuffix(barename,"lua")
- end
- if not lfs.isfile(luaname) then
- report_format("using format name %a",fmtname)
- report_format("no luc/lua file with name %a",barename)
- else
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be run, no runner available for engine %a",name,engine)
- else
- runner {
- flags=primaryflags(),
- fmtfile=quoted(barename),
- luafile=quoted(luaname),
- texfile=quoted(data),
- more=more,
- }
- end
- end
+ runner {
+ flags=primaryflags(),
+ fmtfile=quoted(barename),
+ luafile=quoted(luaname),
+ texfile=quoted(data),
+ more=more,
+ }
end
+ end
end
+ end
end
@@ -24783,8 +24791,8 @@ end -- of closure
-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 988986
--- stripped bytes : 349358
+-- original bytes : 989364
+-- stripped bytes : 391967
-- end library merge
@@ -25707,7 +25715,7 @@ function runners.timedrun(filename) -- just for me
end
function runners.timed(action)
- statistics.timed(action)
+ statistics.timed(action,true)
end
function runners.associate(filename)
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 2763cbc04..168f204c7 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -63,14 +63,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lua"] = package.loaded["l-lua"] or true
--- original size: 6266, stripped down to: 3009
+-- original size: 6266, stripped down to: 2875
if not modules then modules={} end modules ['l-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,tonumber=next,type,tonumber
LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
@@ -78,111 +78,111 @@ LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
LUAVERSION=LUAMAJORVERSION+LUAMINORVERSION/10
if LUAVERSION<5.2 and jit then
- MINORVERSION=2
- LUAVERSION=5.2
+ MINORVERSION=2
+ LUAVERSION=5.2
end
_LUAVERSION=LUAVERSION
if not lpeg then
- lpeg=require("lpeg")
+ lpeg=require("lpeg")
end
if loadstring then
- local loadnormal=load
- function load(first,...)
- if type(first)=="string" then
- return loadstring(first,...)
- else
- return loadnormal(first,...)
- end
+ local loadnormal=load
+ function load(first,...)
+ if type(first)=="string" then
+ return loadstring(first,...)
+ else
+ return loadnormal(first,...)
end
+ end
else
- loadstring=load
+ loadstring=load
end
if not ipairs then
- local function iterate(a,i)
- i=i+1
- local v=a[i]
- if v~=nil then
- return i,v
- end
- end
- function ipairs(a)
- return iterate,a,0
+ local function iterate(a,i)
+ i=i+1
+ local v=a[i]
+ if v~=nil then
+ return i,v
end
+ end
+ function ipairs(a)
+ return iterate,a,0
+ end
end
if not pairs then
- function pairs(t)
- return next,t
- end
+ function pairs(t)
+ return next,t
+ end
end
if not table.unpack then
- table.unpack=_G.unpack
+ table.unpack=_G.unpack
elseif not unpack then
- _G.unpack=table.unpack
+ _G.unpack=table.unpack
end
if not package.loaders then
- package.loaders=package.searchers
+ package.loaders=package.searchers
end
local print,select,tostring=print,select,tostring
local inspectors={}
function setinspector(kind,inspector)
- inspectors[kind]=inspector
+ inspectors[kind]=inspector
end
function inspect(...)
- for s=1,select("#",...) do
- local value=select(s,...)
- if value==nil then
- print("nil")
- else
- local done=false
- local kind=type(value)
- local inspector=inspectors[kind]
- if inspector then
- done=inspector(value)
- if done then
- break
- end
- end
- for kind,inspector in next,inspectors do
- done=inspector(value)
- if done then
- break
- end
- end
- if not done then
- print(tostring(value))
- end
+ for s=1,select("#",...) do
+ local value=select(s,...)
+ if value==nil then
+ print("nil")
+ else
+ local done=false
+ local kind=type(value)
+ local inspector=inspectors[kind]
+ if inspector then
+ done=inspector(value)
+ if done then
+ break
+ end
+ end
+ for kind,inspector in next,inspectors do
+ done=inspector(value)
+ if done then
+ break
end
+ end
+ if not done then
+ print(tostring(value))
+ end
end
+ end
end
local dummy=function() end
function optionalrequire(...)
- local ok,result=xpcall(require,dummy,...)
- if ok then
- return result
- end
+ local ok,result=xpcall(require,dummy,...)
+ if ok then
+ return result
+ end
end
if lua then
- lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
+ lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
end
local flush=io.flush
if flush then
- local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
- local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
- local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
- local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
+ local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
+ local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
+ local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
+ local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
end
FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
if not FFISUPPORTED then
- local okay;okay,ffi=pcall(require,"ffi")
- FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
+ local okay;okay,ffi=pcall(require,"ffi")
+ FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
end
if not FFISUPPORTED then
- ffi=nil
+ ffi=nil
elseif not ffi.number then
- ffi.number=tonumber
+ ffi.number=tonumber
end
if not bit32 then
- bit32=require("l-bit32")
+ bit32=require("l-bit32")
end
@@ -192,14 +192,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-macro"] = package.loaded["l-macro"] or true
--- original size: 10131, stripped down to: 6337
+-- original size: 10131, stripped down to: 5991
if not modules then modules={} end modules ['l-macros']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local S,P,R,V,C,Cs,Cc,Ct,Carg=lpeg.S,lpeg.P,lpeg.R,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg
local lpegmatch=lpeg.match
@@ -229,214 +229,214 @@ local definitions={}
local resolve
local subparser
local report_lua=function(...)
- if logs and logs.reporter then
- report_lua=logs.reporter("system","lua")
- report_lua(...)
- else
- print(format(...))
- end
+ if logs and logs.reporter then
+ report_lua=logs.reporter("system","lua")
+ report_lua(...)
+ else
+ print(format(...))
+ end
end
local safeguard=P("local")*whitespace^1*name*(whitespace+P("="))
resolve=safeguard+C(C(name)*(arguments^-1))/function(raw,s,a)
- local d=definitions[s]
- if d then
- if a then
- local n=#a
- local p=patterns[s][n]
- if p then
- local d=d[n]
- for i=1,n do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return lpegmatch(p,d,1,a) or d
- else
- return raw
- end
- else
- return d[0] or raw
- end
- elseif a then
- for i=1,#a do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
+ local d=definitions[s]
+ if d then
+ if a then
+ local n=#a
+ local p=patterns[s][n]
+ if p then
+ local d=d[n]
+ for i=1,n do
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
end
- return s.."("..concat(a,",")..")"
- else
+ return lpegmatch(p,d,1,a) or d
+ else
return raw
+ end
+ else
+ return d[0] or raw
end
+ elseif a then
+ for i=1,#a do
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
+ end
+ return s.."("..concat(a,",")..")"
+ else
+ return raw
+ end
end
subparser=Cs((resolve+P(1))^1)
local enddefine=P("#enddefine")/""
local beginregister=(C(name)*(arguments+Cc(false))*C((1-enddefine)^1)*enddefine)/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
+ definitions[k]=d
+ end
+ d[n]=lpegmatch(subparser,v) or v
+ return ""
end
local register=(Cs(name)*(arguments+Cc(false))*spaces^0*Cs(body))/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
+ definitions[k]=d
+ end
+ d[n]=lpegmatch(subparser,v) or v
+ return ""
end
local unregister=(C(name)*spaces^0*(arguments+Cc(false)))/function(k,a)
- local n=0
- if a then
- n=#a
- local p=patterns[k]
- if p then
- p[n]=false
- end
- end
- local d=definitions[k]
- if d then
- d[n]=false
+ local n=0
+ if a then
+ n=#a
+ local p=patterns[k]
+ if p then
+ p[n]=false
end
- return ""
+ end
+ local d=definitions[k]
+ if d then
+ d[n]=false
+ end
+ return ""
end
local begindefine=(P("begindefine")*spaces^0/"")*beginregister
-local define=(P("define" )*spaces^0/"")*register
-local undefine=(P("undefine" )*spaces^0/"")*unregister
+local define=(P("define" )*spaces^0/"")*register
+local undefine=(P("undefine" )*spaces^0/"")*unregister
local parser=Cs((((P("#")/"")*(define+begindefine+undefine)*(newline^0/"") )+resolve+P(1) )^0 )
function macros.reset()
- definitions={}
- patterns={}
+ definitions={}
+ patterns={}
end
function macros.showdefinitions()
- for name,list in table.sortedhash(definitions) do
- local arguments=list.a
- if arguments then
- arguments="("..concat(arguments,",")..")"
- else
- arguments=""
- end
- print("macro: "..name..arguments)
- for i=0,#list do
- local l=list[i]
- if l then
- print(" "..l)
- end
- end
+ for name,list in table.sortedhash(definitions) do
+ local arguments=list.a
+ if arguments then
+ arguments="("..concat(arguments,",")..")"
+ else
+ arguments=""
+ end
+ print("macro: "..name..arguments)
+ for i=0,#list do
+ local l=list[i]
+ if l then
+ print(" "..l)
+ end
end
+ end
end
function macros.resolvestring(str)
- return lpegmatch(parser,str) or str
+ return lpegmatch(parser,str) or str
end
function macros.resolving()
- return next(patterns)
+ return next(patterns)
end
local function reload(path,name,data)
- local only=match(name,".-([^/]+)%.lua")
+ local only=match(name,".-([^/]+)%.lua")
+ if only and only~="" then
+ local name=path.."/"..only
+ local f=io.open(name,"wb")
+ f:write(data)
+ f:close()
+ local f=loadfile(name)
+ os.remove(name)
+ return f
+ end
+end
+local function reload(path,name,data)
+ if path and path~="" then
+ local only=string.match(name,".-([^/]+)%.lua")
if only and only~="" then
- local name=path.."/"..only
- local f=io.open(name,"wb")
+ local name=path.."/"..only.."-macro.lua"
+ local f=io.open(name,"wb")
+ if f then
f:write(data)
f:close()
- local f=loadfile(name)
+ local l=loadfile(name)
os.remove(name)
- return f
- end
-end
-local function reload(path,name,data)
- if path and path~="" then
- local only=string.match(name,".-([^/]+)%.lua")
- if only and only~="" then
- local name=path.."/"..only.."-macro.lua"
- local f=io.open(name,"wb")
- if f then
- f:write(data)
- f:close()
- local l=loadfile(name)
- os.remove(name)
- return l
- end
- end
+ return l
+ end
end
- return load(data,name)
+ end
+ return load(data,name)
end
local function loaded(name,trace,detail)
- local f=io.open(name,"rb")
- if not f then
- return false,format("file '%s' not found",name)
- end
- local c=f:read("*a")
- if not c then
- return false,format("file '%s' is invalid",name)
- end
- f:close()
- local n=lpegmatch(parser,c)
- if trace then
- if #n~=#c then
- report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
- if detail then
- report_lua()
- report_lua(n)
- report_lua()
- end
- elseif detail then
- report_lua("no macros expanded in '%s'",name)
- end
+ local f=io.open(name,"rb")
+ if not f then
+ return false,format("file '%s' not found",name)
+ end
+ local c=f:read("*a")
+ if not c then
+ return false,format("file '%s' is invalid",name)
+ end
+ f:close()
+ local n=lpegmatch(parser,c)
+ if trace then
+ if #n~=#c then
+ report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
+ if detail then
+ report_lua()
+ report_lua(n)
+ report_lua()
+ end
+ elseif detail then
+ report_lua("no macros expanded in '%s'",name)
end
- return reload(lfs and lfs.currentdir(),name,n)
+ end
+ return reload(lfs and lfs.currentdir(),name,n)
end
macros.loaded=loaded
function required(name,trace)
- local filename=file.addsuffix(name,"lua")
- local fullname=resolvers and resolvers.find_file(filename) or filename
- if not fullname or fullname=="" then
- return false
- end
- local codeblob=package.loaded[fullname]
- if codeblob then
- return codeblob
- end
- local code,message=loaded(fullname,macros,trace,trace)
- if type(code)=="function" then
- code=code()
- else
- report_lua("error when loading '%s'",fullname)
- return false,message
- end
- if code==nil then
- code=false
- end
- package.loaded[fullname]=code
- return code
+ local filename=file.addsuffix(name,"lua")
+ local fullname=resolvers and resolvers.find_file(filename) or filename
+ if not fullname or fullname=="" then
+ return false
+ end
+ local codeblob=package.loaded[fullname]
+ if codeblob then
+ return codeblob
+ end
+ local code,message=loaded(fullname,macros,trace,trace)
+ if type(code)=="function" then
+ code=code()
+ else
+ report_lua("error when loading '%s'",fullname)
+ return false,message
+ end
+ if code==nil then
+ code=false
+ end
+ package.loaded[fullname]=code
+ return code
end
macros.required=required
@@ -447,14 +447,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true
--- original size: 9747, stripped down to: 6739
+-- original size: 9747, stripped down to: 6313
if not modules then modules={} end modules ['l-sandbox']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local global=_G
local next=next
@@ -480,234 +480,234 @@ local trace=false
local logger=false
local blocked={}
local function report(...)
- tprint("sandbox ! "..format(...))
+ tprint("sandbox ! "..format(...))
end
sandbox.report=report
function sandbox.setreporter(r)
- report=r
- sandbox.report=r
+ report=r
+ sandbox.report=r
end
function sandbox.settrace(v)
- trace=v
+ trace=v
end
function sandbox.setlogger(l)
- logger=type(l)=="function" and l or false
+ logger=type(l)=="function" and l or false
end
local function register(func,overload,comment)
- if type(func)=="function" then
- if type(overload)=="string" then
- comment=overload
- overload=nil
- end
- local function f(...)
- if sandboxed then
- local overload=overloads[f]
- if overload then
- if logger then
- local result={ overload(func,...) }
- logger {
- comment=comments[f] or tostring(f),
- arguments={... },
- result=result[1] and true or false,
- }
- return unpack(result)
- else
- return overload(func,...)
- end
- else
- end
- else
- return func(...)
- end
- end
- if comment then
- comments[f]=comment
- if trace then
- report("registering function: %s",comment)
- end
+ if type(func)=="function" then
+ if type(overload)=="string" then
+ comment=overload
+ overload=nil
+ end
+ local function f(...)
+ if sandboxed then
+ local overload=overloads[f]
+ if overload then
+ if logger then
+ local result={ overload(func,...) }
+ logger {
+ comment=comments[f] or tostring(f),
+ arguments={... },
+ result=result[1] and true or false,
+ }
+ return unpack(result)
+ else
+ return overload(func,...)
+ end
+ else
end
- overloads[f]=overload or false
- originals[f]=func
- return f
+ else
+ return func(...)
+ end
end
+ if comment then
+ comments[f]=comment
+ if trace then
+ report("registering function: %s",comment)
+ end
+ end
+ overloads[f]=overload or false
+ originals[f]=func
+ return f
+ end
end
local function redefine(func,comment)
- if type(func)=="function" then
- skiploads[func]=comment or comments[func] or "unknown"
- if overloads[func]==false then
- overloads[func]=nil
- end
+ if type(func)=="function" then
+ skiploads[func]=comment or comments[func] or "unknown"
+ if overloads[func]==false then
+ overloads[func]=nil
end
+ end
end
sandbox.register=register
sandbox.redefine=redefine
function sandbox.original(func)
- return originals and originals[func] or func
+ return originals and originals[func] or func
end
function sandbox.overload(func,overload,comment)
- comment=comment or comments[func] or "?"
- if type(func)~="function" then
- if trace then
- report("overloading unknown function: %s",comment)
- end
- elseif type(overload)~="function" then
- if trace then
- report("overloading function with bad overload: %s",comment)
- end
- elseif overloads[func]==nil then
- if trace then
- report("function is not registered: %s",comment)
- end
- elseif skiploads[func] then
- if trace then
- report("function is not skipped: %s",comment)
- end
- else
- if trace then
- report("overloading function: %s",comment)
- end
- overloads[func]=overload
+ comment=comment or comments[func] or "?"
+ if type(func)~="function" then
+ if trace then
+ report("overloading unknown function: %s",comment)
+ end
+ elseif type(overload)~="function" then
+ if trace then
+ report("overloading function with bad overload: %s",comment)
+ end
+ elseif overloads[func]==nil then
+ if trace then
+ report("function is not registered: %s",comment)
+ end
+ elseif skiploads[func] then
+ if trace then
+ report("function is not skipped: %s",comment)
+ end
+ else
+ if trace then
+ report("overloading function: %s",comment)
end
- return func
+ overloads[func]=overload
+ end
+ return func
end
local function whatever(specification,what,target)
- if type(specification)~="table" then
- report("%s needs a specification",what)
- elseif type(specification.category)~="string" or type(specification.action)~="function" then
- report("%s needs a category and action",what)
- elseif not sandboxed then
- target[#target+1]=specification
- elseif trace then
- report("already enabled, discarding %s",what)
- end
+ if type(specification)~="table" then
+ report("%s needs a specification",what)
+ elseif type(specification.category)~="string" or type(specification.action)~="function" then
+ report("%s needs a category and action",what)
+ elseif not sandboxed then
+ target[#target+1]=specification
+ elseif trace then
+ report("already enabled, discarding %s",what)
+ end
end
function sandbox.initializer(specification)
- whatever(specification,"initializer",initializers)
+ whatever(specification,"initializer",initializers)
end
function sandbox.finalizer(specification)
- whatever(specification,"finalizer",finalizers)
+ whatever(specification,"finalizer",finalizers)
end
function require(name)
- local n=gsub(name,"^.*[\\/]","")
- local n=gsub(n,"[%.].*$","")
- local b=blocked[n]
- if b==false then
- return nil
- elseif b then
- if trace then
- report("using blocked: %s",n)
- end
- return b
- else
- if trace then
- report("requiring: %s",name)
- end
- return requiem(name)
+ local n=gsub(name,"^.*[\\/]","")
+ local n=gsub(n,"[%.].*$","")
+ local b=blocked[n]
+ if b==false then
+ return nil
+ elseif b then
+ if trace then
+ report("using blocked: %s",n)
end
-end
-function blockrequire(name,lib)
+ return b
+ else
if trace then
- report("preventing reload of: %s",name)
+ report("requiring: %s",name)
end
- blocked[name]=lib or _G[name] or false
+ return requiem(name)
+ end
+end
+function blockrequire(name,lib)
+ if trace then
+ report("preventing reload of: %s",name)
+ end
+ blocked[name]=lib or _G[name] or false
end
function sandbox.enable()
- if not sandboxed then
- debug={
- traceback=debug.traceback,
- }
- for i=1,#initializers do
- initializers[i].action()
- end
- for i=1,#finalizers do
- finalizers[i].action()
- end
- local nnot=0
- local nyes=0
- local cnot={}
- local cyes={}
- local skip={}
- for k,v in next,overloads do
- local c=comments[k]
- if v then
- if c then
- cyes[#cyes+1]=c
- else
- nyes=nyes+1
- end
- else
- if c then
- cnot[#cnot+1]=c
- else
- nnot=nnot+1
- end
- end
- end
- for k,v in next,skiploads do
- skip[#skip+1]=v
- end
- if #cyes>0 then
- sort(cyes)
- report("overloaded known: %s",concat(cyes," | "))
- end
- if nyes>0 then
- report("overloaded unknown: %s",nyes)
- end
- if #cnot>0 then
- sort(cnot)
- report("not overloaded known: %s",concat(cnot," | "))
- end
- if nnot>0 then
- report("not overloaded unknown: %s",nnot)
+ if not sandboxed then
+ debug={
+ traceback=debug.traceback,
+ }
+ for i=1,#initializers do
+ initializers[i].action()
+ end
+ for i=1,#finalizers do
+ finalizers[i].action()
+ end
+ local nnot=0
+ local nyes=0
+ local cnot={}
+ local cyes={}
+ local skip={}
+ for k,v in next,overloads do
+ local c=comments[k]
+ if v then
+ if c then
+ cyes[#cyes+1]=c
+ else
+ nyes=nyes+1
end
- if #skip>0 then
- sort(skip)
- report("not overloaded redefined: %s",concat(skip," | "))
+ else
+ if c then
+ cnot[#cnot+1]=c
+ else
+ nnot=nnot+1
end
- initializers=nil
- finalizers=nil
- originals=nil
- sandboxed=true
+ end
+ end
+ for k,v in next,skiploads do
+ skip[#skip+1]=v
+ end
+ if #cyes>0 then
+ sort(cyes)
+ report("overloaded known: %s",concat(cyes," | "))
+ end
+ if nyes>0 then
+ report("overloaded unknown: %s",nyes)
+ end
+ if #cnot>0 then
+ sort(cnot)
+ report("not overloaded known: %s",concat(cnot," | "))
+ end
+ if nnot>0 then
+ report("not overloaded unknown: %s",nnot)
end
+ if #skip>0 then
+ sort(skip)
+ report("not overloaded redefined: %s",concat(skip," | "))
+ end
+ initializers=nil
+ finalizers=nil
+ originals=nil
+ sandboxed=true
+ end
end
blockrequire("lfs",lfs)
blockrequire("io",io)
blockrequire("os",os)
blockrequire("ffi",ffi)
local function supported(library)
- local l=_G[library]
- return l
+ local l=_G[library]
+ return l
end
loadfile=register(loadfile,"loadfile")
if supported("io") then
- io.open=register(io.open,"io.open")
- io.popen=register(io.popen,"io.popen")
- io.lines=register(io.lines,"io.lines")
- io.output=register(io.output,"io.output")
- io.input=register(io.input,"io.input")
+ io.open=register(io.open,"io.open")
+ io.popen=register(io.popen,"io.popen")
+ io.lines=register(io.lines,"io.lines")
+ io.output=register(io.output,"io.output")
+ io.input=register(io.input,"io.input")
end
if supported("os") then
- os.execute=register(os.execute,"os.execute")
- os.spawn=register(os.spawn,"os.spawn")
- os.exec=register(os.exec,"os.exec")
- os.rename=register(os.rename,"os.rename")
- os.remove=register(os.remove,"os.remove")
+ os.execute=register(os.execute,"os.execute")
+ os.spawn=register(os.spawn,"os.spawn")
+ os.exec=register(os.exec,"os.exec")
+ os.rename=register(os.rename,"os.rename")
+ os.remove=register(os.remove,"os.remove")
end
if supported("lfs") then
- lfs.chdir=register(lfs.chdir,"lfs.chdir")
- lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
- lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
- lfs.isfile=register(lfs.isfile,"lfs.isfile")
- lfs.isdir=register(lfs.isdir,"lfs.isdir")
- lfs.attributes=register(lfs.attributes,"lfs.attributes")
- lfs.dir=register(lfs.dir,"lfs.dir")
- lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
- lfs.touch=register(lfs.touch,"lfs.touch")
- lfs.link=register(lfs.link,"lfs.link")
- lfs.setmode=register(lfs.setmode,"lfs.setmode")
- lfs.readlink=register(lfs.readlink,"lfs.readlink")
- lfs.shortname=register(lfs.shortname,"lfs.shortname")
- lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
+ lfs.chdir=register(lfs.chdir,"lfs.chdir")
+ lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
+ lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
+ lfs.isfile=register(lfs.isfile,"lfs.isfile")
+ lfs.isdir=register(lfs.isdir,"lfs.isdir")
+ lfs.attributes=register(lfs.attributes,"lfs.attributes")
+ lfs.dir=register(lfs.dir,"lfs.dir")
+ lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
+ lfs.touch=register(lfs.touch,"lfs.touch")
+ lfs.link=register(lfs.link,"lfs.link")
+ lfs.setmode=register(lfs.setmode,"lfs.setmode")
+ lfs.readlink=register(lfs.readlink,"lfs.readlink")
+ lfs.shortname=register(lfs.shortname,"lfs.shortname")
+ lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
end
@@ -717,14 +717,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-package"] = package.loaded["l-package"] or true
--- original size: 11605, stripped down to: 8663
+-- original size: 11605, stripped down to: 8299
if not modules then modules={} end modules ['l-package']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type=type
local gsub,format,find=string.gsub,string.format,string.find
@@ -732,40 +732,40 @@ local insert,remove=table.insert,table.remove
local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
local package=package
local searchers=package.searchers or package.loaders
-local filejoin=file and file.join or function(path,name) return path.."/"..name end
-local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
-local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
+local filejoin=file and file.join or function(path,name) return path.."/"..name end
+local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
+local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
local function cleanpath(path)
- return path
+ return path
end
local pattern=Cs((((1-S("\\/"))^0*(S("\\/")^1/"/"))^0*(P(".")^1/"/"+P(1))^1)*-1)
local function lualibfile(name)
- return lpegmatch(pattern,name) or name
+ return lpegmatch(pattern,name) or name
end
local offset=luarocks and 1 or 0
local helpers=package.helpers or {
- cleanpath=cleanpath,
- lualibfile=lualibfile,
- trace=false,
- report=function(...) print(format(...)) end,
- builtin={
- ["preload table"]=searchers[1+offset],
- ["path specification"]=searchers[2+offset],
- ["cpath specification"]=searchers[3+offset],
- ["all in one fallback"]=searchers[4+offset],
- },
- methods={},
- sequence={
- "already loaded",
- "preload table",
- "qualified path",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
- }
+ cleanpath=cleanpath,
+ lualibfile=lualibfile,
+ trace=false,
+ report=function(...) print(format(...)) end,
+ builtin={
+ ["preload table"]=searchers[1+offset],
+ ["path specification"]=searchers[2+offset],
+ ["cpath specification"]=searchers[3+offset],
+ ["all in one fallback"]=searchers[4+offset],
+ },
+ methods={},
+ sequence={
+ "already loaded",
+ "preload table",
+ "qualified path",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
+ }
}
package.helpers=helpers
local methods=helpers.methods
@@ -781,255 +781,255 @@ local nofextralib=-1
local nofpathlua=-1
local nofpathlib=-1
local function listpaths(what,paths)
- local nofpaths=#paths
- if nofpaths>0 then
- for i=1,nofpaths do
- helpers.report("using %s path %i: %s",what,i,paths[i])
- end
- else
- helpers.report("no %s paths defined",what)
+ local nofpaths=#paths
+ if nofpaths>0 then
+ for i=1,nofpaths do
+ helpers.report("using %s path %i: %s",what,i,paths[i])
end
- return nofpaths
+ else
+ helpers.report("no %s paths defined",what)
+ end
+ return nofpaths
end
local function getextraluapaths()
- if helpers.trace and #extraluapaths~=nofextralua then
- nofextralua=listpaths("extra lua",extraluapaths)
- end
- return extraluapaths
+ if helpers.trace and #extraluapaths~=nofextralua then
+ nofextralua=listpaths("extra lua",extraluapaths)
+ end
+ return extraluapaths
end
local function getextralibpaths()
- if helpers.trace and #extralibpaths~=nofextralib then
- nofextralib=listpaths("extra lib",extralibpaths)
- end
- return extralibpaths
+ if helpers.trace and #extralibpaths~=nofextralib then
+ nofextralib=listpaths("extra lib",extralibpaths)
+ end
+ return extralibpaths
end
local function getluapaths()
- local luapath=package.path or ""
- if oldluapath~=luapath then
- luapaths=file.splitpath(luapath,";")
- oldluapath=luapath
- nofpathlua=-1
- end
- if helpers.trace and #luapaths~=nofpathlua then
- nofpathlua=listpaths("builtin lua",luapaths)
- end
- return luapaths
+ local luapath=package.path or ""
+ if oldluapath~=luapath then
+ luapaths=file.splitpath(luapath,";")
+ oldluapath=luapath
+ nofpathlua=-1
+ end
+ if helpers.trace and #luapaths~=nofpathlua then
+ nofpathlua=listpaths("builtin lua",luapaths)
+ end
+ return luapaths
end
local function getlibpaths()
- local libpath=package.cpath or ""
- if oldlibpath~=libpath then
- libpaths=file.splitpath(libpath,";")
- oldlibpath=libpath
- nofpathlib=-1
- end
- if helpers.trace and #libpaths~=nofpathlib then
- nofpathlib=listpaths("builtin lib",libpaths)
- end
- return libpaths
+ local libpath=package.cpath or ""
+ if oldlibpath~=libpath then
+ libpaths=file.splitpath(libpath,";")
+ oldlibpath=libpath
+ nofpathlib=-1
+ end
+ if helpers.trace and #libpaths~=nofpathlib then
+ nofpathlib=listpaths("builtin lib",libpaths)
+ end
+ return libpaths
end
package.luapaths=getluapaths
package.libpaths=getlibpaths
package.extraluapaths=getextraluapaths
package.extralibpaths=getextralibpaths
local hashes={
- lua={},
- lib={},
+ lua={},
+ lib={},
}
local function registerpath(tag,what,target,...)
- local pathlist={... }
- local cleanpath=helpers.cleanpath
- local trace=helpers.trace
- local report=helpers.report
- local hash=hashes[what]
- local function add(path)
- local path=cleanpath(path)
- if not hash[path] then
- target[#target+1]=path
- hash[path]=true
- if trace then
- report("registered %s path %s: %s",tag,#target,path)
- end
- else
- if trace then
- report("duplicate %s path: %s",tag,path)
- end
- end
+ local pathlist={... }
+ local cleanpath=helpers.cleanpath
+ local trace=helpers.trace
+ local report=helpers.report
+ local hash=hashes[what]
+ local function add(path)
+ local path=cleanpath(path)
+ if not hash[path] then
+ target[#target+1]=path
+ hash[path]=true
+ if trace then
+ report("registered %s path %s: %s",tag,#target,path)
+ end
+ else
+ if trace then
+ report("duplicate %s path: %s",tag,path)
+ end
end
- for p=1,#pathlist do
- local path=pathlist[p]
- if type(path)=="table" then
- for i=1,#path do
- add(path[i])
- end
- else
- add(path)
- end
+ end
+ for p=1,#pathlist do
+ local path=pathlist[p]
+ if type(path)=="table" then
+ for i=1,#path do
+ add(path[i])
+ end
+ else
+ add(path)
end
+ end
end
local function pushpath(tag,what,target,path)
- local path=helpers.cleanpath(path)
- insert(target,1,path)
- if helpers.trace then
- helpers.report("pushing %s path in front: %s",tag,path)
- end
+ local path=helpers.cleanpath(path)
+ insert(target,1,path)
+ if helpers.trace then
+ helpers.report("pushing %s path in front: %s",tag,path)
+ end
end
local function poppath(tag,what,target)
- local path=remove(target,1)
- if helpers.trace then
- if path then
- helpers.report("popping %s path from front: %s",tag,path)
- else
- helpers.report("no %s path to pop",tag)
- end
+ local path=remove(target,1)
+ if helpers.trace then
+ if path then
+ helpers.report("popping %s path from front: %s",tag,path)
+ else
+ helpers.report("no %s path to pop",tag)
end
+ end
end
helpers.registerpath=registerpath
function package.extraluapath(...)
- registerpath("extra lua","lua",extraluapaths,...)
+ registerpath("extra lua","lua",extraluapaths,...)
end
function package.pushluapath(path)
- pushpath("extra lua","lua",extraluapaths,path)
+ pushpath("extra lua","lua",extraluapaths,path)
end
function package.popluapath()
- poppath("extra lua","lua",extraluapaths)
+ poppath("extra lua","lua",extraluapaths)
end
function package.extralibpath(...)
- registerpath("extra lib","lib",extralibpaths,...)
+ registerpath("extra lib","lib",extralibpaths,...)
end
function package.pushlibpath(path)
- pushpath("extra lib","lib",extralibpaths,path)
+ pushpath("extra lib","lib",extralibpaths,path)
end
function package.poplibpath()
- poppath("extra lib","lua",extralibpaths)
+ poppath("extra lib","lua",extralibpaths)
end
local function loadedaslib(resolved,rawname)
- local base=gsub(rawname,"%.","_")
- local init="luaopen_"..gsub(base,"%.","_")
- if helpers.trace then
- helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
- end
- return package.loadlib(resolved,init)
+ local base=gsub(rawname,"%.","_")
+ local init="luaopen_"..gsub(base,"%.","_")
+ if helpers.trace then
+ helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+ end
+ return package.loadlib(resolved,init)
end
helpers.loadedaslib=loadedaslib
local function loadedbypath(name,rawname,paths,islib,what)
- local trace=helpers.trace
- for p=1,#paths do
- local path=paths[p]
- local resolved=filejoin(path,name)
- if trace then
- helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
- end
- if isreadable(resolved) then
- if trace then
- helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ for p=1,#paths do
+ local path=paths[p]
+ local resolved=filejoin(path,name)
+ if trace then
+ helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
+ end
+ if isreadable(resolved) then
+ if trace then
+ helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
end
+ end
end
helpers.loadedbypath=loadedbypath
local function loadedbyname(name,rawname)
- if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
- local trace=helpers.trace
- if trace then
- helpers.report("qualified name, identifying '%s'",what,name)
- end
- if isreadable(name) then
- if trace then
- helpers.report("qualified name, '%s' found",what,name)
- end
- return loadfile(name)
- end
+ if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
+ local trace=helpers.trace
+ if trace then
+ helpers.report("qualified name, identifying '%s'",what,name)
end
+ if isreadable(name) then
+ if trace then
+ helpers.report("qualified name, '%s' found",what,name)
+ end
+ return loadfile(name)
+ end
+ end
end
helpers.loadedbyname=loadedbyname
methods["already loaded"]=function(name)
- return package.loaded[name]
+ return package.loaded[name]
end
methods["preload table"]=function(name)
- return builtin["preload table"](name)
+ return builtin["preload table"](name)
end
methods["qualified path"]=function(name)
- return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
+ return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
end
methods["lua extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
+ return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
end
methods["lib extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
+ return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
end
methods["path specification"]=function(name)
- getluapaths()
- return builtin["path specification"](name)
+ getluapaths()
+ return builtin["path specification"](name)
end
methods["cpath specification"]=function(name)
- getlibpaths()
- return builtin["cpath specification"](name)
+ getlibpaths()
+ return builtin["cpath specification"](name)
end
methods["all in one fallback"]=function(name)
- return builtin["all in one fallback"](name)
+ return builtin["all in one fallback"](name)
end
methods["not loaded"]=function(name)
- if helpers.trace then
- helpers.report("unable to locate '%s'",name or "?")
- end
- return nil
+ if helpers.trace then
+ helpers.report("unable to locate '%s'",name or "?")
+ end
+ return nil
end
local level=0
local used={}
helpers.traceused=false
function helpers.loaded(name)
- local sequence=helpers.sequence
- level=level+1
- for i=1,#sequence do
- local method=sequence[i]
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
- end
- local result,rest=methods[method](name)
- if type(result)=="function" then
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
- end
- if helpers.traceused then
- used[#used+1]={ level=level,name=name }
- end
- level=level-1
- return result,rest
- end
+ local sequence=helpers.sequence
+ level=level+1
+ for i=1,#sequence do
+ local method=sequence[i]
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
end
- level=level-1
- return nil
+ local result,rest=methods[method](name)
+ if type(result)=="function" then
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
+ end
+ if helpers.traceused then
+ used[#used+1]={ level=level,name=name }
+ end
+ level=level-1
+ return result,rest
+ end
+ end
+ level=level-1
+ return nil
end
function helpers.showused()
- local n=#used
- if n>0 then
- helpers.report("%s libraries loaded:",n)
- helpers.report()
- for i=1,n do
- local u=used[i]
- helpers.report("%i %a",u.level,u.name)
- end
- helpers.report()
- end
+ local n=#used
+ if n>0 then
+ helpers.report("%s libraries loaded:",n)
+ helpers.report()
+ for i=1,n do
+ local u=used[i]
+ helpers.report("%i %a",u.level,u.name)
+ end
+ helpers.report()
+ end
end
function helpers.unload(name)
- if helpers.trace then
- if package.loaded[name] then
- helpers.report("unloading, name '%s', %s",name,"done")
- else
- helpers.report("unloading, name '%s', %s",name,"not loaded")
- end
+ if helpers.trace then
+ if package.loaded[name] then
+ helpers.report("unloading, name '%s', %s",name,"done")
+ else
+ helpers.report("unloading, name '%s', %s",name,"not loaded")
end
- package.loaded[name]=nil
+ end
+ package.loaded[name]=nil
end
table.insert(searchers,1,helpers.loaded)
if context then
- package.path=""
+ package.path=""
end
@@ -1039,14 +1039,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
--- original size: 38434, stripped down to: 20344
+-- original size: 38434, stripped down to: 19310
if not modules then modules={} end modules ['l-lpeg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
lpeg=require("lpeg")
local lpeg=lpeg
@@ -1057,7 +1057,7 @@ local floor=math.floor
local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt
local lpegtype,lpegmatch,lpegprint=lpeg.type,lpeg.match,lpeg.print
if setinspector then
- setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
+ setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
end
lpeg.patterns=lpeg.patterns or {}
local patterns=lpeg.patterns
@@ -1080,7 +1080,7 @@ local underscore=P("_")
local hexdigit=digit+lowercase+uppercase
local hexdigits=hexdigit^1
local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
-local newline=P("\r")*(P("\n")+P(true))+P("\n")
+local newline=P("\r")*(P("\n")+P(true))+P("\n")
local escaped=P("\\")*anything
local squote=P("'")
local dquote=P('"')
@@ -1089,9 +1089,9 @@ local period=P(".")
local comma=P(",")
local utfbom_32_be=P('\000\000\254\255')
local utfbom_32_le=P('\255\254\000\000')
-local utfbom_16_be=P('\254\255')
-local utfbom_16_le=P('\255\254')
-local utfbom_8=P('\239\187\191')
+local utfbom_16_be=P('\254\255')
+local utfbom_16_le=P('\255\254')
+local utfbom_8=P('\239\187\191')
local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8
local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8")
local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")
@@ -1123,7 +1123,7 @@ patterns.utf8character=utf8character
patterns.validutf8=validutf8char
patterns.validutf8char=validutf8char
local eol=S("\n\r")
-local spacer=S(" \t\f\v")
+local spacer=S(" \t\f\v")
local whitespace=eol+spacer
local nonspacer=1-spacer
local nonwhitespace=1-whitespace
@@ -1132,7 +1132,7 @@ patterns.spacer=spacer
patterns.whitespace=whitespace
patterns.nonspacer=nonspacer
patterns.nonwhitespace=nonwhitespace
-local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
+local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0)
local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0)
@@ -1209,82 +1209,82 @@ patterns.somecontent=(anything-newline-space)^1
patterns.beginline=#(1-newline)
patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0))
function anywhere(pattern)
- return (1-P(pattern))^0*P(pattern)
+ return (1-P(pattern))^0*P(pattern)
end
lpeg.anywhere=anywhere
function lpeg.instringchecker(p)
- p=anywhere(p)
- return function(str)
- return lpegmatch(p,str) and true or false
- end
+ p=anywhere(p)
+ return function(str)
+ return lpegmatch(p,str) and true or false
+ end
end
function lpeg.splitter(pattern,action)
- if action then
- return (((1-P(pattern))^1)/action+1)^0
- else
- return (Cs((1-P(pattern))^1)+1)^0
- end
+ if action then
+ return (((1-P(pattern))^1)/action+1)^0
+ else
+ return (Cs((1-P(pattern))^1)+1)^0
+ end
end
function lpeg.tsplitter(pattern,action)
- if action then
- return Ct((((1-P(pattern))^1)/action+1)^0)
- else
- return Ct((Cs((1-P(pattern))^1)+1)^0)
- end
+ if action then
+ return Ct((((1-P(pattern))^1)/action+1)^0)
+ else
+ return Ct((Cs((1-P(pattern))^1)+1)^0)
+ end
end
local splitters_s,splitters_m,splitters_t={},{},{}
local function splitat(separator,single)
- local splitter=(single and splitters_s[separator]) or splitters_m[separator]
- if not splitter then
- separator=P(separator)
- local other=C((1-separator)^0)
- if single then
- local any=anything
- splitter=other*(separator*C(any^0)+"")
- splitters_s[separator]=splitter
- else
- splitter=other*(separator*other)^0
- splitters_m[separator]=splitter
- end
+ local splitter=(single and splitters_s[separator]) or splitters_m[separator]
+ if not splitter then
+ separator=P(separator)
+ local other=C((1-separator)^0)
+ if single then
+ local any=anything
+ splitter=other*(separator*C(any^0)+"")
+ splitters_s[separator]=splitter
+ else
+ splitter=other*(separator*other)^0
+ splitters_m[separator]=splitter
end
- return splitter
+ end
+ return splitter
end
local function tsplitat(separator)
- local splitter=splitters_t[separator]
- if not splitter then
- splitter=Ct(splitat(separator))
- splitters_t[separator]=splitter
- end
- return splitter
+ local splitter=splitters_t[separator]
+ if not splitter then
+ splitter=Ct(splitat(separator))
+ splitters_t[separator]=splitter
+ end
+ return splitter
end
lpeg.splitat=splitat
lpeg.tsplitat=tsplitat
function string.splitup(str,separator)
- if not separator then
- separator=","
- end
- return lpegmatch(splitters_m[separator] or splitat(separator),str)
+ if not separator then
+ separator=","
+ end
+ return lpegmatch(splitters_m[separator] or splitat(separator),str)
end
local cache={}
function lpeg.split(separator,str)
+ local c=cache[separator]
+ if not c then
+ c=tsplitat(separator)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+function string.split(str,separator)
+ if separator then
local c=cache[separator]
if not c then
- c=tsplitat(separator)
- cache[separator]=c
+ c=tsplitat(separator)
+ cache[separator]=c
end
return lpegmatch(c,str)
-end
-function string.split(str,separator)
- if separator then
- local c=cache[separator]
- if not c then
- c=tsplitat(separator)
- cache[separator]=c
- end
- return lpegmatch(c,str)
- else
- return { str }
- end
+ else
+ return { str }
+ end
end
local spacing=patterns.spacer^0*newline
local empty=spacing*Cc("")
@@ -1294,463 +1294,463 @@ patterns.textline=content
local linesplitter=tsplitat(newline)
patterns.linesplitter=linesplitter
function string.splitlines(str)
- return lpegmatch(linesplitter,str)
+ return lpegmatch(linesplitter,str)
end
local cache={}
function lpeg.checkedsplit(separator,str)
- local c=cache[separator]
- if not c then
- separator=P(separator)
- local other=C((1-separator)^1)
- c=Ct(separator^0*other*(separator^1*other)^0)
- cache[separator]=c
- end
- return lpegmatch(c,str)
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
end
function string.checkedsplit(str,separator)
- local c=cache[separator]
- if not c then
- separator=P(separator)
- local other=C((1-separator)^1)
- c=Ct(separator^0*other*(separator^1*other)^0)
- cache[separator]=c
- end
- return lpegmatch(c,str)
-end
-local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
-local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
+local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
local function f4(s) local c1,c2,c3,c4=byte(s,1,4) return ((c1*64+c2)*64+c3)*64+c4-63447168 end
local utf8byte=patterns.utf8one/byte+patterns.utf8two/f2+patterns.utf8three/f3+patterns.utf8four/f4
patterns.utf8byte=utf8byte
local cache={}
function lpeg.stripper(str)
- if type(str)=="string" then
- local s=cache[str]
- if not s then
- s=Cs(((S(str)^1)/""+1)^0)
- cache[str]=s
- end
- return s
- else
- return Cs(((str^1)/""+1)^0)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs(((S(str)^1)/""+1)^0)
+ cache[str]=s
end
+ return s
+ else
+ return Cs(((str^1)/""+1)^0)
+ end
end
local cache={}
function lpeg.keeper(str)
- if type(str)=="string" then
- local s=cache[str]
- if not s then
- s=Cs((((1-S(str))^1)/""+1)^0)
- cache[str]=s
- end
- return s
- else
- return Cs((((1-str)^1)/""+1)^0)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs((((1-S(str))^1)/""+1)^0)
+ cache[str]=s
end
+ return s
+ else
+ return Cs((((1-str)^1)/""+1)^0)
+ end
end
function lpeg.frontstripper(str)
- return (P(str)+P(true))*Cs(anything^0)
+ return (P(str)+P(true))*Cs(anything^0)
end
function lpeg.endstripper(str)
- return Cs((1-P(str)*endofstring)^0)
+ return Cs((1-P(str)*endofstring)^0)
end
function lpeg.replacer(one,two,makefunction,isutf)
- local pattern
- local u=isutf and utf8char or 1
- if type(one)=="table" then
- local no=#one
- local p=P(false)
- if no==0 then
- for k,v in next,one do
- p=p+P(k)/v
- end
- pattern=Cs((p+u)^0)
- elseif no==1 then
- local o=one[1]
- one,two=P(o[1]),o[2]
- pattern=Cs((one/two+u)^0)
- else
- for i=1,no do
- local o=one[i]
- p=p+P(o[1])/o[2]
- end
- pattern=Cs((p+u)^0)
- end
- else
- pattern=Cs((P(one)/(two or "")+u)^0)
+ local pattern
+ local u=isutf and utf8char or 1
+ if type(one)=="table" then
+ local no=#one
+ local p=P(false)
+ if no==0 then
+ for k,v in next,one do
+ p=p+P(k)/v
+ end
+ pattern=Cs((p+u)^0)
+ elseif no==1 then
+ local o=one[1]
+ one,two=P(o[1]),o[2]
+ pattern=Cs((one/two+u)^0)
+ else
+ for i=1,no do
+ local o=one[i]
+ p=p+P(o[1])/o[2]
+ end
+ pattern=Cs((p+u)^0)
end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ else
+ pattern=Cs((P(one)/(two or "")+u)^0)
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
end
+ else
+ return pattern
+ end
end
function lpeg.finder(lst,makefunction,isutf)
- local pattern
- if type(lst)=="table" then
- pattern=P(false)
- if #lst==0 then
- for k,v in next,lst do
- pattern=pattern+P(k)
- end
- else
- for i=1,#lst do
- pattern=pattern+P(lst[i])
- end
- end
- else
- pattern=P(lst)
- end
- if isutf then
- pattern=((utf8char or 1)-pattern)^0*pattern
+ local pattern
+ if type(lst)=="table" then
+ pattern=P(false)
+ if #lst==0 then
+ for k,v in next,lst do
+ pattern=pattern+P(k)
+ end
else
- pattern=(1-pattern)^0*pattern
+ for i=1,#lst do
+ pattern=pattern+P(lst[i])
+ end
end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ else
+ pattern=P(lst)
+ end
+ if isutf then
+ pattern=((utf8char or 1)-pattern)^0*pattern
+ else
+ pattern=(1-pattern)^0*pattern
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
end
+ else
+ return pattern
+ end
end
local splitters_f,splitters_s={},{}
function lpeg.firstofsplit(separator)
- local splitter=splitters_f[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)
- splitters_f[separator]=splitter
- end
- return splitter
+ local splitter=splitters_f[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)
+ splitters_f[separator]=splitter
+ end
+ return splitter
end
function lpeg.secondofsplit(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=(1-pattern)^0*pattern*C(anything^0)
- splitters_s[separator]=splitter
- end
- return splitter
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=(1-pattern)^0*pattern*C(anything^0)
+ splitters_s[separator]=splitter
+ end
+ return splitter
end
local splitters_s,splitters_p={},{}
function lpeg.beforesuffix(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)*pattern*endofstring
- splitters_s[separator]=splitter
- end
- return splitter
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)*pattern*endofstring
+ splitters_s[separator]=splitter
+ end
+ return splitter
end
function lpeg.afterprefix(separator)
- local splitter=splitters_p[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=pattern*C(anything^0)
- splitters_p[separator]=splitter
- end
- return splitter
+ local splitter=splitters_p[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=pattern*C(anything^0)
+ splitters_p[separator]=splitter
+ end
+ return splitter
end
function lpeg.balancer(left,right)
- left,right=P(left),P(right)
- return P { left*((1-left-right)+V(1))^0*right }
+ left,right=P(left),P(right)
+ return P { left*((1-left-right)+V(1))^0*right }
end
function lpeg.counter(pattern,action)
- local n=0
- local pattern=(P(pattern)/function() n=n+1 end+anything)^0
- if action then
- return function(str) n=0;lpegmatch(pattern,str);action(n) end
- else
- return function(str) n=0;lpegmatch(pattern,str);return n end
- end
+ local n=0
+ local pattern=(P(pattern)/function() n=n+1 end+anything)^0
+ if action then
+ return function(str) n=0;lpegmatch(pattern,str);action(n) end
+ else
+ return function(str) n=0;lpegmatch(pattern,str);return n end
+ end
end
function lpeg.is_lpeg(p)
- return p and lpegtype(p)=="pattern"
+ return p and lpegtype(p)=="pattern"
end
function lpeg.oneof(list,...)
- if type(list)~="table" then
- list={ list,... }
- end
- local p=P(list[1])
- for l=2,#list do
- p=p+P(list[l])
- end
- return p
+ if type(list)~="table" then
+ list={ list,... }
+ end
+ local p=P(list[1])
+ for l=2,#list do
+ p=p+P(list[l])
+ end
+ return p
end
local sort=table.sort
local function copyindexed(old)
- local new={}
- for i=1,#old do
- new[i]=old
- end
- return new
+ local new={}
+ for i=1,#old do
+ new[i]=old
+ end
+ return new
end
local function sortedkeys(tab)
- local keys,s={},0
- for key,_ in next,tab do
- s=s+1
- keys[s]=key
- end
- sort(keys)
- return keys
+ local keys,s={},0
+ for key,_ in next,tab do
+ s=s+1
+ keys[s]=key
+ end
+ sort(keys)
+ return keys
end
function lpeg.append(list,pp,delayed,checked)
- local p=pp
- if #list>0 then
- local keys=copyindexed(list)
- sort(keys)
- for i=#keys,1,-1 do
- local k=keys[i]
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- elseif delayed then
- local keys=sortedkeys(list)
+ local p=pp
+ if #list>0 then
+ local keys=copyindexed(list)
+ sort(keys)
+ for i=#keys,1,-1 do
+ local k=keys[i]
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
+ end
+ elseif delayed then
+ local keys=sortedkeys(list)
+ if p then
+ for i=1,#keys,1 do
+ local k=keys[i]
+ local v=list[k]
+ p=P(k)/list+p
+ end
+ else
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
if p then
- for i=1,#keys,1 do
- local k=keys[i]
- local v=list[k]
- p=P(k)/list+p
- end
+ p=P(k)+p
else
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- if p then
- p=p/list
- end
+ p=P(k)
end
- elseif checked then
- local keys=sortedkeys(list)
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- if k==v then
- p=P(k)+p
- else
- p=P(k)/v+p
- end
- else
- if k==v then
- p=P(k)
- else
- p=P(k)/v
- end
- end
+ end
+ if p then
+ p=p/list
+ end
+ end
+ elseif checked then
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ if k==v then
+ p=P(k)+p
+ else
+ p=P(k)/v+p
end
- else
- local keys=sortedkeys(list)
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- p=P(k)/v+p
- else
- p=P(k)/v
- end
+ else
+ if k==v then
+ p=P(k)
+ else
+ p=P(k)/v
end
+ end
end
- return p
+ else
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ p=P(k)/v+p
+ else
+ p=P(k)/v
+ end
+ end
+ end
+ return p
end
local p_false=P(false)
local p_true=P(true)
local lower=utf and utf.lower or string.lower
local upper=utf and utf.upper or string.upper
function lpeg.setutfcasers(l,u)
- lower=l or lower
- upper=u or upper
+ lower=l or lower
+ upper=u or upper
end
local function make1(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
- local k=keys[i]
- if k~="" then
- local v=t[k]
- if v==true then
- p=p+P(k)*p_true
- elseif v==false then
- else
- p=p+P(k)*make1(v,v[""])
- end
- end
- end
- if rest then
- p=p+p_true
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+P(k)*p_true
+ elseif v==false then
+ else
+ p=p+P(k)*make1(v,v[""])
+ end
end
- return p
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
end
local function make2(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
- local k=keys[i]
- if k~="" then
- local v=t[k]
- if v==true then
- p=p+(P(lower(k))+P(upper(k)))*p_true
- elseif v==false then
- else
- p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
- end
- end
- end
- if rest then
- p=p+p_true
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+(P(lower(k))+P(upper(k)))*p_true
+ elseif v==false then
+ else
+ p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
+ end
end
- return p
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
end
local function utfchartabletopattern(list,insensitive)
- local tree={}
- local n=#list
- if n==0 then
- for s in next,list do
- local t=tree
- local p,pk
- for c in gmatch(s,".") do
- if t==true then
- t={ [c]=true,[""]=true }
- p[pk]=t
- p=t
- t=false
- elseif t==false then
- t={ [c]=false }
- p[pk]=t
- p=t
- t=false
- else
- local tc=t[c]
- if not tc then
- tc=false
- t[c]=false
- end
- p=t
- t=tc
- end
- pk=c
- end
- if t==false then
- p[pk]=true
- elseif t==true then
- else
- t[""]=true
- end
+ local tree={}
+ local n=#list
+ if n==0 then
+ for s in next,list do
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
end
- else
- for i=1,n do
- local s=list[i]
- local t=tree
- local p,pk
- for c in gmatch(s,".") do
- if t==true then
- t={ [c]=true,[""]=true }
- p[pk]=t
- p=t
- t=false
- elseif t==false then
- t={ [c]=false }
- p[pk]=t
- p=t
- t=false
- else
- local tc=t[c]
- if not tc then
- tc=false
- t[c]=false
- end
- p=t
- t=tc
- end
- pk=c
- end
- if t==false then
- p[pk]=true
- elseif t==true then
- else
- t[""]=true
- end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
+ end
+ else
+ for i=1,n do
+ local s=list[i]
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
end
- return (insensitive and make2 or make1)(tree)
+ end
+ return (insensitive and make2 or make1)(tree)
end
lpeg.utfchartabletopattern=utfchartabletopattern
function lpeg.utfreplacer(list,insensitive)
- local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
- return function(str)
- return lpegmatch(pattern,str) or str
- end
+ local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
+ return function(str)
+ return lpegmatch(pattern,str) or str
+ end
end
patterns.containseol=lpeg.finder(eol)
local function nextstep(n,step,result)
- local m=n%step
- local d=floor(n/step)
- if d>0 then
- local v=V(tostring(step))
- local s=result.start
- for i=1,d do
- if s then
- s=v*s
- else
- s=v
- end
- end
- result.start=s
- end
- if step>1 and result.start then
- local v=V(tostring(step/2))
- result[tostring(step)]=v*v
- end
- if step>0 then
- return nextstep(m,step/2,result)
- else
- return result
+ local m=n%step
+ local d=floor(n/step)
+ if d>0 then
+ local v=V(tostring(step))
+ local s=result.start
+ for i=1,d do
+ if s then
+ s=v*s
+ else
+ s=v
+ end
end
+ result.start=s
+ end
+ if step>1 and result.start then
+ local v=V(tostring(step/2))
+ result[tostring(step)]=v*v
+ end
+ if step>0 then
+ return nextstep(m,step/2,result)
+ else
+ return result
+ end
end
function lpeg.times(pattern,n)
- return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
+ return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
end
do
- local trailingzeros=zero^0*-digit
- local stripper=Cs((
- digits*(
- period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
- )+1
- )^0)
- lpeg.patterns.stripzeros=stripper
- local nonzero=digit-zero
- local trailingzeros=zero^1*endofstring
- local stripper=Cs((1-period)^0*(
- period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
- ))
- lpeg.patterns.stripzero=stripper
+ local trailingzeros=zero^0*-digit
+ local stripper=Cs((
+ digits*(
+ period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
+ )+1
+ )^0)
+ lpeg.patterns.stripzeros=stripper
+ local nonzero=digit-zero
+ local trailingzeros=zero^1*endofstring
+ local stripper=Cs((1-period)^0*(
+ period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
+ ))
+ lpeg.patterns.stripzero=stripper
end
local byte_to_HEX={}
local byte_to_hex={}
local byte_to_dec={}
local hex_to_byte={}
for i=0,255 do
- local H=format("%02X",i)
- local h=format("%02x",i)
- local d=format("%03i",i)
- local c=char(i)
- byte_to_HEX[c]=H
- byte_to_hex[c]=h
- byte_to_dec[c]=d
- hex_to_byte[h]=c
- hex_to_byte[H]=c
+ local H=format("%02X",i)
+ local h=format("%02x",i)
+ local d=format("%03i",i)
+ local c=char(i)
+ byte_to_HEX[c]=H
+ byte_to_hex[c]=h
+ byte_to_dec[c]=d
+ hex_to_byte[h]=c
+ hex_to_byte[H]=c
end
local hextobyte=P(2)/hex_to_byte
local bytetoHEX=P(1)/byte_to_HEX
@@ -1769,47 +1769,47 @@ patterns.bytestoHEX=bytestoHEX
patterns.bytestohex=bytestohex
patterns.bytestodec=bytestodec
function string.toHEX(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestoHEX,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestoHEX,s)
+ end
end
function string.tohex(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestohex,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestohex,s)
+ end
end
function string.todec(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestodec,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestodec,s)
+ end
end
function string.tobytes(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(hextobytes,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(hextobytes,s)
+ end
end
local patterns={}
local function containsws(what)
- local p=patterns[what]
- if not p then
- local p1=P(what)*(whitespace+endofstring)*Cc(true)
- local p2=whitespace*P(p1)
- p=P(p1)+P(1-p2)^0*p2+Cc(false)
- patterns[what]=p
- end
- return p
+ local p=patterns[what]
+ if not p then
+ local p1=P(what)*(whitespace+endofstring)*Cc(true)
+ local p2=whitespace*P(p1)
+ p=P(p1)+P(1-p2)^0*p2+Cc(false)
+ patterns[what]=p
+ end
+ return p
end
lpeg.containsws=containsws
function string.containsws(str,what)
- return lpegmatch(patterns[what] or containsws(what),str)
+ return lpegmatch(patterns[what] or containsws(what),str)
end
@@ -1819,14 +1819,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-function"] = package.loaded["l-function"] or true
--- original size: 361, stripped down to: 322
+-- original size: 361, stripped down to: 317
if not modules then modules={} end modules ['l-functions']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
functions=functions or {}
function functions.dummy() end
@@ -1838,14 +1838,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-string"] = package.loaded["l-string"] or true
--- original size: 6461, stripped down to: 3341
+-- original size: 6461, stripped down to: 3255
if not modules then modules={} end modules ['l-string']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local string=string
local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower
@@ -1853,25 +1853,25 @@ local lpegmatch,patterns=lpeg.match,lpeg.patterns
local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs
local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote
function string.unquoted(str)
- return lpegmatch(unquoted,str) or str
+ return lpegmatch(unquoted,str) or str
end
function string.quoted(str)
- return format("%q",str)
+ return format("%q",str)
end
function string.count(str,pattern)
- local n=0
- for _ in gmatch(str,pattern) do
- n=n+1
- end
- return n
+ local n=0
+ for _ in gmatch(str,pattern) do
+ n=n+1
+ end
+ return n
end
function string.limit(str,n,sentinel)
- if #str>n then
- sentinel=sentinel or "..."
- return sub(str,1,(n-#sentinel))..sentinel
- else
- return str
- end
+ if #str>n then
+ sentinel=sentinel or "..."
+ return sub(str,1,(n-#sentinel))..sentinel
+ else
+ return str
+ end
end
local stripper=patterns.stripper
local fullstripper=patterns.fullstripper
@@ -1879,81 +1879,81 @@ local collapser=patterns.collapser
local nospacer=patterns.nospacer
local longtostring=patterns.longtostring
function string.strip(str)
- return str and lpegmatch(stripper,str) or ""
+ return str and lpegmatch(stripper,str) or ""
end
function string.fullstrip(str)
- return str and lpegmatch(fullstripper,str) or ""
+ return str and lpegmatch(fullstripper,str) or ""
end
function string.collapsespaces(str)
- return str and lpegmatch(collapser,str) or ""
+ return str and lpegmatch(collapser,str) or ""
end
function string.nospaces(str)
- return str and lpegmatch(nospacer,str) or ""
+ return str and lpegmatch(nospacer,str) or ""
end
function string.longtostring(str)
- return str and lpegmatch(longtostring,str) or ""
+ return str and lpegmatch(longtostring,str) or ""
end
local pattern=P(" ")^0*P(-1)
function string.is_empty(str)
- if not str or str=="" then
- return true
- else
- return lpegmatch(pattern,str) and true or false
- end
+ if not str or str=="" then
+ return true
+ else
+ return lpegmatch(pattern,str) and true or false
+ end
end
local anything=patterns.anything
local allescapes=Cc("%")*S(".-+%?()[]*")
-local someescapes=Cc("%")*S(".-+%()[]")
-local matchescapes=Cc(".")*S("*?")
+local someescapes=Cc("%")*S(".-+%()[]")
+local matchescapes=Cc(".")*S("*?")
local pattern_a=Cs ((allescapes+anything )^0 )
local pattern_b=Cs ((someescapes+matchescapes+anything )^0 )
local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") )
function string.escapedpattern(str,simple)
- return lpegmatch(simple and pattern_b or pattern_a,str)
+ return lpegmatch(simple and pattern_b or pattern_a,str)
end
function string.topattern(str,lowercase,strict)
- if str=="" or type(str)~="string" then
- return ".*"
- elseif strict then
- str=lpegmatch(pattern_c,str)
- else
- str=lpegmatch(pattern_b,str)
- end
- if lowercase then
- return lower(str)
- else
- return str
- end
+ if str=="" or type(str)~="string" then
+ return ".*"
+ elseif strict then
+ str=lpegmatch(pattern_c,str)
+ else
+ str=lpegmatch(pattern_b,str)
+ end
+ if lowercase then
+ return lower(str)
+ else
+ return str
+ end
end
function string.valid(str,default)
- return (type(str)=="string" and str~="" and str) or default or nil
+ return (type(str)=="string" and str~="" and str) or default or nil
end
string.itself=function(s) return s end
local pattern_c=Ct(C(1)^0)
local pattern_b=Ct((C(1)/byte)^0)
function string.totable(str,bytes)
- return lpegmatch(bytes and pattern_b or pattern_c,str)
+ return lpegmatch(bytes and pattern_b or pattern_c,str)
end
local replacer=lpeg.replacer("@","%%")
function string.tformat(fmt,...)
- return format(lpegmatch(replacer,fmt),...)
+ return format(lpegmatch(replacer,fmt),...)
end
string.quote=string.quoted
string.unquote=string.unquoted
if not string.bytetable then
- local limit=5000
- function string.bytetable(str)
- local n=#str
- if n>limit then
- local t={ byte(str,1,limit) }
- for i=limit+1,n do
- t[i]=byte(str,i)
- end
- return t
- else
- return { byte(str,1,n) }
- end
+ local limit=5000
+ function string.bytetable(str)
+ local n=#str
+ if n>limit then
+ local t={ byte(str,1,limit) }
+ for i=limit+1,n do
+ t[i]=byte(str,i)
+ end
+ return t
+ else
+ return { byte(str,1,n) }
end
+ end
end
@@ -1963,14 +1963,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 40960, stripped down to: 24090
+-- original size: 40960, stripped down to: 21348
if not modules then modules={} end modules ['l-table']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber,select=type,next,tostring,tonumber,select
local table,string=table,string
@@ -1981,147 +1981,147 @@ local lpegmatch,patterns=lpeg.match,lpeg.patterns
local floor=math.floor
local stripper=patterns.stripper
function table.getn(t)
- return t and #t
+ return t and #t
end
function table.strip(tab)
- local lst,l={},0
- for i=1,#tab do
- local s=lpegmatch(stripper,tab[i]) or ""
- if s=="" then
- else
- l=l+1
- lst[l]=s
- end
+ local lst,l={},0
+ for i=1,#tab do
+ local s=lpegmatch(stripper,tab[i]) or ""
+ if s=="" then
+ else
+ l=l+1
+ lst[l]=s
end
- return lst
+ end
+ return lst
end
function table.keys(t)
- if t then
- local keys,k={},0
- for key in next,t do
- k=k+1
- keys[k]=key
- end
- return keys
- else
- return {}
+ if t then
+ local keys,k={},0
+ for key in next,t do
+ k=k+1
+ keys[k]=key
end
+ return keys
+ else
+ return {}
+ end
end
local function compare(a,b)
- local ta=type(a)
- if ta=="number" then
- local tb=type(b)
- if ta==tb then
- return a<b
- elseif tb=="string" then
- return tostring(a)<b
- end
- elseif ta=="string" then
- local tb=type(b)
- if ta==tb then
- return a<b
- else
- return a<tostring(b)
- end
+ local ta=type(a)
+ if ta=="number" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ elseif tb=="string" then
+ return tostring(a)<b
+ end
+ elseif ta=="string" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ else
+ return a<tostring(b)
end
- return tostring(a)<tostring(b)
+ end
+ return tostring(a)<tostring(b)
end
local function sortedkeys(tab)
- if tab then
- local srt,category,s={},0,0
- for key in next,tab do
- s=s+1
- srt[s]=key
- if category==3 then
- elseif category==1 then
- if type(key)~="string" then
- category=3
- end
- elseif category==2 then
- if type(key)~="number" then
- category=3
- end
- else
- local tkey=type(key)
- if tkey=="string" then
- category=1
- elseif tkey=="number" then
- category=2
- else
- category=3
- end
- end
- end
- if s<2 then
- elseif category==3 then
- sort(srt,compare)
+ if tab then
+ local srt,category,s={},0,0
+ for key in next,tab do
+ s=s+1
+ srt[s]=key
+ if category==3 then
+ elseif category==1 then
+ if type(key)~="string" then
+ category=3
+ end
+ elseif category==2 then
+ if type(key)~="number" then
+ category=3
+ end
+ else
+ local tkey=type(key)
+ if tkey=="string" then
+ category=1
+ elseif tkey=="number" then
+ category=2
else
- sort(srt)
+ category=3
end
- return srt
+ end
+ end
+ if s<2 then
+ elseif category==3 then
+ sort(srt,compare)
else
- return {}
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="string" then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if type(key)=="string" then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedindexonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="number" then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if type(key)=="number" then
+ s=s+1
+ srt[s]=key
+ end
end
+ if s>1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashkeys(tab,cmp)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if key then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt,cmp)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if key then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt,cmp)
end
+ return srt
+ else
+ return {}
+ end
end
function table.allkeys(t)
- local keys={}
- for k,v in next,t do
- for k in next,v do
- keys[k]=true
- end
+ local keys={}
+ for k,v in next,t do
+ for k in next,v do
+ keys[k]=true
end
- return sortedkeys(keys)
+ end
+ return sortedkeys(keys)
end
table.sortedkeys=sortedkeys
table.sortedhashonly=sortedhashonly
@@ -2129,927 +2129,927 @@ table.sortedindexonly=sortedindexonly
table.sortedhashkeys=sortedhashkeys
local function nothing() end
local function sortedhash(t,cmp)
- if t then
- local s
- if cmp then
- s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
- else
- s=sortedkeys(t)
- end
- local m=#s
- if m==1 then
- return next,t
- elseif m>0 then
- local n=0
- return function()
- if n<m then
- n=n+1
- local k=s[n]
- return k,t[k]
- end
- end
+ if t then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local m=#s
+ if m==1 then
+ return next,t
+ elseif m>0 then
+ local n=0
+ return function()
+ if n<m then
+ n=n+1
+ local k=s[n]
+ return k,t[k]
end
+ end
end
- return nothing
+ end
+ return nothing
end
table.sortedhash=sortedhash
table.sortedpairs=sortedhash
function table.append(t,list)
- local n=#t
- for i=1,#list do
- n=n+1
- t[n]=list[i]
- end
- return t
+ local n=#t
+ for i=1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ return t
end
function table.prepend(t,list)
- local nl=#list
- local nt=nl+#t
- for i=#t,1,-1 do
- t[nt]=t[i]
- nt=nt-1
- end
- for i=1,#list do
- t[i]=list[i]
- end
- return t
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+ t[nt]=t[i]
+ nt=nt-1
+ end
+ for i=1,#list do
+ t[i]=list[i]
+ end
+ return t
end
function table.merge(t,...)
- t=t or {}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ t=t or {}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.merged(...)
- local t={}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ local t={}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.imerge(t,...)
- local nt=#t
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- nt=nt+1
- t[nt]=nst[j]
- end
+ local nt=#t
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ nt=nt+1
+ t[nt]=nst[j]
end
- return t
+ end
+ return t
end
function table.imerged(...)
- local tmp,ntmp={},0
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- ntmp=ntmp+1
- tmp[ntmp]=nst[j]
- end
+ local tmp,ntmp={},0
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ ntmp=ntmp+1
+ tmp[ntmp]=nst[j]
end
- return tmp
+ end
+ return tmp
end
local function fastcopy(old,metatabletoo)
- if old then
- local new={}
- for k,v in next,old do
- if type(v)=="table" then
- new[k]=fastcopy(v,metatabletoo)
- else
- new[k]=v
- end
- end
- if metatabletoo then
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ if type(v)=="table" then
+ new[k]=fastcopy(v,metatabletoo)
+ else
+ new[k]=v
+ end
end
+ if metatabletoo then
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ end
+ return new
+ else
+ return {}
+ end
end
local function copy(t,tables)
- tables=tables or {}
- local tcopy={}
- if not tables[t] then
- tables[t]=tcopy
- end
- for i,v in next,t do
- if type(i)=="table" then
- if tables[i] then
- i=tables[i]
- else
- i=copy(i,tables)
- end
- end
- if type(v)~="table" then
- tcopy[i]=v
- elseif tables[v] then
- tcopy[i]=tables[v]
- else
- tcopy[i]=copy(v,tables)
- end
+ tables=tables or {}
+ local tcopy={}
+ if not tables[t] then
+ tables[t]=tcopy
+ end
+ for i,v in next,t do
+ if type(i)=="table" then
+ if tables[i] then
+ i=tables[i]
+ else
+ i=copy(i,tables)
+ end
end
- local mt=getmetatable(t)
- if mt then
- setmetatable(tcopy,mt)
+ if type(v)~="table" then
+ tcopy[i]=v
+ elseif tables[v] then
+ tcopy[i]=tables[v]
+ else
+ tcopy[i]=copy(v,tables)
end
- return tcopy
+ end
+ local mt=getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
end
table.fastcopy=fastcopy
table.copy=copy
function table.derive(parent)
- local child={}
- if parent then
- setmetatable(child,{ __index=parent })
- end
- return child
+ local child={}
+ if parent then
+ setmetatable(child,{ __index=parent })
+ end
+ return child
end
function table.tohash(t,value)
- local h={}
- if t then
- if value==nil then value=true end
- for _,v in next,t do
- h[v]=value
- end
+ local h={}
+ if t then
+ if value==nil then value=true end
+ for _,v in next,t do
+ h[v]=value
end
- return h
+ end
+ return h
end
function table.fromhash(t)
- local hsh,h={},0
- for k,v in next,t do
- if v then
- h=h+1
- hsh[h]=k
- end
+ local hsh,h={},0
+ for k,v in next,t do
+ if v then
+ h=h+1
+ hsh[h]=k
end
- return hsh
+ end
+ return hsh
end
local noquotes,hexify,handle,compact,inline,functions,metacheck
local reserved=table.tohash {
- 'and','break','do','else','elseif','end','false','for','function','if',
- 'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
}
local function is_simple_table(t,hexify)
- local nt=#t
- if nt>0 then
- local n=0
- for _,v in next,t do
- n=n+1
- if type(v)=="table" then
- return nil
- end
+ local nt=#t
+ if nt>0 then
+ local n=0
+ for _,v in next,t do
+ n=n+1
+ if type(v)=="table" then
+ return nil
+ end
+ end
+ local haszero=rawget(t,0)
+ if n==nt then
+ local tt={}
+ for i=1,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i]=format("0x%X",v)
+ else
+ tt[i]=v
+ end
+ elseif tv=="string" then
+ tt[i]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i]=v and "true" or "false"
+ else
+ return nil
end
- local haszero=rawget(t,0)
- if n==nt then
- local tt={}
- for i=1,nt do
- local v=t[i]
- local tv=type(v)
- if tv=="number" then
- if hexify then
- tt[i]=format("0x%X",v)
- else
- tt[i]=v
- end
- elseif tv=="string" then
- tt[i]=format("%q",v)
- elseif tv=="boolean" then
- tt[i]=v and "true" or "false"
- else
- return nil
- end
- end
- return tt
- elseif haszero and (n==nt+1) then
- local tt={}
- for i=0,nt do
- local v=t[i]
- local tv=type(v)
- if tv=="number" then
- if hexify then
- tt[i+1]=format("0x%X",v)
- else
- tt[i+1]=v
- end
- elseif tv=="string" then
- tt[i+1]=format("%q",v)
- elseif tv=="boolean" then
- tt[i+1]=v and "true" or "false"
- else
- return nil
- end
- end
- tt[1]="[0] = "..tt[1]
- return tt
+ end
+ return tt
+ elseif haszero and (n==nt+1) then
+ local tt={}
+ for i=0,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i+1]=format("0x%X",v)
+ else
+ tt[i+1]=v
+ end
+ elseif tv=="string" then
+ tt[i+1]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i+1]=v and "true" or "false"
+ else
+ return nil
end
+ end
+ tt[1]="[0] = "..tt[1]
+ return tt
end
- return nil
+ end
+ return nil
end
table.is_simple_table=is_simple_table
local propername=patterns.propername
local function dummy() end
local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- depth=depth.." "
- if indexed then
- handle(format("%s{",depth))
+ if level>0 then
+ depth=depth.." "
+ if indexed then
+ handle(format("%s{",depth))
+ else
+ local tn=type(name)
+ if tn=="number" then
+ if hexify then
+ handle(format("%s[0x%X]={",depth,name))
else
- local tn=type(name)
- if tn=="number" then
- if hexify then
- handle(format("%s[0x%X]={",depth,name))
- else
- handle(format("%s[%s]={",depth,name))
- end
- elseif tn=="string" then
- if noquotes and not reserved[name] and lpegmatch(propername,name) then
- handle(format("%s%s={",depth,name))
- else
- handle(format("%s[%q]={",depth,name))
- end
- elseif tn=="boolean" then
- handle(format("%s[%s]={",depth,name and "true" or "false"))
- else
- handle(format("%s{",depth))
- end
+ handle(format("%s[%s]={",depth,name))
end
+ elseif tn=="string" then
+ if noquotes and not reserved[name] and lpegmatch(propername,name) then
+ handle(format("%s%s={",depth,name))
+ else
+ handle(format("%s[%q]={",depth,name))
+ end
+ elseif tn=="boolean" then
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
+ else
+ handle(format("%s{",depth))
+ end
end
- if root and next(root)~=nil then
- local first,last=nil,0
- if compact then
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
- end
- if last>0 then
- first=1
- end
+ end
+ if root and next(root)~=nil then
+ local first,last=nil,0
+ if compact then
+ last=#root
+ for k=1,last do
+ if rawget(root,k)==nil then
+ last=k-1
+ break
end
- local sk=sortedkeys(root)
- for i=1,#sk do
- local k=sk[i]
- local v=root[k]
- local tv=type(v)
- local tk=type(k)
- if compact and first and tk=="number" and k>=first and k<=last then
- if tv=="number" then
- if hexify then
- handle(format("%s 0x%X,",depth,v))
- else
- handle(format("%s %s,",depth,v))
- end
- elseif tv=="string" then
- handle(format("%s %q,",depth,v))
- elseif tv=="table" then
- if next(v)==nil then
- handle(format("%s {},",depth))
- elseif inline then
- local st=is_simple_table(v,hexify)
- if st then
- handle(format("%s { %s },",depth,concat(st,", ")))
- else
- do_serialize(v,k,depth,level+1,true)
- end
- else
- do_serialize(v,k,depth,level+1,true)
- end
- elseif tv=="boolean" then
- handle(format("%s %s,",depth,v and "true" or "false"))
- elseif tv=="function" then
- if functions then
- handle(format('%s load(%q),',depth,dump(v)))
- else
- handle(format('%s "function",',depth))
- end
- else
- handle(format("%s %q,",depth,tostring(v)))
- end
- elseif k=="__p__" then
- if false then
- handle(format("%s __p__=nil,",depth))
- end
- elseif tv=="number" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=0x%X,",depth,k,v))
- else
- handle(format("%s [%s]=%s,",depth,k,v))
- end
- elseif tk=="boolean" then
- if hexify then
- handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
- else
- handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
- end
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- if hexify then
- handle(format("%s %s=0x%X,",depth,k,v))
- else
- handle(format("%s %s=%s,",depth,k,v))
- end
- else
- if hexify then
- handle(format("%s [%q]=0x%X,",depth,k,v))
- else
- handle(format("%s [%q]=%s,",depth,k,v))
- end
- end
- elseif tv=="string" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%q,",depth,k,v))
- else
- handle(format("%s [%s]=%q,",depth,k,v))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%q,",depth,k,v))
- else
- handle(format("%s [%q]=%q,",depth,k,v))
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]={},",depth,k))
- else
- handle(format("%s [%s]={},",depth,k))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]={},",depth,k and "true" or "false"))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s={},",depth,k))
- else
- handle(format("%s [%q]={},",depth,k))
- end
- elseif inline then
- local st=is_simple_table(v,hexify)
- if st then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
- else
- handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
- else
- handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
- end
- else
- do_serialize(v,k,depth,level+1)
- end
- else
- do_serialize(v,k,depth,level+1)
- end
- elseif tv=="boolean" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
- else
- handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
- else
- handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
- end
- elseif tv=="function" then
- if functions then
- local getinfo=debug and debug.getinfo
- if getinfo then
- local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=load(%q),",depth,k,f))
- else
- handle(format("%s [%s]=load(%q),",depth,k,f))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=load(%q),",depth,k,f))
- else
- handle(format("%s [%q]=load(%q),",depth,k,f))
- end
- end
- end
+ end
+ if last>0 then
+ first=1
+ end
+ end
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if compact and first and tk=="number" and k>=first and k<=last then
+ if tv=="number" then
+ if hexify then
+ handle(format("%s 0x%X,",depth,v))
+ else
+ handle(format("%s %s,",depth,v))
+ end
+ elseif tv=="string" then
+ handle(format("%s %q,",depth,v))
+ elseif tv=="table" then
+ if next(v)==nil then
+ handle(format("%s {},",depth))
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ handle(format("%s { %s },",depth,concat(st,", ")))
else
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
- else
- handle(format("%s [%s]=%q,",depth,k,tostring(v)))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%q,",depth,k,tostring(v)))
- else
- handle(format("%s [%q]=%q,",depth,k,tostring(v)))
- end
+ do_serialize(v,k,depth,level+1,true)
end
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ elseif tv=="boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv=="function" then
+ if functions then
+ handle(format('%s load(%q),',depth,dump(v)))
+ else
+ handle(format('%s "function",',depth))
+ end
+ else
+ handle(format("%s %q,",depth,tostring(v)))
end
- end
- if level>0 then
- handle(format("%s},",depth))
- end
-end
-local function serialize(_handle,root,name,specification)
- local tname=type(name)
- if type(specification)=="table" then
- noquotes=specification.noquotes
- hexify=specification.hexify
- handle=_handle or specification.handle or print
- functions=specification.functions
- compact=specification.compact
- inline=specification.inline and compact
- metacheck=specification.metacheck
- if functions==nil then
- functions=true
- end
- if compact==nil then
- compact=true
- end
- if inline==nil then
- inline=compact
- end
- if metacheck==nil then
- metacheck=true
+ elseif k=="__p__" then
+ if false then
+ handle(format("%s __p__=nil,",depth))
end
- else
- noquotes=false
- hexify=false
- handle=_handle or print
- compact=true
- inline=true
- functions=true
- metacheck=true
- end
- if tname=="string" then
- if name=="return" then
- handle("return {")
+ elseif tv=="number" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ if hexify then
+ handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ else
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
+ end
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ if hexify then
+ handle(format("%s %s=0x%X,",depth,k,v))
+ else
+ handle(format("%s %s=%s,",depth,k,v))
+ end
else
- handle(name.."={")
+ if hexify then
+ handle(format("%s [%q]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v))
+ end
end
- elseif tname=="number" then
- if hexify then
- handle(format("[0x%X]={",name))
+ elseif tv=="string" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,v))
+ else
+ handle(format("%s [%s]=%q,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,v))
else
- handle("["..name.."]={")
+ handle(format("%s [%q]=%q,",depth,k,v))
end
- elseif tname=="boolean" then
- if name then
- handle("return {")
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={},",depth,k))
+ else
+ handle(format("%s [%s]={},",depth,k))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={},",depth,k))
+ else
+ handle(format("%s [%q]={},",depth,k))
+ end
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
else
- handle("{")
+ do_serialize(v,k,depth,level+1)
end
- else
- handle("t={")
- end
- if root then
- if metacheck and getmetatable(root) then
- local dummy=root._w_h_a_t_e_v_e_r_
- root._w_h_a_t_e_v_e_r_=nil
+ elseif tv=="boolean" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
end
- if next(root)~=nil then
- do_serialize(root,name,"",0)
+ elseif tv=="function" then
+ if functions then
+ local getinfo=debug and debug.getinfo
+ if getinfo then
+ local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%s]=load(%q),",depth,k,f))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%q]=load(%q),",depth,k,f))
+ end
+ end
+ end
+ else
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
end
+ end
end
- handle("}")
+ end
+ if level>0 then
+ handle(format("%s},",depth))
+ end
end
-function table.serialize(root,name,specification)
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
+local function serialize(_handle,root,name,specification)
+ local tname=type(name)
+ if type(specification)=="table" then
+ noquotes=specification.noquotes
+ hexify=specification.hexify
+ handle=_handle or specification.handle or print
+ functions=specification.functions
+ compact=specification.compact
+ inline=specification.inline and compact
+ metacheck=specification.metacheck
+ if functions==nil then
+ functions=true
+ end
+ if compact==nil then
+ compact=true
+ end
+ if inline==nil then
+ inline=compact
+ end
+ if metacheck==nil then
+ metacheck=true
+ end
+ else
+ noquotes=false
+ hexify=false
+ handle=_handle or print
+ compact=true
+ inline=true
+ functions=true
+ metacheck=true
+ end
+ if tname=="string" then
+ if name=="return" then
+ handle("return {")
+ else
+ handle(name.."={")
+ end
+ elseif tname=="number" then
+ if hexify then
+ handle(format("[0x%X]={",name))
+ else
+ handle("["..name.."]={")
+ end
+ elseif tname=="boolean" then
+ if name then
+ handle("return {")
+ else
+ handle("{")
+ end
+ else
+ handle("t={")
+ end
+ if root then
+ if metacheck and getmetatable(root) then
+ local dummy=root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_=nil
+ end
+ if next(root)~=nil then
+ do_serialize(root,name,"",0)
end
- serialize(flush,root,name,specification)
- return concat(t,"\n")
+ end
+ handle("}")
+end
+function table.serialize(root,name,specification)
+ local t,n={},0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ end
+ serialize(flush,root,name,specification)
+ return concat(t,"\n")
end
table.tohandle=serialize
local maxtab=2*1024
function table.tofile(filename,root,name,specification)
- local f=io.open(filename,'w')
- if f then
- if maxtab>1 then
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
- if n>maxtab then
- f:write(concat(t,"\n"),"\n")
- t,n={},0
- end
- end
- serialize(flush,root,name,specification)
- f:write(concat(t,"\n"),"\n")
- else
- local function flush(s)
- f:write(s,"\n")
- end
- serialize(flush,root,name,specification)
+ local f=io.open(filename,'w')
+ if f then
+ if maxtab>1 then
+ local t,n={},0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ if n>maxtab then
+ f:write(concat(t,"\n"),"\n")
+ t,n={},0
end
- f:close()
- io.flush()
+ end
+ serialize(flush,root,name,specification)
+ f:write(concat(t,"\n"),"\n")
+ else
+ local function flush(s)
+ f:write(s,"\n")
+ end
+ serialize(flush,root,name,specification)
end
+ f:close()
+ io.flush()
+ end
end
local function flattened(t,f,depth)
- if f==nil then
- f={}
- depth=0xFFFF
- elseif tonumber(f) then
- depth=f
- f={}
- elseif not depth then
- depth=0xFFFF
- end
- for k,v in next,t do
- if type(k)~="number" then
- if depth>0 and type(v)=="table" then
- flattened(v,f,depth-1)
- else
- f[#f+1]=v
- end
- end
+ if f==nil then
+ f={}
+ depth=0xFFFF
+ elseif tonumber(f) then
+ depth=f
+ f={}
+ elseif not depth then
+ depth=0xFFFF
+ end
+ for k,v in next,t do
+ if type(k)~="number" then
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
+ end
end
- for k=1,#t do
- local v=t[k]
- if depth>0 and type(v)=="table" then
- flattened(v,f,depth-1)
- else
- f[#f+1]=v
- end
+ end
+ for k=1,#t do
+ local v=t[k]
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
end
- return f
+ end
+ return f
end
table.flattened=flattened
local function collapsed(t,f,h)
- if f==nil then
- f={}
- h={}
- end
- for k=1,#t do
- local v=t[k]
- if type(v)=="table" then
- collapsed(v,f,h)
- elseif not h[v] then
- f[#f+1]=v
- h[v]=true
- end
+ if f==nil then
+ f={}
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsed(v,f,h)
+ elseif not h[v] then
+ f[#f+1]=v
+ h[v]=true
end
- return f
+ end
+ return f
end
local function collapsedhash(t,h)
- if h==nil then
- h={}
- end
- for k=1,#t do
- local v=t[k]
- if type(v)=="table" then
- collapsedhash(v,h)
- else
- h[v]=true
- end
+ if h==nil then
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsedhash(v,h)
+ else
+ h[v]=true
end
- return h
+ end
+ return h
end
-table.collapsed=collapsed
+table.collapsed=collapsed
table.collapsedhash=collapsedhash
local function unnest(t,f)
- if not f then
- f={}
- end
- for i=1,#t do
- local v=t[i]
- if type(v)=="table" then
- if type(v[1])=="table" then
- unnest(v,f)
- else
- f[#f+1]=v
- end
- else
- f[#f+1]=v
- end
+ if not f then
+ f={}
+ end
+ for i=1,#t do
+ local v=t[i]
+ if type(v)=="table" then
+ if type(v[1])=="table" then
+ unnest(v,f)
+ else
+ f[#f+1]=v
+ end
+ else
+ f[#f+1]=v
end
- return f
+ end
+ return f
end
function table.unnest(t)
- return unnest(t)
+ return unnest(t)
end
local function are_equal(a,b,n,m)
- if a==b then
- return true
- elseif a and b and #a==#b then
- n=n or 1
- m=m or #a
- for i=n,m do
- local ai,bi=a[i],b[i]
- if ai==bi then
- elseif type(ai)=="table" and type(bi)=="table" then
- if not are_equal(ai,bi) then
- return false
- end
- else
- return false
- end
- end
- return true
- else
+ if a==b then
+ return true
+ elseif a and b and #a==#b then
+ n=n or 1
+ m=m or #a
+ for i=n,m do
+ local ai,bi=a[i],b[i]
+ if ai==bi then
+ elseif type(ai)=="table" and type(bi)=="table" then
+ if not are_equal(ai,bi) then
+ return false
+ end
+ else
return false
+ end
end
+ return true
+ else
+ return false
+ end
end
local function identical(a,b)
- if a~=b then
- for ka,va in next,a do
- local vb=b[ka]
- if va==vb then
- elseif type(va)=="table" and type(vb)=="table" then
- if not identical(va,vb) then
- return false
- end
- else
- return false
- end
- end
+ if a~=b then
+ for ka,va in next,a do
+ local vb=b[ka]
+ if va==vb then
+ elseif type(va)=="table" and type(vb)=="table" then
+ if not identical(va,vb) then
+ return false
+ end
+ else
+ return false
+ end
end
- return true
+ end
+ return true
end
table.identical=identical
table.are_equal=are_equal
local function sparse(old,nest,keeptables)
- local new={}
- for k,v in next,old do
- if not (v=="" or v==false) then
- if nest and type(v)=="table" then
- v=sparse(v,nest)
- if keeptables or next(v)~=nil then
- new[k]=v
- end
- else
- new[k]=v
- end
- end
+ local new={}
+ for k,v in next,old do
+ if not (v=="" or v==false) then
+ if nest and type(v)=="table" then
+ v=sparse(v,nest)
+ if keeptables or next(v)~=nil then
+ new[k]=v
+ end
+ else
+ new[k]=v
+ end
end
- return new
+ end
+ return new
end
table.sparse=sparse
function table.compact(t)
- return sparse(t,true,true)
+ return sparse(t,true,true)
end
function table.contains(t,v)
- if t then
- for i=1,#t do
- if t[i]==v then
- return i
- end
- end
+ if t then
+ for i=1,#t do
+ if t[i]==v then
+ return i
+ end
end
- return false
+ end
+ return false
end
function table.count(t)
- local n=0
- for k,v in next,t do
- n=n+1
- end
- return n
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ end
+ return n
end
function table.swapped(t,s)
- local n={}
- if s then
- for k,v in next,s do
- n[k]=v
- end
+ local n={}
+ if s then
+ for k,v in next,s do
+ n[k]=v
end
- for k,v in next,t do
- n[v]=k
- end
- return n
+ end
+ for k,v in next,t do
+ n[v]=k
+ end
+ return n
end
function table.hashed(t)
- for i=1,#t do
- t[t[i]]=i
- end
- return t
+ for i=1,#t do
+ t[t[i]]=i
+ end
+ return t
end
function table.mirrored(t)
- local n={}
- for k,v in next,t do
- n[v]=k
- n[k]=v
- end
- return n
+ local n={}
+ for k,v in next,t do
+ n[v]=k
+ n[k]=v
+ end
+ return n
end
function table.reversed(t)
- if t then
- local tt,tn={},#t
- if tn>0 then
- local ttn=0
- for i=tn,1,-1 do
- ttn=ttn+1
- tt[ttn]=t[i]
- end
- end
- return tt
+ if t then
+ local tt,tn={},#t
+ if tn>0 then
+ local ttn=0
+ for i=tn,1,-1 do
+ ttn=ttn+1
+ tt[ttn]=t[i]
+ end
end
+ return tt
+ end
end
function table.reverse(t)
- if t then
- local n=#t
- local m=n+1
- for i=1,floor(n/2) do
- local j=m-i
- t[i],t[j]=t[j],t[i]
- end
- return t
+ if t then
+ local n=#t
+ local m=n+1
+ for i=1,floor(n/2) do
+ local j=m-i
+ t[i],t[j]=t[j],t[i]
end
+ return t
+ end
end
local function sequenced(t,sep,simple)
- if not t then
- return ""
- elseif type(t)=="string" then
- return t
+ if not t then
+ return ""
+ elseif type(t)=="string" then
+ return t
+ end
+ local n=#t
+ local s={}
+ if n>0 then
+ for i=1,n do
+ local v=t[i]
+ if type(v)=="table" then
+ s[i]="{"..sequenced(v,sep,simple).."}"
+ else
+ s[i]=tostring(t[i])
+ end
end
- local n=#t
- local s={}
- if n>0 then
- for i=1,n do
- local v=t[i]
- if type(v)=="table" then
- s[i]="{"..sequenced(v,sep,simple).."}"
- else
- s[i]=tostring(t[i])
- end
+ else
+ n=0
+ for k,v in sortedhash(t) do
+ if simple then
+ if v==true then
+ n=n+1
+ s[n]=k
+ elseif v and v~="" then
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
+ end
end
- else
- n=0
- for k,v in sortedhash(t) do
- if simple then
- if v==true then
- n=n+1
- s[n]=k
- elseif v and v~="" then
- n=n+1
- if type(v)=="table" then
- s[n]=k.."={"..sequenced(v,sep,simple).."}"
- else
- s[n]=k.."="..tostring(v)
- end
- end
- else
- n=n+1
- if type(v)=="table" then
- s[n]=k.."={"..sequenced(v,sep,simple).."}"
- else
- s[n]=k.."="..tostring(v)
- end
- end
+ else
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
end
+ end
end
- return concat(s,sep or " | ")
+ end
+ return concat(s,sep or " | ")
end
table.sequenced=sequenced
function table.print(t,...)
- if type(t)~="table" then
- print(tostring(t))
- else
- serialize(print,t,...)
- end
+ if type(t)~="table" then
+ print(tostring(t))
+ else
+ serialize(print,t,...)
+ end
end
if setinspector then
- setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
+ setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
end
function table.sub(t,i,j)
- return { unpack(t,i,j) }
+ return { unpack(t,i,j) }
end
function table.is_empty(t)
- return not t or next(t)==nil
+ return not t or next(t)==nil
end
function table.has_one_entry(t)
- return t and next(t,next(t))==nil
+ return t and next(t,next(t))==nil
end
function table.loweredkeys(t)
- local l={}
- for k,v in next,t do
- l[lower(k)]=v
- end
- return l
+ local l={}
+ for k,v in next,t do
+ l[lower(k)]=v
+ end
+ return l
end
function table.unique(old)
- local hash={}
- local new={}
- local n=0
- for i=1,#old do
- local oi=old[i]
- if not hash[oi] then
- n=n+1
- new[n]=oi
- hash[oi]=true
- end
- end
- return new
+ local hash={}
+ local new={}
+ local n=0
+ for i=1,#old do
+ local oi=old[i]
+ if not hash[oi] then
+ n=n+1
+ new[n]=oi
+ hash[oi]=true
+ end
+ end
+ return new
end
function table.sorted(t,...)
- sort(t,...)
- return t
+ sort(t,...)
+ return t
end
function table.values(t,s)
- if t then
- local values,keys,v={},{},0
- for key,value in next,t do
- if not keys[value] then
- v=v+1
- values[v]=value
- keys[k]=key
- end
- end
- if s then
- sort(values)
- end
- return values
- else
- return {}
+ if t then
+ local values,keys,v={},{},0
+ for key,value in next,t do
+ if not keys[value] then
+ v=v+1
+ values[v]=value
+ keys[k]=key
+ end
end
+ if s then
+ sort(values)
+ end
+ return values
+ else
+ return {}
+ end
end
function table.filtered(t,pattern,sort,cmp)
- if t and type(pattern)=="string" then
- if sort then
- local s
- if cmp then
- s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
- else
- s=sortedkeys(t)
- end
- local n=0
- local m=#s
- local function kv(s)
- while n<m do
- n=n+1
- local k=s[n]
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return kv,s
- else
- local n=next(t)
- local function iterator()
- while n~=nil do
- local k=n
- n=next(t,k)
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return iterator,t
+ if t and type(pattern)=="string" then
+ if sort then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local n=0
+ local m=#s
+ local function kv(s)
+ while n<m do
+ n=n+1
+ local k=s[n]
+ if find(k,pattern) then
+ return k,t[k]
+ end
end
- else
- return nothing
+ end
+ return kv,s
+ else
+ local n=next(t)
+ local function iterator()
+ while n~=nil do
+ local k=n
+ n=next(t,k)
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return iterator,t
end
+ else
+ return nothing
+ end
end
if not table.move then
- function table.move(a1,f,e,t,a2)
- if a2 and a1~=a2 then
- for i=f,e do
- a2[t]=a1[i]
- t=t+1
- end
- return a2
- else
- t=t+e-f
- for i=e,f,-1 do
- a1[t]=a1[i]
- t=t-1
- end
- return a1
- end
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1~=a2 then
+ for i=f,e do
+ a2[t]=a1[i]
+ t=t+1
+ end
+ return a2
+ else
+ t=t+e-f
+ for i=e,f,-1 do
+ a1[t]=a1[i]
+ t=t-1
+ end
+ return a1
end
+ end
end
@@ -3059,14 +3059,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-io"] = package.loaded["l-io"] or true
--- original size: 11823, stripped down to: 6945
+-- original size: 11823, stripped down to: 6325
if not modules then modules={} end modules ['l-io']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local io=io
local open,flush,write,read=io.open,io.flush,io.write,io.read
@@ -3074,334 +3074,334 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
local concat=table.concat
local type=type
if string.find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator="\\",";"
+ io.fileseparator,io.pathseparator="\\",";"
else
- io.fileseparator,io.pathseparator="/",":"
+ io.fileseparator,io.pathseparator="/",":"
end
local large=0x01000000
local medium=0x00100000
local small=0x00020000
local function readall(f)
- local size=f:seek("end")
- if size>0 then
- f:seek("set",0)
- return f:read(size)
- else
- return ""
- end
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ return f:read(size)
+ else
+ return ""
+ end
end
io.readall=readall
function io.loaddata(filename,textmode)
- local f=open(filename,(textmode and 'r') or 'rb')
- if f then
- local size=f:seek("end")
- local data=nil
- if size>0 then
- f:seek("set",0)
- data=f:read(size)
- end
- f:close()
- return data
+ local f=open(filename,(textmode and 'r') or 'rb')
+ if f then
+ local size=f:seek("end")
+ local data=nil
+ if size>0 then
+ f:seek("set",0)
+ data=f:read(size)
end
+ f:close()
+ return data
+ end
end
function io.copydata(source,target,action)
- local f=open(source,"rb")
- if f then
- local g=open(target,"wb")
- if g then
- local size=f:seek("end")
- if size>0 then
- f:seek("set",0)
- local data=f:read(size)
- if action then
- data=action(data)
- end
- if data then
- g:write(data)
- end
- end
- g:close()
+ local f=open(source,"rb")
+ if f then
+ local g=open(target,"wb")
+ if g then
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ local data=f:read(size)
+ if action then
+ data=action(data)
end
- f:close()
- flush()
+ if data then
+ g:write(data)
+ end
+ end
+ g:close()
end
+ f:close()
+ flush()
+ end
end
function io.savedata(filename,data,joiner)
- local f=open(filename,"wb")
- if f then
- if type(data)=="table" then
- f:write(concat(data,joiner or ""))
- elseif type(data)=="function" then
- data(f)
- else
- f:write(data or "")
- end
- f:close()
- flush()
- return true
+ local f=open(filename,"wb")
+ if f then
+ if type(data)=="table" then
+ f:write(concat(data,joiner or ""))
+ elseif type(data)=="function" then
+ data(f)
else
- return false
+ f:write(data or "")
end
+ f:close()
+ flush()
+ return true
+ else
+ return false
+ end
end
if fio and fio.readline then
- local readline=fio.readline
- function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=readline(f)
- if line then
- lines[i]=line
- else
- break
- end
- end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
+ local readline=fio.readline
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=readline(f)
+ if line then
+ lines[i]=line
else
- local line=readline(f)
- f:close()
- if line and #line>0 then
- return line
- end
+ break
end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=readline(f)
+ f:close()
+ if line and #line>0 then
+ return line
+ end
end
+ end
else
- function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=f:read("*lines")
- if line then
- lines[i]=line
- else
- break
- end
- end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=f:read("*lines")
+ if line then
+ lines[i]=line
else
- local line=f:read("*line") or ""
- f:close()
- if #line>0 then
- return line
- end
+ break
end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=f:read("*line") or ""
+ f:close()
+ if #line>0 then
+ return line
+ end
end
+ end
end
function io.loadchunk(filename,n)
- local f=open(filename,'rb')
- if f then
- local data=f:read(n or 1024)
- f:close()
- if #data>0 then
- return data
- end
+ local f=open(filename,'rb')
+ if f then
+ local data=f:read(n or 1024)
+ f:close()
+ if #data>0 then
+ return data
end
+ end
end
function io.exists(filename)
- local f=open(filename)
- if f==nil then
- return false
- else
- f:close()
- return true
- end
+ local f=open(filename)
+ if f==nil then
+ return false
+ else
+ f:close()
+ return true
+ end
end
function io.size(filename)
- local f=open(filename)
- if f==nil then
- return 0
- else
- local s=f:seek("end")
- f:close()
- return s
- end
+ local f=open(filename)
+ if f==nil then
+ return 0
+ else
+ local s=f:seek("end")
+ f:close()
+ return s
+ end
end
local function noflines(f)
- if type(f)=="string" then
- local f=open(filename)
- if f then
- local n=f and noflines(f) or 0
- f:close()
- return n
- else
- return 0
- end
+ if type(f)=="string" then
+ local f=open(filename)
+ if f then
+ local n=f and noflines(f) or 0
+ f:close()
+ return n
else
- local n=0
- for _ in f:lines() do
- n=n+1
- end
- f:seek('set',0)
- return n
+ return 0
+ end
+ else
+ local n=0
+ for _ in f:lines() do
+ n=n+1
end
+ f:seek('set',0)
+ return n
+ end
end
io.noflines=noflines
local nextchar={
- [ 4]=function(f)
- return f:read(1,1,1,1)
- end,
- [ 2]=function(f)
- return f:read(1,1)
- end,
- [ 1]=function(f)
- return f:read(1)
- end,
- [-2]=function(f)
- local a,b=f:read(1,1)
- return b,a
- end,
- [-4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- return d,c,b,a
- end
+ [ 4]=function(f)
+ return f:read(1,1,1,1)
+ end,
+ [ 2]=function(f)
+ return f:read(1,1)
+ end,
+ [ 1]=function(f)
+ return f:read(1)
+ end,
+ [-2]=function(f)
+ local a,b=f:read(1,1)
+ return b,a
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ return d,c,b,a
+ end
}
function io.characters(f,n)
- if f then
- return nextchar[n or 1],f
- end
+ if f then
+ return nextchar[n or 1],f
+ end
end
local nextbyte={
- [4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- if d then
- return byte(a),byte(b),byte(c),byte(d)
- end
- end,
- [3]=function(f)
- local a,b,c=f:read(1,1,1)
- if b then
- return byte(a),byte(b),byte(c)
- end
- end,
- [2]=function(f)
- local a,b=f:read(1,1)
- if b then
- return byte(a),byte(b)
- end
- end,
- [1]=function (f)
- local a=f:read(1)
- if a then
- return byte(a)
- end
- end,
- [-2]=function (f)
- local a,b=f:read(1,1)
- if b then
- return byte(b),byte(a)
- end
- end,
- [-3]=function(f)
- local a,b,c=f:read(1,1,1)
- if b then
- return byte(c),byte(b),byte(a)
- end
- end,
- [-4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- if d then
- return byte(d),byte(c),byte(b),byte(a)
- end
+ [4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(a),byte(b),byte(c),byte(d)
+ end
+ end,
+ [3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(a),byte(b),byte(c)
+ end
+ end,
+ [2]=function(f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(a),byte(b)
+ end
+ end,
+ [1]=function (f)
+ local a=f:read(1)
+ if a then
+ return byte(a)
+ end
+ end,
+ [-2]=function (f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(b),byte(a)
+ end
+ end,
+ [-3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(c),byte(b),byte(a)
+ end
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(d),byte(c),byte(b),byte(a)
end
+ end
}
function io.bytes(f,n)
- if f then
- return nextbyte[n or 1],f
- else
- return nil,nil
- end
+ if f then
+ return nextbyte[n or 1],f
+ else
+ return nil,nil
+ end
end
function io.ask(question,default,options)
- while true do
- write(question)
- if options then
- write(format(" [%s]",concat(options,"|")))
- end
- if default then
- write(format(" [%s]",default))
- end
- write(format(" "))
- flush()
- local answer=read()
- answer=gsub(answer,"^%s*(.*)%s*$","%1")
- if answer=="" and default then
- return default
- elseif not options then
- return answer
- else
- for k=1,#options do
- if options[k]==answer then
- return answer
- end
- end
- local pattern="^"..answer
- for k=1,#options do
- local v=options[k]
- if find(v,pattern) then
- return v
- end
- end
+ while true do
+ write(question)
+ if options then
+ write(format(" [%s]",concat(options,"|")))
+ end
+ if default then
+ write(format(" [%s]",default))
+ end
+ write(format(" "))
+ flush()
+ local answer=read()
+ answer=gsub(answer,"^%s*(.*)%s*$","%1")
+ if answer=="" and default then
+ return default
+ elseif not options then
+ return answer
+ else
+ for k=1,#options do
+ if options[k]==answer then
+ return answer
end
+ end
+ local pattern="^"..answer
+ for k=1,#options do
+ local v=options[k]
+ if find(v,pattern) then
+ return v
+ end
+ end
end
+ end
end
local function readnumber(f,n,m)
- if m then
- f:seek("set",n)
- n=m
- end
- if n==1 then
- return byte(f:read(1))
- elseif n==2 then
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
- elseif n==3 then
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
- elseif n==4 then
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==8 then
- local a,b=readnumber(f,4),readnumber(f,4)
- return 0x100*a+b
- elseif n==12 then
- local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
- return 0x10000*a+0x100*b+c
- elseif n==-2 then
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
- elseif n==-3 then
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
- elseif n==-4 then
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==-8 then
- local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
- return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
- else
- return 0
- end
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ if n==1 then
+ return byte(f:read(1))
+ elseif n==2 then
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==3 then
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==4 then
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==8 then
+ local a,b=readnumber(f,4),readnumber(f,4)
+ return 0x100*a+b
+ elseif n==12 then
+ local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
+ return 0x10000*a+0x100*b+c
+ elseif n==-2 then
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==-3 then
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==-4 then
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==-8 then
+ local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
+ return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+ else
+ return 0
+ end
end
io.readnumber=readnumber
function io.readstring(f,n,m)
- if m then
- f:seek("set",n)
- n=m
- end
- local str=gsub(f:read(n),"\000","")
- return str
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ local str=gsub(f:read(n),"\000","")
+ return str
end
@@ -3411,14 +3411,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-number"] = package.loaded["l-number"] or true
--- original size: 5720, stripped down to: 2392
+-- original size: 5720, stripped down to: 2176
if not modules then modules={} end modules ['l-number']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tostring,tonumber=tostring,tonumber
local format,floor,match,rep=string.format,math.floor,string.match,string.rep
@@ -3428,107 +3428,107 @@ local floor=math.floor
number=number or {}
local number=number
if bit32 then
- local bextract=bit32.extract
- local t={
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- }
- function number.tobitstring(b,m,w)
- if not w then
- w=32
- end
- local n=w
- for i=0,w-1 do
- local v=bextract(b,i)
- local k=w-i
- if v==1 then
- n=k
- t[k]="1"
- else
- t[k]="0"
- end
- end
- if w then
- return concat(t,"",1,w)
- elseif m then
- m=33-m*8
- if m<1 then
- m=1
- end
- return concat(t,"",1,m)
- elseif n<8 then
- return concat(t)
- elseif n<16 then
- return concat(t,"",9)
- elseif n<24 then
- return concat(t,"",17)
- else
- return concat(t,"",25)
- end
+ local bextract=bit32.extract
+ local t={
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ }
+ function number.tobitstring(b,m,w)
+ if not w then
+ w=32
+ end
+ local n=w
+ for i=0,w-1 do
+ local v=bextract(b,i)
+ local k=w-i
+ if v==1 then
+ n=k
+ t[k]="1"
+ else
+ t[k]="0"
+ end
+ end
+ if w then
+ return concat(t,"",1,w)
+ elseif m then
+ m=33-m*8
+ if m<1 then
+ m=1
+ end
+ return concat(t,"",1,m)
+ elseif n<8 then
+ return concat(t)
+ elseif n<16 then
+ return concat(t,"",9)
+ elseif n<24 then
+ return concat(t,"",17)
+ else
+ return concat(t,"",25)
end
+ end
else
- function number.tobitstring(n,m)
- if n>0 then
- local t={}
- while n>0 do
- insert(t,1,n%2>0 and 1 or 0)
- n=floor(n/2)
- end
- local nn=8-#t%8
- if nn>0 and nn<8 then
- for i=1,nn do
- insert(t,1,0)
- end
- end
- if m then
- m=m*8-#t
- if m>0 then
- insert(t,1,rep("0",m))
- end
- end
- return concat(t)
- elseif m then
- rep("00000000",m)
- else
- return "00000000"
+ function number.tobitstring(n,m)
+ if n>0 then
+ local t={}
+ while n>0 do
+ insert(t,1,n%2>0 and 1 or 0)
+ n=floor(n/2)
+ end
+ local nn=8-#t%8
+ if nn>0 and nn<8 then
+ for i=1,nn do
+ insert(t,1,0)
+ end
+ end
+ if m then
+ m=m*8-#t
+ if m>0 then
+ insert(t,1,rep("0",m))
end
+ end
+ return concat(t)
+ elseif m then
+ rep("00000000",m)
+ else
+ return "00000000"
end
+ end
end
function number.valid(str,default)
- return tonumber(str) or default or nil
+ return tonumber(str) or default or nil
end
function number.toevenhex(n)
- local s=format("%X",n)
- if #s%2==0 then
- return s
- else
- return "0"..s
- end
+ local s=format("%X",n)
+ if #s%2==0 then
+ return s
+ else
+ return "0"..s
+ end
end
function number.bytetodecimal(b)
- local d=floor(b*100/255+0.5)
- if d>100 then
- return 100
- elseif d<-100 then
- return -100
- else
- return d
- end
+ local d=floor(b*100/255+0.5)
+ if d>100 then
+ return 100
+ elseif d<-100 then
+ return -100
+ else
+ return d
+ end
end
function number.decimaltobyte(d)
- local b=floor(d*255/100+0.5)
- if b>255 then
- return 255
- elseif b<-255 then
- return -255
- else
- return b
- end
+ local b=floor(d*255/100+0.5)
+ if b>255 then
+ return 255
+ elseif b<-255 then
+ return -255
+ else
+ return b
+ end
end
function number.idiv(i,d)
- return floor(i/d)
+ return floor(i/d)
end
@@ -3538,14 +3538,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-set"] = package.loaded["l-set"] or true
--- original size: 1923, stripped down to: 1133
+-- original size: 1923, stripped down to: 1044
if not modules then modules={} end modules ['l-set']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
set=set or {}
local nums={}
@@ -3554,54 +3554,54 @@ local concat=table.concat
local next,type=next,type
set.create=table.tohash
function set.tonumber(t)
- if next(t) then
- local s=""
- for k,v in next,t do
- if v then
- s=s.." "..k
- end
- end
- local n=nums[s]
- if not n then
- n=#tabs+1
- tabs[n]=t
- nums[s]=n
- end
- return n
- else
- return 0
+ if next(t) then
+ local s=""
+ for k,v in next,t do
+ if v then
+ s=s.." "..k
+ end
+ end
+ local n=nums[s]
+ if not n then
+ n=#tabs+1
+ tabs[n]=t
+ nums[s]=n
end
+ return n
+ else
+ return 0
+ end
end
function set.totable(n)
- if n==0 then
- return {}
- else
- return tabs[n] or {}
- end
+ if n==0 then
+ return {}
+ else
+ return tabs[n] or {}
+ end
end
function set.tolist(n)
- if n==0 or not tabs[n] then
- return ""
- else
- local t,n={},0
- for k,v in next,tabs[n] do
- if v then
- n=n+1
- t[n]=k
- end
- end
- return concat(t," ")
+ if n==0 or not tabs[n] then
+ return ""
+ else
+ local t,n={},0
+ for k,v in next,tabs[n] do
+ if v then
+ n=n+1
+ t[n]=k
+ end
end
+ return concat(t," ")
+ end
end
function set.contains(n,s)
- if type(n)=="table" then
- return n[s]
- elseif n==0 then
- return false
- else
- local t=tabs[n]
- return t and t[s]
- end
+ if type(n)=="table" then
+ return n[s]
+ elseif n==0 then
+ return false
+ else
+ local t=tabs[n]
+ return t and t[s]
+ end
end
@@ -3611,14 +3611,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-os"] = package.loaded["l-os"] or true
--- original size: 19347, stripped down to: 11016
+-- original size: 19347, stripped down to: 10258
if not modules then modules={} end modules ['l-os']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local os=os
local date,time=os.date,os.time
@@ -3627,433 +3627,433 @@ local concat=table.concat
local random,ceil,randomseed=math.random,math.ceil,math.randomseed
local rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring=rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring
do
- local selfdir=os.selfdir
- if selfdir=="" then
- selfdir=nil
+ local selfdir=os.selfdir
+ if selfdir=="" then
+ selfdir=nil
+ end
+ if not selfdir then
+ if arg then
+ for i=1,#arg do
+ local a=arg[i]
+ if find(a,"^%-%-[c:]*texmfbinpath=") then
+ selfdir=gsub(a,"^.-=","")
+ break
+ end
+ end
end
if not selfdir then
- if arg then
- for i=1,#arg do
- local a=arg[i]
- if find(a,"^%-%-[c:]*texmfbinpath=") then
- selfdir=gsub(a,"^.-=","")
- break
- end
+ selfdir=os.selfbin or "luatex"
+ if find(selfdir,"[/\\]") then
+ selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
+ elseif os.getenv then
+ local path=os.getenv("PATH")
+ local name=gsub(selfdir,"^.*[/\\][^/\\]","")
+ local patt="[^:]+"
+ if os.type=="windows" then
+ patt="[^;]+"
+ name=name..".exe"
+ end
+ local isfile
+ if lfs then
+ local attributes=lfs.attributes
+ isfile=function(name)
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
+ end
+ else
+ local open=io.open
+ isfile=function(name)
+ local f=open(name)
+ if f then
+ f:close()
+ return true
end
+ end
end
- if not selfdir then
- selfdir=os.selfbin or "luatex"
- if find(selfdir,"[/\\]") then
- selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
- elseif os.getenv then
- local path=os.getenv("PATH")
- local name=gsub(selfdir,"^.*[/\\][^/\\]","")
- local patt="[^:]+"
- if os.type=="windows" then
- patt="[^;]+"
- name=name..".exe"
- end
- local isfile
- if lfs then
- local attributes=lfs.attributes
- isfile=function(name)
- local a=attributes(name,"mode")
- return a=="file" or a=="link" or nil
- end
- else
- local open=io.open
- isfile=function(name)
- local f=open(name)
- if f then
- f:close()
- return true
- end
- end
- end
- for p in gmatch(path,patt) do
- if isfile(p.."/"..name) then
- selfdir=p
- break
- end
- end
- end
+ for p in gmatch(path,patt) do
+ if isfile(p.."/"..name) then
+ selfdir=p
+ break
+ end
end
- os.selfdir=selfdir or "."
+ end
end
+ os.selfdir=selfdir or "."
+ end
end
math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
randomseed(math.initialseed)
if not os.__getenv__ then
- os.__getenv__=os.getenv
- os.__setenv__=os.setenv
- if os.env then
- local osgetenv=os.getenv
- local ossetenv=os.setenv
- local osenv=os.env local _=osenv.PATH
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- if type(v)=="table" then
- v=concat(v,";")
- end
- ossetenv(K,v)
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
- end
- else
- local ossetenv=os.setenv
- local osgetenv=os.getenv
- local osenv={}
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
- end
- local function __index(t,k)
- return os.getenv(k)
- end
- local function __newindex(t,k,v)
- os.setenv(k,v)
- end
- os.env={}
- setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ os.__getenv__=os.getenv
+ os.__setenv__=os.setenv
+ if os.env then
+ local osgetenv=os.getenv
+ local ossetenv=os.setenv
+ local osenv=os.env local _=osenv.PATH
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ if type(v)=="table" then
+ v=concat(v,";")
+ end
+ ossetenv(K,v)
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ else
+ local ossetenv=os.setenv
+ local osgetenv=os.getenv
+ local osenv={}
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ local function __index(t,k)
+ return os.getenv(k)
+ end
+ local function __newindex(t,k,v)
+ os.setenv(k,v)
+ end
+ os.env={}
+ setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
end
local execute=os.execute
local iopopen=io.popen
local function resultof(command)
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- else
- return ""
- end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ else
+ return ""
+ end
end
os.resultof=resultof
function os.pipeto(command)
- return iopopen(command,"w")
+ return iopopen(command,"w")
end
if not io.fileseparator then
- if find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
- else
- io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
- end
+ if find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
+ else
+ io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
+ end
end
os.type=os.type or (io.pathseparator==";" and "windows") or "unix"
-os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
+os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
if os.type=="windows" then
- os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
else
- os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
end
local launchers={
- windows="start %s",
- macosx="open %s",
- unix="xdg-open %s &> /dev/null &",
+ windows="start %s",
+ macosx="open %s",
+ unix="xdg-open %s &> /dev/null &",
}
function os.launch(str)
- execute(format(launchers[os.name] or launchers.unix,str))
+ execute(format(launchers[os.name] or launchers.unix,str))
end
if not os.times then
- function os.times()
- return {
- utime=os.gettimeofday(),
- stime=0,
- cutime=0,
- cstime=0,
- }
- end
+ function os.times()
+ return {
+ utime=os.gettimeofday(),
+ stime=0,
+ cutime=0,
+ cstime=0,
+ }
+ end
end
local gettimeofday=os.gettimeofday or os.clock
os.gettimeofday=gettimeofday
local startuptime=gettimeofday()
function os.runtime()
- return gettimeofday()-startuptime
+ return gettimeofday()-startuptime
end
local resolvers=os.resolvers or {}
os.resolvers=resolvers
setmetatable(os,{ __index=function(t,k)
- local r=resolvers[k]
- return r and r(t,k) or nil
+ local r=resolvers[k]
+ return r and r(t,k) or nil
end })
local name,platform=os.name or "linux",os.getenv("MTX_PLATFORM") or ""
if platform~="" then
- os.platform=platform
+ os.platform=platform
elseif os.type=="windows" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
- local platform=""
- if find(architecture,"AMD64",1,true) then
- platform="win64"
- else
- platform="mswin"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
+ local platform=""
+ if find(architecture,"AMD64",1,true) then
+ platform="win64"
+ else
+ platform="mswin"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="linux" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- local platform=os.getenv("MTX_PLATFORM") or ""
- local musl=find(os.selfdir or "","linuxmusl")
- if platform~="" then
- elseif find(architecture,"x86_64",1,true) then
- platform=musl and "linuxmusl" or "linux-64"
- elseif find(architecture,"ppc",1,true) then
- platform="linux-ppc"
- else
- platform=musl and "linuxmusl" or "linux"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=os.getenv("MTX_PLATFORM") or ""
+ local musl=find(os.selfdir or "","linuxmusl")
+ if platform~="" then
+ elseif find(architecture,"x86_64",1,true) then
+ platform=musl and "linuxmusl" or "linux-64"
+ elseif find(architecture,"ppc",1,true) then
+ platform="linux-ppc"
+ else
+ platform=musl and "linuxmusl" or "linux"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="macosx" then
- function resolvers.platform(t,k)
- local architecture=resultof("echo $HOSTTYPE") or ""
- local platform=""
- if architecture=="" then
- platform="osx-intel"
- elseif find(architecture,"i386",1,true) then
- platform="osx-intel"
- elseif find(architecture,"x86_64",1,true) then
- platform="osx-64"
- else
- platform="osx-ppc"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local architecture=resultof("echo $HOSTTYPE") or ""
+ local platform=""
+ if architecture=="" then
+ platform="osx-intel"
+ elseif find(architecture,"i386",1,true) then
+ platform="osx-intel"
+ elseif find(architecture,"x86_64",1,true) then
+ platform="osx-64"
+ else
+ platform="osx-ppc"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="sunos" then
- function resolvers.platform(t,k)
- local architecture=resultof("uname -m") or ""
- local platform=""
- if find(architecture,"sparc",1,true) then
- platform="solaris-sparc"
- else
- platform="solaris-intel"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"sparc",1,true) then
+ platform="solaris-sparc"
+ else
+ platform="solaris-intel"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="freebsd" then
- function resolvers.platform(t,k)
- local architecture=resultof("uname -m") or ""
- local platform=""
- if find(architecture,"amd64",1,true) then
- platform="freebsd-amd64"
- else
- platform="freebsd"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"amd64",1,true) then
+ platform="freebsd-amd64"
+ else
+ platform="freebsd"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="kfreebsd" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- local platform=""
- if find(architecture,"x86_64",1,true) then
- platform="kfreebsd-amd64"
- else
- platform="kfreebsd-i386"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"x86_64",1,true) then
+ platform="kfreebsd-amd64"
+ else
+ platform="kfreebsd-i386"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
else
- function resolvers.platform(t,k)
- local platform="linux"
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local platform="linux"
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
end
os.newline=name=="windows" and "\013\010" or "\010"
function resolvers.bits(t,k)
- local bits=find(os.platform,"64",1,true) and 64 or 32
- os.bits=bits
- return bits
+ local bits=find(os.platform,"64",1,true) and 64 or 32
+ os.bits=bits
+ return bits
end
local t={ 8,9,"a","b" }
function os.uuid()
- return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
- random(0xFFFF),random(0xFFFF),
- random(0x0FFF),
- t[ceil(random(4))] or 8,random(0x0FFF),
- random(0xFFFF),
- random(0xFFFF),random(0xFFFF),random(0xFFFF)
- )
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
end
local d
function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
- if delta then
- if d>0 then
- return format("+%02i:00",d)
- else
- return format("-%02i:00",-d)
- end
+ d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ if delta then
+ if d>0 then
+ return format("+%02i:00",d)
else
- return 1
+ return format("-%02i:00",-d)
end
+ else
+ return 1
+ end
end
local timeformat=format("%%s%s",os.timezone(true))
local dateformat="!%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.fulltime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=format(timeformat,date(dateformat))
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=format(timeformat,date(dateformat))
+ end
+ return lastdate
end
local dateformat="%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.localtime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=date(dateformat,t)
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=date(dateformat,t)
+ end
+ return lastdate
end
function os.converttime(t,default)
- local t=tonumber(t)
- if t and t>0 then
- return date(dateformat,t)
- else
- return default or "-"
- end
+ local t=tonumber(t)
+ if t and t>0 then
+ return date(dateformat,t)
+ else
+ return default or "-"
+ end
end
local memory={}
local function which(filename)
- local fullname=memory[filename]
- if fullname==nil then
- local suffix=file.suffix(filename)
- local suffixes=suffix=="" and os.binsuffixes or { suffix }
- for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
- local df=file.join(directory,filename)
- for i=1,#suffixes do
- local dfs=file.addsuffix(df,suffixes[i])
- if io.exists(dfs) then
- fullname=dfs
- break
- end
- end
- end
- if not fullname then
- fullname=false
+ local fullname=memory[filename]
+ if fullname==nil then
+ local suffix=file.suffix(filename)
+ local suffixes=suffix=="" and os.binsuffixes or { suffix }
+ for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local df=file.join(directory,filename)
+ for i=1,#suffixes do
+ local dfs=file.addsuffix(df,suffixes[i])
+ if io.exists(dfs) then
+ fullname=dfs
+ break
end
- memory[filename]=fullname
+ end
end
- return fullname
+ if not fullname then
+ fullname=false
+ end
+ memory[filename]=fullname
+ end
+ return fullname
end
os.which=which
os.where=which
function os.today()
- return date("!*t")
+ return date("!*t")
end
function os.now()
- return date("!%Y-%m-%d %H:%M:%S")
+ return date("!%Y-%m-%d %H:%M:%S")
end
if not os.sleep then
- local socket=socket
- function os.sleep(n)
- if not socket then
- socket=require("socket")
- end
- socket.sleep(n)
+ local socket=socket
+ function os.sleep(n)
+ if not socket then
+ socket=require("socket")
end
+ socket.sleep(n)
+ end
end
local function isleapyear(year)
- return (year%4==0) and (year%100~=0 or year%400==0)
+ return (year%4==0) and (year%100~=0 or year%400==0)
end
os.isleapyear=isleapyear
local days={ 31,28,31,30,31,30,31,31,30,31,30,31 }
local function nofdays(year,month)
- if not month then
- return isleapyear(year) and 365 or 364
- else
- return month==2 and isleapyear(year) and 29 or days[month]
- end
+ if not month then
+ return isleapyear(year) and 365 or 364
+ else
+ return month==2 and isleapyear(year) and 29 or days[month]
+ end
end
os.nofdays=nofdays
function os.weekday(day,month,year)
- return date("%w",time { year=year,month=month,day=day })+1
+ return date("%w",time { year=year,month=month,day=day })+1
end
function os.validdate(year,month,day)
- if month<1 then
- month=1
- elseif month>12 then
- month=12
- end
- if day<1 then
- day=1
- else
- local max=nofdays(year,month)
- if day>max then
- day=max
- end
- end
- return year,month,day
+ if month<1 then
+ month=1
+ elseif month>12 then
+ month=12
+ end
+ if day<1 then
+ day=1
+ else
+ local max=nofdays(year,month)
+ if day>max then
+ day=max
+ end
+ end
+ return year,month,day
end
local osexit=os.exit
local exitcode=nil
function os.setexitcode(code)
- exitcode=code
+ exitcode=code
end
function os.exit(c)
- if exitcode~=nil then
- return osexit(exitcode)
- end
- if c~=nil then
- return osexit(c)
- end
- return osexit()
+ if exitcode~=nil then
+ return osexit(exitcode)
+ end
+ if c~=nil then
+ return osexit(c)
+ end
+ return osexit()
end
@@ -4063,19 +4063,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-file"] = package.loaded["l-file"] or true
--- original size: 21804, stripped down to: 10461
+-- original size: 21804, stripped down to: 9980
if not modules then modules={} end modules ['l-file']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
file=file or {}
local file=file
if not lfs then
- lfs=optionalrequire("lfs")
+ lfs=optionalrequire("lfs")
end
local insert,concat=table.insert,table.concat
local match,find,gmatch=string.match,string.find,string.gmatch
@@ -4085,20 +4085,20 @@ local checkedsplit=string.checkedsplit
local P,R,S,C,Cs,Cp,Cc,Ct=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cp,lpeg.Cc,lpeg.Ct
local attributes=lfs.attributes
function lfs.isdir(name)
- return attributes(name,"mode")=="directory"
+ return attributes(name,"mode")=="directory"
end
function lfs.isfile(name)
- local a=attributes(name,"mode")
- return a=="file" or a=="link" or nil
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
end
function lfs.isfound(name)
- local a=attributes(name,"mode")
- return (a=="file" or a=="link") and name or nil
+ local a=attributes(name,"mode")
+ return (a=="file" or a=="link") and name or nil
end
if sandbox then
- sandbox.redefine(lfs.isfile,"lfs.isfile")
- sandbox.redefine(lfs.isdir,"lfs.isdir")
- sandbox.redefine(lfs.isfound,"lfs.isfound")
+ sandbox.redefine(lfs.isfile,"lfs.isfile")
+ sandbox.redefine(lfs.isdir,"lfs.isdir")
+ sandbox.redefine(lfs.isfound,"lfs.isfound")
end
local colon=P(":")
local period=P(".")
@@ -4112,27 +4112,27 @@ local name=noperiod^1
local suffix=period/""*(1-period-slashes)^1*-1
local pattern=C((1-(slashes^1*noslashes^1*-1))^1)*P(1)
local function pathpart(name,default)
- return name and lpegmatch(pattern,name) or default or ""
+ return name and lpegmatch(pattern,name) or default or ""
end
local pattern=(noslashes^0*slashes)^1*C(noslashes^1)*-1
local function basename(name)
- return name and lpegmatch(pattern,name) or name
+ return name and lpegmatch(pattern,name) or name
end
local pattern=(noslashes^0*slashes^1)^0*Cs((1-suffix)^1)*suffix^0
local function nameonly(name)
- return name and lpegmatch(pattern,name) or name
+ return name and lpegmatch(pattern,name) or name
end
local pattern=(noslashes^0*slashes)^0*(noperiod^1*period)^1*C(noperiod^1)*-1
local function suffixonly(name)
- return name and lpegmatch(pattern,name) or ""
+ return name and lpegmatch(pattern,name) or ""
end
local pattern=(noslashes^0*slashes)^0*noperiod^1*((period*C(noperiod^1))^1)*-1+Cc("")
local function suffixesonly(name)
- if name then
- return lpegmatch(pattern,name)
- else
- return ""
- end
+ if name then
+ return lpegmatch(pattern,name)
+ else
+ return ""
+ end
end
file.pathpart=pathpart
file.basename=basename
@@ -4141,7 +4141,7 @@ file.suffixonly=suffixonly
file.suffix=suffixonly
file.suffixesonly=suffixesonly
file.suffixes=suffixesonly
-file.dirname=pathpart
+file.dirname=pathpart
file.extname=suffixonly
local drive=C(R("az","AZ"))*colon
local path=C((noslashes^0*slashes)^0)
@@ -4157,142 +4157,142 @@ local pattern_b=path*base*suffix
local pattern_c=C(drive*path)*C(base*suffix)
local pattern_d=path*rest
function file.splitname(str,splitdrive)
- if not str then
- elseif splitdrive then
- return lpegmatch(pattern_a,str)
- else
- return lpegmatch(pattern_b,str)
- end
+ if not str then
+ elseif splitdrive then
+ return lpegmatch(pattern_a,str)
+ else
+ return lpegmatch(pattern_b,str)
+ end
end
function file.splitbase(str)
- if str then
- return lpegmatch(pattern_d,str)
- else
- return "",str
- end
+ if str then
+ return lpegmatch(pattern_d,str)
+ else
+ return "",str
+ end
end
function file.nametotable(str,splitdrive)
- if str then
- local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
- if splitdrive then
- return {
- path=path,
- drive=drive,
- subpath=subpath,
- name=name,
- base=base,
- suffix=suffix,
- }
- else
- return {
- path=path,
- name=name,
- base=base,
- suffix=suffix,
- }
- end
+ if str then
+ local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
+ if splitdrive then
+ return {
+ path=path,
+ drive=drive,
+ subpath=subpath,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
+ else
+ return {
+ path=path,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
end
+ end
end
local pattern=Cs(((period*(1-period-slashes)^1*-1)/""+1)^1)
function file.removesuffix(name)
- return name and lpegmatch(pattern,name)
+ return name and lpegmatch(pattern,name)
end
local suffix=period/""*(1-period-slashes)^1*-1
local pattern=Cs((noslashes^0*slashes^1)^0*((1-suffix)^1))*Cs(suffix)
function file.addsuffix(filename,suffix,criterium)
- if not filename or not suffix or suffix=="" then
- return filename
- elseif criterium==true then
- return filename.."."..suffix
- elseif not criterium then
- local n,s=lpegmatch(pattern,filename)
- if not s or s=="" then
- return filename.."."..suffix
- else
+ if not filename or not suffix or suffix=="" then
+ return filename
+ elseif criterium==true then
+ return filename.."."..suffix
+ elseif not criterium then
+ local n,s=lpegmatch(pattern,filename)
+ if not s or s=="" then
+ return filename.."."..suffix
+ else
+ return filename
+ end
+ else
+ local n,s=lpegmatch(pattern,filename)
+ if s and s~="" then
+ local t=type(criterium)
+ if t=="table" then
+ for i=1,#criterium do
+ if s==criterium[i] then
return filename
+ end
end
- else
- local n,s=lpegmatch(pattern,filename)
- if s and s~="" then
- local t=type(criterium)
- if t=="table" then
- for i=1,#criterium do
- if s==criterium[i] then
- return filename
- end
- end
- elseif t=="string" then
- if s==criterium then
- return filename
- end
- end
+ elseif t=="string" then
+ if s==criterium then
+ return filename
end
- return (n or filename).."."..suffix
+ end
end
+ return (n or filename).."."..suffix
+ end
end
local suffix=period*(1-period-slashes)^1*-1
local pattern=Cs((1-suffix)^0)
function file.replacesuffix(name,suffix)
- if name and suffix and suffix~="" then
- return lpegmatch(pattern,name).."."..suffix
- else
- return name
- end
+ if name and suffix and suffix~="" then
+ return lpegmatch(pattern,name).."."..suffix
+ else
+ return name
+ end
end
local reslasher=lpeg.replacer(P("\\"),"/")
function file.reslash(str)
- return str and lpegmatch(reslasher,str)
+ return str and lpegmatch(reslasher,str)
end
function file.is_writable(name)
- if not name then
- elseif lfs.isdir(name) then
- name=name.."/m_t_x_t_e_s_t.tmp"
- local f=io.open(name,"wb")
- if f then
- f:close()
- os.remove(name)
- return true
- end
- elseif lfs.isfile(name) then
- local f=io.open(name,"ab")
- if f then
- f:close()
- return true
- end
- else
- local f=io.open(name,"ab")
- if f then
- f:close()
- os.remove(name)
- return true
- end
+ if not name then
+ elseif lfs.isdir(name) then
+ name=name.."/m_t_x_t_e_s_t.tmp"
+ local f=io.open(name,"wb")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
end
- return false
+ elseif lfs.isfile(name) then
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ return true
+ end
+ else
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ end
+ return false
end
local readable=P("r")*Cc(true)
function file.is_readable(name)
- if name then
- local a=attributes(name)
- return a and lpegmatch(readable,a.permissions) or false
- else
- return false
- end
+ if name then
+ local a=attributes(name)
+ return a and lpegmatch(readable,a.permissions) or false
+ else
+ return false
+ end
end
file.isreadable=file.is_readable
file.iswritable=file.is_writable
function file.size(name)
- if name then
- local a=attributes(name)
- return a and a.size or 0
- else
- return 0
- end
+ if name then
+ local a=attributes(name)
+ return a and a.size or 0
+ else
+ return 0
+ end
end
function file.splitpath(str,separator)
- return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
+ return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
end
function file.joinpath(tab,separator)
- return tab and concat(tab,separator or io.pathseparator)
+ return tab and concat(tab,separator or io.pathseparator)
end
local someslash=S("\\/")
local stripper=Cs(P(fwslash)^0/""*reslasher)
@@ -4302,30 +4302,30 @@ local hasroot=fwslash^1
local reslasher=lpeg.replacer(S("\\/"),"/")
local deslasher=lpeg.replacer(S("\\/")^1,"/")
function file.join(one,two,three,...)
- if not two then
- return one=="" and one or lpegmatch(reslasher,one)
- end
- if one=="" then
- return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
- end
- if lpegmatch(isnetwork,one) then
- local one=lpegmatch(reslasher,one)
- local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
- if lpegmatch(hasroot,two) then
- return one..two
- else
- return one.."/"..two
- end
- elseif lpegmatch(isroot,one) then
- local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
- if lpegmatch(hasroot,two) then
- return two
- else
- return "/"..two
- end
- else
- return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
- end
+ if not two then
+ return one=="" and one or lpegmatch(reslasher,one)
+ end
+ if one=="" then
+ return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
+ end
+ if lpegmatch(isnetwork,one) then
+ local one=lpegmatch(reslasher,one)
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return one..two
+ else
+ return one.."/"..two
+ end
+ elseif lpegmatch(isroot,one) then
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return two
+ else
+ return "/"..two
+ end
+ else
+ return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+ end
end
local drivespec=R("az","AZ")^1*colon
local anchors=fwslash+drivespec
@@ -4335,56 +4335,56 @@ local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//")
local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
local absolute=fwslash
function file.collapsepath(str,anchor)
- if not str then
- return
- end
- if anchor==true and not lpegmatch(anchors,str) then
- str=getcurrentdir().."/"..str
- end
- if str=="" or str=="." then
- return "."
- elseif lpegmatch(untouched,str) then
- return lpegmatch(reslasher,str)
- end
- local starter,oldelements=lpegmatch(splitstarter,str)
- local newelements={}
- local i=#oldelements
- while i>0 do
- local element=oldelements[i]
- if element=='.' then
- elseif element=='..' then
- local n=i-1
- while n>0 do
- local element=oldelements[n]
- if element~='..' and element~='.' then
- oldelements[n]='.'
- break
- else
- n=n-1
- end
- end
- if n<1 then
- insert(newelements,1,'..')
- end
- elseif element~="" then
- insert(newelements,1,element)
- end
- i=i-1
- end
- if #newelements==0 then
- return starter or "."
- elseif starter then
- return starter..concat(newelements,'/')
- elseif lpegmatch(absolute,str) then
- return "/"..concat(newelements,'/')
- else
- newelements=concat(newelements,'/')
- if anchor=="." and find(str,"^%./") then
- return "./"..newelements
+ if not str then
+ return
+ end
+ if anchor==true and not lpegmatch(anchors,str) then
+ str=getcurrentdir().."/"..str
+ end
+ if str=="" or str=="." then
+ return "."
+ elseif lpegmatch(untouched,str) then
+ return lpegmatch(reslasher,str)
+ end
+ local starter,oldelements=lpegmatch(splitstarter,str)
+ local newelements={}
+ local i=#oldelements
+ while i>0 do
+ local element=oldelements[i]
+ if element=='.' then
+ elseif element=='..' then
+ local n=i-1
+ while n>0 do
+ local element=oldelements[n]
+ if element~='..' and element~='.' then
+ oldelements[n]='.'
+ break
else
- return newelements
+ n=n-1
end
- end
+ end
+ if n<1 then
+ insert(newelements,1,'..')
+ end
+ elseif element~="" then
+ insert(newelements,1,element)
+ end
+ i=i-1
+ end
+ if #newelements==0 then
+ return starter or "."
+ elseif starter then
+ return starter..concat(newelements,'/')
+ elseif lpegmatch(absolute,str) then
+ return "/"..concat(newelements,'/')
+ else
+ newelements=concat(newelements,'/')
+ if anchor=="." and find(str,"^%./") then
+ return "./"..newelements
+ else
+ return newelements
+ end
+ end
end
local validchars=R("az","09","AZ","--","..")
local pattern_a=lpeg.replacer(1-validchars)
@@ -4392,26 +4392,26 @@ local pattern_a=Cs((validchars+P(1)/"-")^1)
local whatever=P("-")^0/""
local pattern_b=Cs(whatever*(1-whatever*-1)^1)
function file.robustname(str,strict)
- if str then
- str=lpegmatch(pattern_a,str) or str
- if strict then
- return lpegmatch(pattern_b,str) or str
- else
- return str
- end
+ if str then
+ str=lpegmatch(pattern_a,str) or str
+ if strict then
+ return lpegmatch(pattern_b,str) or str
+ else
+ return str
end
+ end
end
local loaddata=io.loaddata
local savedata=io.savedata
file.readdata=loaddata
file.savedata=savedata
function file.copy(oldname,newname)
- if oldname and newname then
- local data=loaddata(oldname)
- if data and data~="" then
- savedata(newname,data)
- end
+ if oldname and newname then
+ local data=loaddata(oldname)
+ if data and data~="" then
+ savedata(newname,data)
end
+ end
end
local letter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -4420,44 +4420,44 @@ local rootbased=fwslash+letter*colon
lpeg.patterns.qualified=qualified
lpeg.patterns.rootbased=rootbased
function file.is_qualified_path(filename)
- return filename and lpegmatch(qualified,filename)~=nil
+ return filename and lpegmatch(qualified,filename)~=nil
end
function file.is_rootbased_path(filename)
- return filename and lpegmatch(rootbased,filename)~=nil
+ return filename and lpegmatch(rootbased,filename)~=nil
end
function file.strip(name,dir)
- if name then
- local b,a=match(name,"^(.-)"..dir.."(.*)$")
- return a~="" and a or name
- end
+ if name then
+ local b,a=match(name,"^(.-)"..dir.."(.*)$")
+ return a~="" and a or name
+ end
end
function lfs.mkdirs(path)
- local full=""
- for sub in gmatch(path,"(/*[^\\/]+)") do
- full=full..sub
- lfs.mkdir(full)
- end
+ local full=""
+ for sub in gmatch(path,"(/*[^\\/]+)") do
+ full=full..sub
+ lfs.mkdir(full)
+ end
end
function file.withinbase(path)
- local l=0
- if not find(path,"^/") then
- path="/"..path
- end
- for dir in gmatch(path,"/([^/]+)") do
- if dir==".." then
- l=l-1
- elseif dir~="." then
- l=l+1
- end
- if l<0 then
- return false
- end
- end
- return true
+ local l=0
+ if not find(path,"^/") then
+ path="/"..path
+ end
+ for dir in gmatch(path,"/([^/]+)") do
+ if dir==".." then
+ l=l-1
+ elseif dir~="." then
+ l=l+1
+ end
+ if l<0 then
+ return false
+ end
+ end
+ return true
end
local symlinkattributes=lfs.symlinkattributes
function lfs.readlink(name)
- return symlinkattributes(name,"target") or nil
+ return symlinkattributes(name,"target") or nil
end
@@ -4467,51 +4467,51 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-gzip"] = package.loaded["l-gzip"] or true
--- original size: 1211, stripped down to: 1002
+-- original size: 1211, stripped down to: 951
if not modules then modules={} end modules ['l-gzip']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not gzip then
- return
+ return
end
local suffix,suffixes=file.suffix,file.suffixes
function gzip.load(filename)
- local f=io.open(filename,"rb")
- if not f then
- elseif suffix(filename)=="gz" then
- f:close()
- local g=gzip.open(filename,"rb")
- if g then
- local str=g:read("*all")
- g:close()
- return str
- end
- else
- local str=f:read("*all")
- f:close()
- return str
- end
+ local f=io.open(filename,"rb")
+ if not f then
+ elseif suffix(filename)=="gz" then
+ f:close()
+ local g=gzip.open(filename,"rb")
+ if g then
+ local str=g:read("*all")
+ g:close()
+ return str
+ end
+ else
+ local str=f:read("*all")
+ f:close()
+ return str
+ end
end
function gzip.save(filename,data)
- if suffix(filename)~="gz" then
- filename=filename..".gz"
- end
- local f=io.open(filename,"wb")
- if f then
- local s=zlib.compress(data or "",9,nil,15+16)
- f:write(s)
- f:close()
- return #s
- end
+ if suffix(filename)~="gz" then
+ filename=filename..".gz"
+ end
+ local f=io.open(filename,"wb")
+ if f then
+ local s=zlib.compress(data or "",9,nil,15+16)
+ f:write(s)
+ f:close()
+ return #s
+ end
end
function gzip.suffix(filename)
- local suffix,extra=suffixes(filename)
- local gzipped=extra=="gz"
- return suffix,gzipped
+ local suffix,extra=suffixes(filename)
+ local gzipped=extra=="gz"
+ return suffix,gzipped
end
@@ -4521,87 +4521,87 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-md5"] = package.loaded["l-md5"] or true
--- original size: 3309, stripped down to: 2314
+-- original size: 3309, stripped down to: 2218
if not modules then modules={} end modules ['l-md5']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not md5 then
- md5=optionalrequire("md5")
+ md5=optionalrequire("md5")
end
if not md5 then
- md5={
- sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
- sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
- }
+ md5={
+ sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
+ sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
+ }
end
local md5,file=md5,file
local gsub=string.gsub
do
- local patterns=lpeg and lpeg.patterns
- if patterns then
- local bytestoHEX=patterns.bytestoHEX
- local bytestohex=patterns.bytestohex
- local bytestodec=patterns.bytestodec
- local lpegmatch=lpeg.match
- local md5sum=md5.sum
- if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
- if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
- if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
- md5.sumhexa=md5.hex
- md5.sumHEXA=md5.HEX
- end
+ local patterns=lpeg and lpeg.patterns
+ if patterns then
+ local bytestoHEX=patterns.bytestoHEX
+ local bytestohex=patterns.bytestohex
+ local bytestodec=patterns.bytestodec
+ local lpegmatch=lpeg.match
+ local md5sum=md5.sum
+ if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
+ if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
+ if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
+ md5.sumhexa=md5.hex
+ md5.sumHEXA=md5.HEX
+ end
end
function file.needsupdating(oldname,newname,threshold)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime then
- local newtime=lfs.attributes(newname,"modification")
- if not newtime then
- return true
- elseif newtime>=oldtime then
- return false
- elseif oldtime-newtime<(threshold or 1) then
- return false
- else
- return true
- end
- else
- return false
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime then
+ local newtime=lfs.attributes(newname,"modification")
+ if not newtime then
+ return true
+ elseif newtime>=oldtime then
+ return false
+ elseif oldtime-newtime<(threshold or 1) then
+ return false
+ else
+ return true
+ end
+ else
+ return false
+ end
end
file.needs_updating=file.needsupdating
function file.syncmtimes(oldname,newname)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime and lfs.isfile(newname) then
- lfs.touch(newname,oldtime,oldtime)
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime and lfs.isfile(newname) then
+ lfs.touch(newname,oldtime,oldtime)
+ end
end
function file.checksum(name)
- if md5 then
- local data=io.loaddata(name)
- if data then
- return md5.HEX(data)
- end
+ if md5 then
+ local data=io.loaddata(name)
+ if data then
+ return md5.HEX(data)
end
- return nil
+ end
+ return nil
end
function file.loadchecksum(name)
- if md5 then
- local data=io.loaddata(name..".md5")
- return data and (gsub(data,"%s",""))
- end
- return nil
+ if md5 then
+ local data=io.loaddata(name..".md5")
+ return data and (gsub(data,"%s",""))
+ end
+ return nil
end
function file.savechecksum(name,checksum)
- if not checksum then checksum=file.checksum(name) end
- if checksum then
- io.savedata(name..".md5",checksum)
- return checksum
- end
- return nil
+ if not checksum then checksum=file.checksum(name) end
+ if checksum then
+ io.savedata(name..".md5",checksum)
+ return checksum
+ end
+ return nil
end
@@ -4611,29 +4611,29 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-sha"] = package.loaded["l-sha"] or true
--- original size: 1085, stripped down to: 987
+-- original size: 1085, stripped down to: 969
if not modules then modules={} end modules ['l-sha']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if sha2 then
- local lpegmatch=lpeg.match
- local lpegpatterns=lpeg.patterns
- local bytestohex=lpegpatterns.bytestohex
- local bytestoHEX=lpegpatterns.bytestoHEX
- local digest256=sha2.digest256
- local digest384=sha2.digest384
- local digest512=sha2.digest512
- sha2.hash256=function(str) return lpegmatch(bytestohex,digest256(str)) end
- sha2.hash384=function(str) return lpegmatch(bytestohex,digest384(str)) end
- sha2.hash512=function(str) return lpegmatch(bytestohex,digest512(str)) end
- sha2.HASH256=function(str) return lpegmatch(bytestoHEX,digest256(str)) end
- sha2.HASH384=function(str) return lpegmatch(bytestoHEX,digest384(str)) end
- sha2.HASH512=function(str) return lpegmatch(bytestoHEX,digest512(str)) end
+ local lpegmatch=lpeg.match
+ local lpegpatterns=lpeg.patterns
+ local bytestohex=lpegpatterns.bytestohex
+ local bytestoHEX=lpegpatterns.bytestoHEX
+ local digest256=sha2.digest256
+ local digest384=sha2.digest384
+ local digest512=sha2.digest512
+ sha2.hash256=function(str) return lpegmatch(bytestohex,digest256(str)) end
+ sha2.hash384=function(str) return lpegmatch(bytestohex,digest384(str)) end
+ sha2.hash512=function(str) return lpegmatch(bytestohex,digest512(str)) end
+ sha2.HASH256=function(str) return lpegmatch(bytestoHEX,digest256(str)) end
+ sha2.HASH384=function(str) return lpegmatch(bytestoHEX,digest384(str)) end
+ sha2.HASH512=function(str) return lpegmatch(bytestoHEX,digest512(str)) end
end
@@ -4643,14 +4643,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-url"] = package.loaded["l-url"] or true
--- original size: 14755, stripped down to: 7236
+-- original size: 14755, stripped down to: 6981
if not modules then modules={} end modules ['l-url']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local char,format,byte=string.char,string.format,string.byte
local concat=table.concat
@@ -4663,14 +4663,14 @@ local url=url
local unescapes={}
local escapes={}
setmetatable(unescapes,{ __index=function(t,k)
- local v=char(tonumber(k,16))
- t[k]=v
- return v
+ local v=char(tonumber(k,16))
+ t[k]=v
+ return v
end })
setmetatable(escapes,{ __index=function(t,k)
- local v=format("%%%02X",byte(k))
- t[k]=v
- return v
+ local v=format("%%%02X",byte(k))
+ t[k]=v
+ return v
end })
local colon=P(":")
local qmark=P("?")
@@ -4689,21 +4689,21 @@ local escaped=(plus/" ")+escapedchar
local noslash=P("/")/""
local plustospace=P("+")/" "
local decoder=Cs((
- plustospace+escapedchar+P("\r\n")/"\n"+P(1)
- )^0 )
+ plustospace+escapedchar+P("\r\n")/"\n"+P(1)
+ )^0 )
local encoder=Cs((
- R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
- )^0 )
+ R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
+ )^0 )
lpegpatterns.urldecoder=decoder
lpegpatterns.urlencoder=encoder
-function url.decode (str) return str and lpegmatch(decoder,str) or str end
-function url.encode (str) return str and lpegmatch(encoder,str) or str end
+function url.decode (str) return str and lpegmatch(decoder,str) or str end
+function url.encode (str) return str and lpegmatch(encoder,str) or str end
function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2)
local authoritystr=Cs((escaped+(1- slash-qmark-hash))^0)
-local pathstr=Cs((escaped+(1- qmark-hash))^0)
-local querystr=Cs(((1- hash))^0)
-local fragmentstr=Cs((escaped+(1- endofstring))^0)
+local pathstr=Cs((escaped+(1- qmark-hash))^0)
+local querystr=Cs(((1- hash))^0)
+local fragmentstr=Cs((escaped+(1- endofstring))^0)
local scheme=schemestr*colon+nothing
local authority=slash*slash*authoritystr+nothing
local path=slash*pathstr+nothing
@@ -4721,19 +4721,19 @@ lpegpatterns.urlescaper=escaper
lpegpatterns.urlunescaper=unescaper
lpegpatterns.urlgetcleaner=getcleaner
function url.unescapeget(str)
- return lpegmatch(getcleaner,str)
+ return lpegmatch(getcleaner,str)
end
local function split(str)
- return (type(str)=="string" and lpegmatch(parser,str)) or str
+ return (type(str)=="string" and lpegmatch(parser,str)) or str
end
local isscheme=schemestr*colon*slash*slash
local function hasscheme(str)
- if str then
- local scheme=lpegmatch(isscheme,str)
- return scheme~="" and scheme or false
- else
- return false
- end
+ if str then
+ local scheme=lpegmatch(isscheme,str)
+ return scheme~="" and scheme or false
+ else
+ return false
+ end
end
local rootletter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -4743,161 +4743,161 @@ local barswapper=replacer("|",":")
local backslashswapper=replacer("\\","/")
local equal=P("=")
local amp=P("&")
-local key=Cs(((plustospace+escapedchar+1)-equal )^0)
+local key=Cs(((plustospace+escapedchar+1)-equal )^0)
local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0)
local splitquery=Cf (Ct("")*P { "sequence",
- sequence=V("pair")*(amp*V("pair"))^0,
- pair=Cg(key*equal*value),
+ sequence=V("pair")*(amp*V("pair"))^0,
+ pair=Cg(key*equal*value),
},rawset)
local userpart=(1-atsign-colon)^1
local serverpart=(1-colon)^1
local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil))
local function hashed(str)
- if not str or str=="" then
- return {
- scheme="invalid",
- original=str,
- }
- end
- local detailed=split(str)
- local rawscheme=""
- local rawquery=""
- local somescheme=false
- local somequery=false
- if detailed then
- rawscheme=detailed[1]
- rawquery=detailed[4]
- somescheme=rawscheme~=""
- somequery=rawquery~=""
- end
- if not somescheme and not somequery then
- return {
- scheme="file",
- authority="",
- path=str,
- query="",
- fragment="",
- original=str,
- noscheme=true,
- filename=str,
- }
- end
- local authority=detailed[2]
- local path=detailed[3]
- local filename
- local username
- local password
- local host
- local port
- if authority~="" then
- username,password,host,port=lpegmatch(splitauthority,authority)
- end
- if authority=="" then
- filename=path
- elseif path=="" then
- filename=""
- else
- filename=authority.."/"..path
- end
+ if not str or str=="" then
return {
- scheme=rawscheme,
- authority=authority,
- path=path,
- query=lpegmatch(unescaper,rawquery),
- queries=lpegmatch(splitquery,rawquery),
- fragment=detailed[5],
- original=str,
- noscheme=false,
- filename=filename,
- host=host,
- port=port,
+ scheme="invalid",
+ original=str,
+ }
+ end
+ local detailed=split(str)
+ local rawscheme=""
+ local rawquery=""
+ local somescheme=false
+ local somequery=false
+ if detailed then
+ rawscheme=detailed[1]
+ rawquery=detailed[4]
+ somescheme=rawscheme~=""
+ somequery=rawquery~=""
+ end
+ if not somescheme and not somequery then
+ return {
+ scheme="file",
+ authority="",
+ path=str,
+ query="",
+ fragment="",
+ original=str,
+ noscheme=true,
+ filename=str,
}
+ end
+ local authority=detailed[2]
+ local path=detailed[3]
+ local filename
+ local username
+ local password
+ local host
+ local port
+ if authority~="" then
+ username,password,host,port=lpegmatch(splitauthority,authority)
+ end
+ if authority=="" then
+ filename=path
+ elseif path=="" then
+ filename=""
+ else
+ filename=authority.."/"..path
+ end
+ return {
+ scheme=rawscheme,
+ authority=authority,
+ path=path,
+ query=lpegmatch(unescaper,rawquery),
+ queries=lpegmatch(splitquery,rawquery),
+ fragment=detailed[5],
+ original=str,
+ noscheme=false,
+ filename=filename,
+ host=host,
+ port=port,
+ }
end
url.split=split
url.hasscheme=hasscheme
url.hashed=hashed
function url.addscheme(str,scheme)
- if hasscheme(str) then
- return str
- elseif not scheme then
- return "file:///"..str
- else
- return scheme..":///"..str
- end
+ if hasscheme(str) then
+ return str
+ elseif not scheme then
+ return "file:///"..str
+ else
+ return scheme..":///"..str
+ end
end
function url.construct(hash)
- local result,r={},0
- local scheme=hash.scheme
- local authority=hash.authority
- local path=hash.path
- local queries=hash.queries
- local fragment=hash.fragment
- if scheme and scheme~="" then
- r=r+1;result[r]=lpegmatch(escaper,scheme)
- r=r+1;result[r]="://"
- end
- if authority and authority~="" then
- r=r+1;result[r]=lpegmatch(escaper,authority)
- end
- if path and path~="" then
- r=r+1;result[r]="/"
- r=r+1;result[r]=lpegmatch(escaper,path)
- end
- if queries then
- local done=false
- for k,v in sortedhash(queries) do
- r=r+1;result[r]=done and "&" or "?"
- r=r+1;result[r]=lpegmatch(escaper,k)
- r=r+1;result[r]="="
- r=r+1;result[r]=lpegmatch(escaper,v)
- done=true
- end
- end
- if fragment and fragment~="" then
- r=r+1;result[r]="#"
- r=r+1;result[r]=lpegmatch(escaper,fragment)
- end
- return concat(result)
+ local result,r={},0
+ local scheme=hash.scheme
+ local authority=hash.authority
+ local path=hash.path
+ local queries=hash.queries
+ local fragment=hash.fragment
+ if scheme and scheme~="" then
+ r=r+1;result[r]=lpegmatch(escaper,scheme)
+ r=r+1;result[r]="://"
+ end
+ if authority and authority~="" then
+ r=r+1;result[r]=lpegmatch(escaper,authority)
+ end
+ if path and path~="" then
+ r=r+1;result[r]="/"
+ r=r+1;result[r]=lpegmatch(escaper,path)
+ end
+ if queries then
+ local done=false
+ for k,v in sortedhash(queries) do
+ r=r+1;result[r]=done and "&" or "?"
+ r=r+1;result[r]=lpegmatch(escaper,k)
+ r=r+1;result[r]="="
+ r=r+1;result[r]=lpegmatch(escaper,v)
+ done=true
+ end
+ end
+ if fragment and fragment~="" then
+ r=r+1;result[r]="#"
+ r=r+1;result[r]=lpegmatch(escaper,fragment)
+ end
+ return concat(result)
end
local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0)
function url.filename(filename)
- local spec=hashed(filename)
- local path=spec.path
- return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
+ local spec=hashed(filename)
+ local path=spec.path
+ return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
end
local function escapestring(str)
- return lpegmatch(escaper,str)
+ return lpegmatch(escaper,str)
end
url.escape=escapestring
function url.query(str)
- if type(str)=="string" then
- return lpegmatch(splitquery,str) or ""
- else
- return str
- end
+ if type(str)=="string" then
+ return lpegmatch(splitquery,str) or ""
+ else
+ return str
+ end
end
function url.toquery(data)
- local td=type(data)
- if td=="string" then
- return #str and escape(data) or nil
- elseif td=="table" then
- if next(data) then
- local t={}
- for k,v in next,data do
- t[#t+1]=format("%s=%s",k,escapestring(v))
- end
- return concat(t,"&")
- end
- else
+ local td=type(data)
+ if td=="string" then
+ return #str and escape(data) or nil
+ elseif td=="table" then
+ if next(data) then
+ local t={}
+ for k,v in next,data do
+ t[#t+1]=format("%s=%s",k,escapestring(v))
+ end
+ return concat(t,"&")
end
+ else
+ end
end
local pattern=Cs(noslash^0*(1-noslash*P(-1))^0)
function url.barepath(path)
- if not path or path=="" then
- return ""
- else
- return lpegmatch(pattern,path)
- end
+ if not path or path=="" then
+ return ""
+ else
+ return lpegmatch(pattern,path)
+ end
end
@@ -4907,14 +4907,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-dir"] = package.loaded["l-dir"] or true
--- original size: 18002, stripped down to: 11863
+-- original size: 18002, stripped down to: 10681
if not modules then modules={} end modules ['l-dir']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,select=type,select
local find,gmatch,match,gsub,sub=string.find,string.gmatch,string.match,string.gsub,string.sub
@@ -4926,478 +4926,478 @@ local dir=dir
local lfs=lfs
local attributes=lfs.attributes
local walkdir=lfs.dir
-local isdir=lfs.isdir
+local isdir=lfs.isdir
local isfile=lfs.isfile
local currentdir=lfs.currentdir
local chdir=lfs.chdir
local mkdir=lfs.mkdir
local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true)
if onwindows then
- local tricky=S("/\\")*P(-1)
- isdir=function(name)
- if lpegmatch(tricky,name) then
- return attributes(name,"mode")=="directory"
- else
- return attributes(name.."/.","mode")=="directory"
- end
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ local tricky=S("/\\")*P(-1)
+ isdir=function(name)
+ if lpegmatch(tricky,name) then
+ return attributes(name,"mode")=="directory"
+ else
+ return attributes(name.."/.","mode")=="directory"
+ end
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
else
- isdir=function(name)
- return attributes(name,"mode")=="directory"
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ isdir=function(name)
+ return attributes(name,"mode")=="directory"
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
end
function dir.current()
- return (gsub(currentdir(),"\\","/"))
+ return (gsub(currentdir(),"\\","/"))
end
local function glob_pattern_function(path,patt,recurse,action)
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- local nofdirs=0
- for name in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- action(full)
- end
- elseif recurse and mode=="directory" then
- if dirs then
- nofdirs=nofdirs+1
- dirs[nofdirs]=full
- else
- nofdirs=1
- dirs={ full }
- end
- end
- end
- end
- if dirs then
- for i=1,nofdirs do
- glob_pattern_function(dirs[i],patt,recurse,action)
- end
- end
- end
-end
-local function glob_pattern_table(path,patt,recurse,result)
- if not result then
- result={}
- end
+ if isdir(path) then
local usedpath
if path=="/" then
- usedpath="/."
+ usedpath="/."
elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
+ usedpath=path.."/."
+ path=path.."/"
else
- usedpath=path
+ usedpath=path
end
local dirs
local nofdirs=0
- local noffiles=#result
- for name,a in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- noffiles=noffiles+1
- result[noffiles]=full
- end
- elseif recurse and mode=="directory" then
- if dirs then
- nofdirs=nofdirs+1
- dirs[nofdirs]=full
- else
- nofdirs=1
- dirs={ full }
- end
- end
+ for name in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ action(full)
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
end
+ end
end
if dirs then
- for i=1,nofdirs do
- glob_pattern_table(dirs[i],patt,recurse,result)
- end
+ for i=1,nofdirs do
+ glob_pattern_function(dirs[i],patt,recurse,action)
+ end
end
- return result
+ end
end
-local function globpattern(path,patt,recurse,method)
- local kind=type(method)
- if patt and sub(patt,1,-3)==path then
- patt=false
+local function glob_pattern_table(path,patt,recurse,result)
+ if not result then
+ result={}
+ end
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ local noffiles=#result
+ for name,a in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ noffiles=noffiles+1
+ result[noffiles]=full
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
+ end
end
- local okay=isdir(path)
- if kind=="function" then
- return okay and glob_pattern_function(path,patt,recurse,method) or {}
- elseif kind=="table" then
- return okay and glob_pattern_table(path,patt,recurse,method) or method
- else
- return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_table(dirs[i],patt,recurse,result)
end
+ end
+ return result
+end
+local function globpattern(path,patt,recurse,method)
+ local kind=type(method)
+ if patt and sub(patt,1,-3)==path then
+ patt=false
+ end
+ local okay=isdir(path)
+ if kind=="function" then
+ return okay and glob_pattern_function(path,patt,recurse,method) or {}
+ elseif kind=="table" then
+ return okay and glob_pattern_table(path,patt,recurse,method) or method
+ else
+ return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
end
dir.globpattern=globpattern
local function collectpattern(path,patt,recurse,result)
- local ok,scanner
- result=result or {}
- if path=="/" then
- ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
- else
- ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
- end
- if ok and type(scanner)=="function" then
- if not find(path,"/$") then
- path=path..'/'
- end
- for name in scanner,first do
- if name=="." then
- elseif name==".." then
- else
- local full=path..name
- local attr=attributes(full)
- local mode=attr.mode
- if mode=='file' then
- if find(full,patt) then
- result[name]=attr
- end
- elseif recurse and mode=="directory" then
- attr.list=collectpattern(full,patt,recurse)
- result[name]=attr
- end
- end
+ local ok,scanner
+ result=result or {}
+ if path=="/" then
+ ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
+ else
+ ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
+ end
+ if ok and type(scanner)=="function" then
+ if not find(path,"/$") then
+ path=path..'/'
+ end
+ for name in scanner,first do
+ if name=="." then
+ elseif name==".." then
+ else
+ local full=path..name
+ local attr=attributes(full)
+ local mode=attr.mode
+ if mode=='file' then
+ if find(full,patt) then
+ result[name]=attr
+ end
+ elseif recurse and mode=="directory" then
+ attr.list=collectpattern(full,patt,recurse)
+ result[name]=attr
end
+ end
end
- return result
+ end
+ return result
end
dir.collectpattern=collectpattern
local separator,pattern
if onwindows then
- local slash=S("/\\")/"/"
- pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
- }
+ local slash=S("/\\")/"/"
+ pattern={
+ [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
+ [3]=Cs(P(1)^0)
+ }
else
- pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
- }
+ pattern={
+ [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ [2]=C(((1-S("*?/"))^0*P("/"))^0),
+ [3]=C(P(1)^0)
+ }
end
local filter=Cs ((
- P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
+ P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
)^0 )
local function glob(str,t)
- if type(t)=="function" then
- if type(str)=="table" then
- for s=1,#str do
- glob(str[s],t)
- end
- elseif isfile(str) then
- t(str)
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- globpattern(start,result,recurse,t)
- end
- end
+ if type(t)=="function" then
+ if type(str)=="table" then
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ elseif isfile(str) then
+ t(str)
+ else
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ globpattern(start,result,recurse,t)
+ end
+ end
+ else
+ if type(str)=="table" then
+ local t=t or {}
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ return t
+ elseif isfile(str) then
+ if t then
+ t[#t+1]=str
+ return t
+ else
+ return { str }
+ end
else
- if type(str)=="table" then
- local t=t or {}
- for s=1,#str do
- glob(str[s],t)
- end
- return t
- elseif isfile(str) then
- if t then
- t[#t+1]=str
- return t
- else
- return { str }
- end
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- return globpattern(start,result,recurse,t)
- else
- return {}
- end
- end
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ return globpattern(start,result,recurse,t)
+ else
+ return {}
+ end
end
+ end
end
dir.glob=glob
local function globfiles(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if recurse then
- globfiles(path.."/"..name,recurse,func,files)
- end
- elseif mode=="file" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if recurse then
+ globfiles(path.."/"..name,recurse,func,files)
+ end
+ elseif mode=="file" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
end
+ end
end
- return files
+ end
+ return files
end
dir.globfiles=globfiles
local function globdirs(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- if recurse then
- globdirs(path.."/"..name,recurse,func,files)
- end
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
+ if recurse then
+ globdirs(path.."/"..name,recurse,func,files)
+ end
end
+ end
end
- return files
+ end
+ return files
end
dir.globdirs=globdirs
function dir.ls(pattern)
- return concat(glob(pattern),"\n")
+ return concat(glob(pattern),"\n")
end
local make_indeed=true
if onwindows then
- function dir.mkdirs(...)
- local n=select("#",...)
- local str
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s=="" then
+ elseif str=="" then
+ str=s
else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s=="" then
- elseif str=="" then
- str=s
- else
- str=str.."/"..s
- end
- end
+ str=str.."/"..s
end
- local pth=""
- local drive=false
- local first,middle,last=match(str,"^(//)(//*)(.*)$")
- if first then
+ end
+ end
+ local pth=""
+ local drive=false
+ local first,middle,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ else
+ first,last=match(str,"^(//)/*(.-)$")
+ if first then
+ middle,last=match(str,"([^/]+)/+(.-)$")
+ if middle then
+ pth="//"..middle
else
- first,last=match(str,"^(//)/*(.-)$")
- if first then
- middle,last=match(str,"([^/]+)/+(.-)$")
- if middle then
- pth="//"..middle
- else
- pth="//"..last
- last=""
- end
- else
- first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
- if first then
- pth,drive=first..middle,true
- else
- middle,last=match(str,"^(/*)(.-)$")
- if not middle then
- last=str
- end
- end
- end
+ pth="//"..last
+ last=""
end
- for s in gmatch(last,"[^/]+") do
- if pth=="" then
- pth=s
- elseif drive then
- pth,drive=pth..s,false
- else
- pth=pth.."/"..s
- end
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
+ else
+ first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
+ if first then
+ pth,drive=first..middle,true
+ else
+ middle,last=match(str,"^(/*)(.-)$")
+ if not middle then
+ last=str
+ end
end
- return pth,(isdir(pth)==true)
+ end
end
+ for s in gmatch(last,"[^/]+") do
+ if pth=="" then
+ pth=s
+ elseif drive then
+ pth,drive=pth..s,false
+ else
+ pth=pth.."/"..s
+ end
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ return pth,(isdir(pth)==true)
+ end
else
- function dir.mkdirs(...)
- local n=select("#",...)
- local str,pth
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
- else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s and s~="" then
- if str~="" then
- str=str.."/"..s
- else
- str=s
- end
- end
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str,pth
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s and s~="" then
+ if str~="" then
+ str=str.."/"..s
+ else
+ str=s
+ end
end
- str=gsub(str,"/+","/")
- if find(str,"^/") then
- pth="/"
- for s in gmatch(str,"[^/]+") do
- local first=(pth=="/")
- if first then
- pth=pth..s
- else
- pth=pth.."/"..s
- end
- if make_indeed and not first and not isdir(pth) then
- mkdir(pth)
- end
- end
+ end
+ end
+ str=gsub(str,"/+","/")
+ if find(str,"^/") then
+ pth="/"
+ for s in gmatch(str,"[^/]+") do
+ local first=(pth=="/")
+ if first then
+ pth=pth..s
else
- pth="."
- for s in gmatch(str,"[^/]+") do
- pth=pth.."/"..s
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
- end
+ pth=pth.."/"..s
+ end
+ if make_indeed and not first and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ else
+ pth="."
+ for s in gmatch(str,"[^/]+") do
+ pth=pth.."/"..s
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
end
- return pth,(isdir(pth)==true)
+ end
end
+ return pth,(isdir(pth)==true)
+ end
end
dir.makedirs=dir.mkdirs
do
- local chdir=sandbox and sandbox.original(chdir) or chdir
- if onwindows then
- local xcurrentdir=dir.current
- function dir.expandname(str)
- local first,nothing,last=match(str,"^(//)(//*)(.*)$")
- if first then
- first=xcurrentdir().."/"
- end
- if not first then
- first,last=match(str,"^(//)/*(.*)$")
- end
- if not first then
- first,last=match(str,"^([a-zA-Z]:)(.*)$")
- if first and not find(last,"^/") then
- local d=currentdir()
- if chdir(first) then
- first=xcurrentdir()
- end
- chdir(d)
- end
- end
- if not first then
- first,last=xcurrentdir(),str
- end
- last=gsub(last,"//","/")
- last=gsub(last,"/%./","/")
- last=gsub(last,"^/*","")
- first=gsub(first,"/*$","")
- if last=="" or last=="." then
- return first
- else
- return first.."/"..last
- end
- end
- else
- function dir.expandname(str)
- if not find(str,"^/") then
- str=currentdir().."/"..str
- end
- str=gsub(str,"//","/")
- str=gsub(str,"/%./","/")
- str=gsub(str,"(.)/%.$","%1")
- return str
+ local chdir=sandbox and sandbox.original(chdir) or chdir
+ if onwindows then
+ local xcurrentdir=dir.current
+ function dir.expandname(str)
+ local first,nothing,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ first=xcurrentdir().."/"
+ end
+ if not first then
+ first,last=match(str,"^(//)/*(.*)$")
+ end
+ if not first then
+ first,last=match(str,"^([a-zA-Z]:)(.*)$")
+ if first and not find(last,"^/") then
+ local d=currentdir()
+ if chdir(first) then
+ first=xcurrentdir()
+ end
+ chdir(d)
end
+ end
+ if not first then
+ first,last=xcurrentdir(),str
+ end
+ last=gsub(last,"//","/")
+ last=gsub(last,"/%./","/")
+ last=gsub(last,"^/*","")
+ first=gsub(first,"/*$","")
+ if last=="" or last=="." then
+ return first
+ else
+ return first.."/"..last
+ end
+ end
+ else
+ function dir.expandname(str)
+ if not find(str,"^/") then
+ str=currentdir().."/"..str
+ end
+ str=gsub(str,"//","/")
+ str=gsub(str,"/%./","/")
+ str=gsub(str,"(.)/%.$","%1")
+ return str
end
+ end
end
file.expandname=dir.expandname
local stack={}
function dir.push(newdir)
- local curdir=currentdir()
- insert(stack,curdir)
- if newdir and newdir~="" then
- chdir(newdir)
- return newdir
- else
- return curdir
- end
+ local curdir=currentdir()
+ insert(stack,curdir)
+ if newdir and newdir~="" then
+ chdir(newdir)
+ return newdir
+ else
+ return curdir
+ end
end
function dir.pop()
- local d=remove(stack)
- if d then
- chdir(d)
- end
- return d
+ local d=remove(stack)
+ if d then
+ chdir(d)
+ end
+ return d
end
local function found(...)
- for i=1,select("#",...) do
- local path=select(i,...)
- local kind=type(path)
- if kind=="string" then
- if isdir(path) then
- return path
- end
- elseif kind=="table" then
- local path=found(unpack(path))
- if path then
- return path
- end
- end
+ for i=1,select("#",...) do
+ local path=select(i,...)
+ local kind=type(path)
+ if kind=="string" then
+ if isdir(path) then
+ return path
+ end
+ elseif kind=="table" then
+ local path=found(unpack(path))
+ if path then
+ return path
+ end
end
+ end
end
dir.found=found
@@ -5408,69 +5408,69 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-boolean"] = package.loaded["l-boolean"] or true
--- original size: 1850, stripped down to: 1568
+-- original size: 1850, stripped down to: 1498
if not modules then modules={} end modules ['l-boolean']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber=type,tonumber
boolean=boolean or {}
local boolean=boolean
function boolean.tonumber(b)
- if b then return 1 else return 0 end
+ if b then return 1 else return 0 end
end
function toboolean(str,tolerant)
- if str==nil then
- return false
- elseif str==false then
- return false
- elseif str==true then
- return true
- elseif str=="true" then
- return true
- elseif str=="false" then
- return false
- elseif not tolerant then
- return false
- elseif str==0 then
- return false
- elseif (tonumber(str) or 0)>0 then
- return true
- else
- return str=="yes" or str=="on" or str=="t"
- end
+ if str==nil then
+ return false
+ elseif str==false then
+ return false
+ elseif str==true then
+ return true
+ elseif str=="true" then
+ return true
+ elseif str=="false" then
+ return false
+ elseif not tolerant then
+ return false
+ elseif str==0 then
+ return false
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
end
string.toboolean=toboolean
function string.booleanstring(str)
- if str=="0" then
- return false
- elseif str=="1" then
- return true
- elseif str=="" then
- return false
- elseif str=="false" then
- return false
- elseif str=="true" then
- return true
- elseif (tonumber(str) or 0)>0 then
- return true
- else
- return str=="yes" or str=="on" or str=="t"
- end
+ if str=="0" then
+ return false
+ elseif str=="1" then
+ return true
+ elseif str=="" then
+ return false
+ elseif str=="false" then
+ return false
+ elseif str=="true" then
+ return true
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
end
function string.is_boolean(str,default,strict)
- if type(str)=="string" then
- if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
- return true
- elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
- return false
- end
+ if type(str)=="string" then
+ if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
+ return true
+ elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
+ return false
end
- return default
+ end
+ return default
end
@@ -5480,22 +5480,22 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 41047, stripped down to: 18594
+-- original size: 41047, stripped down to: 17171
if not modules then modules={} end modules ['l-unicode']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utf=utf or {}
unicode=nil
if not string.utfcharacters then
- local gmatch=string.gmatch
- function string.characters(str)
- return gmatch(str,".[\128-\191]*")
- end
+ local gmatch=string.gmatch
+ function string.characters(str)
+ return gmatch(str,".[\128-\191]*")
+ end
end
utf.characters=string.utfcharacters
local type=type
@@ -5518,304 +5518,304 @@ local p_utfbom=patterns.utfbom
local p_newline=patterns.newline
local p_whitespace=patterns.whitespace
if not utf.char then
- utf.char=string.utfcharacter or (utf8 and utf8.char)
- if not utf.char then
- local char=string.char
- if bit32 then
- local rshift=bit32.rshift
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+rshift(n,6),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+rshift(n,12),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+rshift(n,18),
- 0x80+(rshift(n,12)%0x40),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
+ utf.char=string.utfcharacter or (utf8 and utf8.char)
+ if not utf.char then
+ local char=string.char
+ if bit32 then
+ local rshift=bit32.rshift
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+rshift(n,6),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+rshift(n,12),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+rshift(n,18),
+ 0x80+(rshift(n,12)%0x40),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
else
- local floor=math.floor
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+floor(n/0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+floor(n/0x1000),
- 0x80+(floor(n/0x40)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+floor(n/0x40000),
- 0x80+(floor(n/0x1000)%0x40),
- 0x80+(floor(n/0x40)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
+ return ""
+ end
+ end
+ else
+ local floor=math.floor
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+floor(n/0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+floor(n/0x1000),
+ 0x80+(floor(n/0x40)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+floor(n/0x40000),
+ 0x80+(floor(n/0x1000)%0x40),
+ 0x80+(floor(n/0x40)%0x40),
+ 0x80+(n%0x40)
+ )
+ else
+ return ""
end
+ end
end
+ end
end
if not utf.byte then
- utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
- if not utf.byte then
- function utf.byte(c)
- return lpegmatch(p_utf8byte,c)
- end
+ utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
+ if not utf.byte then
+ function utf.byte(c)
+ return lpegmatch(p_utf8byte,c)
end
+ end
end
local utfchar,utfbyte=utf.char,utf.byte
function utf.filetype(data)
- return data and lpegmatch(p_utftype,data) or "unknown"
+ return data and lpegmatch(p_utftype,data) or "unknown"
end
local toentities=Cs (
- (
- patterns.utf8one+(
- patterns.utf8two+patterns.utf8three+patterns.utf8four
- )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
- )^0
+ (
+ patterns.utf8one+(
+ patterns.utf8two+patterns.utf8three+patterns.utf8four
+ )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
+ )^0
)
patterns.toentities=toentities
function utf.toentities(str)
- return lpegmatch(toentities,str)
+ return lpegmatch(toentities,str)
end
local one=P(1)
local two=C(1)*C(1)
local four=C(R(utfchar(0xD8),utfchar(0xFF)))*C(1)*C(1)*C(1)
local pattern=P("\254\255")*Cs((
- four/function(a,b,c,d)
- local ab=0xFF*byte(a)+byte(b)
- local cd=0xFF*byte(c)+byte(d)
- return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
- end+two/function(a,b)
- return utfchar(byte(a)*256+byte(b))
- end+one
- )^1 )+P("\255\254")*Cs((
- four/function(b,a,d,c)
- local ab=0xFF*byte(a)+byte(b)
- local cd=0xFF*byte(c)+byte(d)
- return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
- end+two/function(b,a)
- return utfchar(byte(a)*256+byte(b))
- end+one
- )^1 )
+ four/function(a,b,c,d)
+ local ab=0xFF*byte(a)+byte(b)
+ local cd=0xFF*byte(c)+byte(d)
+ return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+ end+two/function(a,b)
+ return utfchar(byte(a)*256+byte(b))
+ end+one
+ )^1 )+P("\255\254")*Cs((
+ four/function(b,a,d,c)
+ local ab=0xFF*byte(a)+byte(b)
+ local cd=0xFF*byte(c)+byte(d)
+ return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+ end+two/function(b,a)
+ return utfchar(byte(a)*256+byte(b))
+ end+one
+ )^1 )
function string.toutf(s)
- return lpegmatch(pattern,s) or s
+ return lpegmatch(pattern,s) or s
end
local validatedutf=Cs (
- (
- patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
- )^0
+ (
+ patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
+ )^0
)
patterns.validatedutf=validatedutf
function utf.is_valid(str)
- return type(str)=="string" and lpegmatch(validatedutf,str) or false
+ return type(str)=="string" and lpegmatch(validatedutf,str) or false
end
if not utf.len then
- utf.len=string.utflength or (utf8 and utf8.len)
- if not utf.len then
- local n,f=0,1
- local utfcharcounter=patterns.utfbom^-1*Cmt (
- Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
- function(_,t,d)
- n=n+(t-f)/d
- f=t
- return true
- end
- )^0
- function utf.len(str)
- n,f=0,1
- lpegmatch(utfcharcounter,str or "")
- return n
- end
+ utf.len=string.utflength or (utf8 and utf8.len)
+ if not utf.len then
+ local n,f=0,1
+ local utfcharcounter=patterns.utfbom^-1*Cmt (
+ Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
+ function(_,t,d)
+ n=n+(t-f)/d
+ f=t
+ return true
+ end
+ )^0
+ function utf.len(str)
+ n,f=0,1
+ lpegmatch(utfcharcounter,str or "")
+ return n
end
+ end
end
utf.length=utf.len
if not utf.sub then
- local utflength=utf.length
- local b,e,n,first,last=0,0,0,0,0
- local function slide_zero(s,p)
- n=n+1
- if n>=last then
- e=p-1
- else
- return p
- end
+ local utflength=utf.length
+ local b,e,n,first,last=0,0,0,0,0
+ local function slide_zero(s,p)
+ n=n+1
+ if n>=last then
+ e=p-1
+ else
+ return p
end
- local function slide_one(s,p)
- n=n+1
- if n==first then
- b=p
- end
- if n>=last then
- e=p-1
- else
- return p
- end
+ end
+ local function slide_one(s,p)
+ n=n+1
+ if n==first then
+ b=p
end
- local function slide_two(s,p)
- n=n+1
- if n==first then
- b=p
- else
- return true
- end
+ if n>=last then
+ e=p-1
+ else
+ return p
end
- local pattern_zero=Cmt(p_utf8character,slide_zero)^0
- local pattern_one=Cmt(p_utf8character,slide_one )^0
- local pattern_two=Cmt(p_utf8character,slide_two )^0
- local pattern_first=C(p_utf8character)
- function utf.sub(str,start,stop)
- if not start then
- return str
- end
- if start==0 then
- start=1
- end
- if not stop then
- if start<0 then
- local l=utflength(str)
- start=l+start
- else
- start=start-1
- end
- b,n,first=0,0,start
- lpegmatch(pattern_two,str)
- if n>=first then
- return sub(str,b)
- else
- return ""
- end
- end
- if start<0 or stop<0 then
- local l=utf.length(str)
- if start<0 then
- start=l+start
- if start<=0 then
- start=1
- else
- start=start+1
- end
- end
- if stop<0 then
- stop=l+stop
- if stop==0 then
- stop=1
- else
- stop=stop+1
- end
- end
+ end
+ local function slide_two(s,p)
+ n=n+1
+ if n==first then
+ b=p
+ else
+ return true
+ end
+ end
+ local pattern_zero=Cmt(p_utf8character,slide_zero)^0
+ local pattern_one=Cmt(p_utf8character,slide_one )^0
+ local pattern_two=Cmt(p_utf8character,slide_two )^0
+ local pattern_first=C(p_utf8character)
+ function utf.sub(str,start,stop)
+ if not start then
+ return str
+ end
+ if start==0 then
+ start=1
+ end
+ if not stop then
+ if start<0 then
+ local l=utflength(str)
+ start=l+start
+ else
+ start=start-1
+ end
+ b,n,first=0,0,start
+ lpegmatch(pattern_two,str)
+ if n>=first then
+ return sub(str,b)
+ else
+ return ""
+ end
+ end
+ if start<0 or stop<0 then
+ local l=utf.length(str)
+ if start<0 then
+ start=l+start
+ if start<=0 then
+ start=1
+ else
+ start=start+1
end
- if start==1 and stop==1 then
- return lpegmatch(pattern_first,str) or ""
- elseif start>stop then
- return ""
- elseif start>1 then
- b,e,n,first,last=0,0,0,start-1,stop
- lpegmatch(pattern_one,str)
- if n>=first and e==0 then
- e=#str
- end
- return sub(str,b,e)
+ end
+ if stop<0 then
+ stop=l+stop
+ if stop==0 then
+ stop=1
else
- b,e,n,last=1,0,0,stop
- lpegmatch(pattern_zero,str)
- if e==0 then
- e=#str
- end
- return sub(str,b,e)
+ stop=stop+1
end
+ end
end
+ if start==1 and stop==1 then
+ return lpegmatch(pattern_first,str) or ""
+ elseif start>stop then
+ return ""
+ elseif start>1 then
+ b,e,n,first,last=0,0,0,start-1,stop
+ lpegmatch(pattern_one,str)
+ if n>=first and e==0 then
+ e=#str
+ end
+ return sub(str,b,e)
+ else
+ b,e,n,last=1,0,0,stop
+ lpegmatch(pattern_zero,str)
+ if e==0 then
+ e=#str
+ end
+ return sub(str,b,e)
+ end
+ end
end
function utf.remapper(mapping,option,action)
- local variant=type(mapping)
- if variant=="table" then
- action=action or mapping
- if option=="dynamic" then
- local pattern=false
- table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
- return function(str)
- if not str or str=="" then
- return ""
- else
- if not pattern then
- pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
- end
- return lpegmatch(pattern,str)
- end
- end
- elseif option=="pattern" then
- return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ local variant=type(mapping)
+ if variant=="table" then
+ action=action or mapping
+ if option=="dynamic" then
+ local pattern=false
+ table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
+ return function(str)
+ if not str or str=="" then
+ return ""
else
- local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
- return function(str)
- if not str or str=="" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end,pattern
+ if not pattern then
+ pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ end
+ return lpegmatch(pattern,str)
end
- elseif variant=="function" then
- if option=="pattern" then
- return Cs((p_utf8character/mapping+p_utf8character)^0)
+ end
+ elseif option=="pattern" then
+ return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ else
+ local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
else
- local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
- return function(str)
- if not str or str=="" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end,pattern
+ return lpegmatch(pattern,str)
end
+ end,pattern
+ end
+ elseif variant=="function" then
+ if option=="pattern" then
+ return Cs((p_utf8character/mapping+p_utf8character)^0)
else
- return function(str)
- return str or ""
+ local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
end
+ end,pattern
end
-end
-function utf.replacer(t)
- local r=replacer(t,false,false,true)
+ else
return function(str)
- return lpegmatch(r,str)
+ return str or ""
end
+ end
+end
+function utf.replacer(t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ return lpegmatch(r,str)
+ end
end
function utf.subtituter(t)
- local f=finder (t)
- local r=replacer(t,false,false,true)
- return function(str)
- local i=lpegmatch(f,str)
- if not i then
- return str
- elseif i>#str then
- return str
- else
- return lpegmatch(r,str)
- end
+ local f=finder (t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ local i=lpegmatch(f,str)
+ if not i then
+ return str
+ elseif i>#str then
+ return str
+ else
+ return lpegmatch(r,str)
end
+ end
end
local utflinesplitter=p_utfbom^-1*lpeg.tsplitat(p_newline)
local utfcharsplitter_ows=p_utfbom^-1*Ct(C(p_utf8character)^0)
@@ -5823,25 +5823,25 @@ local utfcharsplitter_iws=p_utfbom^-1*Ct((p_whitespace^1+C(p_utf8character))^0)
local utfcharsplitter_raw=Ct(C(p_utf8character)^0)
patterns.utflinesplitter=utflinesplitter
function utf.splitlines(str)
- return lpegmatch(utflinesplitter,str or "")
+ return lpegmatch(utflinesplitter,str or "")
end
function utf.split(str,ignorewhitespace)
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
+ if ignorewhitespace then
+ return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+ return lpegmatch(utfcharsplitter_ows,str or "")
+ end
end
function utf.totable(str)
- return lpegmatch(utfcharsplitter_raw,str)
+ return lpegmatch(utfcharsplitter_raw,str)
end
function utf.magic(f)
- local str=f:read(4) or ""
- local off=lpegmatch(p_utfoffset,str)
- if off<4 then
- f:seek('set',off)
- end
- return lpegmatch(p_utftype,str)
+ local str=f:read(4) or ""
+ local off=lpegmatch(p_utfoffset,str)
+ if off<4 then
+ f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
end
local utf16_to_utf8_be,utf16_to_utf8_le
local utf32_to_utf8_be,utf32_to_utf8_le
@@ -5855,36 +5855,36 @@ local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_n
local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
local more=0
local p_utf16_to_utf8_be=C(1)*C(1)/function(left,right)
- local now=256*byte(left)+byte(right)
- if more>0 then
- now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ return ""
+ else
+ return utfchar(now)
+ end
end
local p_utf16_to_utf8_le=C(1)*C(1)/function(right,left)
- local now=256*byte(left)+byte(right)
- if more>0 then
- now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ return ""
+ else
+ return utfchar(now)
+ end
end
local p_utf32_to_utf8_be=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
- return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
+ return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
end
local p_utf32_to_utf8_le=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
- return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
+ return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
end
p_utf16_to_utf8_be=P(true)/function() more=0 end*utf_16_be_getbom*Cs(p_utf16_to_utf8_be^0)
p_utf16_to_utf8_le=P(true)/function() more=0 end*utf_16_le_getbom*Cs(p_utf16_to_utf8_le^0)
@@ -5895,88 +5895,88 @@ patterns.utf16_to_utf8_le=p_utf16_to_utf8_le
patterns.utf32_to_utf8_be=p_utf32_to_utf8_be
patterns.utf32_to_utf8_le=p_utf32_to_utf8_le
utf16_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_be,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+ return s
+ end
end
local utf16_to_utf8_be_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_16_be_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf16_to_utf8_be,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_16_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf16_to_utf8_be,s)
end
- return t
+ end
+ return t
end
utf16_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+ return s
+ end
end
local utf16_to_utf8_le_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_16_le_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf16_to_utf8_le,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_16_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf16_to_utf8_le,s)
end
- return t
+ end
+ return t
end
utf32_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_be,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+ return s
+ end
end
local utf32_to_utf8_be_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_32_be_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf32_to_utf8_be,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_32_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf32_to_utf8_be,s)
end
- return t
+ end
+ return t
end
utf32_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+ return s
+ end
end
local utf32_to_utf8_le_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_32_le_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf32_to_utf8_le,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_32_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf32_to_utf8_le,s)
end
- return t
+ end
+ return t
end
utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
@@ -5987,225 +5987,225 @@ utf.utf16_to_utf8_be=utf16_to_utf8_be
utf.utf32_to_utf8_le=utf32_to_utf8_le
utf.utf32_to_utf8_be=utf32_to_utf8_be
function utf.utf8_to_utf8_t(t)
- return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
+ return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
end
function utf.utf16_to_utf8_t(t,endian)
- return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
+ return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
end
function utf.utf32_to_utf8_t(t,endian)
- return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
+ return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
end
local function little(b)
- if b<0x10000 then
- return char(b%256,rshift(b,8))
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
- end
+ if b<0x10000 then
+ return char(b%256,rshift(b,8))
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
end
local function big(b)
- if b<0x10000 then
- return char(rshift(b,8),b%256)
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
- end
+ if b<0x10000 then
+ return char(rshift(b,8),b%256)
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
end
local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
local function utf8_to_utf16_be(str,nobom)
- if nobom then
- return lpegmatch(b_remap,str)
- else
- return char(254,255)..lpegmatch(b_remap,str)
- end
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
end
local function utf8_to_utf16_le(str,nobom)
- if nobom then
- return lpegmatch(l_remap,str)
- else
- return char(255,254)..lpegmatch(l_remap,str)
- end
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
end
utf.utf8_to_utf16_be=utf8_to_utf16_be
utf.utf8_to_utf16_le=utf8_to_utf16_le
function utf.utf8_to_utf16(str,littleendian,nobom)
- if littleendian then
- return utf8_to_utf16_le(str,nobom)
- else
- return utf8_to_utf16_be(str,nobom)
- end
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
end
local pattern=Cs (
- (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
+ (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
)
function utf.tocodes(str,separator)
- return lpegmatch(pattern,str,1,separator or " ")
+ return lpegmatch(pattern,str,1,separator or " ")
end
function utf.ustring(s)
- return format("U+%05X",type(s)=="number" and s or utfbyte(s))
+ return format("U+%05X",type(s)=="number" and s or utfbyte(s))
end
function utf.xstring(s)
- return format("0x%05X",type(s)=="number" and s or utfbyte(s))
+ return format("0x%05X",type(s)=="number" and s or utfbyte(s))
end
function utf.toeight(str)
- if not str or str=="" then
- return nil
- end
- local utftype=lpegmatch(p_utfstricttype,str)
- if utftype=="utf-8" then
- return sub(str,4)
- elseif utftype=="utf-16-be" then
- return utf16_to_utf8_be(str)
- elseif utftype=="utf-16-le" then
- return utf16_to_utf8_le(str)
- else
- return str
- end
+ if not str or str=="" then
+ return nil
+ end
+ local utftype=lpegmatch(p_utfstricttype,str)
+ if utftype=="utf-8" then
+ return sub(str,4)
+ elseif utftype=="utf-16-be" then
+ return utf16_to_utf8_be(str)
+ elseif utftype=="utf-16-le" then
+ return utf16_to_utf8_le(str)
+ else
+ return str
+ end
end
do
- local p_nany=p_utf8character/""
- local cache={}
- function utf.count(str,what)
- if type(what)=="string" then
- local p=cache[what]
- if not p then
- p=Cs((P(what)/" "+p_nany)^0)
- cache[p]=p
- end
- return #lpegmatch(p,str)
- else
- return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
- end
+ local p_nany=p_utf8character/""
+ local cache={}
+ function utf.count(str,what)
+ if type(what)=="string" then
+ local p=cache[what]
+ if not p then
+ p=Cs((P(what)/" "+p_nany)^0)
+ cache[p]=p
+ end
+ return #lpegmatch(p,str)
+ else
+ return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
end
+ end
end
if not string.utfvalues then
- local find=string.find
- local dummy=function()
- end
- function string.utfvalues(str)
- local n=#str
- if n==0 then
- return dummy
- elseif n==1 then
- return function() return utfbyte(str) end
- else
- local p=1
- return function()
- local b,e=find(str,".[\128-\191]*",p)
- if b then
- p=e+1
- return utfbyte(sub(str,b,e))
- end
- end
- end
+ local find=string.find
+ local dummy=function()
+ end
+ function string.utfvalues(str)
+ local n=#str
+ if n==0 then
+ return dummy
+ elseif n==1 then
+ return function() return utfbyte(str) end
+ else
+ local p=1
+ return function()
+ local b,e=find(str,".[\128-\191]*",p)
+ if b then
+ p=e+1
+ return utfbyte(sub(str,b,e))
+ end
+ end
end
+ end
end
utf.values=string.utfvalues
function utf.chrlen(u)
- return
- (u<0x80 and 1) or
- (u<0xE0 and 2) or
- (u<0xF0 and 3) or
- (u<0xF8 and 4) or
- (u<0xFC and 5) or
- (u<0xFE and 6) or 0
+ return
+ (u<0x80 and 1) or
+ (u<0xE0 and 2) or
+ (u<0xF0 and 3) or
+ (u<0xF8 and 4) or
+ (u<0xFC and 5) or
+ (u<0xFE and 6) or 0
end
if bit32 then
- local extract=bit32.extract
- local char=string.char
- function utf.toutf32string(n)
- if n<=0xFF then
- return
- char(n).."\000\000\000"
- elseif n<=0xFFFF then
- return
- char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
- elseif n<=0xFFFFFF then
- return
- char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
- else
- return
- char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
- end
- end
+ local extract=bit32.extract
+ local char=string.char
+ function utf.toutf32string(n)
+ if n<=0xFF then
+ return
+ char(n).."\000\000\000"
+ elseif n<=0xFFFF then
+ return
+ char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
+ elseif n<=0xFFFFFF then
+ return
+ char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
+ else
+ return
+ char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
+ end
+ end
end
local len=utf.len
local rep=rep
function string.utfpadd(s,n)
- if n and n~=0 then
- local l=len(s)
- if n>0 then
- local d=n-l
- if d>0 then
- return rep(c or " ",d)..s
- end
- else
- local d=- n-l
- if d>0 then
- return s..rep(c or " ",d)
- end
- end
+ if n and n~=0 then
+ local l=len(s)
+ if n>0 then
+ local d=n-l
+ if d>0 then
+ return rep(c or " ",d)..s
+ end
+ else
+ local d=- n-l
+ if d>0 then
+ return s..rep(c or " ",d)
+ end
end
- return s
+ end
+ return s
end
do
- local utfcharacters=utf.characters or string.utfcharacters
- local utfchar=utf.char or string.utfcharacter
- lpeg.UP=P
- if utfcharacters then
- function lpeg.US(str)
- local p=P(false)
- for uc in utfcharacters(str) do
- p=p+P(uc)
- end
- return p
- end
- else
- function lpeg.US(str)
- local p=P(false)
- local f=function(uc)
- p=p+P(uc)
- end
- lpegmatch((p_utf8char/f)^0,str)
- return p
- end
+ local utfcharacters=utf.characters or string.utfcharacters
+ local utfchar=utf.char or string.utfcharacter
+ lpeg.UP=P
+ if utfcharacters then
+ function lpeg.US(str)
+ local p=P(false)
+ for uc in utfcharacters(str) do
+ p=p+P(uc)
+ end
+ return p
end
- local range=p_utf8byte*p_utf8byte+Cc(false)
- function lpeg.UR(str,more)
- local first,last
- if type(str)=="number" then
- first=str
- last=more or first
- else
- first,last=lpegmatch(range,str)
- if not last then
- return P(str)
- end
- end
- if first==last then
- return P(str)
- end
- if not utfchar then
- utfchar=utf.char
- end
- if utfchar and (last-first<8) then
- local p=P(false)
- for i=first,last do
- p=p+P(utfchar(i))
- end
- return p
- else
- local f=function(b)
- return b>=first and b<=last
- end
- return p_utf8byte/f
- end
+ else
+ function lpeg.US(str)
+ local p=P(false)
+ local f=function(uc)
+ p=p+P(uc)
+ end
+ lpegmatch((p_utf8char/f)^0,str)
+ return p
+ end
+ end
+ local range=p_utf8byte*p_utf8byte+Cc(false)
+ function lpeg.UR(str,more)
+ local first,last
+ if type(str)=="number" then
+ first=str
+ last=more or first
+ else
+ first,last=lpegmatch(range,str)
+ if not last then
+ return P(str)
+ end
+ end
+ if first==last then
+ return P(str)
+ end
+ if not utfchar then
+ utfchar=utf.char
+ end
+ if utfchar and (last-first<8) then
+ local p=P(false)
+ for i=first,last do
+ p=p+P(utfchar(i))
+ end
+ return p
+ else
+ local f=function(b)
+ return b>=first and b<=last
+ end
+ return p_utf8byte/f
end
+ end
end
@@ -6215,93 +6215,93 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-math"] = package.loaded["l-math"] or true
--- original size: 2555, stripped down to: 1900
+-- original size: 2555, stripped down to: 1831
if not modules then modules={} end modules ['l-math']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not math.ceiling then
- math.ceiling=math.ceil
+ math.ceiling=math.ceil
end
if not math.round then
- local floor=math.floor
- function math.round(x) return floor(x+0.5) end
+ local floor=math.floor
+ function math.round(x) return floor(x+0.5) end
end
if not math.div then
- local floor=math.floor
- function math.div(n,m) return floor(n/m) end
+ local floor=math.floor
+ function math.div(n,m) return floor(n/m) end
end
if not math.mod then
- function math.mod(n,m) return n%m end
+ function math.mod(n,m) return n%m end
end
if not math.sind then
- local sin,cos,tan=math.sin,math.cos,math.tan
- local pipi=2*math.pi/360
- function math.sind(d) return sin(d*pipi) end
- function math.cosd(d) return cos(d*pipi) end
- function math.tand(d) return tan(d*pipi) end
+ local sin,cos,tan=math.sin,math.cos,math.tan
+ local pipi=2*math.pi/360
+ function math.sind(d) return sin(d*pipi) end
+ function math.cosd(d) return cos(d*pipi) end
+ function math.tand(d) return tan(d*pipi) end
end
if not math.odd then
- function math.odd (n) return n%2~=0 end
- function math.even(n) return n%2==0 end
+ function math.odd (n) return n%2~=0 end
+ function math.even(n) return n%2==0 end
end
if not math.cosh then
- local exp=math.exp
- function math.cosh(x)
- local xx=exp(x)
- return (xx+1/xx)/2
- end
- function math.sinh(x)
- local xx=exp(x)
- return (xx-1/xx)/2
- end
- function math.tanh(x)
- local xx=exp(x)
- return (xx-1/xx)/(xx+1/xx)
- end
+ local exp=math.exp
+ function math.cosh(x)
+ local xx=exp(x)
+ return (xx+1/xx)/2
+ end
+ function math.sinh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/2
+ end
+ function math.tanh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/(xx+1/xx)
+ end
end
if not math.pow then
- function math.pow(x,y)
- return x^y
- end
+ function math.pow(x,y)
+ return x^y
+ end
end
if not math.atan2 then
- math.atan2=math.atan
+ math.atan2=math.atan
end
if not math.ldexp then
- function math.ldexp(x,e)
- return x*2.0^e
- end
+ function math.ldexp(x,e)
+ return x*2.0^e
+ end
end
if not math.log10 then
- local log=math.log
- function math.log10(x)
- return log(x,10)
- end
+ local log=math.log
+ function math.log10(x)
+ return log(x,10)
+ end
end
if not math.type then
- function math.type()
- return "float"
- end
+ function math.type()
+ return "float"
+ end
end
if not math.tointeger then
- math.mininteger=-0x4FFFFFFFFFFF
- math.maxinteger=0x4FFFFFFFFFFF
- local floor=math.floor
- function math.tointeger(n)
- local f=floor(n)
- return f==n and f or nil
- end
+ math.mininteger=-0x4FFFFFFFFFFF
+ math.maxinteger=0x4FFFFFFFFFFF
+ local floor=math.floor
+ function math.tointeger(n)
+ local f=floor(n)
+ return f==n and f or nil
+ end
end
if not math.ult then
- local floor=math.floor
- function math.tointeger(m,n)
- return floor(m)<floor(n)
- end
+ local floor=math.floor
+ function math.tointeger(m,n)
+ return floor(m)<floor(n)
+ end
end
@@ -6311,14 +6311,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 43481, stripped down to: 23845
+-- original size: 43481, stripped down to: 23049
if not modules then modules={} end modules ['util-str']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.strings=utilities.strings or {}
@@ -6334,17 +6334,17 @@ local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
local loadstripped=nil
local oldfashioned=LUAVERSION<5.2
if oldfashioned then
- loadstripped=function(str,shortcuts)
- return load(str)
- end
+ loadstripped=function(str,shortcuts)
+ return load(str)
+ end
else
- loadstripped=function(str,shortcuts)
- if shortcuts then
- return load(dump(load(str),true),nil,nil,shortcuts)
- else
- return load(dump(load(str),true))
- end
+ loadstripped=function(str,shortcuts)
+ if shortcuts then
+ return load(dump(load(str),true),nil,nil,shortcuts)
+ else
+ return load(dump(load(str),true))
end
+ end
end
if not number then number={} end
local stripzero=patterns.stripzero
@@ -6362,32 +6362,32 @@ local period=patterns.period
local ptf=1/65536
local bpf=(7200/7227)/65536
local function points(n)
- if n==0 then
- return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
- return "0pt"
- end
- n=n*ptf
- if n%1==0 then
- return format("%ipt",n)
- end
- return lpegmatch(stripzeros,format("%.5fpt",n))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*ptf
+ if n%1==0 then
+ return format("%ipt",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fpt",n))
end
local function basepoints(n)
- if n==0 then
- return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
- return "0pt"
- end
- n=n*bpf
- if n%1==0 then
- return format("%ibp",n)
- end
- return lpegmatch(stripzeros,format("%.5fbp",n))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*bpf
+ if n%1==0 then
+ return format("%ibp",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fbp",n))
end
number.points=points
number.basepoints=basepoints
@@ -6399,65 +6399,65 @@ local trailing=(anyrubish^1*endofstring)/""
local redundant=rubish^3/"\n"
local pattern=Cs(leading*(trailing+redundant+stripped+anything)^0)
function strings.collapsecrlf(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local repeaters={}
function strings.newrepeater(str,offset)
- offset=offset or 0
- local s=repeaters[str]
- if not s then
- s={}
- repeaters[str]=s
- end
- local t=s[offset]
- if t then
- return t
- end
- t={}
- setmetatable(t,{ __index=function(t,k)
- if not k then
- return ""
- end
- local n=k+offset
- local s=n>0 and rep(str,n) or ""
- t[k]=s
- return s
- end })
- s[offset]=t
+ offset=offset or 0
+ local s=repeaters[str]
+ if not s then
+ s={}
+ repeaters[str]=s
+ end
+ local t=s[offset]
+ if t then
return t
+ end
+ t={}
+ setmetatable(t,{ __index=function(t,k)
+ if not k then
+ return ""
+ end
+ local n=k+offset
+ local s=n>0 and rep(str,n) or ""
+ t[k]=s
+ return s
+ end })
+ s[offset]=t
+ return t
end
local extra,tab,start=0,0,4,0
local nspaces=strings.newrepeater(" ")
string.nspaces=nspaces
local pattern=Carg(1)/function(t)
- extra,tab,start=0,t or 7,1
- end*Cs((
+ extra,tab,start=0,t or 7,1
+ end*Cs((
Cp()*patterns.tab/function(position)
- local current=(position-start+1)+extra
- local spaces=tab-(current-1)%tab
- if spaces>0 then
- extra=extra+spaces-1
- return nspaces[spaces]
- else
- return ""
- end
+ local current=(position-start+1)+extra
+ local spaces=tab-(current-1)%tab
+ if spaces>0 then
+ extra=extra+spaces-1
+ return nspaces[spaces]
+ else
+ return ""
+ end
end+newline*Cp()/function(position)
- extra,start=0,position
+ extra,start=0,position
end+anything
- )^1)
+ )^1)
function strings.tabtospace(str,tab)
- return lpegmatch(pattern,str,1,tab or 7)
+ return lpegmatch(pattern,str,1,tab or 7)
end
function string.utfpadding(s,n)
- if not n or n==0 then
- return ""
- end
- local l=utflen(s)
- if n>0 then
- return nspaces[n-l]
- else
- return nspaces[-n-l]
- end
+ if not n or n==0 then
+ return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
end
local optionalspace=spacer^0
local nospace=optionalspace/""
@@ -6475,130 +6475,130 @@ local notrailing=noleading*endofstring
local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 )
local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 )
local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 )
-local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
+local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
local p_retain_normal=Cs ((normalline+normalempty )^0 )
local p_retain_collapse=Cs ((normalline+doubleempty )^0 )
local p_retain_noempty=Cs ((normalline+singleempty )^0 )
local striplinepatterns={
- ["prune"]=p_prune_normal,
- ["prune and collapse"]=p_prune_collapse,
- ["prune and no empty"]=p_prune_noempty,
- ["prune and to space"]=p_prune_intospace,
- ["retain"]=p_retain_normal,
- ["retain and collapse"]=p_retain_collapse,
- ["retain and no empty"]=p_retain_noempty,
- ["collapse"]=patterns.collapser,
+ ["prune"]=p_prune_normal,
+ ["prune and collapse"]=p_prune_collapse,
+ ["prune and no empty"]=p_prune_noempty,
+ ["prune and to space"]=p_prune_intospace,
+ ["retain"]=p_retain_normal,
+ ["retain and collapse"]=p_retain_collapse,
+ ["retain and no empty"]=p_retain_noempty,
+ ["collapse"]=patterns.collapser,
}
setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end })
strings.striplinepatterns=striplinepatterns
function strings.striplines(str,how)
- return str and lpegmatch(striplinepatterns[how],str) or str
+ return str and lpegmatch(striplinepatterns[how],str) or str
end
function strings.collapse(str)
- return str and lpegmatch(p_prune_intospace,str) or str
+ return str and lpegmatch(p_prune_intospace,str) or str
end
strings.striplong=strings.striplines
function strings.nice(str)
- str=gsub(str,"[:%-+_]+"," ")
- return str
+ str=gsub(str,"[:%-+_]+"," ")
+ return str
end
local n=0
local sequenced=table.sequenced
function string.autodouble(s,sep)
- if s==nil then
- return '""'
- end
- local t=type(s)
- if t=="number" then
- return tostring(s)
- end
- if t=="table" then
- return ('"'..sequenced(s,sep or ",")..'"')
- end
- return ('"'..tostring(s)..'"')
+ if s==nil then
+ return '""'
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ('"'..sequenced(s,sep or ",")..'"')
+ end
+ return ('"'..tostring(s)..'"')
end
function string.autosingle(s,sep)
- if s==nil then
- return "''"
- end
- local t=type(s)
- if t=="number" then
- return tostring(s)
- end
- if t=="table" then
- return ("'"..sequenced(s,sep or ",").."'")
- end
- return ("'"..tostring(s).."'")
+ if s==nil then
+ return "''"
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ("'"..sequenced(s,sep or ",").."'")
+ end
+ return ("'"..tostring(s).."'")
end
local tracedchars={ [0]=
- "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
- "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
- "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
- "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
- "[space]",
+ "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
+ "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
+ "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
+ "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
+ "[space]",
}
string.tracedchars=tracedchars
strings.tracers=tracedchars
function string.tracedchar(b)
- if type(b)=="number" then
- return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
- else
- local c=utfbyte(b)
- return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
- end
+ if type(b)=="number" then
+ return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
+ else
+ local c=utfbyte(b)
+ return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
+ end
end
function number.signed(i)
- if i>0 then
- return "+",i
- else
- return "-",-i
- end
+ if i>0 then
+ return "+",i
+ else
+ return "-",-i
+ end
end
local two=digit*digit
local three=two*digit
local prefix=(Carg(1)*three)^1
local splitter=Cs (
- (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
+ (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
)
local splitter3=Cs (
- three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
+ three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
)
patterns.formattednumber=splitter
function number.formatted(n,sep1,sep2)
- if sep1==false then
- if type(n)=="number" then
- n=tostring(n)
- end
- return lpegmatch(splitter3,n,1,sep2 or ".")
+ if sep1==false then
+ if type(n)=="number" then
+ n=tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n)=="number" then
+ n=format("%0.2f",n)
+ end
+ if sep1==true then
+ return lpegmatch(splitter,n,1,".",",")
+ elseif sep1=="." then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
+ elseif sep1=="," then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
else
- if type(n)=="number" then
- n=format("%0.2f",n)
- end
- if sep1==true then
- return lpegmatch(splitter,n,1,".",",")
- elseif sep1=="." then
- return lpegmatch(splitter,n,1,sep1,sep2 or ",")
- elseif sep1=="," then
- return lpegmatch(splitter,n,1,sep1,sep2 or ".")
- else
- return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
- end
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
end
+ end
end
local p=Cs(
- P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
- )
+ P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
+ )
function number.compactfloat(n,fmt)
- if n==0 then
- return "0"
- elseif n==1 then
- return "1"
- end
- n=lpegmatch(p,format(fmt or "%0.3f",n))
- if n=="." or n=="" or n=="-" then
- return "0"
- end
- return n
+ if n==0 then
+ return "0"
+ elseif n==1 then
+ return "1"
+ end
+ n=lpegmatch(p,format(fmt or "%0.3f",n))
+ if n=="." or n=="" or n=="-" then
+ return "0"
+ end
+ return n
end
local zero=P("0")^1/""
local plus=P("+")/""
@@ -6609,41 +6609,41 @@ local exponent=(S("eE")*(plus+Cs((minus*zero^0*endofstring)/"")+minus)*zero^0*(e
local pattern_a=Cs(minus^0*digit^1*(separator/""*trailing+separator*(trailing+digit)^0)*exponent)
local pattern_b=Cs((exponent+anything)^0)
function number.sparseexponent(f,n)
- if not n then
- n=f
- f="%e"
- end
- local tn=type(n)
- if tn=="string" then
- local m=tonumber(n)
- if m then
- return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
- end
- elseif tn=="number" then
- return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ if not n then
+ n=f
+ f="%e"
+ end
+ local tn=type(n)
+ if tn=="string" then
+ local m=tonumber(n)
+ if m then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
end
- return tostring(n)
+ elseif tn=="number" then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ end
+ return tostring(n)
end
local hf={}
local hs={}
setmetatable(hf,{ __index=function(t,k)
- local v="%."..k.."f"
- t[k]=v
- return v
+ local v="%."..k.."f"
+ t[k]=v
+ return v
end } )
setmetatable(hs,{ __index=function(t,k)
- local v="%"..k.."s"
- t[k]=v
- return v
+ local v="%"..k.."s"
+ t[k]=v
+ return v
end } )
function number.formattedfloat(n,b,a)
- local s=format(hf[a],n)
- local l=(b or 0)+(a or 0)+1
- if #s<l then
- return format(hs[l],s)
- else
- return s
- end
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
end
local template=[[
%s
@@ -6652,7 +6652,7 @@ return function(%s) return %s end
]]
local preamble,environment="",{}
if oldfashioned then
- preamble=[[
+ preamble=[[
local lpeg=lpeg
local type=type
local tostring=tostring
@@ -6678,339 +6678,339 @@ local stripzero=lpeg.patterns.stripzero
local stripzeros=lpeg.patterns.stripzeros
]]
else
- environment={
- global=global or _G,
- lpeg=lpeg,
- type=type,
- tostring=tostring,
- tonumber=tonumber,
- format=string.format,
- concat=table.concat,
- signed=number.signed,
- points=number.points,
- basepoints=number.basepoints,
- utfchar=utf.char,
- utfbyte=utf.byte,
- lpegmatch=lpeg.match,
- nspaces=string.nspaces,
- utfpadding=string.utfpadding,
- tracedchar=string.tracedchar,
- autosingle=string.autosingle,
- autodouble=string.autodouble,
- sequenced=table.sequenced,
- formattednumber=number.formatted,
- sparseexponent=number.sparseexponent,
- formattedfloat=number.formattedfloat,
- stripzero=lpeg.patterns.stripzero,
- stripzeros=lpeg.patterns.stripzeros,
- }
+ environment={
+ global=global or _G,
+ lpeg=lpeg,
+ type=type,
+ tostring=tostring,
+ tonumber=tonumber,
+ format=string.format,
+ concat=table.concat,
+ signed=number.signed,
+ points=number.points,
+ basepoints=number.basepoints,
+ utfchar=utf.char,
+ utfbyte=utf.byte,
+ lpegmatch=lpeg.match,
+ nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
+ tracedchar=string.tracedchar,
+ autosingle=string.autosingle,
+ autodouble=string.autodouble,
+ sequenced=table.sequenced,
+ formattednumber=number.formatted,
+ sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat,
+ stripzero=lpeg.patterns.stripzero,
+ stripzeros=lpeg.patterns.stripzeros,
+ }
end
local arguments={ "a1" }
setmetatable(arguments,{ __index=function(t,k)
- local v=t[k-1]..",a"..k
- t[k]=v
- return v
- end
+ local v=t[k-1]..",a"..k
+ t[k]=v
+ return v
+ end
})
local prefix_any=C((sign+space+period+digit)^0)
local prefix_sub=(C((sign+digit)^0)+Cc(0))*period*(C((sign+digit)^0)+Cc(0))
local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
local format_s=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',a%s)",f,n)
- else
- return format("(a%s or '')",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("(a%s or '')",n)
+ end
end
local format_S=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',tostring(a%s))",f,n)
- else
- return format("tostring(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',tostring(a%s))",f,n)
+ else
+ return format("tostring(a%s)",n)
+ end
end
local format_right=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
- return format("(a%s or '')",n)
- elseif f>0 then
- return format("utfpadding(a%s,%i)..a%s",n,f,n)
- else
- return format("a%s..utfpadding(a%s,%i)",n,n,f)
- end
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ elseif f>0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
end
local format_left=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
- return format("(a%s or '')",n)
- end
- if f<0 then
- return format("utfpadding(a%s,%i)..a%s",n,-f,n)
- else
- return format("a%s..utfpadding(a%s,%i)",n,n,-f)
- end
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ end
+ if f<0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
end
local format_q=function()
- n=n+1
- return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
end
local format_Q=function()
- n=n+1
- return format("format('%%q',tostring(a%s))",n)
+ n=n+1
+ return format("format('%%q',tostring(a%s))",n)
end
local format_i=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%si',a%s)",f,n)
- else
- return format("format('%%i',a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%si',a%s)",f,n)
+ else
+ return format("format('%%i',a%s)",n)
+ end
end
local format_d=format_i
local format_I=function(f)
- n=n+1
- return format("format('%%s%%%si',signed(a%s))",f,n)
+ n=n+1
+ return format("format('%%s%%%si',signed(a%s))",f,n)
end
local format_f=function(f)
- n=n+1
- return format("format('%%%sf',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sf',a%s)",f,n)
end
local format_F=function(f)
- n=n+1
- if not f or f=="" then
- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
- else
- return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
- end
+ n=n+1
+ if not f or f=="" then
+ return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
+ else
+ return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
+ end
end
local format_k=function(b,a)
- n=n+1
- return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
+ n=n+1
+ return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
end
local format_g=function(f)
- n=n+1
- return format("format('%%%sg',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sg',a%s)",f,n)
end
local format_G=function(f)
- n=n+1
- return format("format('%%%sG',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sG',a%s)",f,n)
end
local format_e=function(f)
- n=n+1
- return format("format('%%%se',a%s)",f,n)
+ n=n+1
+ return format("format('%%%se',a%s)",f,n)
end
local format_E=function(f)
- n=n+1
- return format("format('%%%sE',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sE',a%s)",f,n)
end
local format_j=function(f)
- n=n+1
- return format("sparseexponent('%%%se',a%s)",f,n)
+ n=n+1
+ return format("sparseexponent('%%%se',a%s)",f,n)
end
local format_J=function(f)
- n=n+1
- return format("sparseexponent('%%%sE',a%s)",f,n)
+ n=n+1
+ return format("sparseexponent('%%%sE',a%s)",f,n)
end
local format_x=function(f)
- n=n+1
- return format("format('%%%sx',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sx',a%s)",f,n)
end
local format_X=function(f)
- n=n+1
- return format("format('%%%sX',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sX',a%s)",f,n)
end
local format_o=function(f)
- n=n+1
- return format("format('%%%so',a%s)",f,n)
+ n=n+1
+ return format("format('%%%so',a%s)",f,n)
end
local format_c=function()
- n=n+1
- return format("utfchar(a%s)",n)
+ n=n+1
+ return format("utfchar(a%s)",n)
end
local format_C=function()
- n=n+1
- return format("tracedchar(a%s)",n)
+ n=n+1
+ return format("tracedchar(a%s)",n)
end
local format_r=function(f)
- n=n+1
- return format("format('%%%s.0f',a%s)",f,n)
+ n=n+1
+ return format("format('%%%s.0f',a%s)",f,n)
end
local format_h=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_H=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_u=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_U=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_p=function()
- n=n+1
- return format("points(a%s)",n)
+ n=n+1
+ return format("points(a%s)",n)
end
local format_b=function()
- n=n+1
- return format("basepoints(a%s)",n)
+ n=n+1
+ return format("basepoints(a%s)",n)
end
local format_t=function(f)
- n=n+1
- if f and f~="" then
- return format("concat(a%s,%q)",n,f)
- else
- return format("concat(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("concat(a%s,%q)",n,f)
+ else
+ return format("concat(a%s)",n)
+ end
end
local format_T=function(f)
- n=n+1
- if f and f~="" then
- return format("sequenced(a%s,%q)",n,f)
- else
- return format("sequenced(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("sequenced(a%s,%q)",n,f)
+ else
+ return format("sequenced(a%s)",n)
+ end
end
local format_l=function()
- n=n+1
- return format("(a%s and 'true' or 'false')",n)
+ n=n+1
+ return format("(a%s and 'true' or 'false')",n)
end
local format_L=function()
- n=n+1
- return format("(a%s and 'TRUE' or 'FALSE')",n)
+ n=n+1
+ return format("(a%s and 'TRUE' or 'FALSE')",n)
end
local format_n=function()
- n=n+1
- return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+ n=n+1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
end
local format_N=function(f)
- n=n+1
- if not f or f=="" then
- f=".9"
- end
- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+ n=n+1
+ if not f or f=="" then
+ f=".9"
+ end
+ return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
end
local format_a=function(f)
- n=n+1
- if f and f~="" then
- return format("autosingle(a%s,%q)",n,f)
- else
- return format("autosingle(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("autosingle(a%s,%q)",n,f)
+ else
+ return format("autosingle(a%s)",n)
+ end
end
local format_A=function(f)
- n=n+1
- if f and f~="" then
- return format("autodouble(a%s,%q)",n,f)
- else
- return format("autodouble(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("autodouble(a%s,%q)",n,f)
+ else
+ return format("autodouble(a%s)",n)
+ end
end
local format_w=function(f)
- n=n+1
- f=tonumber(f)
- if f then
- return format("nspaces[%s+a%s]",f,n)
- else
- return format("nspaces[a%s]",n)
- end
+ n=n+1
+ f=tonumber(f)
+ if f then
+ return format("nspaces[%s+a%s]",f,n)
+ else
+ return format("nspaces[a%s]",n)
+ end
end
local format_W=function(f)
- return format("nspaces[%s]",tonumber(f) or 0)
+ return format("nspaces[%s]",tonumber(f) or 0)
end
local format_m=function(f)
- n=n+1
- if not f or f=="" then
- f=","
- end
- if f=="0" then
- return format([[formattednumber(a%s,false)]],n)
- else
- return format([[formattednumber(a%s,%q,".")]],n,f)
- end
+ n=n+1
+ if not f or f=="" then
+ f=","
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,".")]],n,f)
+ end
end
local format_M=function(f)
- n=n+1
- if not f or f=="" then
- f="."
- end
- if f=="0" then
- return format([[formattednumber(a%s,false)]],n)
- else
- return format([[formattednumber(a%s,%q,",")]],n,f)
- end
+ n=n+1
+ if not f or f=="" then
+ f="."
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,",")]],n,f)
+ end
end
local format_z=function(f)
- n=n+(tonumber(f) or 1)
- return "''"
+ n=n+(tonumber(f) or 1)
+ return "''"
end
local format_rest=function(s)
- return format("%q",s)
+ return format("%q",s)
end
local format_extension=function(extensions,f,name)
- local extension=extensions[name] or "tostring(%s)"
- local f=tonumber(f) or 1
- local w=find(extension,"%.%.%.")
- if f==0 then
- if w then
- extension=gsub(extension,"%.%.%.","")
- end
- return extension
- elseif f==1 then
- if w then
- extension=gsub(extension,"%.%.%.","%%s")
- end
- n=n+1
- local a="a"..n
- return format(extension,a,a)
- elseif f<0 then
- local a="a"..(n+f+1)
- return format(extension,a,a)
- else
- if w then
- extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
- end
- local t={}
- for i=1,f do
- n=n+1
- t[i]="a"..n
- end
- return format(extension,unpack(t))
+ local extension=extensions[name] or "tostring(%s)"
+ local f=tonumber(f) or 1
+ local w=find(extension,"%.%.%.")
+ if f==0 then
+ if w then
+ extension=gsub(extension,"%.%.%.","")
+ end
+ return extension
+ elseif f==1 then
+ if w then
+ extension=gsub(extension,"%.%.%.","%%s")
+ end
+ n=n+1
+ local a="a"..n
+ return format(extension,a,a)
+ elseif f<0 then
+ local a="a"..(n+f+1)
+ return format(extension,a,a)
+ else
+ if w then
+ extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
end
+ local t={}
+ for i=1,f do
+ n=n+1
+ t[i]="a"..n
+ end
+ return format(extension,unpack(t))
+ end
end
local builder=Cs { "start",
- start=(
- (
- P("%")/""*(
- V("!")
+ start=(
+ (
+ P("%")/""*(
+ V("!")
+V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
+V("c")+V("C")+V("S")
+V("Q")
@@ -7026,119 +7026,119 @@ local builder=Cs { "start",
+V("z")
+V(">")
+V("<")
- )+V("*")
- )*(endofstring+Carg(1))
- )^0,
- ["s"]=(prefix_any*P("s"))/format_s,
- ["q"]=(prefix_any*P("q"))/format_q,
- ["i"]=(prefix_any*P("i"))/format_i,
- ["d"]=(prefix_any*P("d"))/format_d,
- ["f"]=(prefix_any*P("f"))/format_f,
- ["F"]=(prefix_any*P("F"))/format_F,
- ["g"]=(prefix_any*P("g"))/format_g,
- ["G"]=(prefix_any*P("G"))/format_G,
- ["e"]=(prefix_any*P("e"))/format_e,
- ["E"]=(prefix_any*P("E"))/format_E,
- ["x"]=(prefix_any*P("x"))/format_x,
- ["X"]=(prefix_any*P("X"))/format_X,
- ["o"]=(prefix_any*P("o"))/format_o,
- ["S"]=(prefix_any*P("S"))/format_S,
- ["Q"]=(prefix_any*P("Q"))/format_Q,
- ["n"]=(prefix_any*P("n"))/format_n,
- ["N"]=(prefix_any*P("N"))/format_N,
- ["k"]=(prefix_sub*P("k"))/format_k,
- ["c"]=(prefix_any*P("c"))/format_c,
- ["C"]=(prefix_any*P("C"))/format_C,
- ["r"]=(prefix_any*P("r"))/format_r,
- ["h"]=(prefix_any*P("h"))/format_h,
- ["H"]=(prefix_any*P("H"))/format_H,
- ["u"]=(prefix_any*P("u"))/format_u,
- ["U"]=(prefix_any*P("U"))/format_U,
- ["p"]=(prefix_any*P("p"))/format_p,
- ["b"]=(prefix_any*P("b"))/format_b,
- ["t"]=(prefix_tab*P("t"))/format_t,
- ["T"]=(prefix_tab*P("T"))/format_T,
- ["l"]=(prefix_any*P("l"))/format_l,
- ["L"]=(prefix_any*P("L"))/format_L,
- ["I"]=(prefix_any*P("I"))/format_I,
- ["w"]=(prefix_any*P("w"))/format_w,
- ["W"]=(prefix_any*P("W"))/format_W,
- ["j"]=(prefix_any*P("j"))/format_j,
- ["J"]=(prefix_any*P("J"))/format_J,
- ["m"]=(prefix_any*P("m"))/format_m,
- ["M"]=(prefix_any*P("M"))/format_M,
- ["z"]=(prefix_any*P("z"))/format_z,
- ["a"]=(prefix_any*P("a"))/format_a,
- ["A"]=(prefix_any*P("A"))/format_A,
- ["<"]=(prefix_any*P("<"))/format_left,
- [">"]=(prefix_any*P(">"))/format_right,
- ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
- ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
- ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
+ )+V("*")
+ )*(endofstring+Carg(1))
+ )^0,
+ ["s"]=(prefix_any*P("s"))/format_s,
+ ["q"]=(prefix_any*P("q"))/format_q,
+ ["i"]=(prefix_any*P("i"))/format_i,
+ ["d"]=(prefix_any*P("d"))/format_d,
+ ["f"]=(prefix_any*P("f"))/format_f,
+ ["F"]=(prefix_any*P("F"))/format_F,
+ ["g"]=(prefix_any*P("g"))/format_g,
+ ["G"]=(prefix_any*P("G"))/format_G,
+ ["e"]=(prefix_any*P("e"))/format_e,
+ ["E"]=(prefix_any*P("E"))/format_E,
+ ["x"]=(prefix_any*P("x"))/format_x,
+ ["X"]=(prefix_any*P("X"))/format_X,
+ ["o"]=(prefix_any*P("o"))/format_o,
+ ["S"]=(prefix_any*P("S"))/format_S,
+ ["Q"]=(prefix_any*P("Q"))/format_Q,
+ ["n"]=(prefix_any*P("n"))/format_n,
+ ["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
+ ["c"]=(prefix_any*P("c"))/format_c,
+ ["C"]=(prefix_any*P("C"))/format_C,
+ ["r"]=(prefix_any*P("r"))/format_r,
+ ["h"]=(prefix_any*P("h"))/format_h,
+ ["H"]=(prefix_any*P("H"))/format_H,
+ ["u"]=(prefix_any*P("u"))/format_u,
+ ["U"]=(prefix_any*P("U"))/format_U,
+ ["p"]=(prefix_any*P("p"))/format_p,
+ ["b"]=(prefix_any*P("b"))/format_b,
+ ["t"]=(prefix_tab*P("t"))/format_t,
+ ["T"]=(prefix_tab*P("T"))/format_T,
+ ["l"]=(prefix_any*P("l"))/format_l,
+ ["L"]=(prefix_any*P("L"))/format_L,
+ ["I"]=(prefix_any*P("I"))/format_I,
+ ["w"]=(prefix_any*P("w"))/format_w,
+ ["W"]=(prefix_any*P("W"))/format_W,
+ ["j"]=(prefix_any*P("j"))/format_j,
+ ["J"]=(prefix_any*P("J"))/format_J,
+ ["m"]=(prefix_any*P("m"))/format_m,
+ ["M"]=(prefix_any*P("M"))/format_M,
+ ["z"]=(prefix_any*P("z"))/format_z,
+ ["a"]=(prefix_any*P("a"))/format_a,
+ ["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
+ ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
+ ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
+ ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
}
local xx=setmetatable({},{ __index=function(t,k) local v=format("%02x",k) t[k]=v return v end })
local XX=setmetatable({},{ __index=function(t,k) local v=format("%02X",k) t[k]=v return v end })
local preset={
- ["%02x"]=function(n) return xx[n] end,
- ["%02X"]=function(n) return XX[n] end,
+ ["%02x"]=function(n) return xx[n] end,
+ ["%02X"]=function(n) return XX[n] end,
}
local direct=P("%")*(sign+space+period+digit)^0*S("sqidfgGeExXo")*endofstring/[[local format = string.format return function(str) return format("%0",str) end]]
local function make(t,str)
- local f=preset[str]
- if f then
- return f
- end
- local p=lpegmatch(direct,str)
- if p then
- f=loadstripped(p)()
+ local f=preset[str]
+ if f then
+ return f
+ end
+ local p=lpegmatch(direct,str)
+ if p then
+ f=loadstripped(p)()
+ else
+ n=0
+ p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
+ if n>0 then
+ p=format(template,preamble,t._preamble_,arguments[n],p)
+ f=loadstripped(p,t._environment_)()
else
- n=0
- p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
- if n>0 then
- p=format(template,preamble,t._preamble_,arguments[n],p)
- f=loadstripped(p,t._environment_)()
- else
- f=function() return str end
- end
+ f=function() return str end
end
- t[str]=f
- return f
+ end
+ t[str]=f
+ return f
end
local function use(t,fmt,...)
- return t[fmt](...)
+ return t[fmt](...)
end
strings.formatters={}
if oldfashioned then
- function strings.formatters.new(noconcat)
- local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} }
- setmetatable(t,{ __index=make,__call=use })
- return t
- end
+ function strings.formatters.new(noconcat)
+ local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
+ end
else
- function strings.formatters.new(noconcat)
- local e={}
- for k,v in next,environment do
- e[k]=v
- end
- local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e }
- setmetatable(t,{ __index=make,__call=use })
- return t
+ function strings.formatters.new(noconcat)
+ local e={}
+ for k,v in next,environment do
+ e[k]=v
end
+ local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
+ end
end
local formatters=strings.formatters.new()
string.formatters=formatters
string.formatter=function(str,...) return formatters[str](...) end
local function add(t,name,template,preamble)
- if type(t)=="table" and t._type_=="formatter" then
- t._extensions_[name]=template or "%s"
- if type(preamble)=="string" then
- t._preamble_=preamble.."\n"..t._preamble_
- elseif type(preamble)=="table" then
- for k,v in next,preamble do
- t._environment_[k]=v
- end
- end
+ if type(t)=="table" and t._type_=="formatter" then
+ t._extensions_[name]=template or "%s"
+ if type(preamble)=="string" then
+ t._preamble_=preamble.."\n"..t._preamble_
+ elseif type(preamble)=="table" then
+ for k,v in next,preamble do
+ t._environment_[k]=v
+ end
end
+ end
end
strings.formatters.add=add
patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+anything)^0)
@@ -7146,44 +7146,44 @@ patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+anything)^0)
patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0)
patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"'))
if oldfashioned then
- add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
- add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
- add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
+ add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
+ add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
+ add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
else
- add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape })
- add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
- add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
+ add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape })
+ add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
+ add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
end
local dquote=patterns.dquote
local equote=patterns.escaped+dquote/'\\"'+1
local cquote=Cc('"')
-local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
+local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
+Cs(cquote*(equote-space)^0*space*equote^0*cquote)
function string.optionalquoted(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local pattern=Cs((newline/(os.newline or "\r")+1)^0)
function string.replacenewlines(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function strings.newcollector()
- local result,r={},0
- return
- function(fmt,str,...)
- r=r+1
- result[r]=str==nil and fmt or formatters[fmt](str,...)
- end,
- function(connector)
- if result then
- local str=concat(result,connector)
- result,r={},0
- return str
- end
- end
+ local result,r={},0
+ return
+ function(fmt,str,...)
+ r=r+1
+ result[r]=str==nil and fmt or formatters[fmt](str,...)
+ end,
+ function(connector)
+ if result then
+ local str=concat(result,connector)
+ result,r={},0
+ return str
+ end
+ end
end
local f_16_16=formatters["%0.5N"]
function number.to16dot16(n)
- return f_16_16(n/65536.0)
+ return f_16_16(n/65536.0)
end
@@ -7193,14 +7193,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 28756, stripped down to: 17693
+-- original size: 28756, stripped down to: 16104
if not modules then modules={} end modules ['util-tab']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.tables=utilities.tables or {}
@@ -7215,219 +7215,219 @@ local formatters=string.formatters
local utftoeight=utf.toeight
local splitter=lpeg.tsplitat(".")
function utilities.tables.definetable(target,nofirst,nolast)
- local composed,t=nil,{}
- local snippets=lpegmatch(splitter,target)
- for i=1,#snippets-(nolast and 1 or 0) do
- local name=snippets[i]
- if composed then
- composed=composed.."."..name
- t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
- else
- composed=name
- if not nofirst then
- t[#t+1]=formatters["%s = %s or { }"](composed,composed)
- end
- end
- end
+ local composed,t=nil,{}
+ local snippets=lpegmatch(splitter,target)
+ for i=1,#snippets-(nolast and 1 or 0) do
+ local name=snippets[i]
if composed then
- if nolast then
- composed=composed.."."..snippets[#snippets]
- end
- return concat(t,"\n"),composed
+ composed=composed.."."..name
+ t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
else
- return "",target
+ composed=name
+ if not nofirst then
+ t[#t+1]=formatters["%s = %s or { }"](composed,composed)
+ end
end
+ end
+ if composed then
+ if nolast then
+ composed=composed.."."..snippets[#snippets]
+ end
+ return concat(t,"\n"),composed
+ else
+ return "",target
+ end
end
function tables.definedtable(...)
- local t=_G
- for i=1,select("#",...) do
- local li=select(i,...)
- local tl=t[li]
- if not tl then
- tl={}
- t[li]=tl
- end
- t=tl
- end
- return t
+ local t=_G
+ for i=1,select("#",...) do
+ local li=select(i,...)
+ local tl=t[li]
+ if not tl then
+ tl={}
+ t[li]=tl
+ end
+ t=tl
+ end
+ return t
end
function tables.accesstable(target,root)
- local t=root or _G
- for name in gmatch(target,"([^%.]+)") do
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ for name in gmatch(target,"([^%.]+)") do
+ t=t[name]
+ if not t then
+ return
end
- return t
+ end
+ return t
end
function tables.migratetable(target,v,root)
- local t=root or _G
- local names=lpegmatch(splitter,target)
- for i=1,#names-1 do
- local name=names[i]
- t[name]=t[name] or {}
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ local names=lpegmatch(splitter,target)
+ for i=1,#names-1 do
+ local name=names[i]
+ t[name]=t[name] or {}
+ t=t[name]
+ if not t then
+ return
end
- t[names[#names]]=v
+ end
+ t[names[#names]]=v
end
function tables.removevalue(t,value)
- if value then
- for i=1,#t do
- if t[i]==value then
- remove(t,i)
- end
- end
+ if value then
+ for i=1,#t do
+ if t[i]==value then
+ remove(t,i)
+ end
end
+ end
end
function tables.replacevalue(t,oldvalue,newvalue)
- if oldvalue and newvalue then
- for i=1,#t do
- if t[i]==oldvalue then
- t[i]=newvalue
- end
- end
+ if oldvalue and newvalue then
+ for i=1,#t do
+ if t[i]==oldvalue then
+ t[i]=newvalue
+ end
end
+ end
end
function tables.insertbeforevalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i,extra)
+ return
end
- insert(t,1,extra)
+ end
+ insert(t,1,extra)
end
function tables.insertaftervalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i+1,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i+1,extra)
+ return
end
- insert(t,#t+1,extra)
+ end
+ insert(t,#t+1,extra)
end
local escape=Cs(Cc('"')*((P('"')/'""'+P(1))^0)*Cc('"'))
function table.tocsv(t,specification)
- if t and #t>0 then
- local result={}
- local r={}
- specification=specification or {}
- local fields=specification.fields
- if type(fields)~="string" then
- fields=sortedkeys(t[1])
- end
- local separator=specification.separator or ","
- local noffields=#fields
- if specification.preamble==true then
- for f=1,noffields do
- r[f]=lpegmatch(escape,tostring(fields[f]))
- end
- result[1]=concat(r,separator)
- end
- for i=1,#t do
- local ti=t[i]
- for f=1,noffields do
- local field=ti[fields[f]]
- if type(field)=="string" then
- r[f]=lpegmatch(escape,field)
- else
- r[f]=tostring(field)
- end
- end
- result[i+1]=concat(r,separator)
+ if t and #t>0 then
+ local result={}
+ local r={}
+ specification=specification or {}
+ local fields=specification.fields
+ if type(fields)~="string" then
+ fields=sortedkeys(t[1])
+ end
+ local separator=specification.separator or ","
+ local noffields=#fields
+ if specification.preamble==true then
+ for f=1,noffields do
+ r[f]=lpegmatch(escape,tostring(fields[f]))
+ end
+ result[1]=concat(r,separator)
+ end
+ for i=1,#t do
+ local ti=t[i]
+ for f=1,noffields do
+ local field=ti[fields[f]]
+ if type(field)=="string" then
+ r[f]=lpegmatch(escape,field)
+ else
+ r[f]=tostring(field)
end
- return concat(result,"\n")
- else
- return ""
+ end
+ result[i+1]=concat(r,separator)
end
+ return concat(result,"\n")
+ else
+ return ""
+ end
end
local nspaces=utilities.strings.newrepeater(" ")
local function toxml(t,d,result,step)
- local r=#result
- for k,v in sortedpairs(t) do
- local s=nspaces[d]
- local tk=type(k)
- local tv=type(v)
- if tv=="table" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</entry>"](s,k)
- else
- r=r+1 result[r]=formatters["%s<%s>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</%s>"](s,k)
- end
- elseif tv=="string" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
- end
- elseif tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
- end
+ local r=#result
+ for k,v in sortedpairs(t) do
+ local s=nspaces[d]
+ local tk=type(k)
+ local tv=type(v)
+ if tv=="table" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</entry>"](s,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</%s>"](s,k)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
+ end
+ elseif tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
end
+ end
end
function table.toxml(t,specification)
- specification=specification or {}
- local name=specification.name
- local noroot=name==false
- local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
- local indent=specification.indent or 0
- local spaces=specification.spaces or 1
- if noroot then
- toxml(t,indent,result,spaces)
- else
- toxml({ [name or "data"]=t },indent,result,spaces)
- end
- return concat(result,"\n")
+ specification=specification or {}
+ local name=specification.name
+ local noroot=name==false
+ local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
+ local indent=specification.indent or 0
+ local spaces=specification.spaces or 1
+ if noroot then
+ toxml(t,indent,result,spaces)
+ else
+ toxml({ [name or "data"]=t },indent,result,spaces)
+ end
+ return concat(result,"\n")
end
function tables.encapsulate(core,capsule,protect)
- if type(capsule)~="table" then
- protect=true
- capsule={}
- end
+ if type(capsule)~="table" then
+ protect=true
+ capsule={}
+ end
+ for key,value in next,core do
+ if capsule[key] then
+ print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
+ os.exit()
+ else
+ capsule[key]=value
+ end
+ end
+ if protect then
for key,value in next,core do
+ core[key]=nil
+ end
+ setmetatable(core,{
+ __index=capsule,
+ __newindex=function(t,key,value)
if capsule[key] then
- print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
- os.exit()
+ print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
+ os.exit()
else
- capsule[key]=value
+ rawset(t,key,value)
end
- end
- if protect then
- for key,value in next,core do
- core[key]=nil
- end
- setmetatable(core,{
- __index=capsule,
- __newindex=function(t,key,value)
- if capsule[key] then
- print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
- os.exit()
- else
- rawset(t,key,value)
- end
- end
- } )
- end
+ end
+ } )
+ end
end
local f_hashed_string=formatters["[%q]=%q,"]
local f_hashed_number=formatters["[%q]=%s,"]
@@ -7441,157 +7441,157 @@ local f_ordered_string=formatters["%q,"]
local f_ordered_number=formatters["%s,"]
local f_ordered_boolean=formatters["%l,"]
function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- for i=0,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
- end
- end
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ for i=0,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
- end
- end
- else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
- end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ else
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_hashed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_hashed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_hashed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
- return r
+ end
end
- return concat(fastserialize(t,true))
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
+ end
+ return concat(fastserialize(t,true))
end
function table.deserialize(str)
- if not str or str=="" then
- return
- end
- local code=load(str)
- if not code then
- return
- end
- code=code()
- if not code then
- return
- end
- return code
+ if not str or str=="" then
+ return
+ end
+ local code=load(str)
+ if not code then
+ return
+ end
+ code=code()
+ if not code then
+ return
+ end
+ return code
end
function table.load(filename,loader)
- if filename then
- local t=(loader or io.loaddata)(filename)
- if t and t~="" then
- local t=utftoeight(t)
- t=load(t)
- if type(t)=="function" then
- t=t()
- if type(t)=="table" then
- return t
- end
- end
+ if filename then
+ local t=(loader or io.loaddata)(filename)
+ if t and t~="" then
+ local t=utftoeight(t)
+ t=load(t)
+ if type(t)=="function" then
+ t=t()
+ if type(t)=="table" then
+ return t
end
+ end
end
+ end
end
function table.save(filename,t,n,...)
- io.savedata(filename,table.serialize(t,n==nil and true or n,...))
+ io.savedata(filename,table.serialize(t,n==nil and true or n,...))
end
local f_key_value=formatters["%s=%q"]
local f_add_table=formatters[" {%t},\n"]
local f_return_table=formatters["return {\n%t}"]
local function slowdrop(t)
- local r={}
- local l={}
- for i=1,#t do
- local ti=t[i]
- local j=0
- for k,v in next,ti do
- j=j+1
- l[j]=f_key_value(k,v)
- end
- r[i]=f_add_table(l)
- end
- return f_return_table(r)
+ local r={}
+ local l={}
+ for i=1,#t do
+ local ti=t[i]
+ local j=0
+ for k,v in next,ti do
+ j=j+1
+ l[j]=f_key_value(k,v)
+ end
+ r[i]=f_add_table(l)
+ end
+ return f_return_table(r)
end
local function fastdrop(t)
- local r={ "return {\n" }
- local m=1
- for i=1,#t do
- local ti=t[i]
- m=m+1 r[m]=" {"
- for k,v in next,ti do
- m=m+1 r[m]=f_key_value(k,v)
- end
- m=m+1 r[m]="},\n"
- end
- m=m+1
- r[m]="}"
- return concat(r)
+ local r={ "return {\n" }
+ local m=1
+ for i=1,#t do
+ local ti=t[i]
+ m=m+1 r[m]=" {"
+ for k,v in next,ti do
+ m=m+1 r[m]=f_key_value(k,v)
+ end
+ m=m+1 r[m]="},\n"
+ end
+ m=m+1
+ r[m]="}"
+ return concat(r)
end
function table.drop(t,slow)
- if #t==0 then
- return "return { }"
- elseif slow==true then
- return slowdrop(t)
- else
- return fastdrop(t)
- end
+ if #t==0 then
+ return "return { }"
+ elseif slow==true then
+ return slowdrop(t)
+ else
+ return fastdrop(t)
+ end
end
local selfmapper={ __index=function(t,k) t[k]=k return k end }
-function table.twowaymapper(t)
- if not t then
- t={}
- else
- local zero=rawget(t,0)
- for i=zero and 0 or 1,#t do
- local ti=t[i]
- if ti then
- local i=tostring(i)
- t[i]=ti
- t[ti]=i
- end
- end
+function table.twowaymapper(t)
+ if not t then
+ t={}
+ else
+ local zero=rawget(t,0)
+ for i=zero and 0 or 1,#t do
+ local ti=t[i]
+ if ti then
+ local i=tostring(i)
+ t[i]=ti
+ t[ti]=i
+ end
end
- setmetatable(t,selfmapper)
- return t
+ end
+ setmetatable(t,selfmapper)
+ return t
end
local f_start_key_idx=formatters["%w{"]
local f_start_key_num=formatters["%w[%s]={"]
@@ -7629,223 +7629,223 @@ local spaces=utilities.strings.newrepeater(" ")
local original_serialize=table.serialize
local is_simple_table=table.is_simple_table
local function serialize(root,name,specification)
- if type(specification)=="table" then
- return original_serialize(root,name,specification)
- end
- local t
- local n=1
- local unknown=false
- local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- n=n+1
- if indexed then
- t[n]=f_start_key_idx(depth)
+ if type(specification)=="table" then
+ return original_serialize(root,name,specification)
+ end
+ local t
+ local n=1
+ local unknown=false
+ local function do_serialize(root,name,depth,level,indexed)
+ if level>0 then
+ n=n+1
+ if indexed then
+ t[n]=f_start_key_idx(depth)
+ else
+ local tn=type(name)
+ if tn=="number" then
+ t[n]=f_start_key_num(depth,name)
+ elseif tn=="string" then
+ t[n]=f_start_key_str(depth,name)
+ elseif tn=="boolean" then
+ t[n]=f_start_key_boo(depth,name)
+ else
+ t[n]=f_start_key_nop(depth)
+ end
+ end
+ depth=depth+1
+ end
+ if root and next(root)~=nil then
+ local first=nil
+ local last=0
+ last=#root
+ for k=1,last do
+ if rawget(root,k)==nil then
+ last=k-1
+ break
+ end
+ end
+ if last>0 then
+ first=1
+ end
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if first and tk=="number" and k<=last and k>=first then
+ if tv=="number" then
+ n=n+1 t[n]=f_val_num(depth,v)
+ elseif tv=="string" then
+ n=n+1 t[n]=f_val_str(depth,v)
+ elseif tv=="table" then
+ if next(v)==nil then
+ n=n+1 t[n]=f_val_not(depth)
else
- local tn=type(name)
- if tn=="number" then
- t[n]=f_start_key_num(depth,name)
- elseif tn=="string" then
- t[n]=f_start_key_str(depth,name)
- elseif tn=="boolean" then
- t[n]=f_start_key_boo(depth,name)
- else
- t[n]=f_start_key_nop(depth)
- end
- end
- depth=depth+1
- end
- if root and next(root)~=nil then
- local first=nil
- local last=0
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
+ local st=is_simple_table(v)
+ if st then
+ n=n+1 t[n]=f_val_seq(depth,st)
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
end
- if last>0 then
- first=1
+ elseif tv=="boolean" then
+ n=n+1 t[n]=f_val_boo(depth,v)
+ elseif unknown then
+ n=n+1 t[n]=f_val_str(depth,tostring(v))
+ end
+ elseif tv=="number" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_num(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_num(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
+ end
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_not(depth,k)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_not(depth,k)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_not(depth,k)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
end
- local sk=sortedkeys(root)
- for i=1,#sk do
- local k=sk[i]
- local v=root[k]
- local tv=type(v)
- local tk=type(k)
- if first and tk=="number" and k<=last and k>=first then
- if tv=="number" then
- n=n+1 t[n]=f_val_num(depth,v)
- elseif tv=="string" then
- n=n+1 t[n]=f_val_str(depth,v)
- elseif tv=="table" then
- if next(v)==nil then
- n=n+1 t[n]=f_val_not(depth)
- else
- local st=is_simple_table(v)
- if st then
- n=n+1 t[n]=f_val_seq(depth,st)
- else
- do_serialize(v,k,depth,level+1,true)
- end
- end
- elseif tv=="boolean" then
- n=n+1 t[n]=f_val_boo(depth,v)
- elseif unknown then
- n=n+1 t[n]=f_val_str(depth,tostring(v))
- end
- elseif tv=="number" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_num(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_num(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
- end
- elseif tv=="string" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_not(depth,k)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_not(depth,k)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_not(depth,k)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
- end
- else
- local st=is_simple_table(v)
- if not st then
- do_serialize(v,k,depth,level+1)
- elseif tk=="number" then
- n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
- end
- end
- elseif tv=="boolean" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
- end
- else
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
- end
- end
+ else
+ local st=is_simple_table(v)
+ if not st then
+ do_serialize(v,k,depth,level+1)
+ elseif tk=="number" then
+ n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
end
- end
- if level>0 then
- n=n+1 t[n]=f_stop(depth-1)
- end
- end
- local tname=type(name)
- if tname=="string" then
- if name=="return" then
- t={ f_table_return() }
- else
- t={ f_table_name(name) }
- end
- elseif tname=="number" then
- t={ f_table_entry(name) }
- elseif tname=="boolean" then
- if name then
- t={ f_table_return() }
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
+ end
else
- t={ f_table_direct() }
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
+ end
end
+ end
+ end
+ if level>0 then
+ n=n+1 t[n]=f_stop(depth-1)
+ end
+ end
+ local tname=type(name)
+ if tname=="string" then
+ if name=="return" then
+ t={ f_table_return() }
else
- t={ f_table_name("t") }
+ t={ f_table_name(name) }
end
- if root then
- if getmetatable(root) then
- local dummy=root._w_h_a_t_e_v_e_r_
- root._w_h_a_t_e_v_e_r_=nil
- end
- if next(root)~=nil then
- local st=is_simple_table(root)
- if st then
- return t[1]..f_fin_seq(st)
- else
- do_serialize(root,name,1,0)
- end
- end
+ elseif tname=="number" then
+ t={ f_table_entry(name) }
+ elseif tname=="boolean" then
+ if name then
+ t={ f_table_return() }
+ else
+ t={ f_table_direct() }
+ end
+ else
+ t={ f_table_name("t") }
+ end
+ if root then
+ if getmetatable(root) then
+ local dummy=root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_=nil
+ end
+ if next(root)~=nil then
+ local st=is_simple_table(root)
+ if st then
+ return t[1]..f_fin_seq(st)
+ else
+ do_serialize(root,name,1,0)
+ end
end
- n=n+1
- t[n]=f_table_finish()
- return concat(t,"\n")
+ end
+ n=n+1
+ t[n]=f_table_finish()
+ return concat(t,"\n")
end
table.serialize=serialize
if setinspector then
- setinspector("table",function(v)
- if type(v)=="table" then
- print(serialize(v,"table",{ metacheck=false }))
- return true
- end
- end)
+ setinspector("table",function(v)
+ if type(v)=="table" then
+ print(serialize(v,"table",{ metacheck=false }))
+ return true
+ end
+ end)
end
local mt={
- __newindex=function(t,k,v)
- local n=t.last+1
- t.last=n
- t.list[n]=k
- t.hash[k]=v
- end,
- __index=function(t,k)
- return t.hash[k]
- end,
- __len=function(t)
- return t.last
- end,
+ __newindex=function(t,k,v)
+ local n=t.last+1
+ t.last=n
+ t.list[n]=k
+ t.hash[k]=v
+ end,
+ __index=function(t,k)
+ return t.hash[k]
+ end,
+ __len=function(t)
+ return t.last
+ end,
}
function table.orderedhash()
- return setmetatable({ list={},hash={},last=0 },mt)
+ return setmetatable({ list={},hash={},last=0 },mt)
end
function table.ordered(t)
- local n=t.last
- if n>0 then
- local l=t.list
- local i=1
- local h=t.hash
- local f=function()
- if i<=n then
- local k=i
- local v=h[l[k]]
- i=i+1
- return k,v
- end
- end
- return f,1,h[l[1]]
- else
- return function() end
+ local n=t.last
+ if n>0 then
+ local l=t.list
+ local i=1
+ local h=t.hash
+ local f=function()
+ if i<=n then
+ local k=i
+ local v=h[l[k]]
+ i=i+1
+ return k,v
+ end
end
+ return f,1,h[l[1]]
+ else
+ return function() end
+ end
end
@@ -7855,14 +7855,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fil"] = package.loaded["util-fil"] or true
--- original size: 8607, stripped down to: 6990
+-- original size: 8607, stripped down to: 6727
if not modules then modules={} end modules ['util-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber=tonumber
local byte=string.byte
@@ -7872,280 +7872,280 @@ local files={}
utilities.files=files
local zerobased={}
function files.open(filename,zb)
- local f=io.open(filename,"rb")
- if f then
- zerobased[f]=zb or false
- end
- return f
+ local f=io.open(filename,"rb")
+ if f then
+ zerobased[f]=zb or false
+ end
+ return f
end
function files.close(f)
- zerobased[f]=nil
- f:close()
+ zerobased[f]=nil
+ f:close()
end
function files.size(f)
- local current=f:seek()
- local size=f:seek("end")
- f:seek("set",current)
- return size
+ local current=f:seek()
+ local size=f:seek("end")
+ f:seek("set",current)
+ return size
end
files.getsize=files.size
function files.setposition(f,n)
- if zerobased[f] then
- f:seek("set",n)
- else
- f:seek("set",n-1)
- end
+ if zerobased[f] then
+ f:seek("set",n)
+ else
+ f:seek("set",n-1)
+ end
end
function files.getposition(f)
- if zerobased[f] then
- return f:seek()
- else
- return f:seek()+1
- end
+ if zerobased[f] then
+ return f:seek()
+ else
+ return f:seek()+1
+ end
end
function files.look(f,n,chars)
- local p=f:seek()
- local s=f:read(n)
- f:seek("set",p)
- if chars then
- return s
- else
- return byte(s,1,#s)
- end
+ local p=f:seek()
+ local s=f:read(n)
+ f:seek("set",p)
+ if chars then
+ return s
+ else
+ return byte(s,1,#s)
+ end
end
function files.skip(f,n)
- if n==1 then
- f:read(n)
- else
- f:seek("set",f:seek()+n)
- end
+ if n==1 then
+ f:read(n)
+ else
+ f:seek("set",f:seek()+n)
+ end
end
function files.readbyte(f)
- return byte(f:read(1))
+ return byte(f:read(1))
end
function files.readbytes(f,n)
- return byte(f:read(n),1,n)
+ return byte(f:read(n),1,n)
end
function files.readbytetable(f,n)
- local s=f:read(n or 1)
- return { byte(s,1,#s) }
+ local s=f:read(n or 1)
+ return { byte(s,1,#s) }
end
function files.readchar(f)
- return f:read(1)
+ return f:read(1)
end
function files.readstring(f,n)
- return f:read(n or 1)
+ return f:read(n or 1)
end
-function files.readinteger1(f)
- local n=byte(f:read(1))
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+function files.readinteger1(f)
+ local n=byte(f:read(1))
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-files.readcardinal1=files.readbyte
+files.readcardinal1=files.readbyte
files.readcardinal=files.readcardinal1
files.readinteger=files.readinteger1
files.readsignedbyte=files.readinteger1
function files.readcardinal2(f)
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
end
function files.readcardinal2le(f)
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
end
function files.readinteger2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function files.readinteger2le(f)
- local b,a=byte(f:read(2),1,2)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local b,a=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function files.readcardinal3(f)
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
end
function files.readcardinal3le(f)
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
end
function files.readinteger3(f)
- local a,b,c=byte(f:read(3),1,3)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local a,b,c=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function files.readinteger3le(f)
- local c,b,a=byte(f:read(3),1,3)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local c,b,a=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function files.readcardinal4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function files.readcardinal4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function files.readinteger4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function files.readinteger4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local d,c,b,a=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function files.readfixed2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- tonumber((a-0x100).."."..b)
- else
- tonumber((a ).."."..b)
- end
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function files.readfixed4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
- else
- tonumber((0x100*a+b ).."."..(0x100*c+d))
- end
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
end
if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function files.read2dot14(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- local n=-(0x100*a+b)
- return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- else
- local n=0x100*a+b
- return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- end
+ local extract=bit32.extract
+ local band=bit32.band
+ function files.read2dot14(f)
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+ else
+ local n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function files.skipshort(f,n)
- f:read(2*(n or 1))
+ f:read(2*(n or 1))
end
function files.skiplong(f,n)
- f:read(4*(n or 1))
+ f:read(4*(n or 1))
end
if bit32 then
- local rshift=bit32.rshift
- function files.writecardinal2(f,n)
- local a=char(n%256)
- n=rshift(n,8)
- local b=char(n%256)
- f:write(b,a)
- end
-else
- local floor=math.floor
- function files.writecardinal2(f,n)
- local a=char(n%256)
- n=floor(n/256)
- local b=char(n%256)
- f:write(b,a)
- end
-end
-function files.writecardinal4(f,n)
+ local rshift=bit32.rshift
+ function files.writecardinal2(f,n)
local a=char(n%256)
n=rshift(n,8)
local b=char(n%256)
- n=rshift(n,8)
- local c=char(n%256)
- n=rshift(n,8)
- local d=char(n%256)
- f:write(d,c,b,a)
+ f:write(b,a)
+ end
+else
+ local floor=math.floor
+ function files.writecardinal2(f,n)
+ local a=char(n%256)
+ n=floor(n/256)
+ local b=char(n%256)
+ f:write(b,a)
+ end
+end
+function files.writecardinal4(f,n)
+ local a=char(n%256)
+ n=rshift(n,8)
+ local b=char(n%256)
+ n=rshift(n,8)
+ local c=char(n%256)
+ n=rshift(n,8)
+ local d=char(n%256)
+ f:write(d,c,b,a)
end
function files.writestring(f,s)
- f:write(char(byte(s,1,#s)))
+ f:write(char(byte(s,1,#s)))
end
function files.writebyte(f,b)
- f:write(char(b))
+ f:write(char(b))
end
if fio and fio.readcardinal1 then
- files.readcardinal1=fio.readcardinal1
- files.readcardinal2=fio.readcardinal2
- files.readcardinal3=fio.readcardinal3
- files.readcardinal4=fio.readcardinal4
- files.readinteger1=fio.readinteger1
- files.readinteger2=fio.readinteger2
- files.readinteger3=fio.readinteger3
- files.readinteger4=fio.readinteger4
- files.readfixed2=fio.readfixed2
- files.readfixed4=fio.readfixed4
- files.read2dot14=fio.read2dot14
- files.setposition=fio.setposition
- files.getposition=fio.getposition
- files.readbyte=files.readcardinal1
- files.readsignedbyte=files.readinteger1
- files.readcardinal=files.readcardinal1
- files.readinteger=files.readinteger1
- local skipposition=fio.skipposition
- files.skipposition=skipposition
- files.readbytes=fio.readbytes
- files.readbytetable=fio.readbytetable
- function files.skipshort(f,n)
- skipposition(f,2*(n or 1))
- end
- function files.skiplong(f,n)
- skipposition(f,4*(n or 1))
- end
+ files.readcardinal1=fio.readcardinal1
+ files.readcardinal2=fio.readcardinal2
+ files.readcardinal3=fio.readcardinal3
+ files.readcardinal4=fio.readcardinal4
+ files.readinteger1=fio.readinteger1
+ files.readinteger2=fio.readinteger2
+ files.readinteger3=fio.readinteger3
+ files.readinteger4=fio.readinteger4
+ files.readfixed2=fio.readfixed2
+ files.readfixed4=fio.readfixed4
+ files.read2dot14=fio.read2dot14
+ files.setposition=fio.setposition
+ files.getposition=fio.getposition
+ files.readbyte=files.readcardinal1
+ files.readsignedbyte=files.readinteger1
+ files.readcardinal=files.readcardinal1
+ files.readinteger=files.readinteger1
+ local skipposition=fio.skipposition
+ files.skipposition=skipposition
+ files.readbytes=fio.readbytes
+ files.readbytetable=fio.readbytetable
+ function files.skipshort(f,n)
+ skipposition(f,2*(n or 1))
+ end
+ function files.skiplong(f,n)
+ skipposition(f,4*(n or 1))
+ end
end
if fio and fio.readcardinaltable then
- files.readcardinaltable=fio.readcardinaltable
- files.readintegertable=fio.readintegertable
+ files.readcardinaltable=fio.readcardinaltable
+ files.readintegertable=fio.readintegertable
else
- local readcardinal1=files.readcardinal1
- local readcardinal2=files.readcardinal2
- local readcardinal3=files.readcardinal3
- local readcardinal4=files.readcardinal4
- function files.readcardinaltable(f,n,b)
- local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
- return t
- end
- local readinteger1=files.readinteger1
- local readinteger2=files.readinteger2
- local readinteger3=files.readinteger3
- local readinteger4=files.readinteger4
- function files.readintegertable(f,n,b)
- local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
- return t
- end
+ local readcardinal1=files.readcardinal1
+ local readcardinal2=files.readcardinal2
+ local readcardinal3=files.readcardinal3
+ local readcardinal4=files.readcardinal4
+ function files.readcardinaltable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readcardinal1(f) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
+ return t
+ end
+ local readinteger1=files.readinteger1
+ local readinteger2=files.readinteger2
+ local readinteger3=files.readinteger3
+ local readinteger4=files.readinteger4
+ function files.readintegertable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readinteger1(f) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
+ return t
+ end
end
@@ -8155,14 +8155,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sac"] = package.loaded["util-sac"] or true
--- original size: 11065, stripped down to: 8695
+-- original size: 11065, stripped down to: 8209
if not modules then modules={} end modules ['util-sac']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local byte,sub=string.byte,string.sub
local tonumber=tonumber
@@ -8170,397 +8170,397 @@ utilities=utilities or {}
local streams={}
utilities.streams=streams
function streams.open(filename,zerobased)
- local f=filename and io.loaddata(filename)
- if f then
- return { f,1,#f,zerobased or false }
- end
+ local f=filename and io.loaddata(filename)
+ if f then
+ return { f,1,#f,zerobased or false }
+ end
end
function streams.openstring(f,zerobased)
- if f then
- return { f,1,#f,zerobased or false }
- end
+ if f then
+ return { f,1,#f,zerobased or false }
+ end
end
function streams.close()
end
function streams.size(f)
- return f and f[3] or 0
+ return f and f[3] or 0
end
function streams.setposition(f,i)
- if f[4] then
- if i<=0 then
- f[2]=1
- else
- f[2]=i+1
- end
+ if f[4] then
+ if i<=0 then
+ f[2]=1
else
- if i<=1 then
- f[2]=1
- else
- f[2]=i
- end
+ f[2]=i+1
end
-end
-function streams.getposition(f)
- if f[4] then
- return f[2]-1
+ else
+ if i<=1 then
+ f[2]=1
else
- return f[2]
+ f[2]=i
end
+ end
+end
+function streams.getposition(f)
+ if f[4] then
+ return f[2]-1
+ else
+ return f[2]
+ end
end
function streams.look(f,n,chars)
- local b=f[2]
- local e=b+n-1
- if chars then
- return sub(f[1],b,e)
- else
- return byte(f[1],b,e)
- end
+ local b=f[2]
+ local e=b+n-1
+ if chars then
+ return sub(f[1],b,e)
+ else
+ return byte(f[1],b,e)
+ end
end
function streams.skip(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readbyte(f)
- local i=f[2]
- f[2]=i+1
- return byte(f[1],i)
+ local i=f[2]
+ f[2]=i+1
+ return byte(f[1],i)
end
function streams.readbytes(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return byte(f[1],i,j-1)
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return byte(f[1],i,j-1)
end
function streams.readbytetable(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return { byte(f[1],i,j-1) }
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return { byte(f[1],i,j-1) }
end
function streams.skipbytes(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readchar(f)
- local i=f[2]
- f[2]=i+1
- return sub(f[1],i,i)
+ local i=f[2]
+ f[2]=i+1
+ return sub(f[1],i,i)
end
function streams.readstring(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return sub(f[1],i,j-1)
-end
-function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- local n=byte(f[1],i)
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return sub(f[1],i,j-1)
+end
+function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ local n=byte(f[1],i)
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-streams.readcardinal1=streams.readbyte
+streams.readcardinal1=streams.readbyte
streams.readcardinal=streams.readcardinal1
streams.readinteger=streams.readinteger1
function streams.readcardinal2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readcardinal2LE(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readinteger2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readinteger2le(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readcardinal3(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readcardinal3le(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readinteger3(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readinteger3le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readcardinal4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function streams.readinteger4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function streams.readinteger4le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local d,c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local d,c,b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function streams.readfixed2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- tonumber((a-0x100).."."..b)
- else
- tonumber((a ).."."..b)
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function streams.readfixed4(f)
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
+end
+if bit32 then
+ local extract=bit32.extract
+ local band=bit32.band
+ function streams.read2dot14(f)
local i=f[2]
- local j=i+3
+ local j=i+1
f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
+ local a,b=byte(f[1],i,j)
if a>=0x80 then
- tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
else
- tonumber((0x100*a+b ).."."..(0x100*c+d))
- end
-end
-if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function streams.read2dot14(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- local n=-(0x100*a+b)
- return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- else
- local n=0x100*a+b
- return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- end
+ local n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function streams.skipshort(f,n)
- f[2]=f[2]+2*(n or 1)
+ f[2]=f[2]+2*(n or 1)
end
function streams.skiplong(f,n)
- f[2]=f[2]+4*(n or 1)
+ f[2]=f[2]+4*(n or 1)
end
if sio and sio.readcardinal2 then
- local readcardinal1=sio.readcardinal1
- local readcardinal2=sio.readcardinal2
- local readcardinal3=sio.readcardinal3
- local readcardinal4=sio.readcardinal4
- local readinteger1=sio.readinteger1
- local readinteger2=sio.readinteger2
- local readinteger3=sio.readinteger3
- local readinteger4=sio.readinteger4
- local readfixed2=sio.readfixed2
- local readfixed4=sio.readfixed4
- local read2dot14=sio.read2dot14
- local readbytes=sio.readbytes
- local readbytetable=sio.readbytetable
- function streams.readcardinal1(f)
- local i=f[2]
- f[2]=i+1
- return readcardinal1(f[1],i)
- end
- function streams.readcardinal2(f)
- local i=f[2]
- f[2]=i+2
- return readcardinal2(f[1],i)
- end
- function streams.readcardinal3(f)
- local i=f[2]
- f[2]=i+3
- return readcardinal3(f[1],i)
- end
- function streams.readcardinal4(f)
- local i=f[2]
- f[2]=i+4
- return readcardinal4(f[1],i)
- end
- function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- return readinteger1(f[1],i)
- end
- function streams.readinteger2(f)
- local i=f[2]
- f[2]=i+2
- return readinteger2(f[1],i)
- end
- function streams.readinteger3(f)
- local i=f[2]
- f[2]=i+3
- return readinteger3(f[1],i)
- end
- function streams.readinteger4(f)
- local i=f[2]
- f[2]=i+4
- return readinteger4(f[1],i)
- end
- function streams.read2dot4(f)
- local i=f[2]
- f[2]=i+2
- return read2dot4(f[1],i)
- end
- function streams.readbytes(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytes(f[1],i,n)
+ local readcardinal1=sio.readcardinal1
+ local readcardinal2=sio.readcardinal2
+ local readcardinal3=sio.readcardinal3
+ local readcardinal4=sio.readcardinal4
+ local readinteger1=sio.readinteger1
+ local readinteger2=sio.readinteger2
+ local readinteger3=sio.readinteger3
+ local readinteger4=sio.readinteger4
+ local readfixed2=sio.readfixed2
+ local readfixed4=sio.readfixed4
+ local read2dot14=sio.read2dot14
+ local readbytes=sio.readbytes
+ local readbytetable=sio.readbytetable
+ function streams.readcardinal1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readcardinal1(f[1],i)
+ end
+ function streams.readcardinal2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readcardinal2(f[1],i)
+ end
+ function streams.readcardinal3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readcardinal3(f[1],i)
+ end
+ function streams.readcardinal4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readcardinal4(f[1],i)
+ end
+ function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readinteger1(f[1],i)
+ end
+ function streams.readinteger2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readinteger2(f[1],i)
+ end
+ function streams.readinteger3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readinteger3(f[1],i)
+ end
+ function streams.readinteger4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readinteger4(f[1],i)
+ end
+ function streams.read2dot4(f)
+ local i=f[2]
+ f[2]=i+2
+ return read2dot4(f[1],i)
+ end
+ function streams.readbytes(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- function streams.readbytetable(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytetable(f[1],i,n)
+ return readbytes(f[1],i,n)
+ end
+ function streams.readbytetable(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- streams.readbyte=streams.readcardinal1
- streams.readsignedbyte=streams.readinteger1
- streams.readcardinal=streams.readcardinal1
- streams.readinteger=streams.readinteger1
+ return readbytetable(f[1],i,n)
+ end
+ streams.readbyte=streams.readcardinal1
+ streams.readsignedbyte=streams.readinteger1
+ streams.readcardinal=streams.readcardinal1
+ streams.readinteger=streams.readinteger1
end
if sio and sio.readcardinaltable then
- local readcardinaltable=sio.readcardinaltable
- local readintegertable=sio.readintegertable
- function utilities.streams.readcardinaltable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readcardinaltable(f[1],i,n,b)
+ local readcardinaltable=sio.readcardinaltable
+ local readintegertable=sio.readintegertable
+ function utilities.streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- function utilities.streams.readintegertable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readintegertable(f[1],i,n,b)
+ return readcardinaltable(f[1],i,n,b)
+ end
+ function utilities.streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
+ return readintegertable(f[1],i,n,b)
+ end
else
- local readcardinal1=streams.readcardinal1
- local readcardinal2=streams.readcardinal2
- local readcardinal3=streams.readcardinal3
- local readcardinal4=streams.readcardinal4
- function streams.readcardinaltable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
- return t
+ local readcardinal1=streams.readcardinal1
+ local readcardinal2=streams.readcardinal2
+ local readcardinal3=streams.readcardinal3
+ local readcardinal4=streams.readcardinal4
+ function streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- local readinteger1=streams.readinteger1
- local readinteger2=streams.readinteger2
- local readinteger3=streams.readinteger3
- local readinteger4=streams.readinteger4
- function streams.readintegertable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
- return t
+ local t={}
+ if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
+ return t
+ end
+ local readinteger1=streams.readinteger1
+ local readinteger2=streams.readinteger2
+ local readinteger3=streams.readinteger3
+ local readinteger4=streams.readinteger4
+ function streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
+ local t={}
+ if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
+ return t
+ end
end
@@ -8570,168 +8570,168 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sto"] = package.loaded["util-sto"] or true
--- original size: 6661, stripped down to: 3245
+-- original size: 6661, stripped down to: 3074
if not modules then modules={} end modules ['util-sto']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type
utilities=utilities or {}
utilities.storage=utilities.storage or {}
local storage=utilities.storage
function storage.mark(t)
- if not t then
- print("\nfatal error: storage cannot be marked\n")
- os.exit()
- return
- end
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ if not t then
+ print("\nfatal error: storage cannot be marked\n")
+ os.exit()
+ return
+ end
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.allocate(t)
- t=t or {}
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ t=t or {}
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.marked(t)
- local m=getmetatable(t)
- return m and m.__storage__
+ local m=getmetatable(t)
+ return m and m.__storage__
end
function storage.checked(t)
- if not t then
- report("\nfatal error: storage has not been allocated\n")
- os.exit()
- return
- end
- return t
+ if not t then
+ report("\nfatal error: storage has not been allocated\n")
+ os.exit()
+ return
+ end
+ return t
end
function storage.setinitializer(data,initialize)
- local m=getmetatable(data) or {}
- m.__index=function(data,k)
- m.__index=nil
- initialize()
- return data[k]
- end
- setmetatable(data,m)
+ local m=getmetatable(data) or {}
+ m.__index=function(data,k)
+ m.__index=nil
+ initialize()
+ return data[k]
+ end
+ setmetatable(data,m)
end
local keyisvalue={ __index=function(t,k)
- t[k]=k
- return k
+ t[k]=k
+ return k
end }
function storage.sparse(t)
- t=t or {}
- setmetatable(t,keyisvalue)
- return t
-end
-local function f_empty () return "" end
-local function f_self (t,k) t[k]=k return k end
-local function f_table (t,k) local v={} t[k]=v return v end
-local function f_number(t,k) t[k]=0 return 0 end
-local function f_ignore() end
+ t=t or {}
+ setmetatable(t,keyisvalue)
+ return t
+end
+local function f_empty () return "" end
+local function f_self (t,k) t[k]=k return k end
+local function f_table (t,k) local v={} t[k]=v return v end
+local function f_number(t,k) t[k]=0 return 0 end
+local function f_ignore() end
local f_index={
- ["empty"]=f_empty,
- ["self"]=f_self,
- ["table"]=f_table,
- ["number"]=f_number,
+ ["empty"]=f_empty,
+ ["self"]=f_self,
+ ["table"]=f_table,
+ ["number"]=f_number,
}
function table.setmetatableindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- else
- setmetatable(t,{ __index=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ else
+ setmetatable(t,{ __index=i })
+ end
+ return t
end
local f_index={
- ["ignore"]=f_ignore,
+ ["ignore"]=f_ignore,
}
function table.setmetatablenewindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__newindex=i
- else
- setmetatable(t,{ __newindex=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__newindex=i
+ else
+ setmetatable(t,{ __newindex=i })
+ end
+ return t
end
function table.setmetatablecall(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- if m then
- m.__call=f
- else
- setmetatable(t,{ __call=f })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__call=f
+ else
+ setmetatable(t,{ __call=f })
+ end
+ return t
end
function table.setmetatableindices(t,f,n,c)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- m.__newindex=n
- m.__call=c
- else
- setmetatable(t,{
- __index=i,
- __newindex=n,
- __call=c,
- })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ m.__newindex=n
+ m.__call=c
+ else
+ setmetatable(t,{
+ __index=i,
+ __newindex=n,
+ __call=c,
+ })
+ end
+ return t
end
function table.setmetatablekey(t,key,value)
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m[key]=value
- return t
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m[key]=value
+ return t
end
function table.getmetatablekey(t,key,value)
- local m=getmetatable(t)
- return m and m[key]
+ local m=getmetatable(t)
+ return m and m[key]
end
function table.makeweak(t)
- if not t then
- t={}
- end
- local m=getmetatable(t)
- if m then
- m.__mode="v"
- else
- setmetatable(t,{ __mode="v" })
- end
- return t
+ if not t then
+ t={}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__mode="v"
+ else
+ setmetatable(t,{ __mode="v" })
+ end
+ return t
end
@@ -8741,14 +8741,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 23400, stripped down to: 16473
+-- original size: 23400, stripped down to: 15802
if not modules then modules={} end modules ['util-prs']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local lpeg,table,string=lpeg,table,string
local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp
@@ -8790,8 +8790,8 @@ local noparent=1-(lparent+rparent)
local nobracket=1-(lbracket+rbracket)
local escape,left,right=P("\\"),P('{'),P('}')
lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+ [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
+ [2]=left*V(1)*right
}
local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -8799,9 +8799,9 @@ local nestedbrackets=P { lbracket*(nobracket+V(1))^0*rbracket }
local spaces=space^0
local argument=Cs((lbrace/"")*((nobrace+nestedbraces)^0)*(rbrace/""))
local content=(1-endofstring)^0
-lpegpatterns.nestedbraces=nestedbraces
+lpegpatterns.nestedbraces=nestedbraces
lpegpatterns.nestedparents=nestedparents
-lpegpatterns.nested=nestedbraces
+lpegpatterns.nested=nestedbraces
lpegpatterns.argument=argument
lpegpatterns.content=content
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
@@ -8813,7 +8813,7 @@ local key=C((1-space-equal-comma)^1)
local pattern_b=spaces*comma^0*spaces*(key*((spaces*equal*spaces*value)+C("")))
local hash={}
local function set(key,value)
- hash[key]=value
+ hash[key]=value
end
local pattern_a_s=(pattern_a/set)^1
local pattern_b_s=(pattern_b/set)^1
@@ -8824,300 +8824,300 @@ patterns.settings_to_hash_b=pattern_b_s
patterns.settings_to_hash_c=pattern_c_s
patterns.settings_to_hash_d=pattern_d_s
function parsers.make_settings_to_hash_pattern(set,how)
- if how=="strict" then
- return (pattern_c/set)^1
- elseif how=="tolerant" then
- return (pattern_b/set)^1
- else
- return (pattern_a/set)^1
- end
+ if how=="strict" then
+ return (pattern_c/set)^1
+ elseif how=="tolerant" then
+ return (pattern_b/set)^1
+ else
+ return (pattern_a/set)^1
+ end
end
function parsers.settings_to_hash(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_a_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_a_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_colon_too(str)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- else
- hash={}
- lpegmatch(pattern_d_s,str)
- return hash
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ else
+ hash={}
+ lpegmatch(pattern_d_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_tolerant(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_b_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_b_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_strict(str,existing)
- if not str or str=="" then
- return nil
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
- elseif str and str~="" then
- hash=existing or {}
- lpegmatch(pattern_c_s,str)
- return next(hash) and hash
+ if not str or str=="" then
+ return nil
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
+ else
+ return str
end
+ elseif str and str~="" then
+ hash=existing or {}
+ lpegmatch(pattern_c_s,str)
+ return next(hash) and hash
+ end
end
local separator=comma*space^0
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
local pattern=spaces*Ct(value*(separator*value)^0)
patterns.settings_to_array=pattern
function parsers.settings_to_array(str,strict)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- elseif strict then
- if find(str,"{",1,true) then
- return lpegmatch(pattern,str)
- else
- return { str }
- end
- elseif find(str,",",1,true) then
- return lpegmatch(pattern,str)
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ elseif strict then
+ if find(str,"{",1,true) then
+ return lpegmatch(pattern,str)
else
- return { str }
+ return { str }
end
+ elseif find(str,",",1,true) then
+ return lpegmatch(pattern,str)
+ else
+ return { str }
+ end
end
function parsers.settings_to_numbers(str)
- if not str or str=="" then
- return {}
- end
- if type(str)=="table" then
- elseif find(str,",",1,true) then
- str=lpegmatch(pattern,str)
- else
- return { tonumber(str) }
- end
- for i=1,#str do
- str[i]=tonumber(str[i])
- end
- return str
+ if not str or str=="" then
+ return {}
+ end
+ if type(str)=="table" then
+ elseif find(str,",",1,true) then
+ str=lpegmatch(pattern,str)
+ else
+ return { tonumber(str) }
+ end
+ for i=1,#str do
+ str[i]=tonumber(str[i])
+ end
+ return str
end
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
local pattern=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_obey_fences(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache_a={}
local cache_b={}
function parsers.groupedsplitat(symbol,withaction)
- if not symbol then
- symbol=","
- end
- local pattern=(withaction and cache_b or cache_a)[symbol]
- if not pattern then
- local symbols=S(symbol)
- local separator=space^0*symbols*space^0
- local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
- if withaction then
- local withvalue=Carg(1)*value/function(f,s) return f(s) end
- pattern=spaces*withvalue*(separator*withvalue)^0
- cache_b[symbol]=pattern
- else
- pattern=spaces*Ct(value*(separator*value)^0)
- cache_a[symbol]=pattern
- end
- end
- return pattern
+ if not symbol then
+ symbol=","
+ end
+ local pattern=(withaction and cache_b or cache_a)[symbol]
+ if not pattern then
+ local symbols=S(symbol)
+ local separator=space^0*symbols*space^0
+ local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
+ if withaction then
+ local withvalue=Carg(1)*value/function(f,s) return f(s) end
+ pattern=spaces*withvalue*(separator*withvalue)^0
+ cache_b[symbol]=pattern
+ else
+ pattern=spaces*Ct(value*(separator*value)^0)
+ cache_a[symbol]=pattern
+ end
+ end
+ return pattern
end
local pattern_a=parsers.groupedsplitat(",",false)
local pattern_b=parsers.groupedsplitat(",",true)
function parsers.stripped_settings_to_array(str)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_a,str)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_a,str)
+ end
end
function parsers.process_stripped_settings(str,action)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_b,str,1,action)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_b,str,1,action)
+ end
end
local function set(t,v)
- t[#t+1]=v
+ t[#t+1]=v
end
local value=P(Carg(1)*value)/set
local pattern=value*(separator*value)^0*Carg(1)
function parsers.add_settings_to_array(t,str)
- return lpegmatch(pattern,str,nil,t)
+ return lpegmatch(pattern,str,nil,t)
end
function parsers.hash_to_string(h,separator,yes,no,strict,omit)
- if h then
- local t,tn,s={},0,sortedkeys(h)
- omit=omit and tohash(omit)
- for i=1,#s do
- local key=s[i]
- if not omit or not omit[key] then
- local value=h[key]
- if type(value)=="boolean" then
- if yes and no then
- if value then
- tn=tn+1
- t[tn]=key..'='..yes
- elseif not strict then
- tn=tn+1
- t[tn]=key..'='..no
- end
- elseif value or not strict then
- tn=tn+1
- t[tn]=key..'='..tostring(value)
- end
- else
- tn=tn+1
- t[tn]=key..'='..value
- end
- end
+ if h then
+ local t,tn,s={},0,sortedkeys(h)
+ omit=omit and tohash(omit)
+ for i=1,#s do
+ local key=s[i]
+ if not omit or not omit[key] then
+ local value=h[key]
+ if type(value)=="boolean" then
+ if yes and no then
+ if value then
+ tn=tn+1
+ t[tn]=key..'='..yes
+ elseif not strict then
+ tn=tn+1
+ t[tn]=key..'='..no
+ end
+ elseif value or not strict then
+ tn=tn+1
+ t[tn]=key..'='..tostring(value)
+ end
+ else
+ tn=tn+1
+ t[tn]=key..'='..value
end
- return concat(t,separator or ",")
- else
- return ""
+ end
end
+ return concat(t,separator or ",")
+ else
+ return ""
+ end
end
function parsers.array_to_string(a,separator)
- if a then
- return concat(a,separator or ",")
- else
- return ""
- end
+ if a then
+ return concat(a,separator or ",")
+ else
+ return ""
+ end
end
local pattern=Cf(Ct("")*Cg(C((1-S(", "))^1)*S(", ")^0*Cc(true))^1,rawset)
function utilities.parsers.settings_to_set(str)
- return str and lpegmatch(pattern,str) or {}
+ return str and lpegmatch(pattern,str) or {}
end
hashes.settings_to_set=table.setmetatableindex(function(t,k)
- local v=k and lpegmatch(pattern,k) or {}
- t[k]=v
- return v
+ local v=k and lpegmatch(pattern,k) or {}
+ t[k]=v
+ return v
end)
getmetatable(hashes.settings_to_set).__mode="kv"
function parsers.simple_hash_to_string(h,separator)
- local t,tn={},0
- for k,v in sortedhash(h) do
- if v then
- tn=tn+1
- t[tn]=k
- end
+ local t,tn={},0
+ for k,v in sortedhash(h) do
+ if v then
+ tn=tn+1
+ t[tn]=k
end
- return concat(t,separator or ",")
+ end
+ return concat(t,separator or ",")
end
local str=Cs(lpegpatterns.unquoted)+C((1-whitespace-equal)^1)
local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset)
local splitter=setting^1
function utilities.parsers.options_to_hash(str,target)
- return str and lpegmatch(splitter,str,1,target or {}) or {}
+ return str and lpegmatch(splitter,str,1,target or {}) or {}
end
local splitter=lpeg.tsplitat(" ")
function utilities.parsers.options_to_array(str)
- return str and lpegmatch(splitter,str) or {}
+ return str and lpegmatch(splitter,str) or {}
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1)
local pattern_a=spaces*Ct(value*(separator*value)^0)
local function repeater(n,str)
- if not n then
- return str
+ if not n then
+ return str
+ else
+ local s=lpegmatch(pattern_a,str)
+ if n==1 then
+ return unpack(s)
else
- local s=lpegmatch(pattern_a,str)
- if n==1 then
- return unpack(s)
- else
- local t,tn={},0
- for i=1,n do
- for j=1,#s do
- tn=tn+1
- t[tn]=s[j]
- end
- end
- return unpack(t)
+ local t,tn={},0
+ for i=1,n do
+ for j=1,#s do
+ tn=tn+1
+ t[tn]=s[j]
end
+ end
+ return unpack(t)
end
+ end
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+(C(digit^1)/tonumber*lparent*Cs((noparent+nestedparents)^1)*rparent)/repeater+C((nestedbraces+(1-comma))^1)
local pattern_b=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_with_repeat(str,expand)
- if expand then
- return lpegmatch(pattern_b,str) or {}
- else
- return lpegmatch(pattern_a,str) or {}
- end
+ if expand then
+ return lpegmatch(pattern_b,str) or {}
+ else
+ return lpegmatch(pattern_a,str) or {}
+ end
end
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace
local pattern=Ct((space+value)^0)
function parsers.arguments_to_table(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function parsers.getparameters(self,class,parentclass,settings)
- local sc=self[class]
- if not sc then
- sc={}
- self[class]=sc
- if parentclass then
- local sp=self[parentclass]
- if not sp then
- sp={}
- self[parentclass]=sp
- end
- setmetatableindex(sc,sp)
- end
+ local sc=self[class]
+ if not sc then
+ sc={}
+ self[class]=sc
+ if parentclass then
+ local sp=self[parentclass]
+ if not sp then
+ sp={}
+ self[parentclass]=sp
+ end
+ setmetatableindex(sc,sp)
end
- parsers.settings_to_hash(settings,sc)
+ end
+ parsers.settings_to_hash(settings,sc)
end
function parsers.listitem(str)
- return gmatch(str,"[^, ]+")
+ return gmatch(str,"[^, ]+")
end
local pattern=Cs { "start",
- start=V("one")+V("two")+V("three"),
- rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
- thousand=digit*digit*digit,
- one=digit*V("rest"),
- two=digit*digit*V("rest"),
- three=V("thousand")*V("rest"),
+ start=V("one")+V("two")+V("three"),
+ rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
+ thousand=digit*digit*digit,
+ one=digit*V("rest"),
+ two=digit*digit*V("rest"),
+ three=V("thousand")*V("rest"),
}
lpegpatterns.splitthousands=pattern
function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local optionalwhitespace=whitespace^0
lpegpatterns.words=Ct((Cs((1-punctuation-whitespace)^1)+anything)^1)
@@ -9131,75 +9131,75 @@ local key=C((1-equal)^1)
local value=dquote*C((1-dquote-escape*dquote)^0)*dquote
local pattern=Cf(Ct("")*(Cg(key*equal*value)*separator^0)^1,rawset)^0*P(-1)
function parsers.keq_to_hash(str)
- if str and str~="" then
- return lpegmatch(pattern,str)
- else
- return {}
- end
+ if str and str~="" then
+ return lpegmatch(pattern,str)
+ else
+ return {}
+ end
end
local defaultspecification={ separator=",",quote='"' }
function parsers.csvsplitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=specification.quote
- local separator=S(separator~="" and separator or ",")
- local whatever=C((1-separator-newline)^0)
- if quotechar and quotechar~="" then
- local quotedata=nil
- for chr in gmatch(quotechar,".") do
- local quotechar=P(chr)
- local quoteword=quotechar*C((1-quotechar)^0)*quotechar
- if quotedata then
- quotedata=quotedata+quoteword
- else
- quotedata=quoteword
- end
- end
- whatever=quotedata+whatever
- end
- local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
- return function(data)
- return lpegmatch(parser,data)
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=specification.quote
+ local separator=S(separator~="" and separator or ",")
+ local whatever=C((1-separator-newline)^0)
+ if quotechar and quotechar~="" then
+ local quotedata=nil
+ for chr in gmatch(quotechar,".") do
+ local quotechar=P(chr)
+ local quoteword=quotechar*C((1-quotechar)^0)*quotechar
+ if quotedata then
+ quotedata=quotedata+quoteword
+ else
+ quotedata=quoteword
+ end
end
+ whatever=quotedata+whatever
+ end
+ local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
+ return function(data)
+ return lpegmatch(parser,data)
+ end
end
function parsers.rfc4180splitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=P(specification.quote)
- local dquotechar=quotechar*quotechar
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=P(specification.quote)
+ local dquotechar=quotechar*quotechar
/specification.quote
- local separator=S(separator~="" and separator or ",")
- local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
- local non_escaped=C((1-quotechar-newline-separator)^1)
- local field=escaped+non_escaped+Cc("")
- local record=Ct(field*(separator*field)^1)
- local headerline=record*Cp()
- local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
- local headeryes=Ct(morerecords)
- local headernop=Ct(record*morerecords)
- return function(data,getheader)
- if getheader then
- local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(headeryes,data,position)
- return data,header
- else
- return lpegmatch(headernop,data)
- end
- end
+ local separator=S(separator~="" and separator or ",")
+ local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
+ local non_escaped=C((1-quotechar-newline-separator)^1)
+ local field=escaped+non_escaped+Cc("")
+ local record=Ct(field*(separator*field)^1)
+ local headerline=record*Cp()
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
+ return function(data,getheader)
+ if getheader then
+ local header,position=lpegmatch(headerline,data)
+ local data=lpegmatch(headeryes,data,position)
+ return data,header
+ else
+ return lpegmatch(headernop,data)
+ end
+ end
end
local function ranger(first,last,n,action)
- if not first then
- elseif last==true then
- for i=first,n or first do
- action(i)
- end
- elseif last then
- for i=first,last do
- action(i)
- end
- else
- action(first)
+ if not first then
+ elseif last==true then
+ for i=first,n or first do
+ action(i)
+ end
+ elseif last then
+ for i=first,last do
+ action(i)
end
+ else
+ action(first)
+ end
end
local cardinal=lpegpatterns.cardinal/tonumber
local spacers=lpegpatterns.spacer^0
@@ -9207,89 +9207,89 @@ local endofstring=lpegpatterns.endofstring
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
function parsers.stepper(str,n,action)
- if type(n)=="function" then
- lpegmatch(stepper,str,1,false,n or print)
- else
- lpegmatch(stepper,str,1,n,action or print)
- end
+ if type(n)=="function" then
+ lpegmatch(stepper,str,1,false,n or print)
+ else
+ lpegmatch(stepper,str,1,n,action or print)
+ end
end
local pattern_math=Cs((P("%")/"\\percent "+P("^")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
local pattern_text=Cs((P("%")/"\\percent "+(P("^")/"\\high")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
patterns.unittotex=pattern
function parsers.unittotex(str,textmode)
- return lpegmatch(textmode and pattern_text or pattern_math,str)
+ return lpegmatch(textmode and pattern_text or pattern_math,str)
end
local pattern=Cs((P("^")/"<sup>"*lpegpatterns.integer*Cc("</sup>")+anything)^0)
function parsers.unittoxml(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache={}
local spaces=lpegpatterns.space^0
local dummy=function() end
setmetatableindex(cache,function(t,k)
- local separator=P(k)
- local value=(1-separator)^0
- local pattern=spaces*C(value)*separator^0*Cp()
- t[k]=pattern
- return pattern
+ local separator=P(k)
+ local value=(1-separator)^0
+ local pattern=spaces*C(value)*separator^0*Cp()
+ t[k]=pattern
+ return pattern
end)
local commalistiterator=cache[","]
function utilities.parsers.iterator(str,separator)
- local n=#str
- if n==0 then
- return dummy
- else
- local pattern=separator and cache[separator] or commalistiterator
- local p=1
- return function()
- if p<=n then
- local s,e=lpegmatch(pattern,str,p)
- if e then
- p=e
- return s
- end
- end
+ local n=#str
+ if n==0 then
+ return dummy
+ else
+ local pattern=separator and cache[separator] or commalistiterator
+ local p=1
+ return function()
+ if p<=n then
+ local s,e=lpegmatch(pattern,str,p)
+ if e then
+ p=e
+ return s
end
+ end
end
+ end
end
local function initialize(t,name)
- local source=t[name]
- if source then
- local result={}
- for k,v in next,t[name] do
- result[k]=v
- end
- return result
- else
- return {}
+ local source=t[name]
+ if source then
+ local result={}
+ for k,v in next,t[name] do
+ result[k]=v
end
+ return result
+ else
+ return {}
+ end
end
local function fetch(t,name)
- return t[name] or {}
+ return t[name] or {}
end
local function process(result,more)
- for k,v in next,more do
- result[k]=v
- end
- return result
+ for k,v in next,more do
+ result[k]=v
+ end
+ return result
end
local name=C((1-S(", "))^1)
local parser=(Carg(1)*name/initialize)*(S(", ")^1*(Carg(1)*name/fetch))^0
local merge=Cf(parser,process)
function utilities.parsers.mergehashes(hash,list)
- return lpegmatch(merge,list,1,hash)
+ return lpegmatch(merge,list,1,hash)
end
function utilities.parsers.runtime(time)
- if not time then
- time=os.runtime()
- end
- local days=div(time,24*60*60)
- time=mod(time,24*60*60)
- local hours=div(time,60*60)
- time=mod(time,60*60)
- local minutes=div(time,60)
- local seconds=mod(time,60)
- return days,hours,minutes,seconds
+ if not time then
+ time=os.runtime()
+ end
+ local days=div(time,24*60*60)
+ time=mod(time,24*60*60)
+ local hours=div(time,60*60)
+ time=mod(time,60*60)
+ local minutes=div(time,60)
+ local seconds=mod(time,60)
+ return days,hours,minutes,seconds
end
local spacing=whitespace^0
local apply=P("->")
@@ -9297,11 +9297,11 @@ local method=C((1-apply)^1)
local token=lbrace*C((1-rbrace)^1)*rbrace+C(anything^1)
local pattern=spacing*(method*spacing*apply+Carg(1))*spacing*token
function utilities.parsers.splitmethod(str,default)
- if str then
- return lpegmatch(pattern,str,1,default or false)
- else
- return default or false,""
- end
+ if str then
+ return lpegmatch(pattern,str,1,default or false)
+ else
+ return default or false,""
+ end
end
@@ -9311,14 +9311,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fmt"] = package.loaded["util-fmt"] or true
--- original size: 2274, stripped down to: 1781
+-- original size: 2274, stripped down to: 1607
if not modules then modules={} end modules ['util-fmt']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.formatters=utilities.formatters or {}
@@ -9329,60 +9329,60 @@ local strip=string.strip
local lpegmatch=lpeg.match
local stripper=lpeg.patterns.stripzeros
function formatters.stripzeros(str)
- return lpegmatch(stripper,str)
+ return lpegmatch(stripper,str)
end
function formatters.formatcolumns(result,between)
- if result and #result>0 then
- between=between or " "
- local widths,numbers={},{}
- local first=result[1]
- local n=#first
- for i=1,n do
- widths[i]=0
- end
- for i=1,#result do
- local r=result[i]
- for j=1,n do
- local rj=r[j]
- local tj=type(rj)
- if tj=="number" then
- numbers[j]=true
- end
- if tj~="string" then
- rj=tostring(rj)
- r[j]=rj
- end
- local w=#rj
- if w>widths[j] then
- widths[j]=w
- end
- end
+ if result and #result>0 then
+ between=between or " "
+ local widths,numbers={},{}
+ local first=result[1]
+ local n=#first
+ for i=1,n do
+ widths[i]=0
+ end
+ for i=1,#result do
+ local r=result[i]
+ for j=1,n do
+ local rj=r[j]
+ local tj=type(rj)
+ if tj=="number" then
+ numbers[j]=true
+ end
+ if tj~="string" then
+ rj=tostring(rj)
+ r[j]=rj
+ end
+ local w=#rj
+ if w>widths[j] then
+ widths[j]=w
end
- for i=1,n do
- local w=widths[i]
- if numbers[i] then
- if w>80 then
- widths[i]="%s"..between
- else
- widths[i]="%0"..w.."i"..between
- end
- else
- if w>80 then
- widths[i]="%s"..between
- elseif w>0 then
- widths[i]="%-"..w.."s"..between
- else
- widths[i]="%s"
- end
- end
+ end
+ end
+ for i=1,n do
+ local w=widths[i]
+ if numbers[i] then
+ if w>80 then
+ widths[i]="%s"..between
+ else
+ widths[i]="%0"..w.."i"..between
end
- local template=strip(concat(widths))
- for i=1,#result do
- local str=format(template,unpack(result[i]))
- result[i]=strip(str)
+ else
+ if w>80 then
+ widths[i]="%s"..between
+ elseif w>0 then
+ widths[i]="%-"..w.."s"..between
+ else
+ widths[i]="%s"
end
+ end
end
- return result
+ local template=strip(concat(widths))
+ for i=1,#result do
+ local str=format(template,unpack(result[i]))
+ result[i]=strip(str)
+ end
+ end
+ return result
end
@@ -9414,7 +9414,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true
--- original size: 4870, stripped down to: 3861
+-- original size: 4870, stripped down to: 3527
local type,tostring,setmetatable=type,tostring,setmetatable
@@ -9427,67 +9427,67 @@ local tcp6=socket.tcp6
local getaddrinfo=socket.dns.getaddrinfo
local defaulthost="0.0.0.0"
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("socket")
- report(fmt,first,...)
- elseif fmt then
- fmt="socket: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("socket")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="socket: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
socket.report=report
function socket.connect4(address,port,laddress,lport)
- return connect(address,port,laddress,lport,"inet")
+ return connect(address,port,laddress,lport,"inet")
end
function socket.connect6(address,port,laddress,lport)
- return connect(address,port,laddress,lport,"inet6")
+ return connect(address,port,laddress,lport,"inet6")
end
function socket.bind(host,port,backlog)
- if host=="*" or host=="" then
- host=defaulthost
- end
- local addrinfo,err=getaddrinfo(host)
- if not addrinfo then
- return nil,err
- end
- for i=1,#addrinfo do
- local alt=addrinfo[i]
- local sock,err=(alt.family=="inet" and tcp4 or tcp6)()
- if not sock then
- return nil,err or "unknown error"
- end
- sock:setoption("reuseaddr",true)
- local res,err=sock:bind(alt.addr,port)
- if res then
- res,err=sock:listen(backlog)
- if res then
- return sock
- else
- sock:close()
- end
- else
- sock:close()
- end
+ if host=="*" or host=="" then
+ host=defaulthost
+ end
+ local addrinfo,err=getaddrinfo(host)
+ if not addrinfo then
+ return nil,err
+ end
+ for i=1,#addrinfo do
+ local alt=addrinfo[i]
+ local sock,err=(alt.family=="inet" and tcp4 or tcp6)()
+ if not sock then
+ return nil,err or "unknown error"
+ end
+ sock:setoption("reuseaddr",true)
+ local res,err=sock:bind(alt.addr,port)
+ if res then
+ res,err=sock:listen(backlog)
+ if res then
+ return sock
+ else
+ sock:close()
+ end
+ else
+ sock:close()
end
- return nil,"invalid address"
+ end
+ return nil,"invalid address"
end
socket.try=socket.newtry()
function socket.choose(list)
- return function(name,opt1,opt2)
- if type(name)~="string" then
- name,opt1,opt2="default",name,opt1
- end
- local f=list[name or "nil"]
- if f then
- return f(opt1,opt2)
- else
- report("error: unknown key '%s'",tostring(name))
- end
+ return function(name,opt1,opt2)
+ if type(name)~="string" then
+ name,opt1,opt2="default",name,opt1
+ end
+ local f=list[name or "nil"]
+ if f then
+ return f(opt1,opt2)
+ else
+ report("error: unknown key '%s'",tostring(name))
end
+ end
end
local sourcet={}
local sinkt={}
@@ -9495,88 +9495,88 @@ socket.sourcet=sourcet
socket.sinkt=sinkt
socket.BLOCKSIZE=2048
sinkt["close-when-done"]=function(sock)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function(self,chunk,err)
- if chunk then
- return sock:send(chunk)
- else
- sock:close()
- return 1
- end
- end
- }
- )
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },
+ {
+ __call=function(self,chunk,err)
+ if chunk then
+ return sock:send(chunk)
+ else
+ sock:close()
+ return 1
+ end
+ end
+ }
+ )
end
sinkt["keep-open"]=function(sock)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function(self,chunk,err)
- if chunk then
- return sock:send(chunk)
- else
- return 1
- end
- end
- }
- )
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },{
+ __call=function(self,chunk,err)
+ if chunk then
+ return sock:send(chunk)
+ else
+ return 1
+ end
+ end
+ }
+ )
end
sinkt["default"]=sinkt["keep-open"]
socket.sink=socket.choose(sinkt)
sourcet["by-length"]=function(sock,length)
- local blocksize=socket.BLOCKSIZE
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function()
- if length<=0 then
- return nil
- end
- local chunk,err=sock:receive(min(blocksize,length))
- if err then
- return nil,err
- end
- length=length-#chunk
- return chunk
- end
- }
- )
+ local blocksize=socket.BLOCKSIZE
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },
+ {
+ __call=function()
+ if length<=0 then
+ return nil
+ end
+ local chunk,err=sock:receive(min(blocksize,length))
+ if err then
+ return nil,err
+ end
+ length=length-#chunk
+ return chunk
+ end
+ }
+ )
end
sourcet["until-closed"]=function(sock)
- local blocksize=socket.BLOCKSIZE
- local done=false
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function()
- if done then
- return nil
- end
- local chunk,status,partial=sock:receive(blocksize)
- if not status then
- return chunk
- elseif status=="closed" then
- sock:close()
- done=true
- return partial
- else
- return nil,status
- end
- end
- }
- )
+ local blocksize=socket.BLOCKSIZE
+ local done=false
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },{
+ __call=function()
+ if done then
+ return nil
+ end
+ local chunk,status,partial=sock:receive(blocksize)
+ if not status then
+ return chunk
+ elseif status=="closed" then
+ sock:close()
+ done=true
+ return partial
+ else
+ return nil,status
+ end
+ end
+ }
+ )
end
sourcet["default"]=sourcet["until-closed"]
socket.source=socket.choose(sourcet)
@@ -9590,7 +9590,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
--- original size: 25844, stripped down to: 16066
+-- original size: 25844, stripped down to: 14821
local socket=socket or require("socket")
@@ -9608,333 +9608,333 @@ local resumecoroutine=coroutine.resume
local yieldcoroutine=coroutine.yield
local runningcoroutine=coroutine.running
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("copas")
- report(fmt,first,...)
- elseif fmt then
- fmt="copas: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("copas")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="copas: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
local copas={
- _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project",
- _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services",
- _VERSION="Copas 2.0.1",
- autoclose=true,
- running=false,
- report=report,
+ _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project",
+ _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services",
+ _VERSION="Copas 2.0.1",
+ autoclose=true,
+ running=false,
+ report=report,
}
local function statushandler(status,...)
- if status then
- return...
- end
- local err=(...)
- if type(err)=="table" then
- err=err[1]
- end
- report("error: %s",tostring(err))
- return nil,err
+ if status then
+ return...
+ end
+ local err=(...)
+ if type(err)=="table" then
+ err=err[1]
+ end
+ report("error: %s",tostring(err))
+ return nil,err
end
function socket.protect(func)
- return function(...)
- return statushandler(pcall(func,...))
- end
+ return function(...)
+ return statushandler(pcall(func,...))
+ end
end
function socket.newtry(finalizer)
- return function (...)
- local status=(...)
- if not status then
- local detail=select(2,...)
- pcall(finalizer,detail)
- report("error: %s",tostring(detail))
- return
- end
- return...
+ return function (...)
+ local status=(...)
+ if not status then
+ local detail=select(2,...)
+ pcall(finalizer,detail)
+ report("error: %s",tostring(detail))
+ return
end
+ return...
+ end
end
local function newset()
- local reverse={}
- local set={}
- local queue={}
- setmetatable(set,{
- __index={
- insert=function(set,value)
- if not reverse[value] then
- local n=#set+1
- set[n]=value
- reverse[value]=n
- end
- end,
- remove=function(set,value)
- local index=reverse[value]
- if index then
- reverse[value]=nil
- local n=#set
- local top=set[n]
- set[n]=nil
- if top~=value then
- reverse[top]=index
- set[index]=top
- end
- end
- end,
- push=function (set,key,itm)
- local entry=queue[key]
- if entry==nil then
- queue[key]={ itm }
- else
- entry[#entry+1]=itm
- end
- end,
- pop=function (set,key)
- local top=queue[key]
- if top~=nil then
- local ret=remove(top,1)
- if top[1]==nil then
- queue[key]=nil
- end
- return ret
- end
- end
- }
- } )
- return set
-end
-local _sleeping={
- times={},
- cos={},
- lethargy={},
- insert=function()
- end,
- remove=function()
+ local reverse={}
+ local set={}
+ local queue={}
+ setmetatable(set,{
+ __index={
+ insert=function(set,value)
+ if not reverse[value] then
+ local n=#set+1
+ set[n]=value
+ reverse[value]=n
+ end
end,
- push=function(self,sleeptime,co)
- if not co then
- return
- end
- if sleeptime<0 then
- self.lethargy[co]=true
- return
- else
- sleeptime=gettime()+sleeptime
+ remove=function(set,value)
+ local index=reverse[value]
+ if index then
+ reverse[value]=nil
+ local n=#set
+ local top=set[n]
+ set[n]=nil
+ if top~=value then
+ reverse[top]=index
+ set[index]=top
end
- local t=self.times
- local c=self.cos
- local i=1
- local n=#t
- while i<=n and t[i]<=sleeptime do
- i=i+1
- end
- insert(t,i,sleeptime)
- insert(c,i,co)
- end,
- getnext=
- function(self)
- local t=self.times
- local delay=t[1] and t[1]-gettime() or nil
- return delay and max(delay,0) or nil
+ end
end,
- pop=
- function(self,time)
- local t=self.times
- local c=self.cos
- if #t==0 or time<t[1] then
- return
- end
- local co=c[1]
- remove(t,1)
- remove(c,1)
- return co
+ push=function (set,key,itm)
+ local entry=queue[key]
+ if entry==nil then
+ queue[key]={ itm }
+ else
+ entry[#entry+1]=itm
+ end
end,
- wakeup=function(self,co)
- local let=self.lethargy
- if let[co] then
- self:push(0,co)
- let[co]=nil
- else
- local c=self.cos
- local t=self.times
- for i=1,#c do
- if c[i]==co then
- remove(c,i)
- remove(t,i)
- self:push(0,co)
- return
- end
- end
- end
+ pop=function (set,key)
+ local top=queue[key]
+ if top~=nil then
+ local ret=remove(top,1)
+ if top[1]==nil then
+ queue[key]=nil
+ end
+ return ret
+ end
+ end
+ }
+ } )
+ return set
+end
+local _sleeping={
+ times={},
+ cos={},
+ lethargy={},
+ insert=function()
+ end,
+ remove=function()
+ end,
+ push=function(self,sleeptime,co)
+ if not co then
+ return
+ end
+ if sleeptime<0 then
+ self.lethargy[co]=true
+ return
+ else
+ sleeptime=gettime()+sleeptime
+ end
+ local t=self.times
+ local c=self.cos
+ local i=1
+ local n=#t
+ while i<=n and t[i]<=sleeptime do
+ i=i+1
+ end
+ insert(t,i,sleeptime)
+ insert(c,i,co)
+ end,
+ getnext=
+ function(self)
+ local t=self.times
+ local delay=t[1] and t[1]-gettime() or nil
+ return delay and max(delay,0) or nil
+ end,
+ pop=
+ function(self,time)
+ local t=self.times
+ local c=self.cos
+ if #t==0 or time<t[1] then
+ return
+ end
+ local co=c[1]
+ remove(t,1)
+ remove(c,1)
+ return co
+ end,
+ wakeup=function(self,co)
+ local let=self.lethargy
+ if let[co] then
+ self:push(0,co)
+ let[co]=nil
+ else
+ local c=self.cos
+ local t=self.times
+ for i=1,#c do
+ if c[i]==co then
+ remove(c,i)
+ remove(t,i)
+ self:push(0,co)
+ return
end
+ end
+ end
+ end
}
local _servers=newset()
local _reading=newset()
local _writing=newset()
local _reading_log={}
local _writing_log={}
-local _is_timeout={
- timeout=true,
- wantread=true,
- wantwrite=true,
+local _is_timeout={
+ timeout=true,
+ wantread=true,
+ wantwrite=true,
}
local function isTCP(socket)
- return not find(tostring(socket),"^udp")
+ return not find(tostring(socket),"^udp")
end
local function copasreceive(client,pattern,part)
- if not pattern or pattern=="" then
- pattern="*l"
- end
- local current_log=_reading_log
- local s,err
- repeat
- s,err,part=client:receive(pattern,part)
- if s or (not _is_timeout[err]) then
- current_log[client]=nil
- return s,err,part
- end
- if err=="wantwrite" then
- current_log=_writing_log
- current_log[client]=gettime()
- yieldcoroutine(client,_writing)
- else
- current_log=_reading_log
- current_log[client]=gettime()
- yieldcoroutine(client,_reading)
- end
- until false
+ if not pattern or pattern=="" then
+ pattern="*l"
+ end
+ local current_log=_reading_log
+ local s,err
+ repeat
+ s,err,part=client:receive(pattern,part)
+ if s or (not _is_timeout[err]) then
+ current_log[client]=nil
+ return s,err,part
+ end
+ if err=="wantwrite" then
+ current_log=_writing_log
+ current_log[client]=gettime()
+ yieldcoroutine(client,_writing)
+ else
+ current_log=_reading_log
+ current_log[client]=gettime()
+ yieldcoroutine(client,_reading)
+ end
+ until false
end
local function copasreceivefrom(client,size)
- local s,err,port
- if not size or size==0 then
- size=UDP_DATAGRAM_MAX
- end
- repeat
- s,err,port=client:receivefrom(size)
- if s or err~="timeout" then
- _reading_log[client]=nil
- return s,err,port
- end
- _reading_log[client]=gettime()
- yieldcoroutine(client,_reading)
- until false
+ local s,err,port
+ if not size or size==0 then
+ size=UDP_DATAGRAM_MAX
+ end
+ repeat
+ s,err,port=client:receivefrom(size)
+ if s or err~="timeout" then
+ _reading_log[client]=nil
+ return s,err,port
+ end
+ _reading_log[client]=gettime()
+ yieldcoroutine(client,_reading)
+ until false
end
local function copasreceivepartial(client,pattern,part)
- if not pattern or pattern=="" then
- pattern="*l"
- end
- local logger=_reading_log
- local queue=_reading
- local s,err
- repeat
- s,err,part=client:receive(pattern,part)
- if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then
- logger[client]=nil
- return s,err,part
- end
- if err=="wantwrite" then
- logger=_writing_log
- queue=_writing
- else
- logger=_reading_log
- queue=_reading
- end
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- until false
+ if not pattern or pattern=="" then
+ pattern="*l"
+ end
+ local logger=_reading_log
+ local queue=_reading
+ local s,err
+ repeat
+ s,err,part=client:receive(pattern,part)
+ if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then
+ logger[client]=nil
+ return s,err,part
+ end
+ if err=="wantwrite" then
+ logger=_writing_log
+ queue=_writing
+ else
+ logger=_reading_log
+ queue=_reading
+ end
+ logger[client]=gettime()
+ yieldcoroutine(client,queue)
+ until false
end
local function copassend(client,data,from,to)
- if not from then
- from=1
- end
- local lastIndex=from-1
- local logger=_writing_log
- local queue=_writing
- local s,err
- repeat
- s,err,lastIndex=client:send(data,lastIndex+1,to)
- if random(100)>90 then
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- end
- if s or not _is_timeout[err] then
- logger[client]=nil
- return s,err,lastIndex
- end
- if err=="wantread" then
- logger=_reading_log
- queue=_reading
- else
- logger=_writing_log
- queue=_writing
- end
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- until false
+ if not from then
+ from=1
+ end
+ local lastIndex=from-1
+ local logger=_writing_log
+ local queue=_writing
+ local s,err
+ repeat
+ s,err,lastIndex=client:send(data,lastIndex+1,to)
+ if random(100)>90 then
+ logger[client]=gettime()
+ yieldcoroutine(client,queue)
+ end
+ if s or not _is_timeout[err] then
+ logger[client]=nil
+ return s,err,lastIndex
+ end
+ if err=="wantread" then
+ logger=_reading_log
+ queue=_reading
+ else
+ logger=_writing_log
+ queue=_writing
+ end
+ logger[client]=gettime()
+ yieldcoroutine(client,queue)
+ until false
end
local function copassendto(client,data,ip,port)
- repeat
- local s,err=client:sendto(data,ip,port)
- if random(100)>90 then
- _writing_log[client]=gettime()
- yieldcoroutine(client,_writing)
- end
- if s or err~="timeout" then
- _writing_log[client]=nil
- return s,err
- end
- _writing_log[client]=gettime()
- yieldcoroutine(client,_writing)
- until false
+ repeat
+ local s,err=client:sendto(data,ip,port)
+ if random(100)>90 then
+ _writing_log[client]=gettime()
+ yieldcoroutine(client,_writing)
+ end
+ if s or err~="timeout" then
+ _writing_log[client]=nil
+ return s,err
+ end
+ _writing_log[client]=gettime()
+ yieldcoroutine(client,_writing)
+ until false
end
local function copasconnect(skt,host,port)
- skt:settimeout(0)
- local ret,err,tried_more_than_once
- repeat
- ret,err=skt:connect (host,port)
- if ret or (err~="timeout" and err~="Operation already in progress") then
- if not ret and err=="already connected" and tried_more_than_once then
- ret=1
- err=nil
- end
- _writing_log[skt]=nil
- return ret,err
- end
- tried_more_than_once=tried_more_than_once or true
- _writing_log[skt]=gettime()
- yieldcoroutine(skt,_writing)
- until false
+ skt:settimeout(0)
+ local ret,err,tried_more_than_once
+ repeat
+ ret,err=skt:connect (host,port)
+ if ret or (err~="timeout" and err~="Operation already in progress") then
+ if not ret and err=="already connected" and tried_more_than_once then
+ ret=1
+ err=nil
+ end
+ _writing_log[skt]=nil
+ return ret,err
+ end
+ tried_more_than_once=tried_more_than_once or true
+ _writing_log[skt]=gettime()
+ yieldcoroutine(skt,_writing)
+ until false
end
local function copasdohandshake(skt,sslt)
- if not ssl then
- ssl=require("ssl")
- end
- if not ssl then
- report("error: no ssl library")
- return
- end
- local nskt,err=ssl.wrap(skt,sslt)
- if not nskt then
- report("error: %s",tostring(err))
- return
- end
- nskt:settimeout(0)
- local queue
- repeat
- local success,err=nskt:dohandshake()
- if success then
- return nskt
- elseif err=="wantwrite" then
- queue=_writing
- elseif err=="wantread" then
- queue=_reading
- else
- report("error: %s",tostring(err))
- return
- end
- yieldcoroutine(nskt,queue)
- until false
+ if not ssl then
+ ssl=require("ssl")
+ end
+ if not ssl then
+ report("error: no ssl library")
+ return
+ end
+ local nskt,err=ssl.wrap(skt,sslt)
+ if not nskt then
+ report("error: %s",tostring(err))
+ return
+ end
+ nskt:settimeout(0)
+ local queue
+ repeat
+ local success,err=nskt:dohandshake()
+ if success then
+ return nskt
+ elseif err=="wantwrite" then
+ queue=_writing
+ elseif err=="wantread" then
+ queue=_reading
+ else
+ report("error: %s",tostring(err))
+ return
+ end
+ yieldcoroutine(nskt,queue)
+ until false
end
local function copasflush(client)
end
@@ -9948,326 +9948,326 @@ copas.copasreceivePartial=copasreceivepartial
copas.dohandshake=copasdohandshake
copas.flush=copasflush
local function _skt_mt_tostring(self)
- return tostring(self.socket).." (copas wrapped)"
+ return tostring(self.socket).." (copas wrapped)"
end
local _skt_mt_tcp_index={
- send=function(self,data,from,to)
- return copassend (self.socket,data,from,to)
- end,
- receive=function (self,pattern,prefix)
- if self.timeout==0 then
- return copasreceivePartial(self.socket,pattern,prefix)
- else
- return copasreceive(self.socket,pattern,prefix)
- end
- end,
- flush=function (self)
- return copasflush(self.socket)
- end,
- settimeout=function (self,time)
- self.timeout=time
- return true
- end,
- connect=function(self,...)
- local res,err=copasconnect(self.socket,...)
- if res and self.ssl_params then
- res,err=self:dohandshake()
- end
- return res,err
- end,
- close=function(self,...)
- return self.socket:close(...)
- end,
- bind=function(self,...)
- return self.socket:bind(...)
- end,
- getsockname=function(self,...)
- return self.socket:getsockname(...)
- end,
- getstats=function(self,...)
- return self.socket:getstats(...)
- end,
- setstats=function(self,...)
- return self.socket:setstats(...)
- end,
- listen=function(self,...)
- return self.socket:listen(...)
- end,
- accept=function(self,...)
- return self.socket:accept(...)
- end,
- setoption=function(self,...)
- return self.socket:setoption(...)
- end,
- getpeername=function(self,...)
- return self.socket:getpeername(...)
- end,
- shutdown=function(self,...)
- return self.socket:shutdown(...)
- end,
- dohandshake=function(self,sslt)
- self.ssl_params=sslt or self.ssl_params
- local nskt,err=copasdohandshake(self.socket,self.ssl_params)
- if not nskt then
- return nskt,err
- end
- self.socket=nskt
- return self
- end,
+ send=function(self,data,from,to)
+ return copassend (self.socket,data,from,to)
+ end,
+ receive=function (self,pattern,prefix)
+ if self.timeout==0 then
+ return copasreceivePartial(self.socket,pattern,prefix)
+ else
+ return copasreceive(self.socket,pattern,prefix)
+ end
+ end,
+ flush=function (self)
+ return copasflush(self.socket)
+ end,
+ settimeout=function (self,time)
+ self.timeout=time
+ return true
+ end,
+ connect=function(self,...)
+ local res,err=copasconnect(self.socket,...)
+ if res and self.ssl_params then
+ res,err=self:dohandshake()
+ end
+ return res,err
+ end,
+ close=function(self,...)
+ return self.socket:close(...)
+ end,
+ bind=function(self,...)
+ return self.socket:bind(...)
+ end,
+ getsockname=function(self,...)
+ return self.socket:getsockname(...)
+ end,
+ getstats=function(self,...)
+ return self.socket:getstats(...)
+ end,
+ setstats=function(self,...)
+ return self.socket:setstats(...)
+ end,
+ listen=function(self,...)
+ return self.socket:listen(...)
+ end,
+ accept=function(self,...)
+ return self.socket:accept(...)
+ end,
+ setoption=function(self,...)
+ return self.socket:setoption(...)
+ end,
+ getpeername=function(self,...)
+ return self.socket:getpeername(...)
+ end,
+ shutdown=function(self,...)
+ return self.socket:shutdown(...)
+ end,
+ dohandshake=function(self,sslt)
+ self.ssl_params=sslt or self.ssl_params
+ local nskt,err=copasdohandshake(self.socket,self.ssl_params)
+ if not nskt then
+ return nskt,err
+ end
+ self.socket=nskt
+ return self
+ end,
}
local _skt_mt_tcp={
- __tostring=_skt_mt_tostring,
- __index=_skt_mt_tcp_index,
+ __tostring=_skt_mt_tostring,
+ __index=_skt_mt_tcp_index,
}
local _skt_mt_udp_index={
- sendto=function (self,...)
- return copassendto(self.socket,...)
- end,
- receive=function (self,size)
- return copasreceive(self.socket,size or UDP_DATAGRAM_MAX)
- end,
- receivefrom=function (self,size)
- return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX)
- end,
- setpeername=function(self,...)
- return self.socket:getpeername(...)
- end,
- setsockname=function(self,...)
- return self.socket:setsockname(...)
- end,
- close=function(self,...)
- return true
- end
+ sendto=function (self,...)
+ return copassendto(self.socket,...)
+ end,
+ receive=function (self,size)
+ return copasreceive(self.socket,size or UDP_DATAGRAM_MAX)
+ end,
+ receivefrom=function (self,size)
+ return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX)
+ end,
+ setpeername=function(self,...)
+ return self.socket:getpeername(...)
+ end,
+ setsockname=function(self,...)
+ return self.socket:setsockname(...)
+ end,
+ close=function(self,...)
+ return true
+ end
}
local _skt_mt_udp={
- __tostring=_skt_mt_tostring,
- __index=_skt_mt_udp_index,
+ __tostring=_skt_mt_tostring,
+ __index=_skt_mt_udp_index,
}
for k,v in next,_skt_mt_tcp_index do
- if not _skt_mt_udp_index[k] then
- _skt_mt_udp_index[k]=v
- end
+ if not _skt_mt_udp_index[k] then
+ _skt_mt_udp_index[k]=v
+ end
end
local function wrap(skt,sslt)
- if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
- return skt
- end
- skt:settimeout(0)
- if isTCP(skt) then
- return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp)
- else
- return setmetatable ({ socket=skt },_skt_mt_udp)
- end
+ if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
+ return skt
+ end
+ skt:settimeout(0)
+ if isTCP(skt) then
+ return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp)
+ else
+ return setmetatable ({ socket=skt },_skt_mt_udp)
+ end
end
copas.wrap=wrap
function copas.handler(handler,sslparams)
- return function (skt,...)
- skt=wrap(skt)
- if sslparams then
- skt:dohandshake(sslparams)
- end
- return handler(skt,...)
+ return function (skt,...)
+ skt=wrap(skt)
+ if sslparams then
+ skt:dohandshake(sslparams)
end
+ return handler(skt,...)
+ end
end
local _errhandlers={}
function copas.setErrorHandler(err)
- local co=runningcoroutine()
- if co then
- _errhandlers[co]=err
- end
+ local co=runningcoroutine()
+ if co then
+ _errhandlers[co]=err
+ end
end
local function _deferror (msg,co,skt)
- report("%s (%s) (%s)",msg,tostring(co),tostring(skt))
+ report("%s (%s) (%s)",msg,tostring(co),tostring(skt))
end
local function _doTick (co,skt,...)
- if not co then
- return
+ if not co then
+ return
+ end
+ local ok,res,new_q=resumecoroutine(co,skt,...)
+ if ok and res and new_q then
+ new_q:insert(res)
+ new_q:push(res,co)
+ else
+ if not ok then
+ pcall(_errhandlers[co] or _deferror,res,co,skt)
end
- local ok,res,new_q=resumecoroutine(co,skt,...)
- if ok and res and new_q then
- new_q:insert(res)
- new_q:push(res,co)
- else
- if not ok then
- pcall(_errhandlers[co] or _deferror,res,co,skt)
- end
- if skt and copas.autoclose and isTCP(skt) then
- skt:close()
- end
- _errhandlers[co]=nil
+ if skt and copas.autoclose and isTCP(skt) then
+ skt:close()
end
+ _errhandlers[co]=nil
+ end
end
local function _accept(input,handler)
- local client=input:accept()
- if client then
- client:settimeout(0)
- local co=createcoroutine(handler)
- _doTick (co,client)
- end
- return client
+ local client=input:accept()
+ if client then
+ client:settimeout(0)
+ local co=createcoroutine(handler)
+ _doTick (co,client)
+ end
+ return client
end
local function _tickRead(skt)
- _doTick(_reading:pop(skt),skt)
+ _doTick(_reading:pop(skt),skt)
end
local function _tickWrite(skt)
- _doTick(_writing:pop(skt),skt)
+ _doTick(_writing:pop(skt),skt)
end
local function addTCPserver(server,handler,timeout)
- server:settimeout(timeout or 0)
- _servers[server]=handler
- _reading:insert(server)
+ server:settimeout(timeout or 0)
+ _servers[server]=handler
+ _reading:insert(server)
end
local function addUDPserver(server,handler,timeout)
- server:settimeout(timeout or 0)
- local co=createcoroutine(handler)
- _reading:insert(server)
- _doTick(co,server)
+ server:settimeout(timeout or 0)
+ local co=createcoroutine(handler)
+ _reading:insert(server)
+ _doTick(co,server)
end
function copas.addserver(server,handler,timeout)
- if isTCP(server) then
- addTCPserver(server,handler,timeout)
- else
- addUDPserver(server,handler,timeout)
- end
+ if isTCP(server) then
+ addTCPserver(server,handler,timeout)
+ else
+ addUDPserver(server,handler,timeout)
+ end
end
function copas.removeserver(server,keep_open)
- local s=server
- local mt=getmetatable(server)
- if mt==_skt_mt_tcp or mt==_skt_mt_udp then
- s=server.socket
- end
- _servers[s]=nil
- _reading:remove(s)
- if keep_open then
- return true
- end
- return server:close()
+ local s=server
+ local mt=getmetatable(server)
+ if mt==_skt_mt_tcp or mt==_skt_mt_udp then
+ s=server.socket
+ end
+ _servers[s]=nil
+ _reading:remove(s)
+ if keep_open then
+ return true
+ end
+ return server:close()
end
function copas.addthread(handler,...)
- local thread=createcoroutine(function(_,...) return handler(...) end)
- _doTick(thread,nil,...)
- return thread
+ local thread=createcoroutine(function(_,...) return handler(...) end)
+ _doTick(thread,nil,...)
+ return thread
end
local _tasks={}
local function addtaskRead(task)
- task.def_tick=_tickRead
- _tasks[task]=true
+ task.def_tick=_tickRead
+ _tasks[task]=true
end
local function addtaskWrite(task)
- task.def_tick=_tickWrite
- _tasks[task]=true
+ task.def_tick=_tickWrite
+ _tasks[task]=true
end
local function tasks()
- return next,_tasks
+ return next,_tasks
end
local _readable_t={
- events=function(self)
- local i=0
- return function ()
- i=i+1
- return self._evs[i]
- end
- end,
- tick=function(self,input)
- local handler=_servers[input]
- if handler then
- input=_accept(input,handler)
- else
- _reading:remove(input)
- self.def_tick(input)
- end
- end
+ events=function(self)
+ local i=0
+ return function ()
+ i=i+1
+ return self._evs[i]
+ end
+ end,
+ tick=function(self,input)
+ local handler=_servers[input]
+ if handler then
+ input=_accept(input,handler)
+ else
+ _reading:remove(input)
+ self.def_tick(input)
+ end
+ end
}
addtaskRead(_readable_t)
local _writable_t={
- events=function(self)
- local i=0
- return function()
- i=i+1
- return self._evs[i]
- end
- end,
- tick=function(self,output)
- _writing:remove(output)
- self.def_tick(output)
- end
+ events=function(self)
+ local i=0
+ return function()
+ i=i+1
+ return self._evs[i]
+ end
+ end,
+ tick=function(self,output)
+ _writing:remove(output)
+ self.def_tick(output)
+ end
}
addtaskWrite(_writable_t)
local _sleeping_t={
- tick=function(self,time,...)
- _doTick(_sleeping:pop(time),...)
- end
+ tick=function(self,time,...)
+ _doTick(_sleeping:pop(time),...)
+ end
}
function copas.sleep(sleeptime)
- yieldcoroutine((sleeptime or 0),_sleeping)
+ yieldcoroutine((sleeptime or 0),_sleeping)
end
function copas.wakeup(co)
- _sleeping:wakeup(co)
+ _sleeping:wakeup(co)
end
local last_cleansing=0
local function _select(timeout)
- local now=gettime()
- local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout)
- _readable_t._evs=r_evs
- _writable_t._evs=w_evs
- if (last_cleansing-now)>WATCH_DOG_TIMEOUT then
- last_cleansing=now
- for skt,time in next,_reading_log do
- if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
- local n=#r_evs+1
- _reading_log[skt]=nil
- r_evs[n]=skt
- r_evs[skt]=n
- end
- end
- for skt,time in next,_writing_log do
- if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
- local n=#w_evs+1
- _writing_log[skt]=nil
- w_evs[n]=skt
- w_evs[skt]=n
- end
- end
+ local now=gettime()
+ local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout)
+ _readable_t._evs=r_evs
+ _writable_t._evs=w_evs
+ if (last_cleansing-now)>WATCH_DOG_TIMEOUT then
+ last_cleansing=now
+ for skt,time in next,_reading_log do
+ if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
+ local n=#r_evs+1
+ _reading_log[skt]=nil
+ r_evs[n]=skt
+ r_evs[skt]=n
+ end
end
- if err=="timeout" and #r_evs+#w_evs>0 then
- return nil
- else
- return err
+ for skt,time in next,_writing_log do
+ if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
+ local n=#w_evs+1
+ _writing_log[skt]=nil
+ w_evs[n]=skt
+ w_evs[skt]=n
+ end
end
+ end
+ if err=="timeout" and #r_evs+#w_evs>0 then
+ return nil
+ else
+ return err
+ end
end
local function copasfinished()
- return not (next(_reading) or next(_writing) or _sleeping:getnext())
+ return not (next(_reading) or next(_writing) or _sleeping:getnext())
end
local function copasstep(timeout)
- _sleeping_t:tick(gettime())
- local nextwait=_sleeping:getnext()
- if nextwait then
- timeout=timeout and min(nextwait,timeout) or nextwait
- elseif copasfinished() then
- return false
- end
- local err=_select(timeout)
- if err then
- if err=="timeout" then
- return false
- end
- return nil,err
+ _sleeping_t:tick(gettime())
+ local nextwait=_sleeping:getnext()
+ if nextwait then
+ timeout=timeout and min(nextwait,timeout) or nextwait
+ elseif copasfinished() then
+ return false
+ end
+ local err=_select(timeout)
+ if err then
+ if err=="timeout" then
+ return false
end
- for task in tasks() do
- for event in task:events() do
- task:tick(event)
- end
+ return nil,err
+ end
+ for task in tasks() do
+ for event in task:events() do
+ task:tick(event)
end
- return true
+ end
+ return true
end
copas.finished=copasfinished
copas.step=copasstep
function copas.loop(timeout)
- copas.running=true
- while not copasfinished() do
- copasstep(timeout)
- end
- copas.running=false
+ copas.running=true
+ while not copasfinished() do
+ copasstep(timeout)
+ end
+ copas.running=false
end
package.loaded["copas"]=copas
@@ -10278,321 +10278,321 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true
--- original size: 8709, stripped down to: 6105
+-- original size: 8709, stripped down to: 5411
local select,unpack=select,unpack
local insert,remove=table.insert,table.remove
local sub=string.sub
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("ltn12")
- report(fmt,first,...)
- elseif fmt then
- fmt="ltn12: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("ltn12")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="ltn12: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
local filter={}
local source={}
local sink={}
local pump={}
local ltn12={
- _VERSION="LTN12 1.0.3",
- BLOCKSIZE=2048,
- filter=filter,
- source=source,
- sink=sink,
- pump=pump,
- report=report,
+ _VERSION="LTN12 1.0.3",
+ BLOCKSIZE=2048,
+ filter=filter,
+ source=source,
+ sink=sink,
+ pump=pump,
+ report=report,
}
function filter.cycle(low,ctx,extra)
- if low then
- return function(chunk)
- return (low(ctx,chunk,extra))
- end
+ if low then
+ return function(chunk)
+ return (low(ctx,chunk,extra))
end
+ end
end
function filter.chain(...)
- local arg={... }
- local n=select('#',...)
- local top=1
- local index=1
- local retry=""
- return function(chunk)
- retry=chunk and retry
- while true do
- local action=arg[index]
- if index==top then
- chunk=action(chunk)
- if chunk=="" or top==n then
- return chunk
- elseif chunk then
- index=index+1
- else
- top=top+1
- index=top
- end
- else
- chunk=action(chunk or "")
- if chunk=="" then
- index=index-1
- chunk=retry
- elseif chunk then
- if index==n then
- return chunk
- else
- index=index+1
- end
- else
- report("error: filter returned inappropriate 'nil'")
- return
- end
- end
+ local arg={... }
+ local n=select('#',...)
+ local top=1
+ local index=1
+ local retry=""
+ return function(chunk)
+ retry=chunk and retry
+ while true do
+ local action=arg[index]
+ if index==top then
+ chunk=action(chunk)
+ if chunk=="" or top==n then
+ return chunk
+ elseif chunk then
+ index=index+1
+ else
+ top=top+1
+ index=top
+ end
+ else
+ chunk=action(chunk or "")
+ if chunk=="" then
+ index=index-1
+ chunk=retry
+ elseif chunk then
+ if index==n then
+ return chunk
+ else
+ index=index+1
+ end
+ else
+ report("error: filter returned inappropriate 'nil'")
+ return
end
+ end
end
+ end
end
local function empty()
- return nil
+ return nil
end
function source.empty()
- return empty
+ return empty
end
local function sourceerror(err)
- return function()
- return nil,err
- end
+ return function()
+ return nil,err
+ end
end
source.error=sourceerror
function source.file(handle,io_err)
- if handle then
- local blocksize=ltn12.BLOCKSIZE
- return function()
- local chunk=handle:read(blocksize)
- if not chunk then
- handle:close()
- end
- return chunk
- end
- else
- return sourceerror(io_err or "unable to open file")
+ if handle then
+ local blocksize=ltn12.BLOCKSIZE
+ return function()
+ local chunk=handle:read(blocksize)
+ if not chunk then
+ handle:close()
+ end
+ return chunk
end
+ else
+ return sourceerror(io_err or "unable to open file")
+ end
end
function source.simplify(src)
- return function()
- local chunk,err_or_new=src()
- if err_or_new then
- src=err_or_new
- end
- if chunk then
- return chunk
- else
- return nil,err_or_new
- end
+ return function()
+ local chunk,err_or_new=src()
+ if err_or_new then
+ src=err_or_new
+ end
+ if chunk then
+ return chunk
+ else
+ return nil,err_or_new
end
+ end
end
function source.string(s)
- if s then
- local blocksize=ltn12.BLOCKSIZE
- local i=1
- return function()
- local nexti=i+blocksize
- local chunk=sub(s,i,nexti-1)
- i=nexti
- if chunk~="" then
- return chunk
- else
- return nil
- end
- end
- else return source.empty() end
+ if s then
+ local blocksize=ltn12.BLOCKSIZE
+ local i=1
+ return function()
+ local nexti=i+blocksize
+ local chunk=sub(s,i,nexti-1)
+ i=nexti
+ if chunk~="" then
+ return chunk
+ else
+ return nil
+ end
+ end
+ else return source.empty() end
end
function source.rewind(src)
- local t={}
- return function(chunk)
- if chunk then
- insert(t,chunk)
- else
- chunk=remove(t)
- if chunk then
- return chunk
- else
- return src()
- end
- end
+ local t={}
+ return function(chunk)
+ if chunk then
+ insert(t,chunk)
+ else
+ chunk=remove(t)
+ if chunk then
+ return chunk
+ else
+ return src()
+ end
end
+ end
end
function source.chain(src,f,...)
- if... then
- f=filter.chain(f,...)
+ if... then
+ f=filter.chain(f,...)
+ end
+ local last_in=""
+ local last_out=""
+ local state="feeding"
+ local err
+ return function()
+ if not last_out then
+ report("error: source is empty")
+ return
end
- local last_in=""
- local last_out=""
- local state="feeding"
- local err
- return function()
+ while true do
+ if state=="feeding" then
+ last_in,err=src()
+ if err then
+ return nil,err
+ end
+ last_out=f(last_in)
if not last_out then
- report("error: source is empty")
- return
+ if last_in then
+ report("error: filter returned inappropriate 'nil'")
+ end
+ return nil
+ elseif last_out~="" then
+ state="eating"
+ if last_in then
+ last_in=""
+ end
+ return last_out
end
- while true do
- if state=="feeding" then
- last_in,err=src()
- if err then
- return nil,err
- end
- last_out=f(last_in)
- if not last_out then
- if last_in then
- report("error: filter returned inappropriate 'nil'")
- end
- return nil
- elseif last_out~="" then
- state="eating"
- if last_in then
- last_in=""
- end
- return last_out
- end
- else
- last_out=f(last_in)
- if last_out=="" then
- if last_in=="" then
- state="feeding"
- else
- report("error: filter returned nothing")
- return
- end
- elseif not last_out then
- if last_in then
- report("filter returned inappropriate 'nil'")
- end
- return nil
- else
- return last_out
- end
- end
+ else
+ last_out=f(last_in)
+ if last_out=="" then
+ if last_in=="" then
+ state="feeding"
+ else
+ report("error: filter returned nothing")
+ return
+ end
+ elseif not last_out then
+ if last_in then
+ report("filter returned inappropriate 'nil'")
+ end
+ return nil
+ else
+ return last_out
end
+ end
end
+ end
end
function source.cat(...)
- local arg={... }
- local src=remove(arg,1)
- return function()
- while src do
- local chunk,err=src()
- if chunk then
- return chunk
- end
- if err then
- return nil,err
- end
- src=remove(arg,1)
- end
+ local arg={... }
+ local src=remove(arg,1)
+ return function()
+ while src do
+ local chunk,err=src()
+ if chunk then
+ return chunk
+ end
+ if err then
+ return nil,err
+ end
+ src=remove(arg,1)
end
+ end
end
function sink.table(t)
- if not t then
- t={}
- end
- local f=function(chunk,err)
- if chunk then
- insert(t,chunk)
- end
- return 1
+ if not t then
+ t={}
+ end
+ local f=function(chunk,err)
+ if chunk then
+ insert(t,chunk)
end
- return f,t
+ return 1
+ end
+ return f,t
end
function sink.simplify(snk)
- return function(chunk,err)
- local ret,err_or_new=snk(chunk,err)
- if not ret then
- return nil,err_or_new
- end
- if err_or_new then
- snk=err_or_new
- end
- return 1
+ return function(chunk,err)
+ local ret,err_or_new=snk(chunk,err)
+ if not ret then
+ return nil,err_or_new
end
+ if err_or_new then
+ snk=err_or_new
+ end
+ return 1
+ end
end
local function null()
- return 1
+ return 1
end
function sink.null()
- return null
+ return null
end
local function sinkerror(err)
- return function()
- return nil,err
- end
+ return function()
+ return nil,err
+ end
end
sink.error=sinkerror
function sink.file(handle,io_err)
- if handle then
- return function(chunk,err)
- if not chunk then
- handle:close()
- return 1
- else
- return handle:write(chunk)
- end
- end
- else
- return sinkerror(io_err or "unable to open file")
+ if handle then
+ return function(chunk,err)
+ if not chunk then
+ handle:close()
+ return 1
+ else
+ return handle:write(chunk)
+ end
end
+ else
+ return sinkerror(io_err or "unable to open file")
+ end
end
function sink.chain(f,snk,...)
- if... then
- local args={ f,snk,... }
- snk=remove(args,#args)
- f=filter.chain(unpack(args))
- end
- return function(chunk,err)
- if chunk~="" then
- local filtered=f(chunk)
- local done=chunk and ""
- while true do
- local ret,snkerr=snk(filtered,err)
- if not ret then
- return nil,snkerr
- end
- if filtered==done then
- return 1
- end
- filtered=f(done)
- end
- else
- return 1
+ if... then
+ local args={ f,snk,... }
+ snk=remove(args,#args)
+ f=filter.chain(unpack(args))
+ end
+ return function(chunk,err)
+ if chunk~="" then
+ local filtered=f(chunk)
+ local done=chunk and ""
+ while true do
+ local ret,snkerr=snk(filtered,err)
+ if not ret then
+ return nil,snkerr
+ end
+ if filtered==done then
+ return 1
end
+ filtered=f(done)
+ end
+ else
+ return 1
end
+ end
end
function pump.step(src,snk)
- local chunk,src_err=src()
- local ret,snk_err=snk(chunk,src_err)
- if chunk and ret then
- return 1
- else
- return nil,src_err or snk_err
- end
+ local chunk,src_err=src()
+ local ret,snk_err=snk(chunk,src_err)
+ if chunk and ret then
+ return 1
+ else
+ return nil,src_err or snk_err
+ end
end
function pump.all(src,snk,step)
- if not step then
- step=pump.step
- end
- while true do
- local ret,err=step(src,snk)
- if not ret then
- if err then
- return nil,err
- else
- return 1
- end
- end
+ if not step then
+ step=pump.step
+ end
+ while true do
+ local ret,err=step(src,snk)
+ if not ret then
+ if err then
+ return nil,err
+ else
+ return 1
+ end
end
+ end
end
package.loaded["ltn12"]=ltn12
@@ -10603,7 +10603,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true
--- original size: 2328, stripped down to: 1930
+-- original size: 2328, stripped down to: 1874
local type,tostring=type,tostring
@@ -10611,17 +10611,17 @@ local mime=require("mime.core")
local ltn12=ltn12 or require("ltn12")
local filtercycle=ltn12.filter.cycle
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("mime")
- report(fmt,first,...)
- elseif fmt then
- fmt="mime: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("mime")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="mime: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
mime.report=report
local encodet={}
@@ -10639,48 +10639,48 @@ local mime_qpwrp=mime.qpwrp
local mime_eol=mime_eol
local mime_dot=mime_dot
encodet['base64']=function()
- return filtercycle(mime_b64,"")
+ return filtercycle(mime_b64,"")
end
encodet['quoted-printable']=function(mode)
- return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n")
+ return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n")
end
decodet['base64']=function()
- return filtercycle(mime_unb64,"")
+ return filtercycle(mime_unb64,"")
end
decodet['quoted-printable']=function()
- return filtercycle(mime_unqp,"")
+ return filtercycle(mime_unqp,"")
end
local wraptext=function(length)
- if not length then
- length=76
- end
- return filtercycle(mime_wrp,length,length)
+ if not length then
+ length=76
+ end
+ return filtercycle(mime_wrp,length,length)
end
local wrapquoted=function()
- return filtercycle(mime_qpwrp,76,76)
+ return filtercycle(mime_qpwrp,76,76)
end
wrapt['text']=wraptext
wrapt['base64']=wraptext
wrapt['default']=wraptext
wrapt['quoted-printable']=wrapquoted
function mime.normalize(marker)
- return filtercycle(mime_eol,0,marker)
+ return filtercycle(mime_eol,0,marker)
end
function mime.stuff()
- return filtercycle(mime_dot,2)
+ return filtercycle(mime_dot,2)
end
local function choose(list)
- return function(name,opt1,opt2)
- if type(name)~="string" then
- name,opt1,opt2="default",name,opt1
- end
- local filter=list[name or "nil"]
- if filter then
- return filter(opt1,opt2)
- else
- report("error: unknown key '%s'",tostring(name))
- end
+ return function(name,opt1,opt2)
+ if type(name)~="string" then
+ name,opt1,opt2="default",name,opt1
+ end
+ local filter=list[name or "nil"]
+ if filter then
+ return filter(opt1,opt2)
+ else
+ report("error: unknown key '%s'",tostring(name))
end
+ end
end
mime.encode=choose(encodet)
mime.decode=choose(decodet)
@@ -10694,7 +10694,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true
--- original size: 6863, stripped down to: 5657
+-- original size: 6863, stripped down to: 5269
local tonumber,tostring,type=tonumber,tostring,type
@@ -10702,246 +10702,246 @@ local gsub,sub,match,find,format,byte,char=string.gsub,string.sub,string.match,s
local insert=table.insert
local socket=socket or require("socket")
local url={
- _VERSION="URL 1.0.3",
+ _VERSION="URL 1.0.3",
}
socket.url=url
function url.escape(s)
- return (gsub(s,"([^A-Za-z0-9_])",function(c)
- return format("%%%02x",byte(c))
- end))
+ return (gsub(s,"([^A-Za-z0-9_])",function(c)
+ return format("%%%02x",byte(c))
+ end))
end
local function make_set(t)
- local s={}
- for i=1,#t do
- s[t[i]]=true
- end
- return s
+ local s={}
+ for i=1,#t do
+ s[t[i]]=true
+ end
+ return s
end
local segment_set=make_set {
- "-","_",".","!","~","*","'","(",
- ")",":","@","&","=","+","$",",",
+ "-","_",".","!","~","*","'","(",
+ ")",":","@","&","=","+","$",",",
}
local function protect_segment(s)
- return gsub(s,"([^A-Za-z0-9_])",function(c)
- if segment_set[c] then
- return c
- else
- return format("%%%02X",byte(c))
- end
- end)
+ return gsub(s,"([^A-Za-z0-9_])",function(c)
+ if segment_set[c] then
+ return c
+ else
+ return format("%%%02X",byte(c))
+ end
+ end)
end
function url.unescape(s)
- return (gsub(s,"%%(%x%x)",function(hex)
- return char(tonumber(hex,16))
- end))
+ return (gsub(s,"%%(%x%x)",function(hex)
+ return char(tonumber(hex,16))
+ end))
end
local function absolute_path(base_path,relative_path)
- if find(relative_path,"^/") then
- return relative_path
- end
- local path=gsub(base_path,"[^/]*$","")
- path=path..relative_path
- path=gsub(path,"([^/]*%./)",function (s)
- if s~="./" then
- return s
- else
- return ""
- end
+ if find(relative_path,"^/") then
+ return relative_path
+ end
+ local path=gsub(base_path,"[^/]*$","")
+ path=path..relative_path
+ path=gsub(path,"([^/]*%./)",function (s)
+ if s~="./" then
+ return s
+ else
+ return ""
+ end
+ end)
+ path=gsub(path,"/%.$","/")
+ local reduced
+ while reduced~=path do
+ reduced=path
+ path=gsub(reduced,"([^/]*/%.%./)",function (s)
+ if s~="../../" then
+ return ""
+ else
+ return s
+ end
end)
- path=gsub(path,"/%.$","/")
- local reduced
- while reduced~=path do
- reduced=path
- path=gsub(reduced,"([^/]*/%.%./)",function (s)
- if s~="../../" then
- return ""
- else
- return s
- end
- end)
+ end
+ path=gsub(reduced,"([^/]*/%.%.)$",function (s)
+ if s~="../.." then
+ return ""
+ else
+ return s
end
- path=gsub(reduced,"([^/]*/%.%.)$",function (s)
- if s~="../.." then
- return ""
- else
- return s
- end
- end)
- return path
+ end)
+ return path
end
function url.parse(url,default)
- local parsed={}
- for k,v in next,default or parsed do
- parsed[k]=v
- end
- if not url or url=="" then
- return nil,"invalid url"
- end
- url=gsub(url,"#(.*)$",function(f)
- parsed.fragment=f
- return ""
- end)
- url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s)
- parsed.scheme=s
- return ""
- end)
- url=gsub(url,"^//([^/]*)",function(n)
- parsed.authority=n
- return ""
- end)
- url=gsub(url,"%?(.*)",function(q)
- parsed.query=q
- return ""
- end)
- url=gsub(url,"%;(.*)",function(p)
- parsed.params=p
- return ""
- end)
- if url~="" then
- parsed.path=url
- end
- local authority=parsed.authority
- if not authority then
- return parsed
- end
- authority=gsub(authority,"^([^@]*)@",function(u)
- parsed.userinfo=u
- return ""
- end)
- authority=gsub(authority,":([^:%]]*)$",function(p)
- parsed.port=p
- return ""
- end)
- if authority~="" then
- parsed.host=match(authority,"^%[(.+)%]$") or authority
- end
- local userinfo=parsed.userinfo
- if not userinfo then
- return parsed
- end
- userinfo=gsub(userinfo,":([^:]*)$",function(p)
- parsed.password=p
- return ""
- end)
- parsed.user=userinfo
+ local parsed={}
+ for k,v in next,default or parsed do
+ parsed[k]=v
+ end
+ if not url or url=="" then
+ return nil,"invalid url"
+ end
+ url=gsub(url,"#(.*)$",function(f)
+ parsed.fragment=f
+ return ""
+ end)
+ url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s)
+ parsed.scheme=s
+ return ""
+ end)
+ url=gsub(url,"^//([^/]*)",function(n)
+ parsed.authority=n
+ return ""
+ end)
+ url=gsub(url,"%?(.*)",function(q)
+ parsed.query=q
+ return ""
+ end)
+ url=gsub(url,"%;(.*)",function(p)
+ parsed.params=p
+ return ""
+ end)
+ if url~="" then
+ parsed.path=url
+ end
+ local authority=parsed.authority
+ if not authority then
return parsed
+ end
+ authority=gsub(authority,"^([^@]*)@",function(u)
+ parsed.userinfo=u
+ return ""
+ end)
+ authority=gsub(authority,":([^:%]]*)$",function(p)
+ parsed.port=p
+ return ""
+ end)
+ if authority~="" then
+ parsed.host=match(authority,"^%[(.+)%]$") or authority
+ end
+ local userinfo=parsed.userinfo
+ if not userinfo then
+ return parsed
+ end
+ userinfo=gsub(userinfo,":([^:]*)$",function(p)
+ parsed.password=p
+ return ""
+ end)
+ parsed.user=userinfo
+ return parsed
end
function url.build(parsed)
- local url=parsed.path or ""
- if parsed.params then
- url=url..";"..parsed.params
- end
- if parsed.query then
- url=url.."?"..parsed.query
- end
- local authority=parsed.authority
- if parsed.host then
- authority=parsed.host
- if find(authority,":") then
- authority="["..authority.."]"
- end
- if parsed.port then
- authority=authority..":"..tostring(parsed.port)
- end
- local userinfo=parsed.userinfo
- if parsed.user then
- userinfo=parsed.user
- if parsed.password then
- userinfo=userinfo..":"..parsed.password
- end
- end
- if userinfo then authority=userinfo.."@"..authority end
+ local url=parsed.path or ""
+ if parsed.params then
+ url=url..";"..parsed.params
+ end
+ if parsed.query then
+ url=url.."?"..parsed.query
+ end
+ local authority=parsed.authority
+ if parsed.host then
+ authority=parsed.host
+ if find(authority,":") then
+ authority="["..authority.."]"
+ end
+ if parsed.port then
+ authority=authority..":"..tostring(parsed.port)
end
- if authority then
- url="//"..authority..url
- end
- if parsed.scheme then
- url=parsed.scheme..":"..url
- end
- if parsed.fragment then
- url=url.."#"..parsed.fragment
+ local userinfo=parsed.userinfo
+ if parsed.user then
+ userinfo=parsed.user
+ if parsed.password then
+ userinfo=userinfo..":"..parsed.password
+ end
end
- return url
+ if userinfo then authority=userinfo.."@"..authority end
+ end
+ if authority then
+ url="//"..authority..url
+ end
+ if parsed.scheme then
+ url=parsed.scheme..":"..url
+ end
+ if parsed.fragment then
+ url=url.."#"..parsed.fragment
+ end
+ return url
end
function url.absolute(base_url,relative_url)
- local base_parsed
- if type(base_url)=="table" then
- base_parsed=base_url
- base_url=url.build(base_parsed)
- else
- base_parsed=url.parse(base_url)
- end
- local relative_parsed=url.parse(relative_url)
- if not base_parsed then
- return relative_url
- elseif not relative_parsed then
- return base_url
- elseif relative_parsed.scheme then
- return relative_url
- else
- relative_parsed.scheme=base_parsed.scheme
- if not relative_parsed.authority then
- relative_parsed.authority=base_parsed.authority
- if not relative_parsed.path then
- relative_parsed.path=base_parsed.path
- if not relative_parsed.params then
- relative_parsed.params=base_parsed.params
- if not relative_parsed.query then
- relative_parsed.query=base_parsed.query
- end
- end
- else
- relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path)
- end
+ local base_parsed
+ if type(base_url)=="table" then
+ base_parsed=base_url
+ base_url=url.build(base_parsed)
+ else
+ base_parsed=url.parse(base_url)
+ end
+ local relative_parsed=url.parse(relative_url)
+ if not base_parsed then
+ return relative_url
+ elseif not relative_parsed then
+ return base_url
+ elseif relative_parsed.scheme then
+ return relative_url
+ else
+ relative_parsed.scheme=base_parsed.scheme
+ if not relative_parsed.authority then
+ relative_parsed.authority=base_parsed.authority
+ if not relative_parsed.path then
+ relative_parsed.path=base_parsed.path
+ if not relative_parsed.params then
+ relative_parsed.params=base_parsed.params
+ if not relative_parsed.query then
+ relative_parsed.query=base_parsed.query
+ end
end
- return url.build(relative_parsed)
+ else
+ relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path)
+ end
end
+ return url.build(relative_parsed)
+ end
end
function url.parse_path(path)
- local parsed={}
- path=path or ""
- gsub(path,"([^/]+)",function (s)
- insert(parsed,s)
- end)
- for i=1,#parsed do
- parsed[i]=url.unescape(parsed[i])
- end
- if sub(path,1,1)=="/" then
- parsed.is_absolute=1
- end
- if sub(path,-1,-1)=="/" then
- parsed.is_directory=1
- end
- return parsed
+ local parsed={}
+ path=path or ""
+ gsub(path,"([^/]+)",function (s)
+ insert(parsed,s)
+ end)
+ for i=1,#parsed do
+ parsed[i]=url.unescape(parsed[i])
+ end
+ if sub(path,1,1)=="/" then
+ parsed.is_absolute=1
+ end
+ if sub(path,-1,-1)=="/" then
+ parsed.is_directory=1
+ end
+ return parsed
end
function url.build_path(parsed,unsafe)
- local path=""
- local n=#parsed
- if unsafe then
- for i=1,n-1 do
- path=path..parsed[i].."/"
- end
- if n>0 then
- path=path..parsed[n]
- if parsed.is_directory then
- path=path.."/"
- end
- end
- else
- for i=1,n-1 do
- path=path..protect_segment(parsed[i]).."/"
- end
- if n>0 then
- path=path..protect_segment(parsed[n])
- if parsed.is_directory then
- path=path.."/"
- end
- end
+ local path=""
+ local n=#parsed
+ if unsafe then
+ for i=1,n-1 do
+ path=path..parsed[i].."/"
end
- if parsed.is_absolute then
- path="/"..path
+ if n>0 then
+ path=path..parsed[n]
+ if parsed.is_directory then
+ path=path.."/"
+ end
end
- return path
+ else
+ for i=1,n-1 do
+ path=path..protect_segment(parsed[i]).."/"
+ end
+ if n>0 then
+ path=path..protect_segment(parsed[n])
+ if parsed.is_directory then
+ path=path.."/"
+ end
+ end
+ end
+ if parsed.is_absolute then
+ path="/"..path
+ end
+ return path
end
package.loaded["socket.url"]=url
@@ -10952,7 +10952,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true
--- original size: 5721, stripped down to: 3878
+-- original size: 5721, stripped down to: 3754
local next=next
@@ -10962,128 +10962,128 @@ local socket=socket or require("socket")
local headers={}
socket.headers=headers
local canonic={
- ["accept"]="Accept",
- ["accept-charset"]="Accept-Charset",
- ["accept-encoding"]="Accept-Encoding",
- ["accept-language"]="Accept-Language",
- ["accept-ranges"]="Accept-Ranges",
- ["action"]="Action",
- ["alternate-recipient"]="Alternate-Recipient",
- ["age"]="Age",
- ["allow"]="Allow",
- ["arrival-date"]="Arrival-Date",
- ["authorization"]="Authorization",
- ["bcc"]="Bcc",
- ["cache-control"]="Cache-Control",
- ["cc"]="Cc",
- ["comments"]="Comments",
- ["connection"]="Connection",
- ["content-description"]="Content-Description",
- ["content-disposition"]="Content-Disposition",
- ["content-encoding"]="Content-Encoding",
- ["content-id"]="Content-ID",
- ["content-language"]="Content-Language",
- ["content-length"]="Content-Length",
- ["content-location"]="Content-Location",
- ["content-md5"]="Content-MD5",
- ["content-range"]="Content-Range",
- ["content-transfer-encoding"]="Content-Transfer-Encoding",
- ["content-type"]="Content-Type",
- ["cookie"]="Cookie",
- ["date"]="Date",
- ["diagnostic-code"]="Diagnostic-Code",
- ["dsn-gateway"]="DSN-Gateway",
- ["etag"]="ETag",
- ["expect"]="Expect",
- ["expires"]="Expires",
- ["final-log-id"]="Final-Log-ID",
- ["final-recipient"]="Final-Recipient",
- ["from"]="From",
- ["host"]="Host",
- ["if-match"]="If-Match",
- ["if-modified-since"]="If-Modified-Since",
- ["if-none-match"]="If-None-Match",
- ["if-range"]="If-Range",
- ["if-unmodified-since"]="If-Unmodified-Since",
- ["in-reply-to"]="In-Reply-To",
- ["keywords"]="Keywords",
- ["last-attempt-date"]="Last-Attempt-Date",
- ["last-modified"]="Last-Modified",
- ["location"]="Location",
- ["max-forwards"]="Max-Forwards",
- ["message-id"]="Message-ID",
- ["mime-version"]="MIME-Version",
- ["original-envelope-id"]="Original-Envelope-ID",
- ["original-recipient"]="Original-Recipient",
- ["pragma"]="Pragma",
- ["proxy-authenticate"]="Proxy-Authenticate",
- ["proxy-authorization"]="Proxy-Authorization",
- ["range"]="Range",
- ["received"]="Received",
- ["received-from-mta"]="Received-From-MTA",
- ["references"]="References",
- ["referer"]="Referer",
- ["remote-mta"]="Remote-MTA",
- ["reply-to"]="Reply-To",
- ["reporting-mta"]="Reporting-MTA",
- ["resent-bcc"]="Resent-Bcc",
- ["resent-cc"]="Resent-Cc",
- ["resent-date"]="Resent-Date",
- ["resent-from"]="Resent-From",
- ["resent-message-id"]="Resent-Message-ID",
- ["resent-reply-to"]="Resent-Reply-To",
- ["resent-sender"]="Resent-Sender",
- ["resent-to"]="Resent-To",
- ["retry-after"]="Retry-After",
- ["return-path"]="Return-Path",
- ["sender"]="Sender",
- ["server"]="Server",
- ["smtp-remote-recipient"]="SMTP-Remote-Recipient",
- ["status"]="Status",
- ["subject"]="Subject",
- ["te"]="TE",
- ["to"]="To",
- ["trailer"]="Trailer",
- ["transfer-encoding"]="Transfer-Encoding",
- ["upgrade"]="Upgrade",
- ["user-agent"]="User-Agent",
- ["vary"]="Vary",
- ["via"]="Via",
- ["warning"]="Warning",
- ["will-retry-until"]="Will-Retry-Until",
- ["www-authenticate"]="WWW-Authenticate",
- ["x-mailer"]="X-Mailer",
+ ["accept"]="Accept",
+ ["accept-charset"]="Accept-Charset",
+ ["accept-encoding"]="Accept-Encoding",
+ ["accept-language"]="Accept-Language",
+ ["accept-ranges"]="Accept-Ranges",
+ ["action"]="Action",
+ ["alternate-recipient"]="Alternate-Recipient",
+ ["age"]="Age",
+ ["allow"]="Allow",
+ ["arrival-date"]="Arrival-Date",
+ ["authorization"]="Authorization",
+ ["bcc"]="Bcc",
+ ["cache-control"]="Cache-Control",
+ ["cc"]="Cc",
+ ["comments"]="Comments",
+ ["connection"]="Connection",
+ ["content-description"]="Content-Description",
+ ["content-disposition"]="Content-Disposition",
+ ["content-encoding"]="Content-Encoding",
+ ["content-id"]="Content-ID",
+ ["content-language"]="Content-Language",
+ ["content-length"]="Content-Length",
+ ["content-location"]="Content-Location",
+ ["content-md5"]="Content-MD5",
+ ["content-range"]="Content-Range",
+ ["content-transfer-encoding"]="Content-Transfer-Encoding",
+ ["content-type"]="Content-Type",
+ ["cookie"]="Cookie",
+ ["date"]="Date",
+ ["diagnostic-code"]="Diagnostic-Code",
+ ["dsn-gateway"]="DSN-Gateway",
+ ["etag"]="ETag",
+ ["expect"]="Expect",
+ ["expires"]="Expires",
+ ["final-log-id"]="Final-Log-ID",
+ ["final-recipient"]="Final-Recipient",
+ ["from"]="From",
+ ["host"]="Host",
+ ["if-match"]="If-Match",
+ ["if-modified-since"]="If-Modified-Since",
+ ["if-none-match"]="If-None-Match",
+ ["if-range"]="If-Range",
+ ["if-unmodified-since"]="If-Unmodified-Since",
+ ["in-reply-to"]="In-Reply-To",
+ ["keywords"]="Keywords",
+ ["last-attempt-date"]="Last-Attempt-Date",
+ ["last-modified"]="Last-Modified",
+ ["location"]="Location",
+ ["max-forwards"]="Max-Forwards",
+ ["message-id"]="Message-ID",
+ ["mime-version"]="MIME-Version",
+ ["original-envelope-id"]="Original-Envelope-ID",
+ ["original-recipient"]="Original-Recipient",
+ ["pragma"]="Pragma",
+ ["proxy-authenticate"]="Proxy-Authenticate",
+ ["proxy-authorization"]="Proxy-Authorization",
+ ["range"]="Range",
+ ["received"]="Received",
+ ["received-from-mta"]="Received-From-MTA",
+ ["references"]="References",
+ ["referer"]="Referer",
+ ["remote-mta"]="Remote-MTA",
+ ["reply-to"]="Reply-To",
+ ["reporting-mta"]="Reporting-MTA",
+ ["resent-bcc"]="Resent-Bcc",
+ ["resent-cc"]="Resent-Cc",
+ ["resent-date"]="Resent-Date",
+ ["resent-from"]="Resent-From",
+ ["resent-message-id"]="Resent-Message-ID",
+ ["resent-reply-to"]="Resent-Reply-To",
+ ["resent-sender"]="Resent-Sender",
+ ["resent-to"]="Resent-To",
+ ["retry-after"]="Retry-After",
+ ["return-path"]="Return-Path",
+ ["sender"]="Sender",
+ ["server"]="Server",
+ ["smtp-remote-recipient"]="SMTP-Remote-Recipient",
+ ["status"]="Status",
+ ["subject"]="Subject",
+ ["te"]="TE",
+ ["to"]="To",
+ ["trailer"]="Trailer",
+ ["transfer-encoding"]="Transfer-Encoding",
+ ["upgrade"]="Upgrade",
+ ["user-agent"]="User-Agent",
+ ["vary"]="Vary",
+ ["via"]="Via",
+ ["warning"]="Warning",
+ ["will-retry-until"]="Will-Retry-Until",
+ ["www-authenticate"]="WWW-Authenticate",
+ ["x-mailer"]="X-Mailer",
}
headers.canonic=setmetatable(canonic,{
- __index=function(t,k)
- socket.report("invalid header: %s",k)
- t[k]=k
- return k
- end
+ __index=function(t,k)
+ socket.report("invalid header: %s",k)
+ t[k]=k
+ return k
+ end
})
function headers.normalize(headers)
- if not headers then
- return {}
- end
- local normalized={}
- for k,v in next,headers do
- normalized[#normalized+1]=canonic[k]..": "..v
- end
- normalized[#normalized+1]=""
- normalized[#normalized+1]=""
- return concat(normalized,"\r\n")
+ if not headers then
+ return {}
+ end
+ local normalized={}
+ for k,v in next,headers do
+ normalized[#normalized+1]=canonic[k]..": "..v
+ end
+ normalized[#normalized+1]=""
+ normalized[#normalized+1]=""
+ return concat(normalized,"\r\n")
end
function headers.lower(lowered,headers)
- if not lowered then
- return {}
- end
- if not headers then
- lowered,headers={},lowered
- end
- for k,v in next,headers do
- lowered[lower(k)]=v
- end
- return lowered
+ if not lowered then
+ return {}
+ end
+ if not headers then
+ lowered,headers={},lowered
+ end
+ for k,v in next,headers do
+ lowered[lower(k)]=v
+ end
+ return lowered
end
socket.headers=headers
package.loaded["socket.headers"]=headers
@@ -11095,13 +11095,13 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true
--- original size: 3116, stripped down to: 2643
+-- original size: 3116, stripped down to: 2533
local setmetatable,next,type,tonumber=setmetatable,next,type,tonumber
local find,upper=string.find,string.upper
local socket=socket or require("socket")
-local ltn12=ltn12 or require("ltn12")
+local ltn12=ltn12 or require("ltn12")
local skipsocket=socket.skip
local sinksocket=socket.sink
local tcpsocket=socket.tcp
@@ -11109,111 +11109,111 @@ local ltn12pump=ltn12.pump
local pumpall=ltn12pump.all
local pumpstep=ltn12pump.step
local tp={
- TIMEOUT=60,
+ TIMEOUT=60,
}
socket.tp=tp
local function get_reply(c)
- local line,err=c:receive()
- local reply=line
- if err then return
- nil,err
- end
- local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
- if not code then
- return nil,"invalid server reply"
- end
- if sep=="-" then
- local current
- repeat
- line,err=c:receive()
- if err then
- return nil,err
- end
- current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
- reply=reply.."\n"..line
- until code==current and sep==" "
- end
- return code,reply
+ local line,err=c:receive()
+ local reply=line
+ if err then return
+ nil,err
+ end
+ local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
+ if not code then
+ return nil,"invalid server reply"
+ end
+ if sep=="-" then
+ local current
+ repeat
+ line,err=c:receive()
+ if err then
+ return nil,err
+ end
+ current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
+ reply=reply.."\n"..line
+ until code==current and sep==" "
+ end
+ return code,reply
end
local methods={}
local mt={ __index=methods }
function methods.getpeername(self)
- return self.c:getpeername()
+ return self.c:getpeername()
end
function methods.getsockname(self)
- return self.c:getpeername()
+ return self.c:getpeername()
end
function methods.check(self,ok)
- local code,reply=get_reply(self.c)
- if not code then
- return nil,reply
- end
- local c=tonumber(code)
- local t=type(ok)
- if t=="function" then
- return ok(c,reply)
- elseif t=="table" then
- for i=1,#ok do
- if find(code,ok[i]) then
- return c,reply
- end
- end
- return nil,reply
- elseif find(code,ok) then
+ local code,reply=get_reply(self.c)
+ if not code then
+ return nil,reply
+ end
+ local c=tonumber(code)
+ local t=type(ok)
+ if t=="function" then
+ return ok(c,reply)
+ elseif t=="table" then
+ for i=1,#ok do
+ if find(code,ok[i]) then
return c,reply
- else
- return nil,reply
+ end
end
+ return nil,reply
+ elseif find(code,ok) then
+ return c,reply
+ else
+ return nil,reply
+ end
end
function methods.command(self,cmd,arg)
- cmd=upper(cmd)
- if arg then
- cmd=cmd.." "..arg.."\r\n"
- else
- cmd=cmd.."\r\n"
- end
- return self.c:send(cmd)
+ cmd=upper(cmd)
+ if arg then
+ cmd=cmd.." "..arg.."\r\n"
+ else
+ cmd=cmd.."\r\n"
+ end
+ return self.c:send(cmd)
end
function methods.sink(self,snk,pat)
- local chunk,err=self.c:receive(pat)
- return snk(chunk,err)
+ local chunk,err=self.c:receive(pat)
+ return snk(chunk,err)
end
function methods.send(self,data)
- return self.c:send(data)
+ return self.c:send(data)
end
function methods.receive(self,pat)
- return self.c:receive(pat)
+ return self.c:receive(pat)
end
function methods.getfd(self)
- return self.c:getfd()
+ return self.c:getfd()
end
function methods.dirty(self)
- return self.c:dirty()
+ return self.c:dirty()
end
function methods.getcontrol(self)
- return self.c
+ return self.c
end
function methods.source(self,source,step)
- local sink=sinksocket("keep-open",self.c)
- local ret,err=pumpall(source,sink,step or pumpstep)
- return ret,err
+ local sink=sinksocket("keep-open",self.c)
+ local ret,err=pumpall(source,sink,step or pumpstep)
+ return ret,err
end
function methods.close(self)
- self.c:close()
- return 1
+ self.c:close()
+ return 1
end
function tp.connect(host,port,timeout,create)
- local c,e=(create or tcpsocket)()
- if not c then
- return nil,e
- end
- c:settimeout(timeout or tp.TIMEOUT)
- local r,e=c:connect(host,port)
- if not r then
- c:close()
- return nil,e
- end
- return setmetatable({ c=c },mt)
+ local c,e=(create or tcpsocket)()
+ if not c then
+ return nil,e
+ end
+ c:settimeout(timeout or tp.TIMEOUT)
+ local r,e=c:connect(host,port)
+ if not r then
+ c:close()
+ return nil,e
+ end
+ return setmetatable({ c=c },mt)
end
package.loaded["socket.tp"]=tp
@@ -11224,16 +11224,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true
--- original size: 12577, stripped down to: 10069
+-- original size: 12577, stripped down to: 9577
local tostring,tonumber,setmetatable,next,type=tostring,tonumber,setmetatable,next,type
local find,lower,format,gsub,match=string.find,string.lower,string.format,string.gsub,string.match
local concat=table.concat
-local socket=socket or require("socket")
-local url=socket.url or require("socket.url")
-local ltn12=ltn12 or require("ltn12")
-local mime=mime or require("mime")
+local socket=socket or require("socket")
+local url=socket.url or require("socket.url")
+local ltn12=ltn12 or require("ltn12")
+local mime=mime or require("mime")
local headers=socket.headers or require("socket.headers")
local normalizeheaders=headers.normalize
local parseurl=url.parse
@@ -11257,345 +11257,345 @@ local sinktable=ltn12.sink.table
local lowerheaders=headers.lower
local mimeb64=mime.b64
local http={
- TIMEOUT=60,
- USERAGENT=socket._VERSION,
+ TIMEOUT=60,
+ USERAGENT=socket._VERSION,
}
socket.http=http
local PORT=80
local SCHEMES={
- http=true,
+ http=true,
}
local function receiveheaders(sock,headers)
- if not headers then
- headers={}
- end
- local line,err=sock:receive()
+ if not headers then
+ headers={}
+ end
+ local line,err=sock:receive()
+ if err then
+ return nil,err
+ end
+ while line~="" do
+ local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
+ if not (name and value) then
+ return nil,"malformed reponse headers"
+ end
+ name=lower(name)
+ line,err=sock:receive()
if err then
+ return nil,err
+ end
+ while find(line,"^%s") do
+ value=value..line
+ line=sock:receive()
+ if err then
return nil,err
+ end
end
- while line~="" do
- local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
- if not (name and value) then
- return nil,"malformed reponse headers"
- end
- name=lower(name)
- line,err=sock:receive()
+ local found=headers[name]
+ if found then
+ value=found..", "..value
+ end
+ headers[name]=value
+ end
+ return headers
+end
+socket.sourcet["http-chunked"]=function(sock,headers)
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },{
+ __call=function()
+ local line,err=sock:receive()
if err then
- return nil,err
+ return nil,err
end
- while find(line,"^%s") do
- value=value..line
- line=sock:receive()
- if err then
- return nil,err
- end
+ local size=tonumber(gsub(line,";.*",""),16)
+ if not size then
+ return nil,"invalid chunk size"
end
- local found=headers[name]
- if found then
- value=found..", "..value
+ if size>0 then
+ local chunk,err,part=sock:receive(size)
+ if chunk then
+ sock:receive()
+ end
+ return chunk,err
+ else
+ headers,err=receiveheaders(sock,headers)
+ if not headers then
+ return nil,err
+ end
end
- headers[name]=value
- end
- return headers
-end
-socket.sourcet["http-chunked"]=function(sock,headers)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function()
- local line,err=sock:receive()
- if err then
- return nil,err
- end
- local size=tonumber(gsub(line,";.*",""),16)
- if not size then
- return nil,"invalid chunk size"
- end
- if size>0 then
- local chunk,err,part=sock:receive(size)
- if chunk then
- sock:receive()
- end
- return chunk,err
- else
- headers,err=receiveheaders(sock,headers)
- if not headers then
- return nil,err
- end
- end
- end
- }
- )
+ end
+ }
+ )
end
socket.sinkt["http-chunked"]=function(sock)
- return setmetatable(
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function(self,chunk,err)
- if not chunk then
- chunk=""
- end
- return sock:send(format("%X\r\n%s\r\n",#chunk,chunk))
- end
- })
+ return setmetatable(
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },
+ {
+ __call=function(self,chunk,err)
+ if not chunk then
+ chunk=""
+ end
+ return sock:send(format("%X\r\n%s\r\n",#chunk,chunk))
+ end
+ })
end
local methods={}
local mt={ __index=methods }
local function openhttp(host,port,create)
- local c=trysocket((create or tcpsocket)())
- local h=setmetatable({ c=c },mt)
- local try=newtrysocket(function() h:close() end)
- h.try=try
- try(c:settimeout(http.TIMEOUT))
- try(c:connect(host,port or PORT))
- return h
+ local c=trysocket((create or tcpsocket)())
+ local h=setmetatable({ c=c },mt)
+ local try=newtrysocket(function() h:close() end)
+ h.try=try
+ try(c:settimeout(http.TIMEOUT))
+ try(c:connect(host,port or PORT))
+ return h
end
http.open=openhttp
function methods.sendrequestline(self,method,uri)
- local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri)
- return self.try(self.c:send(requestline))
+ local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri)
+ return self.try(self.c:send(requestline))
end
function methods.sendheaders(self,headers)
- self.try(self.c:send(normalizeheaders(headers)))
- return 1
+ self.try(self.c:send(normalizeheaders(headers)))
+ return 1
end
function methods.sendbody(self,headers,source,step)
- if not source then
- source=emptysource()
- end
- if not step then
- step=pumpstep
- end
- local mode="http-chunked"
- if headers["content-length"] then
- mode="keep-open"
- end
- return self.try(pumpall(source,sinksocket(mode,self.c),step))
+ if not source then
+ source=emptysource()
+ end
+ if not step then
+ step=pumpstep
+ end
+ local mode="http-chunked"
+ if headers["content-length"] then
+ mode="keep-open"
+ end
+ return self.try(pumpall(source,sinksocket(mode,self.c),step))
end
function methods.receivestatusline(self)
- local try=self.try
- local status=try(self.c:receive(5))
- if status~="HTTP/" then
- return nil,status
- end
- status=try(self.c:receive("*l",status))
- local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)"))
- return try(tonumber(code),status)
+ local try=self.try
+ local status=try(self.c:receive(5))
+ if status~="HTTP/" then
+ return nil,status
+ end
+ status=try(self.c:receive("*l",status))
+ local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)"))
+ return try(tonumber(code),status)
end
function methods.receiveheaders(self)
- return self.try(receiveheaders(self.c))
+ return self.try(receiveheaders(self.c))
end
function methods.receivebody(self,headers,sink,step)
- if not sink then
- sink=sinknull()
- end
- if not step then
- step=pumpstep
- end
- local length=tonumber(headers["content-length"])
- local encoding=headers["transfer-encoding"]
- local mode="default"
- if encoding and encoding~="identity" then
- mode="http-chunked"
- elseif length then
- mode="by-length"
- end
- return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step))
+ if not sink then
+ sink=sinknull()
+ end
+ if not step then
+ step=pumpstep
+ end
+ local length=tonumber(headers["content-length"])
+ local encoding=headers["transfer-encoding"]
+ local mode="default"
+ if encoding and encoding~="identity" then
+ mode="http-chunked"
+ elseif length then
+ mode="by-length"
+ end
+ return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step))
end
function methods.receive09body(self,status,sink,step)
- local source=rewindsource(sourcesocket("until-closed",self.c))
- source(status)
- return self.try(pumpall(source,sink,step))
+ local source=rewindsource(sourcesocket("until-closed",self.c))
+ source(status)
+ return self.try(pumpall(source,sink,step))
end
function methods.close(self)
- return self.c:close()
+ return self.c:close()
end
local function adjusturi(request)
- if not request.proxy and not http.PROXY then
- request={
- path=trysocket(request.path,"invalid path 'nil'"),
- params=request.params,
- query=request.query,
- fragment=request.fragment,
- }
- end
- return buildurl(request)
+ if not request.proxy and not http.PROXY then
+ request={
+ path=trysocket(request.path,"invalid path 'nil'"),
+ params=request.params,
+ query=request.query,
+ fragment=request.fragment,
+ }
+ end
+ return buildurl(request)
end
local function adjustheaders(request)
- local headers={
- ["user-agent"]=http.USERAGENT,
- ["host"]=gsub(request.authority,"^.-@",""),
- ["connection"]="close, TE",
- ["te"]="trailers"
- }
- local username=request.user
- local password=request.password
+ local headers={
+ ["user-agent"]=http.USERAGENT,
+ ["host"]=gsub(request.authority,"^.-@",""),
+ ["connection"]="close, TE",
+ ["te"]="trailers"
+ }
+ local username=request.user
+ local password=request.password
+ if username and password then
+ headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password)))
+ end
+ local proxy=request.proxy or http.PROXY
+ if proxy then
+ proxy=parseurl(proxy)
+ local username=proxy.user
+ local password=proxy.password
if username and password then
- headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password)))
- end
- local proxy=request.proxy or http.PROXY
- if proxy then
- proxy=parseurl(proxy)
- local username=proxy.user
- local password=proxy.password
- if username and password then
- headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password))
- end
- end
- local requestheaders=request.headers
- if requestheaders then
- headers=lowerheaders(headers,requestheaders)
+ headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password))
end
- return headers
+ end
+ local requestheaders=request.headers
+ if requestheaders then
+ headers=lowerheaders(headers,requestheaders)
+ end
+ return headers
end
local default={
- host="",
- port=PORT,
- path="/",
- scheme="http"
+ host="",
+ port=PORT,
+ path="/",
+ scheme="http"
}
local function adjustrequest(originalrequest)
- local url=originalrequest.url
- local request=url and parseurl(url,default) or {}
- for k,v in next,originalrequest do
- request[k]=v
- end
- local host=request.host
- local port=request.port
- local uri=request.uri
- if not host or host=="" then
- trysocket(nil,"invalid host '"..tostring(host).."'")
- end
- if port=="" then
- request.port=PORT
- end
- if not uri or uri=="" then
- request.uri=adjusturi(request)
- end
- request.headers=adjustheaders(request)
- local proxy=request.proxy or http.PROXY
- if proxy then
- proxy=parseurl(proxy)
- request.host=proxy.host
- request.port=proxy.port or 3128
- end
- return request
+ local url=originalrequest.url
+ local request=url and parseurl(url,default) or {}
+ for k,v in next,originalrequest do
+ request[k]=v
+ end
+ local host=request.host
+ local port=request.port
+ local uri=request.uri
+ if not host or host=="" then
+ trysocket(nil,"invalid host '"..tostring(host).."'")
+ end
+ if port=="" then
+ request.port=PORT
+ end
+ if not uri or uri=="" then
+ request.uri=adjusturi(request)
+ end
+ request.headers=adjustheaders(request)
+ local proxy=request.proxy or http.PROXY
+ if proxy then
+ proxy=parseurl(proxy)
+ request.host=proxy.host
+ request.port=proxy.port or 3128
+ end
+ return request
end
local maxredericts=4
local validredirects={ [301]=true,[302]=true,[303]=true,[307]=true }
local validmethods={ [false]=true,GET=true,HEAD=true }
local function shouldredirect(request,code,headers)
- local location=headers.location
- if not location then
- return false
- end
- location=gsub(location,"%s","")
- if location=="" then
- return false
- end
- local scheme=match(location,"^([%w][%w%+%-%.]*)%:")
- if scheme and not SCHEMES[scheme] then
- return false
- end
- local method=request.method
- local redirect=request.redirect
- local redirects=request.nredirects or 0
- return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts
+ local location=headers.location
+ if not location then
+ return false
+ end
+ location=gsub(location,"%s","")
+ if location=="" then
+ return false
+ end
+ local scheme=match(location,"^([%w][%w%+%-%.]*)%:")
+ if scheme and not SCHEMES[scheme] then
+ return false
+ end
+ local method=request.method
+ local redirect=request.redirect
+ local redirects=request.nredirects or 0
+ return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts
end
local function shouldreceivebody(request,code)
- if request.method=="HEAD" then
- return nil
- end
- if code==204 or code==304 then
- return nil
- end
- if code>=100 and code<200 then
- return nil
- end
- return 1
+ if request.method=="HEAD" then
+ return nil
+ end
+ if code==204 or code==304 then
+ return nil
+ end
+ if code>=100 and code<200 then
+ return nil
+ end
+ return 1
end
local tredirect,trequest,srequest
tredirect=function(request,location)
- local result,code,headers,status=trequest {
- url=absoluteurl(request.url,location),
- source=request.source,
- sink=request.sink,
- headers=request.headers,
- proxy=request.proxy,
- nredirects=(request.nredirects or 0)+1,
- create=request.create,
- }
- if not headers then
- headers={}
- end
- if not headers.location then
- headers.location=location
- end
- return result,code,headers,status
+ local result,code,headers,status=trequest {
+ url=absoluteurl(request.url,location),
+ source=request.source,
+ sink=request.sink,
+ headers=request.headers,
+ proxy=request.proxy,
+ nredirects=(request.nredirects or 0)+1,
+ create=request.create,
+ }
+ if not headers then
+ headers={}
+ end
+ if not headers.location then
+ headers.location=location
+ end
+ return result,code,headers,status
end
trequest=function(originalrequest)
- local request=adjustrequest(originalrequest)
- local connection=openhttp(request.host,request.port,request.create)
- local headers=request.headers
- connection:sendrequestline(request.method,request.uri)
- connection:sendheaders(headers)
- if request.source then
- connection:sendbody(headers,request.source,request.step)
- end
- local code,status=connection:receivestatusline()
- if not code then
- connection:receive09body(status,request.sink,request.step)
- return 1,200
- end
- while code==100 do
- headers=connection:receiveheaders()
- code,status=connection:receivestatusline()
- end
+ local request=adjustrequest(originalrequest)
+ local connection=openhttp(request.host,request.port,request.create)
+ local headers=request.headers
+ connection:sendrequestline(request.method,request.uri)
+ connection:sendheaders(headers)
+ if request.source then
+ connection:sendbody(headers,request.source,request.step)
+ end
+ local code,status=connection:receivestatusline()
+ if not code then
+ connection:receive09body(status,request.sink,request.step)
+ return 1,200
+ end
+ while code==100 do
headers=connection:receiveheaders()
- if shouldredirect(request,code,headers) and not request.source then
- connection:close()
- return tredirect(originalrequest,headers.location)
- end
- if shouldreceivebody(request,code) then
- connection:receivebody(headers,request.sink,request.step)
- end
+ code,status=connection:receivestatusline()
+ end
+ headers=connection:receiveheaders()
+ if shouldredirect(request,code,headers) and not request.source then
connection:close()
- return 1,code,headers,status
+ return tredirect(originalrequest,headers.location)
+ end
+ if shouldreceivebody(request,code) then
+ connection:receivebody(headers,request.sink,request.step)
+ end
+ connection:close()
+ return 1,code,headers,status
end
local function genericform(url,body)
- local buffer={}
- local request={
- url=url,
- sink=sinktable(buffer),
- target=buffer,
+ local buffer={}
+ local request={
+ url=url,
+ sink=sinktable(buffer),
+ target=buffer,
+ }
+ if body then
+ request.source=stringsource(body)
+ request.method="POST"
+ request.headers={
+ ["content-length"]=#body,
+ ["content-type"]="application/x-www-form-urlencoded"
}
- if body then
- request.source=stringsource(body)
- request.method="POST"
- request.headers={
- ["content-length"]=#body,
- ["content-type"]="application/x-www-form-urlencoded"
- }
- end
- return request
+ end
+ return request
end
http.genericform=genericform
srequest=function(url,body)
- local request=genericform(url,body)
- local _,code,headers,status=trequest(request)
- return concat(request.target),code,headers,status
+ local request=genericform(url,body)
+ local _,code,headers,status=trequest(request)
+ return concat(request.target),code,headers,status
end
http.request=protectsocket(function(request,body)
- if type(request)=="string" then
- return srequest(request,body)
- else
- return trequest(request)
- end
+ if type(request)=="string" then
+ return srequest(request,body)
+ else
+ return trequest(request)
+ end
end)
package.loaded["socket.http"]=http
@@ -11606,16 +11606,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true
--- original size: 10357, stripped down to: 8900
+-- original size: 10357, stripped down to: 8548
local setmetatable,type,next=setmetatable,type,next
local find,format,gsub,match=string.find,string.format,string.gsub,string.match
local concat=table.concat
local mod=math.mod
-local socket=socket or require("socket")
+local socket=socket or require("socket")
local url=socket.url or require("socket.url")
-local tp=socket.tp or require("socket.tp")
+local tp=socket.tp or require("socket.tp")
local ltn12=ltn12 or require("ltn12")
local tcpsocket=socket.tcp
local trysocket=socket.try
@@ -11633,341 +11633,341 @@ local pumpstep=ltn12.pump.step
local sourcestring=ltn12.source.string
local sinktable=ltn12.sink.table
local ftp={
- TIMEOUT=60,
- USER="ftp",
- PASSWORD="anonymous@anonymous.org",
+ TIMEOUT=60,
+ USER="ftp",
+ PASSWORD="anonymous@anonymous.org",
}
socket.ftp=ftp
local PORT=21
local methods={}
local mt={ __index=methods }
function ftp.open(server,port,create)
- local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create))
- local f=setmetatable({ tp=tp },metat)
- f.try=newtrysocket(function() f:close() end)
- return f
+ local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create))
+ local f=setmetatable({ tp=tp },metat)
+ f.try=newtrysocket(function() f:close() end)
+ return f
end
function methods.portconnect(self)
- local try=self.try
- local server=self.server
- try(server:settimeout(ftp.TIMEOUT))
- self.data=try(server:accept())
- try(self.data:settimeout(ftp.TIMEOUT))
+ local try=self.try
+ local server=self.server
+ try(server:settimeout(ftp.TIMEOUT))
+ self.data=try(server:accept())
+ try(self.data:settimeout(ftp.TIMEOUT))
end
function methods.pasvconnect(self)
- local try=self.try
- self.data=try(tcpsocket())
- self(self.data:settimeout(ftp.TIMEOUT))
- self(self.data:connect(self.pasvt.address,self.pasvt.port))
+ local try=self.try
+ self.data=try(tcpsocket())
+ self(self.data:settimeout(ftp.TIMEOUT))
+ self(self.data:connect(self.pasvt.address,self.pasvt.port))
end
function methods.login(self,user,password)
- local try=self.try
- local tp=self.tp
- try(tp:command("user",user or ftp.USER))
- local code,reply=try(tp:check{"2..",331})
- if code==331 then
- try(tp:command("pass",password or ftp.PASSWORD))
- try(tp:check("2.."))
- end
- return 1
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("user",user or ftp.USER))
+ local code,reply=try(tp:check{"2..",331})
+ if code==331 then
+ try(tp:command("pass",password or ftp.PASSWORD))
+ try(tp:check("2.."))
+ end
+ return 1
end
function methods.pasv(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("pasv"))
- local code,reply=try(self.tp:check("2.."))
- local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
- local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern))
- try(a and b and c and d and p1 and p2,reply)
- local address=format("%d.%d.%d.%d",a,b,c,d)
- local port=p1*256+p2
- local server=self.server
- self.pasvt={
- address=address,
- port=port,
- }
- if server then
- server:close()
- self.server=nil
- end
- return address,port
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("pasv"))
+ local code,reply=try(self.tp:check("2.."))
+ local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
+ local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern))
+ try(a and b and c and d and p1 and p2,reply)
+ local address=format("%d.%d.%d.%d",a,b,c,d)
+ local port=p1*256+p2
+ local server=self.server
+ self.pasvt={
+ address=address,
+ port=port,
+ }
+ if server then
+ server:close()
+ self.server=nil
+ end
+ return address,port
end
function methods.epsv(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("epsv"))
- local code,reply=try(tp:check("229"))
- local pattern="%((.)(.-)%1(.-)%1(.-)%1%)"
- local d,prt,address,port=match(reply,pattern)
- try(port,"invalid epsv response")
- local address=tp:getpeername()
- local server=self.server
- self.pasvt={
- address=address,
- port=port,
- }
- if self.server then
- server:close()
- self.server=nil
- end
- return address,port
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("epsv"))
+ local code,reply=try(tp:check("229"))
+ local pattern="%((.)(.-)%1(.-)%1(.-)%1%)"
+ local d,prt,address,port=match(reply,pattern)
+ try(port,"invalid epsv response")
+ local address=tp:getpeername()
+ local server=self.server
+ self.pasvt={
+ address=address,
+ port=port,
+ }
+ if self.server then
+ server:close()
+ self.server=nil
+ end
+ return address,port
end
function methods.port(self,address,port)
- local try=self.try
- local tp=self.tp
- self.pasvt=nil
- if not address then
- address,port=try(tp:getsockname())
- self.server=try(bindsocket(address,0))
- address,port=try(self.server:getsockname())
- try(self.server:settimeout(ftp.TIMEOUT))
- end
- local pl=mod(port,256)
- local ph=(port-pl)/256
- local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",")
- try(tp:command("port",arg))
- try(tp:check("2.."))
- return 1
+ local try=self.try
+ local tp=self.tp
+ self.pasvt=nil
+ if not address then
+ address,port=try(tp:getsockname())
+ self.server=try(bindsocket(address,0))
+ address,port=try(self.server:getsockname())
+ try(self.server:settimeout(ftp.TIMEOUT))
+ end
+ local pl=mod(port,256)
+ local ph=(port-pl)/256
+ local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",")
+ try(tp:command("port",arg))
+ try(tp:check("2.."))
+ return 1
end
function methods.eprt(self,family,address,port)
- local try=self.try
- local tp=self.tp
- self.pasvt=nil
- if not address then
- address,port=try(tp:getsockname())
- self.server=try(bindsocket(address,0))
- address,port=try(self.server:getsockname())
- try(self.server:settimeout(ftp.TIMEOUT))
- end
- local arg=format("|%s|%s|%d|",family,address,port)
- try(tp:command("eprt",arg))
- try(tp:check("2.."))
- return 1
+ local try=self.try
+ local tp=self.tp
+ self.pasvt=nil
+ if not address then
+ address,port=try(tp:getsockname())
+ self.server=try(bindsocket(address,0))
+ address,port=try(self.server:getsockname())
+ try(self.server:settimeout(ftp.TIMEOUT))
+ end
+ local arg=format("|%s|%s|%d|",family,address,port)
+ try(tp:command("eprt",arg))
+ try(tp:check("2.."))
+ return 1
end
function methods.send(self,sendt)
- local try=self.try
- local tp=self.tp
- try(self.pasvt or self.server,"need port or pasv first")
- if self.pasvt then
- self:pasvconnect()
- end
- local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]",""))
- if argument=="" then
- argument=nil
- end
- local command=sendt.command or "stor"
- try(tp:command(command,argument))
- local code,reply=try(tp:check{"2..","1.."})
- if not self.pasvt then
- self:portconnect()
- end
- local step=sendt.step or pumpstep
- local readt={ tp }
- local checkstep=function(src,snk)
- local readyt=selectsocket(readt,nil,0)
- if readyt[tp] then
- code=try(tp:check("2.."))
- end
- return step(src,snk)
- end
- local sink=sinksocket("close-when-done",self.data)
- try(pumpall(sendt.source,sink,checkstep))
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- self.data:close()
- local sent=skipsocket(1,self.data:getstats())
- self.data=nil
- return sent
+ local try=self.try
+ local tp=self.tp
+ try(self.pasvt or self.server,"need port or pasv first")
+ if self.pasvt then
+ self:pasvconnect()
+ end
+ local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]",""))
+ if argument=="" then
+ argument=nil
+ end
+ local command=sendt.command or "stor"
+ try(tp:command(command,argument))
+ local code,reply=try(tp:check{"2..","1.."})
+ if not self.pasvt then
+ self:portconnect()
+ end
+ local step=sendt.step or pumpstep
+ local readt={ tp }
+ local checkstep=function(src,snk)
+ local readyt=selectsocket(readt,nil,0)
+ if readyt[tp] then
+ code=try(tp:check("2.."))
+ end
+ return step(src,snk)
+ end
+ local sink=sinksocket("close-when-done",self.data)
+ try(pumpall(sendt.source,sink,checkstep))
+ if find(code,"1..") then
+ try(tp:check("2.."))
+ end
+ self.data:close()
+ local sent=skipsocket(1,self.data:getstats())
+ self.data=nil
+ return sent
end
function methods.receive(self,recvt)
- local try=self.try
- local tp=self.tp
- try(self.pasvt or self.server,"need port or pasv first")
- if self.pasvt then self:pasvconnect() end
- local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]",""))
- if argument=="" then
- argument=nil
- end
- local command=recvt.command or "retr"
- try(tp:command(command,argument))
- local code,reply=try(tp:check{"1..","2.."})
- if code>=200 and code<=299 then
- recvt.sink(reply)
- return 1
- end
- if not self.pasvt then
- self:portconnect()
- end
- local source=sourcesocket("until-closed",self.data)
- local step=recvt.step or pumpstep
- try(pumpall(source,recvt.sink,step))
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- self.data:close()
- self.data=nil
+ local try=self.try
+ local tp=self.tp
+ try(self.pasvt or self.server,"need port or pasv first")
+ if self.pasvt then self:pasvconnect() end
+ local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]",""))
+ if argument=="" then
+ argument=nil
+ end
+ local command=recvt.command or "retr"
+ try(tp:command(command,argument))
+ local code,reply=try(tp:check{"1..","2.."})
+ if code>=200 and code<=299 then
+ recvt.sink(reply)
return 1
+ end
+ if not self.pasvt then
+ self:portconnect()
+ end
+ local source=sourcesocket("until-closed",self.data)
+ local step=recvt.step or pumpstep
+ try(pumpall(source,recvt.sink,step))
+ if find(code,"1..") then
+ try(tp:check("2.."))
+ end
+ self.data:close()
+ self.data=nil
+ return 1
end
function methods.cwd(self,dir)
- local try=self.try
- local tp=self.tp
- try(tp:command("cwd",dir))
- try(tp:check(250))
- return 1
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("cwd",dir))
+ try(tp:check(250))
+ return 1
end
function methods.type(self,typ)
- local try=self.try
- local tp=self.tp
- try(tp:command("type",typ))
- try(tp:check(200))
- return 1
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("type",typ))
+ try(tp:check(200))
+ return 1
end
function methods.greet(self)
- local try=self.try
- local tp=self.tp
- local code=try(tp:check{"1..","2.."})
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- return 1
+ local try=self.try
+ local tp=self.tp
+ local code=try(tp:check{"1..","2.."})
+ if find(code,"1..") then
+ try(tp:check("2.."))
+ end
+ return 1
end
function methods.quit(self)
- local try=self.try
- try(self.tp:command("quit"))
- try(self.tp:check("2.."))
- return 1
+ local try=self.try
+ try(self.tp:command("quit"))
+ try(self.tp:check("2.."))
+ return 1
end
function methods.close(self)
- local data=self.data
- if data then
- data:close()
- end
- local server=self.server
- if server then
- server:close()
- end
- local tp=self.tp
- if tp then
- tp:close()
- end
+ local data=self.data
+ if data then
+ data:close()
+ end
+ local server=self.server
+ if server then
+ server:close()
+ end
+ local tp=self.tp
+ if tp then
+ tp:close()
+ end
end
local function override(t)
- if t.url then
- local u=parseurl(t.url)
- for k,v in next,t do
- u[k]=v
- end
- return u
- else
- return t
+ if t.url then
+ local u=parseurl(t.url)
+ for k,v in next,t do
+ u[k]=v
end
+ return u
+ else
+ return t
+ end
end
local function tput(putt)
- putt=override(putt)
- local host=putt.host
- trysocket(host,"missing hostname")
- local f=ftp.open(host,putt.port,putt.create)
- f:greet()
- f:login(putt.user,putt.password)
- local typ=putt.type
- if typ then
- f:type(typ)
- end
- f:epsv()
- local sent=f:send(putt)
- f:quit()
- f:close()
- return sent
+ putt=override(putt)
+ local host=putt.host
+ trysocket(host,"missing hostname")
+ local f=ftp.open(host,putt.port,putt.create)
+ f:greet()
+ f:login(putt.user,putt.password)
+ local typ=putt.type
+ if typ then
+ f:type(typ)
+ end
+ f:epsv()
+ local sent=f:send(putt)
+ f:quit()
+ f:close()
+ return sent
end
local default={
- path="/",
- scheme="ftp",
+ path="/",
+ scheme="ftp",
}
local function genericform(u)
- local t=trysocket(parseurl(u,default))
- trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'")
- trysocket(t.host,"missing hostname")
- local pat="^type=(.)$"
- if t.params then
- local typ=skipsocket(2,find(t.params,pat))
- t.type=typ
- trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'")
- end
- return t
+ local t=trysocket(parseurl(u,default))
+ trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'")
+ trysocket(t.host,"missing hostname")
+ local pat="^type=(.)$"
+ if t.params then
+ local typ=skipsocket(2,find(t.params,pat))
+ t.type=typ
+ trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'")
+ end
+ return t
end
ftp.genericform=genericform
local function sput(u,body)
- local putt=genericform(u)
- putt.source=sourcestring(body)
- return tput(putt)
+ local putt=genericform(u)
+ putt.source=sourcestring(body)
+ return tput(putt)
end
ftp.put=protectsocket(function(putt,body)
- if type(putt)=="string" then
- return sput(putt,body)
- else
- return tput(putt)
- end
+ if type(putt)=="string" then
+ return sput(putt,body)
+ else
+ return tput(putt)
+ end
end)
local function tget(gett)
- gett=override(gett)
- local host=gett.host
- trysocket(host,"missing hostname")
- local f=ftp.open(host,gett.port,gett.create)
- f:greet()
- f:login(gett.user,gett.password)
- if gett.type then
- f:type(gett.type)
- end
- f:epsv()
- f:receive(gett)
- f:quit()
- return f:close()
+ gett=override(gett)
+ local host=gett.host
+ trysocket(host,"missing hostname")
+ local f=ftp.open(host,gett.port,gett.create)
+ f:greet()
+ f:login(gett.user,gett.password)
+ if gett.type then
+ f:type(gett.type)
+ end
+ f:epsv()
+ f:receive(gett)
+ f:quit()
+ return f:close()
end
local function sget(u)
- local gett=genericform(u)
- local t={}
- gett.sink=sinktable(t)
- tget(gett)
- return concat(t)
+ local gett=genericform(u)
+ local t={}
+ gett.sink=sinktable(t)
+ tget(gett)
+ return concat(t)
end
ftp.command=protectsocket(function(cmdt)
- cmdt=override(cmdt)
- local command=cmdt.command
- local argument=cmdt.argument
- local check=cmdt.check
- local host=cmdt.host
- trysocket(host,"missing hostname")
- trysocket(command,"missing command")
- local f=ftp.open(host,cmdt.port,cmdt.create)
- local try=f.try
- local tp=f.tp
- f:greet()
- f:login(cmdt.user,cmdt.password)
- if type(command)=="table" then
- local argument=argument or {}
- for i=1,#command do
- local cmd=command[i]
- try(tp:command(cmd,argument[i]))
- if check and check[i] then
- try(tp:check(check[i]))
- end
- end
- else
- try(tp:command(command,argument))
- if check then
- try(tp:check(check))
- end
+ cmdt=override(cmdt)
+ local command=cmdt.command
+ local argument=cmdt.argument
+ local check=cmdt.check
+ local host=cmdt.host
+ trysocket(host,"missing hostname")
+ trysocket(command,"missing command")
+ local f=ftp.open(host,cmdt.port,cmdt.create)
+ local try=f.try
+ local tp=f.tp
+ f:greet()
+ f:login(cmdt.user,cmdt.password)
+ if type(command)=="table" then
+ local argument=argument or {}
+ for i=1,#command do
+ local cmd=command[i]
+ try(tp:command(cmd,argument[i]))
+ if check and check[i] then
+ try(tp:check(check[i]))
+ end
end
- f:quit()
- return f:close()
+ else
+ try(tp:command(command,argument))
+ if check then
+ try(tp:check(check))
+ end
+ end
+ f:quit()
+ return f:close()
end)
ftp.get=protectsocket(function(gett)
- if type(gett)=="string" then
- return sget(gett)
- else
- return tget(gett)
- end
+ if type(gett)=="string" then
+ return sget(gett)
+ else
+ return tget(gett)
+ end
end)
package.loaded["socket.ftp"]=ftp
@@ -11978,18 +11978,18 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true
--- original size: 7018, stripped down to: 6095
+-- original size: 7018, stripped down to: 5883
local type,setmetatable,next=type,setmetatable,next
local find,lower,format=string.find,string.lower,string.format
local osdate,osgetenv=os.date,os.getenv
local random=math.random
-local socket=socket or require("socket")
+local socket=socket or require("socket")
local headers=socket.headers or require("socket.headers")
-local ltn12=ltn12 or require("ltn12")
+local ltn12=ltn12 or require("ltn12")
local tp=socket.tp or require("socket.tp")
-local mime=mime or require("mime")
+local mime=mime or require("mime")
local mimeb64=mime.b64
local mimestuff=mime.stuff
local skipsocket=socket.skip
@@ -12002,212 +12002,212 @@ local createcoroutine=coroutine.create
local resumecoroutine=coroutine.resume
local yieldcoroutine=coroutine.resume
local smtp={
- TIMEOUT=60,
- SERVER="localhost",
- PORT=25,
- DOMAIN=osgetenv("SERVER_NAME") or "localhost",
- ZONE="-0000",
+ TIMEOUT=60,
+ SERVER="localhost",
+ PORT=25,
+ DOMAIN=osgetenv("SERVER_NAME") or "localhost",
+ ZONE="-0000",
}
socket.smtp=smtp
local methods={}
local mt={ __index=methods }
function methods.greet(self,domain)
- local try=self.try
- local tp=self.tp
- try(tp:check("2.."))
- try(tp:command("EHLO",domain or _M.DOMAIN))
- return skipsocket(1,try(tp:check("2..")))
+ local try=self.try
+ local tp=self.tp
+ try(tp:check("2.."))
+ try(tp:command("EHLO",domain or _M.DOMAIN))
+ return skipsocket(1,try(tp:check("2..")))
end
function methods.mail(self,from)
- local try=self.try
- local tp=self.tp
- try(tp:command("MAIL","FROM:"..from))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("MAIL","FROM:"..from))
+ return try(tp:check("2.."))
end
function methods.rcpt(self,to)
- local try=self.try
- local tp=self.tp
- try(tp:command("RCPT","TO:"..to))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("RCPT","TO:"..to))
+ return try(tp:check("2.."))
end
function methods.data(self,src,step)
- local try=self.try
- local tp=self.tp
- try(tp:command("DATA"))
- try(tp:check("3.."))
- try(tp:source(src,step))
- try(tp:send("\r\n.\r\n"))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("DATA"))
+ try(tp:check("3.."))
+ try(tp:source(src,step))
+ try(tp:send("\r\n.\r\n"))
+ return try(tp:check("2.."))
end
function methods.quit(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("QUIT"))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("QUIT"))
+ return try(tp:check("2.."))
end
function methods.close(self)
- return self.tp:close()
+ return self.tp:close()
end
function methods.login(self,user,password)
- local try=self.try
- local tp=self.tp
- try(tp:command("AUTH","LOGIN"))
- try(tp:check("3.."))
- try(tp:send(mimeb64(user).."\r\n"))
- try(tp:check("3.."))
- try(tp:send(mimeb64(password).."\r\n"))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("AUTH","LOGIN"))
+ try(tp:check("3.."))
+ try(tp:send(mimeb64(user).."\r\n"))
+ try(tp:check("3.."))
+ try(tp:send(mimeb64(password).."\r\n"))
+ return try(tp:check("2.."))
end
function methods.plain(self,user,password)
- local try=self.try
- local tp=self.tp
- local auth="PLAIN "..mimeb64("\0"..user.."\0"..password)
- try(tp:command("AUTH",auth))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ local auth="PLAIN "..mimeb64("\0"..user.."\0"..password)
+ try(tp:command("AUTH",auth))
+ return try(tp:check("2.."))
end
function methods.auth(self,user,password,ext)
- if not user or not password then
- return 1
- end
- local try=self.try
- if find(ext,"AUTH[^\n]+LOGIN") then
- return self:login(user,password)
- elseif find(ext,"AUTH[^\n]+PLAIN") then
- return self:plain(user,password)
- else
- try(nil,"authentication not supported")
- end
+ if not user or not password then
+ return 1
+ end
+ local try=self.try
+ if find(ext,"AUTH[^\n]+LOGIN") then
+ return self:login(user,password)
+ elseif find(ext,"AUTH[^\n]+PLAIN") then
+ return self:plain(user,password)
+ else
+ try(nil,"authentication not supported")
+ end
end
function methods.send(self,mail)
- self:mail(mail.from)
- local receipt=mail.rcpt
- if type(receipt)=="table" then
- for i=1,#receipt do
- self:rcpt(receipt[i])
- end
- elseif receipt then
- self:rcpt(receipt)
+ self:mail(mail.from)
+ local receipt=mail.rcpt
+ if type(receipt)=="table" then
+ for i=1,#receipt do
+ self:rcpt(receipt[i])
end
- self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step)
+ elseif receipt then
+ self:rcpt(receipt)
+ end
+ self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step)
end
local function opensmtp(self,server,port,create)
- if not server or server=="" then
- server=smtp.SERVER
- end
- if not port or port=="" then
- port=smtp.PORT
- end
- local s={
- tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)),
- try=newtrysocket(function()
- s:close()
- end),
- }
- setmetatable(s,mt)
- return s
+ if not server or server=="" then
+ server=smtp.SERVER
+ end
+ if not port or port=="" then
+ port=smtp.PORT
+ end
+ local s={
+ tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)),
+ try=newtrysocket(function()
+ s:close()
+ end),
+ }
+ setmetatable(s,mt)
+ return s
end
smtp.open=opensmtp
local nofboundaries=0
local function newboundary()
- nofboundaries=nofboundaries+1
- return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries)
+ nofboundaries=nofboundaries+1
+ return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries)
end
local send_message
local function send_headers(headers)
- yieldcoroutine(normalizeheaders(headers))
+ yieldcoroutine(normalizeheaders(headers))
end
local function send_multipart(message)
- local boundary=newboundary()
- local headers=lowerheaders(message.headers)
- local body=message.body
- local preamble=body.preamble
- local epilogue=body.epilogue
- local content=headers['content-type'] or 'multipart/mixed'
- headers['content-type']=content..'; boundary="'..boundary..'"'
- send_headers(headers)
- if preamble then
- yieldcoroutine(preamble)
- yieldcoroutine("\r\n")
- end
- for i=1,#body do
- yieldcoroutine("\r\n--"..boundary.."\r\n")
- send_message(body[i])
- end
- yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n")
- if epilogue then
- yieldcoroutine(epilogue)
- yieldcoroutine("\r\n")
- end
+ local boundary=newboundary()
+ local headers=lowerheaders(message.headers)
+ local body=message.body
+ local preamble=body.preamble
+ local epilogue=body.epilogue
+ local content=headers['content-type'] or 'multipart/mixed'
+ headers['content-type']=content..'; boundary="'..boundary..'"'
+ send_headers(headers)
+ if preamble then
+ yieldcoroutine(preamble)
+ yieldcoroutine("\r\n")
+ end
+ for i=1,#body do
+ yieldcoroutine("\r\n--"..boundary.."\r\n")
+ send_message(body[i])
+ end
+ yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n")
+ if epilogue then
+ yieldcoroutine(epilogue)
+ yieldcoroutine("\r\n")
+ end
end
local default_content_type='text/plain; charset="UTF-8"'
local function send_source(message)
- local headers=lowerheaders(message.headers)
- if not headers['content-type'] then
- headers['content-type']=default_content_type
- end
- send_headers(headers)
- local getchunk=message.body
- while true do
- local chunk,err=getchunk()
- if err then
- yieldcoroutine(nil,err)
- elseif chunk then
- yieldcoroutine(chunk)
- else
- break
- end
+ local headers=lowerheaders(message.headers)
+ if not headers['content-type'] then
+ headers['content-type']=default_content_type
+ end
+ send_headers(headers)
+ local getchunk=message.body
+ while true do
+ local chunk,err=getchunk()
+ if err then
+ yieldcoroutine(nil,err)
+ elseif chunk then
+ yieldcoroutine(chunk)
+ else
+ break
end
+ end
end
local function send_string(message)
- local headers=lowerheaders(message.headers)
- if not headers['content-type'] then
- headers['content-type']=default_content_type
- end
- send_headers(headers)
- yieldcoroutine(message.body)
+ local headers=lowerheaders(message.headers)
+ if not headers['content-type'] then
+ headers['content-type']=default_content_type
+ end
+ send_headers(headers)
+ yieldcoroutine(message.body)
end
function send_message(message)
- local body=message.body
- if type(body)=="table" then
- send_multipart(message)
- elseif type(body)=="function" then
- send_source(message)
- else
- send_string(message)
- end
+ local body=message.body
+ if type(body)=="table" then
+ send_multipart(message)
+ elseif type(body)=="function" then
+ send_source(message)
+ else
+ send_string(message)
+ end
end
local function adjust_headers(message)
- local headers=lowerheaders(message.headers)
- if not headers["date"] then
- headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE)
- end
- if not headers["x-mailer"] then
- headers["x-mailer"]=socket._VERSION
- end
- headers["mime-version"]="1.0"
- return headers
+ local headers=lowerheaders(message.headers)
+ if not headers["date"] then
+ headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE)
+ end
+ if not headers["x-mailer"] then
+ headers["x-mailer"]=socket._VERSION
+ end
+ headers["mime-version"]="1.0"
+ return headers
end
function smtp.message(message)
- message.headers=adjust_headers(message)
- local action=createcoroutine(function()
- send_message(message)
- end)
- return function()
- local ret,a,b=resumecoroutine(action)
- if ret then
- return a,b
- else
- return nil,a
- end
+ message.headers=adjust_headers(message)
+ local action=createcoroutine(function()
+ send_message(message)
+ end)
+ return function()
+ local ret,a,b=resumecoroutine(action)
+ if ret then
+ return a,b
+ else
+ return nil,a
end
+ end
end
smtp.send=protectsocket(function(mail)
- local snd=opensmtp(smtp,mail.server,mail.port,mail.create)
- local ext=snd:greet(mail.domain)
- snd:auth(mail.user,mail.password,ext)
- snd:send(mail)
- snd:quit()
- return snd:close()
+ local snd=opensmtp(smtp,mail.server,mail.port,mail.create)
+ local ext=snd:greet(mail.domain)
+ snd:auth(mail.user,mail.password,ext)
+ snd:send(mail)
+ snd:quit()
+ return snd:close()
end)
package.loaded["socket.smtp"]=smtp
@@ -12218,14 +12218,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-set"] = package.loaded["trac-set"] or true
--- original size: 13340, stripped down to: 9459
+-- original size: 13340, stripped down to: 8826
if not modules then modules={} end modules ['trac-set']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber=type,next,tostring,tonumber
local concat,sortedhash=table.concat,table.sortedhash
@@ -12240,317 +12240,317 @@ utilities.setters=setters
local data={}
local trace_initialize=false
function setters.initialize(filename,name,values)
- local setter=data[name]
- if setter then
- frozen=true
- local data=setter.data
- if data then
- for key,newvalue in sortedhash(values) do
- local newvalue=is_boolean(newvalue,newvalue,true)
- local functions=data[key]
- if functions then
- local oldvalue=functions.value
- if functions.frozen then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
- end
- elseif #functions>0 and not oldvalue then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
- end
- for i=1,#functions do
- functions[i](newvalue)
- end
- functions.value=newvalue
- functions.frozen=functions.frozen or frozen
- else
- if trace_initialize then
- setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
- end
- end
- else
- functions={ default=newvalue,frozen=frozen }
- data[key]=functions
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
- end
- end
+ local setter=data[name]
+ if setter then
+ frozen=true
+ local data=setter.data
+ if data then
+ for key,newvalue in sortedhash(values) do
+ local newvalue=is_boolean(newvalue,newvalue,true)
+ local functions=data[key]
+ if functions then
+ local oldvalue=functions.value
+ if functions.frozen then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
+ end
+ elseif #functions>0 and not oldvalue then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
+ end
+ for i=1,#functions do
+ functions[i](newvalue)
+ end
+ functions.value=newvalue
+ functions.frozen=functions.frozen or frozen
+ else
+ if trace_initialize then
+ setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
end
- return true
+ end
+ else
+ functions={ default=newvalue,frozen=frozen }
+ data[key]=functions
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
+ end
end
+ end
+ return true
end
+ end
end
local function set(t,what,newvalue)
- local data=t.data
- if not data.frozen then
- local done=t.done
- if type(what)=="string" then
- what=settings_to_hash(what)
- end
- if type(what)~="table" then
- return
- end
- if not done then
- done={}
- t.done=done
- end
- for w,value in sortedhash(what) do
- if value=="" then
- value=newvalue
- elseif not value then
- value=false
- else
- value=is_boolean(value,value,true)
- end
- w=topattern(w,true,true)
- for name,functions in sortedhash(data) do
- if done[name] then
- elseif find(name,w) then
- done[name]=true
- for i=1,#functions do
- functions[i](value)
- end
- functions.value=value
- end
- end
+ local data=t.data
+ if not data.frozen then
+ local done=t.done
+ if type(what)=="string" then
+ what=settings_to_hash(what)
+ end
+ if type(what)~="table" then
+ return
+ end
+ if not done then
+ done={}
+ t.done=done
+ end
+ for w,value in sortedhash(what) do
+ if value=="" then
+ value=newvalue
+ elseif not value then
+ value=false
+ else
+ value=is_boolean(value,value,true)
+ end
+ w=topattern(w,true,true)
+ for name,functions in sortedhash(data) do
+ if done[name] then
+ elseif find(name,w) then
+ done[name]=true
+ for i=1,#functions do
+ functions[i](value)
+ end
+ functions.value=value
end
+ end
end
+ end
end
local function reset(t)
- local data=t.data
- if not data.frozen then
- for name,functions in sortedthash(data) do
- for i=1,#functions do
- functions[i](false)
- end
- functions.value=false
- end
+ local data=t.data
+ if not data.frozen then
+ for name,functions in sortedthash(data) do
+ for i=1,#functions do
+ functions[i](false)
+ end
+ functions.value=false
end
+ end
end
local function enable(t,what)
- set(t,what,true)
+ set(t,what,true)
end
local function disable(t,what)
- local data=t.data
- if not what or what=="" then
- t.done={}
- reset(t)
- else
- set(t,what,false)
- end
+ local data=t.data
+ if not what or what=="" then
+ t.done={}
+ reset(t)
+ else
+ set(t,what,false)
+ end
end
function setters.register(t,what,...)
- local data=t.data
- what=lower(what)
- local functions=data[what]
- if not functions then
- functions={}
- data[what]=functions
- if trace_initialize then
- t.report("defining %a",what)
- end
- end
- local default=functions.default
- for i=1,select("#",...) do
- local fnc=select(i,...)
- local typ=type(fnc)
- if typ=="string" then
- if trace_initialize then
- t.report("coupling %a to %a",what,fnc)
- end
- local s=fnc
- fnc=function(value) set(t,s,value) end
- elseif typ~="function" then
- fnc=nil
- end
- if fnc then
- functions[#functions+1]=fnc
- local value=functions.value or default
- if value~=nil then
- fnc(value)
- functions.value=value
- end
- end
+ local data=t.data
+ what=lower(what)
+ local functions=data[what]
+ if not functions then
+ functions={}
+ data[what]=functions
+ if trace_initialize then
+ t.report("defining %a",what)
+ end
+ end
+ local default=functions.default
+ for i=1,select("#",...) do
+ local fnc=select(i,...)
+ local typ=type(fnc)
+ if typ=="string" then
+ if trace_initialize then
+ t.report("coupling %a to %a",what,fnc)
+ end
+ local s=fnc
+ fnc=function(value) set(t,s,value) end
+ elseif typ~="function" then
+ fnc=nil
+ end
+ if fnc then
+ functions[#functions+1]=fnc
+ local value=functions.value or default
+ if value~=nil then
+ fnc(value)
+ functions.value=value
+ end
end
- return false
+ end
+ return false
end
function setters.enable(t,what)
- local e=t.enable
- t.enable,t.done=enable,{}
- enable(t,what)
- t.enable,t.done=e,{}
+ local e=t.enable
+ t.enable,t.done=enable,{}
+ enable(t,what)
+ t.enable,t.done=e,{}
end
function setters.disable(t,what)
- local e=t.disable
- t.disable,t.done=disable,{}
- disable(t,what)
- t.disable,t.done=e,{}
+ local e=t.disable
+ t.disable,t.done=disable,{}
+ disable(t,what)
+ t.disable,t.done=e,{}
end
function setters.reset(t)
- t.done={}
- reset(t)
+ t.done={}
+ reset(t)
end
function setters.list(t)
- local list=table.sortedkeys(t.data)
- local user,system={},{}
- for l=1,#list do
- local what=list[l]
- if find(what,"^%*") then
- system[#system+1]=what
- else
- user[#user+1]=what
- end
+ local list=table.sortedkeys(t.data)
+ local user,system={},{}
+ for l=1,#list do
+ local what=list[l]
+ if find(what,"^%*") then
+ system[#system+1]=what
+ else
+ user[#user+1]=what
end
- return user,system
+ end
+ return user,system
end
function setters.show(t)
- local list=setters.list(t)
- t.report()
- for k=1,#list do
- local name=list[k]
- local functions=t.data[name]
- if functions then
- local value=functions.value
- local default=functions.default
- local modules=#functions
- if default==nil then
- default="unset"
- elseif type(default)=="table" then
- default=concat(default,"|")
- else
- default=tostring(default)
- end
- if value==nil then
- value="unset"
- elseif type(value)=="table" then
- value=concat(value,"|")
- else
- value=tostring(value)
- end
- t.report(name)
- t.report(" modules : %i",modules)
- t.report(" default : %s",default)
- t.report(" value : %s",value)
- t.report()
- end
+ local list=setters.list(t)
+ t.report()
+ for k=1,#list do
+ local name=list[k]
+ local functions=t.data[name]
+ if functions then
+ local value=functions.value
+ local default=functions.default
+ local modules=#functions
+ if default==nil then
+ default="unset"
+ elseif type(default)=="table" then
+ default=concat(default,"|")
+ else
+ default=tostring(default)
+ end
+ if value==nil then
+ value="unset"
+ elseif type(value)=="table" then
+ value=concat(value,"|")
+ else
+ value=tostring(value)
+ end
+ t.report(name)
+ t.report(" modules : %i",modules)
+ t.report(" default : %s",default)
+ t.report(" value : %s",value)
+ t.report()
end
+ end
end
local enable,disable,register,list,show=setters.enable,setters.disable,setters.register,setters.list,setters.show
function setters.report(setter,...)
- print(format("%-15s : %s\n",setter.name,format(...)))
+ print(format("%-15s : %s\n",setter.name,format(...)))
end
local function default(setter,name)
- local d=setter.data[name]
- return d and d.default
+ local d=setter.data[name]
+ return d and d.default
end
local function value(setter,name)
- local d=setter.data[name]
- return d and (d.value or d.default)
+ local d=setter.data[name]
+ return d and (d.value or d.default)
end
function setters.new(name)
- local setter
- setter={
- data=allocate(),
- name=name,
- report=function(...) setters.report (setter,...) end,
- enable=function(...) enable (setter,...) end,
- disable=function(...) disable (setter,...) end,
- reset=function(...) reset (setter,...) end,
- register=function(...) register(setter,...) end,
- list=function(...) list (setter,...) end,
- show=function(...) show (setter,...) end,
- default=function(...) return default (setter,...) end,
- value=function(...) return value (setter,...) end,
- }
- data[name]=setter
- return setter
+ local setter
+ setter={
+ data=allocate(),
+ name=name,
+ report=function(...) setters.report (setter,...) end,
+ enable=function(...) enable (setter,...) end,
+ disable=function(...) disable (setter,...) end,
+ reset=function(...) reset (setter,...) end,
+ register=function(...) register(setter,...) end,
+ list=function(...) list (setter,...) end,
+ show=function(...) show (setter,...) end,
+ default=function(...) return default (setter,...) end,
+ value=function(...) return value (setter,...) end,
+ }
+ data[name]=setter
+ return setter
end
trackers=setters.new("trackers")
directives=setters.new("directives")
experiments=setters.new("experiments")
-local t_enable,t_disable=trackers .enable,trackers .disable
+local t_enable,t_disable=trackers .enable,trackers .disable
local d_enable,d_disable=directives .enable,directives .disable
local e_enable,e_disable=experiments.enable,experiments.disable
-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 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)
function directives.enable(...)
- if trace_directives then
- directives.report("enabling: % t",{...})
- end
- d_enable(...)
+ if trace_directives then
+ directives.report("enabling: % t",{...})
+ end
+ d_enable(...)
end
function directives.disable(...)
- if trace_directives then
- directives.report("disabling: % t",{...})
- end
- d_disable(...)
+ if trace_directives then
+ directives.report("disabling: % t",{...})
+ end
+ d_disable(...)
end
function experiments.enable(...)
- if trace_experiments then
- experiments.report("enabling: % t",{...})
- end
- e_enable(...)
+ if trace_experiments then
+ experiments.report("enabling: % t",{...})
+ end
+ e_enable(...)
end
function experiments.disable(...)
- if trace_experiments then
- experiments.report("disabling: % t",{...})
- end
- e_disable(...)
+ if trace_experiments then
+ experiments.report("disabling: % t",{...})
+ end
+ e_disable(...)
end
directives.register("system.nostatistics",function(v)
- if statistics then
- statistics.enable=not v
- else
- end
+ if statistics then
+ statistics.enable=not v
+ else
+ end
end)
directives.register("system.nolibraries",function(v)
- if libraries then
- libraries=nil
- else
- end
+ if libraries then
+ libraries=nil
+ else
+ end
end)
if environment then
- local engineflags=environment.engineflags
- if engineflags then
- local list=engineflags["c:trackers"] or engineflags["trackers"]
- if type(list)=="string" then
- setters.initialize("commandline flags","trackers",settings_to_hash(list))
- end
- local list=engineflags["c:directives"] or engineflags["directives"]
- if type(list)=="string" then
- setters.initialize("commandline flags","directives",settings_to_hash(list))
- end
+ local engineflags=environment.engineflags
+ if engineflags then
+ local list=engineflags["c:trackers"] or engineflags["trackers"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","trackers",settings_to_hash(list))
end
+ local list=engineflags["c:directives"] or engineflags["directives"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","directives",settings_to_hash(list))
+ end
+ end
end
if texconfig then
- local function set(k,v)
- v=tonumber(v)
- if v then
- texconfig[k]=v
- end
- end
- directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
- directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
- directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
- directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
- directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
- directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
- directives.register("luatex.paramsize",function(v) set("param_size",v) end)
- directives.register("luatex.savesize",function(v) set("save_size",v) end)
- directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
+ local function set(k,v)
+ v=tonumber(v)
+ if v then
+ texconfig[k]=v
+ end
+ end
+ directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
+ directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
+ directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
+ directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
+ directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
+ directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
+ directives.register("luatex.paramsize",function(v) set("param_size",v) end)
+ directives.register("luatex.savesize",function(v) set("save_size",v) end)
+ directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
end
local data=table.setmetatableindex("table")
updaters={
- register=function(what,f)
- local d=data[what]
- d[#d+1]=f
- end,
- apply=function(what,...)
- local d=data[what]
- for i=1,#d do
- d[i](...)
- end
- end,
+ register=function(what,f)
+ local d=data[what]
+ d[#d+1]=f
+ end,
+ apply=function(what,...)
+ local d=data[what]
+ for i=1,#d do
+ d[i](...)
+ end
+ end,
}
@@ -12560,14 +12560,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-log"] = package.loaded["trac-log"] or true
--- original size: 32608, stripped down to: 22574
+-- original size: 32608, stripped down to: 20925
if not modules then modules={} end modules ['trac-log']={
- version=1.001,
- comment="companion to trac-log.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,select,print=next,type,select,print
local format,gmatch,find=string.format,string.gmatch,string.find
@@ -12578,7 +12578,7 @@ local datetime=os.date
local openfile=io.open
local runningtex=tex and (tex.jobname or tex.formatname)
local write_nl=runningtex and texio and texio.write_nl or print
-local write=runningtex and texio and texio.write or io.write
+local write=runningtex and texio and texio.write or io.write
local setmetatableindex=table.setmetatableindex
local formatters=string.formatters
local settings_to_hash=utilities.parsers.settings_to_hash
@@ -12594,404 +12594,404 @@ webpage : http://www.pragma-ade.nl / http://tex.aanhet.net
wiki : http://contextgarden.net
]]
formatters.add (
- formatters,"unichr",
- [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
+ formatters,"unichr",
+ [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
)
formatters.add (
- formatters,"chruni",
- [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
+ formatters,"chruni",
+ [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
)
local function ignore() end
setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end)
local report,subreport,status,settarget,setformats,settranslations
local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters,newline
if runningtex then
- if texio.setescape then
- texio.setescape(0)
- end
- if arg then
- for k,v in next,arg do
- if v=="--ansi" or v=="--c:ansi" then
- variant="ansi"
- break
- end
- end
- end
- local function useluawrites()
- local texio_write_nl=texio.write_nl
- local texio_write=texio.write
- local io_write=io.write
- write_nl=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write_nl("log",...)
- texio_write_nl("term","")
- io_write(...)
- elseif target=="log" then
- texio_write_nl("log",...)
- elseif target=="term" then
- texio_write_nl("term","")
- io_write(...)
- elseif type(target)=="number" then
- texio_write_nl(target,...)
- elseif target~="none" then
- texio_write_nl("log",target,...)
- texio_write_nl("term","")
- io_write(target,...)
- end
- end
- write=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write("log",...)
- io_write(...)
- elseif target=="log" then
- texio_write("log",...)
- elseif target=="term" then
- io_write(...)
- elseif type(target)=="number" then
- texio_write(target,...)
- elseif target~="none" then
- texio_write("log",target,...)
- io_write(target,...)
- end
- end
- texio.write=write
- texio.write_nl=write_nl
- useluawrites=ignore
- end
- local whereto="both"
- local target=nil
- local targets=nil
- local formats=table.setmetatableindex("self")
- local translations=table.setmetatableindex("self")
- local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
- local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="log",
- log="log",
- file="log",
- console="term",
- terminal="term",
- both="term and log",
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="none",
- log="none",
- file="none",
- console="term",
- terminal="term",
- both="term",
- },
- }
- }
- logs.flush=io.flush
- writer=function(...)
- write_nl(target,...)
- end
- newline=function()
- write_nl(target,"\n")
- end
- report=function(a,b,c,...)
- if c~=nil then
- write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,report_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,report_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
- end
- direct=function(a,b,c,...)
- if c~=nil then
- return direct_yes(translations[a],formatters[formats[b]](c,...))
- elseif b then
- return direct_yes(translations[a],formats[b])
- elseif a then
- return direct_nop(translations[a])
- else
- return ""
- end
- end
- subreport=function(a,s,b,c,...)
- if c~=nil then
- write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
- elseif a then
- write_nl(target,subreport_nop(translations[a],translations[s]))
- else
- write_nl(target,"\n")
- end
- end
- subdirect=function(a,s,b,c,...)
- if c~=nil then
- return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
- elseif b then
- return subdirect_yes(translations[a],translations[s],formats[b])
- elseif a then
- return subdirect_nop(translations[a],translations[s])
- else
- return ""
- end
+ if texio.setescape then
+ texio.setescape(0)
+ end
+ if arg then
+ for k,v in next,arg do
+ if v=="--ansi" or v=="--c:ansi" then
+ variant="ansi"
+ break
+ end
end
- status=function(a,b,c,...)
- if c~=nil then
- write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,status_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,status_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
+ end
+ local function useluawrites()
+ local texio_write_nl=texio.write_nl
+ local texio_write=texio.write
+ local io_write=io.write
+ write_nl=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write_nl("log",...)
+ texio_write_nl("term","")
+ io_write(...)
+ elseif target=="log" then
+ texio_write_nl("log",...)
+ elseif target=="term" then
+ texio_write_nl("term","")
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write_nl(target,...)
+ elseif target~="none" then
+ texio_write_nl("log",target,...)
+ texio_write_nl("term","")
+ io_write(target,...)
+ end
end
- settarget=function(askedwhereto)
- whereto=askedwhereto or whereto or "both"
- target=targets[whereto]
- if not target then
- whereto="both"
- target=targets[whereto]
- end
- if target=="term" or target=="term and log" then
- logs.flush=io.flush
- else
- logs.flush=ignore
- end
+ write=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write("log",...)
+ io_write(...)
+ elseif target=="log" then
+ texio_write("log",...)
+ elseif target=="term" then
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write(target,...)
+ elseif target~="none" then
+ texio_write("log",target,...)
+ io_write(target,...)
+ end
end
- local stack={}
- pushtarget=function(newtarget)
- insert(stack,target)
- settarget(newtarget)
+ texio.write=write
+ texio.write_nl=write_nl
+ useluawrites=ignore
+ end
+ local whereto="both"
+ local target=nil
+ local targets=nil
+ local formats=table.setmetatableindex("self")
+ local translations=table.setmetatableindex("self")
+ local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
+ local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="log",
+ log="log",
+ file="log",
+ console="term",
+ terminal="term",
+ both="term and log",
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="none",
+ log="none",
+ file="none",
+ console="term",
+ terminal="term",
+ both="term",
+ },
+ }
+ }
+ logs.flush=io.flush
+ writer=function(...)
+ write_nl(target,...)
+ end
+ newline=function()
+ write_nl(target,"\n")
+ end
+ report=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,report_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,report_nop(translations[a]))
+ else
+ write_nl(target,"\n")
end
- poptarget=function()
- if #stack>0 then
- settarget(remove(stack))
- end
+ end
+ direct=function(a,b,c,...)
+ if c~=nil then
+ return direct_yes(translations[a],formatters[formats[b]](c,...))
+ elseif b then
+ return direct_yes(translations[a],formats[b])
+ elseif a then
+ return direct_nop(translations[a])
+ else
+ return ""
end
- setformats=function(f)
- formats=f
+ end
+ subreport=function(a,s,b,c,...)
+ if c~=nil then
+ write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
+ elseif a then
+ write_nl(target,subreport_nop(translations[a],translations[s]))
+ else
+ write_nl(target,"\n")
end
- settranslations=function(t)
- translations=t
+ end
+ subdirect=function(a,s,b,c,...)
+ if c~=nil then
+ return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
+ elseif b then
+ return subdirect_yes(translations[a],translations[s],formats[b])
+ elseif a then
+ return subdirect_nop(translations[a],translations[s])
+ else
+ return ""
end
- setprocessor=function(f)
- local writeline=write_nl
- write_nl=function(target,...)
- writeline(target,f(...))
- end
+ end
+ status=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,status_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,status_nop(translations[a]))
+ else
+ write_nl(target,"\n")
+ end
+ end
+ settarget=function(askedwhereto)
+ whereto=askedwhereto or whereto or "both"
+ target=targets[whereto]
+ if not target then
+ whereto="both"
+ target=targets[whereto]
+ end
+ if target=="term" or target=="term and log" then
+ logs.flush=io.flush
+ else
+ logs.flush=ignore
+ end
+ end
+ local stack={}
+ pushtarget=function(newtarget)
+ insert(stack,target)
+ settarget(newtarget)
+ end
+ poptarget=function()
+ if #stack>0 then
+ settarget(remove(stack))
+ end
+ end
+ setformats=function(f)
+ formats=f
+ end
+ settranslations=function(t)
+ translations=t
+ end
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(target,...)
+ writeline(target,f(...))
+ end
+ end
+ setformatters=function(specification)
+ local t=nil
+ local f=nil
+ local d=variants.default
+ if not specification then
+ elseif type(specification)=="table" then
+ t=specification.targets
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ t=v.targets
+ f=v.formats
+ variant=specification
+ end
end
- setformatters=function(specification)
- local t=nil
- local f=nil
- local d=variants.default
- if not specification then
- elseif type(specification)=="table" then
- t=specification.targets
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- t=v.targets
- f=v.formats
- variant=specification
- end
- end
- targets=t or d.targets
- target=targets[whereto] or target
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- direct_yes=f.direct_yes
- direct_nop=f.direct_nop
- subdirect_yes=f.subdirect_yes
- subdirect_nop=f.subdirect_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- if variant=="ansi" then
- useluawrites()
- end
- settarget(whereto)
- end
- setformatters(variant)
- setlogfile=ignore
- settimedlog=ignore
+ targets=t or d.targets
+ target=targets[whereto] or target
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ direct_yes=f.direct_yes
+ direct_nop=f.direct_nop
+ subdirect_yes=f.subdirect_yes
+ subdirect_nop=f.subdirect_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ if variant=="ansi" then
+ useluawrites()
+ end
+ settarget(whereto)
+ end
+ setformatters(variant)
+ setlogfile=ignore
+ settimedlog=ignore
else
- local report_yes,subreport_yes,status_yes
- local report_nop,subreport_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- }
- logs.flush=ignore
- writer=function(s)
- write_nl(s)
- end
- newline=function()
- write_nl("\n")
+ local report_yes,subreport_yes,status_yes
+ local report_nop,subreport_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ }
+ logs.flush=ignore
+ writer=function(s)
+ write_nl(s)
+ end
+ newline=function()
+ write_nl("\n")
+ end
+ report=function(a,b,c,...)
+ if c then
+ write_nl(report_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(report_yes(a,b))
+ elseif a then
+ write_nl(report_nop(a))
+ else
+ write_nl("")
end
- report=function(a,b,c,...)
- if c then
- write_nl(report_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(report_yes(a,b))
- elseif a then
- write_nl(report_nop(a))
- else
- write_nl("")
- end
+ end
+ subreport=function(a,sub,b,c,...)
+ if c then
+ write_nl(subreport_yes(a,sub,formatters[b](c,...)))
+ elseif b then
+ write_nl(subreport_yes(a,sub,b))
+ elseif a then
+ write_nl(subreport_nop(a,sub))
+ else
+ write_nl("")
end
- subreport=function(a,sub,b,c,...)
- if c then
- write_nl(subreport_yes(a,sub,formatters[b](c,...)))
- elseif b then
- write_nl(subreport_yes(a,sub,b))
- elseif a then
- write_nl(subreport_nop(a,sub))
- else
- write_nl("")
+ end
+ status=function(a,b,c,...)
+ if c then
+ write_nl(status_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(status_yes(a,b))
+ elseif a then
+ write_nl(status_nop(a))
+ else
+ write_nl("\n")
+ end
+ end
+ direct=ignore
+ subdirect=ignore
+ settarget=ignore
+ pushtarget=ignore
+ poptarget=ignore
+ setformats=ignore
+ settranslations=ignore
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(f(s))
+ end
+ end
+ setformatters=function(specification)
+ local f=nil
+ local d=variants.default
+ if specification then
+ if type(specification)=="table" then
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ f=v.formats
end
+ end
end
- status=function(a,b,c,...)
- if c then
- write_nl(status_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(status_yes(a,b))
- elseif a then
- write_nl(status_nop(a))
- else
- write_nl("\n")
- end
- end
- direct=ignore
- subdirect=ignore
- settarget=ignore
- pushtarget=ignore
- poptarget=ignore
- setformats=ignore
- settranslations=ignore
- setprocessor=function(f)
- local writeline=write_nl
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ end
+ setformatters(variant)
+ setlogfile=function(name,keepopen)
+ if name and name~="" then
+ local localtime=os.localtime
+ local writeline=write_nl
+ if keepopen then
+ local f=io.open(name,"ab")
write_nl=function(s)
- writeline(f(s))
+ writeline(s)
+ f:write(localtime()," | ",s,"\n")
end
- end
- setformatters=function(specification)
- local f=nil
- local d=variants.default
- if specification then
- if type(specification)=="table" then
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- f=v.formats
- end
- end
- end
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- end
- setformatters(variant)
- setlogfile=function(name,keepopen)
- if name and name~="" then
- local localtime=os.localtime
- local writeline=write_nl
- if keepopen then
- local f=io.open(name,"ab")
- write_nl=function(s)
- writeline(s)
- f:write(localtime()," | ",s,"\n")
- end
- else
- write_nl=function(s)
- writeline(s)
- local f=io.open(name,"ab")
- f:write(localtime()," | ",s,"\n")
- f:close()
- end
- end
- end
- setlogfile=ignore
- end
- settimedlog=function()
- local localtime=os.localtime
- local writeline=write_nl
+ else
write_nl=function(s)
- writeline(localtime().." | "..s)
+ writeline(s)
+ local f=io.open(name,"ab")
+ f:write(localtime()," | ",s,"\n")
+ f:close()
end
- settimedlog=ignore
+ end
end
+ setlogfile=ignore
+ end
+ settimedlog=function()
+ local localtime=os.localtime
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(localtime().." | "..s)
+ end
+ settimedlog=ignore
+ end
end
logs.report=report
logs.subreport=subreport
@@ -13013,186 +13013,186 @@ local data={}
local states=nil
local force=false
function logs.reporter(category,subcategory)
- local logger=data[category]
- if not logger then
- local state=states==true
- if not state and type(states)=="table" then
- for c,_ in next,states do
- if find(category,c) then
- state=true
- break
- end
- end
+ local logger=data[category]
+ if not logger then
+ local state=states==true
+ if not state and type(states)=="table" then
+ for c,_ in next,states do
+ if find(category,c) then
+ state=true
+ break
end
- logger={
- reporters={},
- state=state,
- }
- data[category]=logger
- end
- local reporter=logger.reporters[subcategory or "default"]
- if not reporter then
- if subcategory then
- reporter=function(...)
- if force or not logger.state then
- subreport(category,subcategory,...)
- end
- end
- logger.reporters[subcategory]=reporter
- else
- local tag=category
- reporter=function(...)
- if force or not logger.state then
- report(category,...)
- end
- end
- logger.reporters.default=reporter
+ end
+ end
+ logger={
+ reporters={},
+ state=state,
+ }
+ data[category]=logger
+ end
+ local reporter=logger.reporters[subcategory or "default"]
+ if not reporter then
+ if subcategory then
+ reporter=function(...)
+ if force or not logger.state then
+ subreport(category,subcategory,...)
+ end
+ end
+ logger.reporters[subcategory]=reporter
+ else
+ local tag=category
+ reporter=function(...)
+ if force or not logger.state then
+ report(category,...)
end
+ end
+ logger.reporters.default=reporter
end
- return reporter
+ end
+ return reporter
end
logs.new=logs.reporter
local ctxreport=logs.writer
function logs.setmessenger(m)
- ctxreport=m
+ ctxreport=m
end
function logs.messenger(category,subcategory)
- if subcategory then
- return function(...)
- ctxreport(subdirect(category,subcategory,...))
- end
- else
- return function(...)
- ctxreport(direct(category,...))
- end
+ if subcategory then
+ return function(...)
+ ctxreport(subdirect(category,subcategory,...))
end
+ else
+ return function(...)
+ ctxreport(direct(category,...))
+ end
+ end
end
local function setblocked(category,value)
- if category==true or category=="all" then
- category,value="*",true
- elseif category==false then
- category,value="*",false
- elseif value==nil then
- value=true
- end
- if category=="*" then
- states=value
+ if category==true or category=="all" then
+ category,value="*",true
+ elseif category==false then
+ category,value="*",false
+ elseif value==nil then
+ value=true
+ end
+ if category=="*" then
+ states=value
+ for k,v in next,data do
+ v.state=value
+ end
+ else
+ alllocked=false
+ states=settings_to_hash(category,type(states)=="table" and states or nil)
+ for c in next,states do
+ local v=data[c]
+ if v then
+ v.state=value
+ else
+ c=topattern(c,true,true)
for k,v in next,data do
+ if find(k,c) then
v.state=value
+ end
end
- else
- alllocked=false
- states=settings_to_hash(category,type(states)=="table" and states or nil)
- for c in next,states do
- local v=data[c]
- if v then
- v.state=value
- else
- c=topattern(c,true,true)
- for k,v in next,data do
- if find(k,c) then
- v.state=value
- end
- end
- end
- end
+ end
end
+ end
end
function logs.disable(category,value)
- setblocked(category,value==nil and true or value)
+ setblocked(category,value==nil and true or value)
end
function logs.enable(category)
- setblocked(category,false)
+ setblocked(category,false)
end
function logs.categories()
- return sortedkeys(data)
+ return sortedkeys(data)
end
function logs.show()
- local n,c,s,max=0,0,0,0
- for category,v in table.sortedpairs(data) do
- n=n+1
- local state=v.state
- local reporters=v.reporters
- local nc=#category
- if nc>c then
- c=nc
- end
- for subcategory,_ in next,reporters do
- local ns=#subcategory
- if ns>c then
- s=ns
- end
- local m=nc+ns
- if m>max then
- max=m
- end
- end
- local subcategories=concat(sortedkeys(reporters),", ")
- if state==true then
- state="disabled"
- elseif state==false then
- state="enabled"
- else
- state="unknown"
- end
- report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ local n,c,s,max=0,0,0,0
+ for category,v in table.sortedpairs(data) do
+ n=n+1
+ local state=v.state
+ local reporters=v.reporters
+ local nc=#category
+ if nc>c then
+ c=nc
+ end
+ for subcategory,_ in next,reporters do
+ local ns=#subcategory
+ if ns>c then
+ s=ns
+ end
+ local m=nc+ns
+ if m>max then
+ max=m
+ end
+ end
+ local subcategories=concat(sortedkeys(reporters),", ")
+ if state==true then
+ state="disabled"
+ elseif state==false then
+ state="enabled"
+ else
+ state="unknown"
end
- report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
+ report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ end
+ report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
end
local delayed_reporters={}
setmetatableindex(delayed_reporters,function(t,k)
- local v=logs.reporter(k.name)
- t[k]=v
- return v
+ local v=logs.reporter(k.name)
+ t[k]=v
+ return v
end)
function utilities.setters.report(setter,...)
- delayed_reporters[setter](...)
+ delayed_reporters[setter](...)
end
directives.register("logs.blocked",function(v)
- setblocked(v,true)
+ setblocked(v,true)
end)
directives.register("logs.target",function(v)
- settarget(v)
+ settarget(v)
end)
if tex then
- local report=logs.reporter("pages")
- local texgetcount=tex and tex.getcount
- local real,user,sub=0,0,0
- function logs.start_page_number()
- real=texgetcount("realpageno")
- user=texgetcount("userpageno")
- sub=texgetcount("subpageno")
- end
- local timing=false
- local lasttime=nil
- trackers.register("pages.timing",function(v)
- timing=""
- end)
- function logs.stop_page_number()
- if timing then
- local elapsed=statistics.currenttime(statistics)
- local average,page
- if not lasttime or real<2 then
- average=elapsed
- page=elapsed
- else
- average=elapsed/(real-1)
- page=elapsed-lasttime
- end
- lasttime=elapsed
- timing=formatters[", total %0.03f, page %0.03f, average %0.03f"](elapsed,page,average)
- end
- if real<=0 then
- report("flushing page%s",timing)
- elseif user<=0 then
- report("flushing realpage %s%s",real,timing)
- elseif sub<=0 then
- report("flushing realpage %s, userpage %s%s",real,user,timing)
- else
- report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
- end
- logs.flush()
+ local report=logs.reporter("pages")
+ local texgetcount=tex and tex.getcount
+ local real,user,sub=0,0,0
+ function logs.start_page_number()
+ real=texgetcount("realpageno")
+ user=texgetcount("userpageno")
+ sub=texgetcount("subpageno")
+ end
+ local timing=false
+ local lasttime=nil
+ trackers.register("pages.timing",function(v)
+ timing=""
+ end)
+ function logs.stop_page_number()
+ if timing then
+ local elapsed=statistics.currenttime(statistics)
+ local average,page
+ if not lasttime or real<2 then
+ average=elapsed
+ page=elapsed
+ else
+ average=elapsed/(real-1)
+ page=elapsed-lasttime
+ end
+ lasttime=elapsed
+ timing=formatters[", total %0.03f, page %0.03f, average %0.03f"](elapsed,page,average)
end
+ if real<=0 then
+ report("flushing page%s",timing)
+ elseif user<=0 then
+ report("flushing realpage %s%s",real,timing)
+ elseif sub<=0 then
+ report("flushing realpage %s, userpage %s%s",real,user,timing)
+ else
+ report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
+ end
+ logs.flush()
+ end
end
local nesting=0
local verbose=false
@@ -13216,222 +13216,222 @@ logs.help=ignore
local Carg,C,lpegmatch=lpeg.Carg,lpeg.C,lpeg.match
local p_newline=lpeg.patterns.newline
local linewise=(
- Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
+ Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
)^1
local function reportlines(t,str)
- if str then
- lpegmatch(linewise,str,1,t)
- end
+ if str then
+ lpegmatch(linewise,str,1,t)
+ end
end
local function reportbanner(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- t.report()
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ t.report()
+ end
end
local function reportversion(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ end
end
local function reporthelp(t,...)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="string" then
- reportlines(t,helpinfo)
- elseif type(helpinfo)=="table" then
- for i=1,select("#",...) do
- reportlines(t,t.helpinfo[select(i,...)])
- if i<n then
- t.report()
- end
- end
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="string" then
+ reportlines(t,helpinfo)
+ elseif type(helpinfo)=="table" then
+ for i=1,select("#",...) do
+ reportlines(t,t.helpinfo[select(i,...)])
+ if i<n then
+ t.report()
+ end
end
+ end
end
local function reportinfo(t)
- t.report()
- reportlines(t,t.moreinfo)
+ t.report()
+ reportlines(t,t.moreinfo)
end
local function reportexport(t,method)
- report(t.helpinfo)
+ report(t.helpinfo)
end
local reporters={
- lines=reportlines,
- banner=reportbanner,
- version=reportversion,
- help=reporthelp,
- info=reportinfo,
- export=reportexport,
+ lines=reportlines,
+ banner=reportbanner,
+ version=reportversion,
+ help=reporthelp,
+ info=reportinfo,
+ export=reportexport,
}
local exporters={
}
logs.reporters=reporters
logs.exporters=exporters
function logs.application(t)
- t.name=t.name or "unknown"
- t.banner=t.banner
- t.moreinfo=moreinfo
- t.report=logs.reporter(t.name)
- t.help=function(...)
- reporters.banner(t)
- reporters.help(t,...)
- reporters.info(t)
- end
- t.export=function(...)
- reporters.export(t,...)
- end
- t.identify=function()
- reporters.banner(t)
- end
- t.version=function()
- reporters.version(t)
- end
- return t
+ t.name=t.name or "unknown"
+ t.banner=t.banner
+ t.moreinfo=moreinfo
+ t.report=logs.reporter(t.name)
+ t.help=function(...)
+ reporters.banner(t)
+ reporters.help(t,...)
+ reporters.info(t)
+ end
+ t.export=function(...)
+ reporters.export(t,...)
+ end
+ t.identify=function()
+ reporters.banner(t)
+ end
+ t.version=function()
+ reporters.version(t)
+ end
+ return t
end
local f_syslog=formatters["%s %s => %s => %s => %s\r"]
function logs.system(whereto,process,jobname,category,fmt,arg,...)
- local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
- for i=1,10 do
- local f=openfile(whereto,"a")
- if f then
- f:write(message)
- f:close()
- break
- else
- sleep(0.1)
- end
+ local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
+ for i=1,10 do
+ local f=openfile(whereto,"a")
+ if f then
+ f:write(message)
+ f:close()
+ break
+ else
+ sleep(0.1)
end
+ end
end
local report_system=logs.reporter("system","logs")
function logs.obsolete(old,new)
- local o=loadstring("return "..new)()
- if type(o)=="function" then
- return function(...)
- report_system("function %a is obsolete, use %a",old,new)
- loadstring(old.."="..new.." return "..old)()(...)
- end
- elseif type(o)=="table" then
- local t,m={},{}
- m.__index=function(t,k)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- return o[k]
- end
- m.__newindex=function(t,k,v)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- o[k]=v
- end
- if libraries then
- libraries.obsolete[old]=t
- end
- setmetatable(t,m)
- return t
+ local o=loadstring("return "..new)()
+ if type(o)=="function" then
+ return function(...)
+ report_system("function %a is obsolete, use %a",old,new)
+ loadstring(old.."="..new.." return "..old)()(...)
+ end
+ elseif type(o)=="table" then
+ local t,m={},{}
+ m.__index=function(t,k)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ return o[k]
+ end
+ m.__newindex=function(t,k,v)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ o[k]=v
+ end
+ if libraries then
+ libraries.obsolete[old]=t
end
+ setmetatable(t,m)
+ return t
+ end
end
if utilities then
- utilities.report=report_system
+ utilities.report=report_system
end
if tex and tex.error then
- function logs.texerrormessage(...)
- tex.error(format(...))
- end
+ function logs.texerrormessage(...)
+ tex.error(format(...))
+ end
else
- function logs.texerrormessage(...)
- print(format(...))
- end
+ function logs.texerrormessage(...)
+ print(format(...))
+ end
end
io.stdout:setvbuf('no')
io.stderr:setvbuf('no')
if package.helpers.report then
- package.helpers.report=logs.reporter("package loader")
+ package.helpers.report=logs.reporter("package loader")
end
if tex then
- local finalactions={}
- local fatalerrors={}
- local possiblefatal={}
- local loggingerrors=false
- function logs.loggingerrors()
- return loggingerrors
- end
- directives.register("logs.errors",function(v)
- loggingerrors=v
- if type(v)=="string" then
- fatalerrors=settings_to_hash(v)
- else
- fatalerrors={}
- end
- end)
- function logs.registerfinalactions(...)
- insert(finalactions,...)
- end
- local what=nil
- local report=nil
- local state=nil
- local target=nil
- local function startlogging(t,r,w,s)
- target=t
- state=force
- force=true
- report=type(r)=="function" and r or logs.reporter(r)
- what=w
- pushtarget(target)
+ local finalactions={}
+ local fatalerrors={}
+ local possiblefatal={}
+ local loggingerrors=false
+ function logs.loggingerrors()
+ return loggingerrors
+ end
+ directives.register("logs.errors",function(v)
+ loggingerrors=v
+ if type(v)=="string" then
+ fatalerrors=settings_to_hash(v)
+ else
+ fatalerrors={}
+ end
+ end)
+ function logs.registerfinalactions(...)
+ insert(finalactions,...)
+ end
+ local what=nil
+ local report=nil
+ local state=nil
+ local target=nil
+ local function startlogging(t,r,w,s)
+ target=t
+ state=force
+ force=true
+ report=type(r)=="function" and r or logs.reporter(r)
+ what=w
+ pushtarget(target)
+ newline()
+ if s then
+ report("start %s: %s",what,s)
+ else
+ report("start %s",what)
+ end
+ if target=="logfile" then
+ newline()
+ end
+ return report
+ end
+ local function stoplogging()
+ if target=="logfile" then
+ newline()
+ end
+ report("stop %s",what)
+ if target=="logfile" then
+ newline()
+ end
+ poptarget()
+ state=oldstate
+ end
+ function logs.startfilelogging(...)
+ return startlogging("logfile",...)
+ end
+ logs.stopfilelogging=stoplogging
+ local done=false
+ function logs.starterrorlogging(r,w,...)
+ if not done then
+ pushtarget("terminal")
+ newline()
+ logs.report("error logging","start possible issues")
+ poptarget()
+ done=true
+ end
+ if fatalerrors[w] then
+ possiblefatal[w]=true
+ end
+ return startlogging("terminal",r,w,...)
+ end
+ logs.stoperrorlogging=stoplogging
+ function logs.finalactions()
+ if #finalactions>0 then
+ for i=1,#finalactions do
+ finalactions[i]()
+ end
+ if done then
+ pushtarget("terminal")
newline()
- if s then
- report("start %s: %s",what,s)
- else
- report("start %s",what)
- end
- if target=="logfile" then
- newline()
- end
- return report
- end
- local function stoplogging()
- if target=="logfile" then
- newline()
- end
- report("stop %s",what)
- if target=="logfile" then
- newline()
- end
+ logs.report("error logging","stop possible issues")
poptarget()
- state=oldstate
- end
- function logs.startfilelogging(...)
- return startlogging("logfile",...)
- end
- logs.stopfilelogging=stoplogging
- local done=false
- function logs.starterrorlogging(r,w,...)
- if not done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","start possible issues")
- poptarget()
- done=true
- end
- if fatalerrors[w] then
- possiblefatal[w]=true
- end
- return startlogging("terminal",r,w,...)
- end
- logs.stoperrorlogging=stoplogging
- function logs.finalactions()
- if #finalactions>0 then
- for i=1,#finalactions do
- finalactions[i]()
- end
- if done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","stop possible issues")
- poptarget()
- end
- return next(possiblefatal) and sortedkeys(possiblefatal) or false
- end
+ end
+ return next(possiblefatal) and sortedkeys(possiblefatal) or false
end
+ end
end
@@ -13441,14 +13441,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
--- original size: 8684, stripped down to: 6000
+-- original size: 9000, stripped down to: 6003
if not modules then modules={} end modules ['trac-inf']={
- version=1.001,
- comment="companion to trac-inf.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-inf.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber,select=type,tonumber,select
local format,lower,find=string.format,string.lower,string.find
@@ -13463,86 +13463,86 @@ statistics.enable=true
statistics.threshold=0.01
local statusinfo,n,registered,timers={},0,{},{}
setmetatableindex(timers,function(t,k)
- local v={ timing=0,loadtime=0 }
- t[k]=v
- return v
+ local v={ timing=0,loadtime=0 }
+ t[k]=v
+ return v
end)
local function hastiming(instance)
- return instance and timers[instance]
+ return instance and timers[instance]
end
local function resettiming(instance)
- timers[instance or "notimer"]={ timing=0,loadtime=0 }
+ timers[instance or "notimer"]={ timing=0,loadtime=0 }
end
local ticks=clock
local seconds=function(n) return n or 0 end
local function starttiming(instance,reset)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if reset then
- it=0
- timer.loadtime=0
- end
- if it==0 then
- timer.starttime=ticks()
- if not timer.loadtime then
- timer.loadtime=0
- end
- end
- timer.timing=it+1
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if reset then
+ it=0
+ timer.loadtime=0
+ end
+ if it==0 then
+ timer.starttime=ticks()
+ if not timer.loadtime then
+ timer.loadtime=0
+ end
+ end
+ timer.timing=it+1
end
local function stoptiming(instance)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it>1 then
- timer.timing=it-1
- else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- local stoptime=ticks()
- local loadtime=stoptime-starttime
- timer.stoptime=stoptime
- timer.loadtime=timer.loadtime+loadtime
- timer.timing=0
- timer.starttime=0
- return loadtime
- end
- end
- return 0
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
+ timer.timing=it-1
+ else
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ local stoptime=ticks()
+ local loadtime=stoptime-starttime
+ timer.stoptime=stoptime
+ timer.loadtime=timer.loadtime+loadtime
+ timer.timing=0
+ timer.starttime=0
+ return loadtime
+ end
+ end
+ return 0
end
local function elapsed(instance)
- if type(instance)=="number" then
- return instance
- else
- local timer=timers[instance or "notimer"]
- return timer and seconds(timer.loadtime) or 0
- end
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ return timer and seconds(timer.loadtime) or 0
+ end
end
local function currenttime(instance)
- if type(instance)=="number" then
- return instance
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
else
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it>1 then
- else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- return seconds(timer.loadtime+ticks()-starttime)
- end
- end
- return 0
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ return seconds(timer.loadtime+ticks()-starttime)
+ end
end
+ return 0
+ end
end
local function elapsedtime(instance)
- return format("%0.3f",elapsed(instance))
+ return format("%0.3f",elapsed(instance))
end
local function elapsedindeed(instance)
- return elapsed(instance)>statistics.threshold
+ return elapsed(instance)>statistics.threshold
end
local function elapsedseconds(instance,rest)
- if elapsedindeed(instance) then
- return format("%0.3f seconds %s",elapsed(instance),rest or "")
- end
+ if elapsedindeed(instance) then
+ return format("%0.3f seconds %s",elapsed(instance),rest or "")
+ end
end
statistics.hastiming=hastiming
statistics.resettiming=resettiming
@@ -13554,91 +13554,98 @@ statistics.elapsedtime=elapsedtime
statistics.elapsedindeed=elapsedindeed
statistics.elapsedseconds=elapsedseconds
function statistics.register(tag,fnc)
- if statistics.enable and type(fnc)=="function" then
- local rt=registered[tag] or (#statusinfo+1)
- statusinfo[rt]={ tag,fnc }
- registered[tag]=rt
- if #tag>n then n=#tag end
- end
+ if statistics.enable and type(fnc)=="function" then
+ local rt=registered[tag] or (#statusinfo+1)
+ statusinfo[rt]={ tag,fnc }
+ registered[tag]=rt
+ if #tag>n then n=#tag end
+ end
end
local report=logs.reporter("mkiv lua stats")
function statistics.show()
- if statistics.enable then
- local register=statistics.register
- register("used platform",function()
- return format("%s, type: %s, binary subtree: %s",
- os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
- end)
- register("used engine",function()
- return format("%s version %s with functionality level %s, banner: %s",
- LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
- end)
- register("control sequences",function()
- return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
- end)
- register("callbacks",statistics.callbacks)
- if TEXENGINE=="luajittex" and JITSUPPORTED then
- local jitstatus=jit.status
- if jitstatus then
- local jitstatus={ jitstatus() }
- if jitstatus[1] then
- register("luajit options",concat(jitstatus," ",2))
- end
- end
- end
- register("lua properties",function()
- local hashchar=tonumber(status.luatex_hashchars)
- local hashtype=status.luatex_hashtype
- local mask=lua.mask or "ascii"
- return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
- jit and "luajit" or "lua",
- LUAVERSION,
- statistics.memused(),
- hashtype or "default",
- hashchar and 2^hashchar or "unknown",
- mask,
- mask=="utf" and "τεχ" or "tex")
- end)
- register("runtime",statistics.runtime)
- logs.newline()
- for i=1,#statusinfo do
- local s=statusinfo[i]
- local r=s[2]()
- if r then
- report("%s: %s",s[1],r)
- end
+ if statistics.enable then
+ local register=statistics.register
+ register("used platform",function()
+ return format("%s, type: %s, binary subtree: %s",
+ os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
+ end)
+ register("used engine",function()
+ return format("%s version %s with functionality level %s, banner: %s",
+ LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
+ end)
+ register("control sequences",function()
+ return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
+ end)
+ register("callbacks",statistics.callbacks)
+ if TEXENGINE=="luajittex" and JITSUPPORTED then
+ local jitstatus=jit.status
+ if jitstatus then
+ local jitstatus={ jitstatus() }
+ if jitstatus[1] then
+ register("luajit options",concat(jitstatus," ",2))
end
- statistics.enable=false
+ end
+ end
+ register("lua properties",function()
+ local hashchar=tonumber(status.luatex_hashchars)
+ local hashtype=status.luatex_hashtype
+ local mask=lua.mask or "ascii"
+ return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
+ jit and "luajit" or "lua",
+ LUAVERSION,
+ statistics.memused(),
+ hashtype or "default",
+ hashchar and 2^hashchar or "unknown",
+ mask,
+ mask=="utf" and "τεχ" or "tex")
+ end)
+ register("runtime",statistics.runtime)
+ logs.newline()
+ for i=1,#statusinfo do
+ local s=statusinfo[i]
+ local r=s[2]()
+ if r then
+ report("%s: %s",s[1],r)
+ end
end
+ statistics.enable=false
+ end
end
function statistics.memused()
- local round=math.round or math.floor
- return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
+ local round=math.round or math.floor
+ return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
end
starttiming(statistics)
function statistics.formatruntime(runtime)
- return format("%s seconds",runtime)
+ return format("%s seconds",runtime)
end
function statistics.runtime()
- stoptiming(statistics)
- return statistics.formatruntime(elapsedtime(statistics))
+ stoptiming(statistics)
+ local runtime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
end
local report=logs.reporter("system")
-function statistics.timed(action)
- starttiming("run")
- action()
- stoptiming("run")
- report("total runtime: %s seconds",elapsedtime("run"))
+function statistics.timed(action,all)
+ starttiming("run")
+ action()
+ stoptiming("run")
+ local runtime=tonumber(elapsedtime("run"))
+ if all then
+ local alltime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime)
+ else
+ report("total runtime: %0.3f seconds",runtime)
+ end
end
function statistics.tracefunction(base,tag,...)
- for i=1,select("#",...) do
- local name=select(i,...)
- local stat={}
- local func=base[name]
- setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
- base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
- statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
- end
+ for i=1,select("#",...) do
+ local name=select(i,...)
+ local stat={}
+ local func=base[name]
+ setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
+ base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
+ statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
+ end
end
@@ -13648,144 +13655,144 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
--- original size: 5841, stripped down to: 3511
+-- original size: 5841, stripped down to: 3352
if not modules then modules={} end modules ['trac-pro']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
-local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
+local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
local report_system=logs.reporter("system","protection")
namespaces=namespaces or {}
local namespaces=namespaces
local registered={}
local function report_index(k,name)
- if trace_namespaces then
- report_system("reference to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("reference to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("reference to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("reference to %a in protected namespace %a",k,name)
+ end
end
local function report_newindex(k,name)
- if trace_namespaces then
- report_system("assignment to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("assignment to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("assignment to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("assignment to %a in protected namespace %a",k,name)
+ end
end
local function register(name)
- local data=name=="global" and _G or _G[name]
- if not data then
- return
- end
- registered[name]=data
- local m=getmetatable(data)
- if not m then
- m={}
- setmetatable(data,m)
- end
- local index,newindex={},{}
- m.__saved__index=m.__index
- m.__no__index=function(t,k)
- if not index[k] then
- index[k]=true
- report_index(k,name)
- end
- return nil
+ local data=name=="global" and _G or _G[name]
+ if not data then
+ return
+ end
+ registered[name]=data
+ local m=getmetatable(data)
+ if not m then
+ m={}
+ setmetatable(data,m)
+ end
+ local index,newindex={},{}
+ m.__saved__index=m.__index
+ m.__no__index=function(t,k)
+ if not index[k] then
+ index[k]=true
+ report_index(k,name)
end
- m.__saved__newindex=m.__newindex
- m.__no__newindex=function(t,k,v)
- if not newindex[k] then
- newindex[k]=true
- report_newindex(k,name)
- end
- rawset(t,k,v)
+ return nil
+ end
+ m.__saved__newindex=m.__newindex
+ m.__no__newindex=function(t,k,v)
+ if not newindex[k] then
+ newindex[k]=true
+ report_newindex(k,name)
end
- m.__protection__depth=0
+ rawset(t,k,v)
+ end
+ m.__protection__depth=0
end
local function private(name)
- local data=registered[name]
+ local data=registered[name]
+ if not data then
+ data=_G[name]
if not data then
- data=_G[name]
- if not data then
- data={}
- _G[name]=data
- end
- register(name)
+ data={}
+ _G[name]=data
end
- return data
+ register(name)
+ end
+ return data
end
local function protect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>0 then
- m.__protection__depth=pd+1
- else
- m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
- m.__index,m.__newindex=m.__no__index,m.__no__newindex
- m.__protection__depth=1
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>0 then
+ m.__protection__depth=pd+1
+ else
+ m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
+ m.__index,m.__newindex=m.__no__index,m.__no__newindex
+ m.__protection__depth=1
+ end
end
local function unprotect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>1 then
- m.__protection__depth=pd-1
- else
- m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
- m.__protection__depth=0
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>1 then
+ m.__protection__depth=pd-1
+ else
+ m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
+ m.__protection__depth=0
+ end
end
local function protectall()
- for name,_ in next,registered do
- if name~="global" then
- protect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ protect(name)
end
+ end
end
local function unprotectall()
- for name,_ in next,registered do
- if name~="global" then
- unprotect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ unprotect(name)
end
+ end
end
-namespaces.register=register
-namespaces.private=private
+namespaces.register=register
+namespaces.private=private
namespaces.protect=protect
namespaces.unprotect=unprotect
namespaces.protectall=protectall
namespaces.unprotectall=unprotectall
namespaces.private("namespaces") registered={} register("global")
directives.register("system.protect",function(v)
- if v then
- protectall()
- else
- unprotectall()
- end
+ if v then
+ protectall()
+ else
+ unprotectall()
+ end
end)
directives.register("system.checkglobals",function(v)
- if v then
- report_system("enabling global namespace guard")
- protect("global")
- else
- report_system("disabling global namespace guard")
- unprotect("global")
- end
+ if v then
+ report_system("enabling global namespace guard")
+ protect("global")
+ else
+ report_system("disabling global namespace guard")
+ unprotect("global")
+ end
end)
@@ -13795,15 +13802,15 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lua"] = package.loaded["util-lua"] or true
--- original size: 6664, stripped down to: 4800
+-- original size: 6664, stripped down to: 4589
if not modules then modules={} end modules ['util-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment="the strip code is written by Peter Cawley",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ comment="the strip code is written by Peter Cawley",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format
local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage
@@ -13814,151 +13821,151 @@ local report_lua=logs.reporter("system","lua")
local report_mem=logs.reporter("system","lua memory")
local tracestripping=false
local tracememory=false
-luautilities.stripcode=true
+luautilities.stripcode=true
luautilities.alwaysstripcode=false
luautilities.nofstrippedchunks=0
luautilities.nofstrippedbytes=0
local strippedchunks={}
luautilities.strippedchunks=strippedchunks
luautilities.suffixes={
- tma="tma",
- tmc=jit and "tmb" or "tmc",
- lua="lua",
- luc=jit and "lub" or "luc",
- lui="lui",
- luv="luv",
- luj="luj",
- tua="tua",
- tuc="tuc",
+ tma="tma",
+ tmc=jit and "tmb" or "tmc",
+ lua="lua",
+ luc=jit and "lub" or "luc",
+ lui="lui",
+ luv="luv",
+ luj="luj",
+ tua="tua",
+ tuc="tuc",
}
local function register(name)
- if tracestripping then
- report_lua("stripped bytecode from %a",name or "unknown")
- end
- strippedchunks[#strippedchunks+1]=name
- luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
+ if tracestripping then
+ report_lua("stripped bytecode from %a",name or "unknown")
+ end
+ strippedchunks[#strippedchunks+1]=name
+ luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
end
local function stupidcompile(luafile,lucfile,strip)
- local code=io.loaddata(luafile)
- if code and code~="" then
- code=load(code)
- if code then
- code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
- if code and code~="" then
- register(name)
- io.savedata(lucfile,code)
- return true,0
- end
- else
- report_lua("fatal error %a in file %a",1,luafile)
- end
- else
- report_lua("fatal error %a in file %a",2,luafile)
- end
- return false,0
-end
-function luautilities.loadedluacode(fullname,forcestrip,name,macros)
- name=name or fullname
- if macros then
- macros=lua.macros
- end
- local code,message
- if macros then
- code,message=macros.loaded(fullname,true,false)
- else
- code,message=loadfile(fullname)
- end
+ local code=io.loaddata(luafile)
+ if code and code~="" then
+ code=load(code)
if code then
- code()
- else
- report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
- code,message=loadfile(fullname)
- end
- if forcestrip and luautilities.stripcode then
- if type(forcestrip)=="function" then
- forcestrip=forcestrip(fullname)
- end
- if forcestrip or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
- elseif luautilities.alwaysstripcode then
+ code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
+ if code and code~="" then
register(name)
- return load(dump(code,true)),0
+ io.savedata(lucfile,code)
+ return true,0
+ end
else
- return code,0
+ report_lua("fatal error %a in file %a",1,luafile)
end
+ else
+ report_lua("fatal error %a in file %a",2,luafile)
+ end
+ return false,0
+end
+function luautilities.loadedluacode(fullname,forcestrip,name,macros)
+ name=name or fullname
+ if macros then
+ macros=lua.macros
+ end
+ local code,message
+ if macros then
+ code,message=macros.loaded(fullname,true,false)
+ else
+ code,message=loadfile(fullname)
+ end
+ if code then
+ code()
+ else
+ report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
+ code,message=loadfile(fullname)
+ end
+ if forcestrip and luautilities.stripcode then
+ if type(forcestrip)=="function" then
+ forcestrip=forcestrip(fullname)
+ end
+ if forcestrip or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
+ elseif luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.strippedloadstring(code,name,forcestrip)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.loadstring(code,name)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- return code,0
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ return code,0
end
function luautilities.compile(luafile,lucfile,cleanup,strip,fallback)
- report_lua("compiling %a into %a",luafile,lucfile)
- os.remove(lucfile)
- local done=stupidcompile(luafile,lucfile,strip~=false)
- if done then
- report_lua("dumping %a into %a stripped",luafile,lucfile)
- if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
- report_lua("removing %a",luafile)
- os.remove(luafile)
- end
- end
- return done
+ report_lua("compiling %a into %a",luafile,lucfile)
+ os.remove(lucfile)
+ local done=stupidcompile(luafile,lucfile,strip~=false)
+ if done then
+ report_lua("dumping %a into %a stripped",luafile,lucfile)
+ if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+ report_lua("removing %a",luafile)
+ os.remove(luafile)
+ end
+ end
+ return done
end
function luautilities.loadstripped(...)
- local l=load(...)
- if l then
- return load(dump(l,true))
- end
+ local l=load(...)
+ if l then
+ return load(dump(l,true))
+ end
end
local finalizers={}
setmetatable(finalizers,{
- __gc=function(t)
- for i=1,#t do
- pcall(t[i])
- end
+ __gc=function(t)
+ for i=1,#t do
+ pcall(t[i])
end
+ end
} )
function luautilities.registerfinalizer(f)
- finalizers[#finalizers+1]=f
+ finalizers[#finalizers+1]=f
end
function luautilities.checkmemory(previous,threshold,trace)
- local current=collectgarbage("count")
- if previous then
- local checked=(threshold or 64)*1024
- local delta=current-previous
- if current-previous>checked then
- collectgarbage("collect")
- local afterwards=collectgarbage("count")
- if trace or tracememory then
- report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
- previous/1024,current/1024,delta/1024,threshold,afterwards)
- end
- return afterwards
- elseif trace or tracememory then
- report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
- previous/1024,current/1024,delta/1024,threshold)
- end
+ local current=collectgarbage("count")
+ if previous then
+ local checked=(threshold or 64)*1024
+ local delta=current-previous
+ if current-previous>checked then
+ collectgarbage("collect")
+ local afterwards=collectgarbage("count")
+ if trace or tracememory then
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
+ previous/1024,current/1024,delta/1024,threshold,afterwards)
+ end
+ return afterwards
+ elseif trace or tracememory then
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
+ previous/1024,current/1024,delta/1024,threshold)
end
- return current
+ end
+ return current
end
@@ -13968,14 +13975,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-deb"] = package.loaded["util-deb"] or true
--- original size: 9955, stripped down to: 7311
+-- original size: 9955, stripped down to: 6693
if not modules then modules={} end modules ['util-deb']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber=type,next,tostring,tonumber
local format,find,sub,gsub=string.format,string.find,string.sub,string.gsub
@@ -13994,266 +14001,266 @@ local names={}
local initialize=false
if not (FFISUPPORTED and ffi) then
elseif os.type=="windows" then
- initialize=function()
- local kernel=ffilib("kernel32","system")
- if kernel then
- local tonumber=ffi.number or tonumber
- ffi.cdef[[
+ initialize=function()
+ local kernel=ffilib("kernel32","system")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ ffi.cdef[[
int QueryPerformanceFrequency(int64_t *lpFrequency);
int QueryPerformanceCounter(int64_t *lpPerformanceCount);
]]
- local target=ffi.new("__int64[1]")
- ticks=function()
- if kernel.QueryPerformanceCounter(target)==1 then
- return tonumber(target[0])
- else
- return 0
- end
- end
- local target=ffi.new("__int64[1]")
- seconds=function(ticks)
- if kernel.QueryPerformanceFrequency(target)==1 then
- return ticks/tonumber(target[0])
- else
- return 0
- end
- end
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
end
- initialize=false
+ end
end
+ initialize=false
+ end
elseif os.type=="unix" then
- initialize=function()
- local C=ffi.C
- local tonumber=ffi.number or tonumber
- ffi.cdef [[
+ initialize=function()
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ ffi.cdef [[
/* what a mess */
typedef int clk_id_t;
typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
typedef struct timespec { long sec; long nsec; } ctx_timespec;
int clock_gettime(clk_id_t timerid, struct timespec *t);
]]
- local target=ffi.new("ctx_timespec[?]",1)
- local clock=C.CLOCK_PROCESS_CPUTIME_ID
- ticks=function ()
- C.clock_gettime(clock,target)
- return tonumber(target[0].sec*1000000000+target[0].nsec)
- end
- seconds=function(ticks)
- return ticks/1000000000
- end
- initialize=false
+ local target=ffi.new("ctx_timespec[?]",1)
+ local clock=C.CLOCK_PROCESS_CPUTIME_ID
+ ticks=function ()
+ C.clock_gettime(clock,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
end
+ seconds=function(ticks)
+ return ticks/1000000000
+ end
+ initialize=false
+ end
end
setmetatableindex(names,function(t,name)
- local v=setmetatableindex(function(t,source)
- local v=setmetatableindex(function(t,line)
- local v={ total=0,count=0,nesting=0 }
- t[line]=v
- return v
- end)
- t[source]=v
- return v
+ local v=setmetatableindex(function(t,source)
+ local v=setmetatableindex(function(t,line)
+ local v={ total=0,count=0,nesting=0 }
+ t[line]=v
+ return v
end)
- t[name]=v
+ t[source]=v
return v
+ end)
+ t[name]=v
+ return v
end)
local getinfo=nil
local sethook=nil
local function hook(where)
- local f=getinfo(2,"nSl")
- if f then
- local source=f.short_src
- if not source then
- return
- end
- local line=f.linedefined or 0
- local name=f.name
- if not name then
- local what=f.what
- if what=="C" then
- name="<anonymous>"
- else
- name=f.namewhat or what or "<unknown>"
- end
- end
- local data=names[name][source][line]
- if where=="call" then
- local nesting=data.nesting
- if nesting==0 then
- data.count=data.count+1
- insert(data,ticks())
- data.nesting=1
- else
- data.nesting=nesting+1
- end
- elseif where=="return" then
- local nesting=data.nesting
- if nesting==1 then
- local t=remove(data)
- if t then
- data.total=data.total+ticks()-t
- end
- data.nesting=0
- else
- data.nesting=nesting-1
- end
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
+ end
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ local nesting=data.nesting
+ if nesting==0 then
+ data.count=data.count+1
+ insert(data,ticks())
+ data.nesting=1
+ else
+ data.nesting=nesting+1
+ end
+ elseif where=="return" then
+ local nesting=data.nesting
+ if nesting==1 then
+ local t=remove(data)
+ if t then
+ data.total=data.total+ticks()-t
end
+ data.nesting=0
+ else
+ data.nesting=nesting-1
+ end
end
+ end
end
function debugger.showstats(printer,threshold)
- local printer=printer or report
- local calls=0
- local functions=0
- local dataset={}
- local length=0
- local realtime=0
- local totaltime=0
- local threshold=threshold or 0
- for name,sources in next,names do
- for source,lines in next,sources do
- for line,data in next,lines do
- local count=data.count
- if count>threshold then
- if #name>length then
- length=#name
- end
- local total=data.total
- local real=total
- if real>0 then
- real=total-(count*overhead/dummycalls)
- if real<0 then
- real=0
- end
- realtime=realtime+real
- end
- totaltime=totaltime+total
- if line<0 then
- line=0
- end
- dataset[#dataset+1]={ real,total,count,name,source,line }
- end
- end
+ local printer=printer or report
+ local calls=0
+ local functions=0
+ local dataset={}
+ local length=0
+ local realtime=0
+ local totaltime=0
+ local threshold=threshold or 0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ local count=data.count
+ if count>threshold then
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ realtime=realtime+real
+ end
+ totaltime=totaltime+total
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
end
+ end
end
- sort(dataset,function(a,b)
- if a[1]==b[1] then
- if a[2]==b[2] then
- if a[3]==b[3] then
- if a[4]==b[4] then
- if a[5]==b[5] then
- return a[6]<b[6]
- else
- return a[5]<b[5]
- end
- else
- return a[4]<b[4]
- end
- else
- return b[3]<a[3]
- end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
else
- return b[2]<a[2]
+ return a[5]<b[5]
end
+ else
+ return a[4]<b[4]
+ end
else
- return b[1]<a[1]
+ return b[3]<a[3]
end
- end)
- if length>50 then
- length=50
- end
- local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
- for i=1,#dataset do
- local data=dataset[i]
- local real=data[1]
- local total=data[2]
- local count=data[3]
- local name=data[4]
- local source=data[5]
- local line=data[6]
- calls=calls+count
- functions=functions+1
- name=gsub(name,"%s+"," ")
- if #name>length then
- name=sub(name,1,length)
- end
- printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
- end
- printer("")
- printer(format("functions : %i",functions))
- printer(format("calls : %i",calls))
- printer(format("overhead : %f",seconds(overhead/1000)))
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
+ end
+ local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
+ for i=1,#dataset do
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ calls=calls+count
+ functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
+ end
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
end
local function getdebug()
- if sethook and getinfo then
- return
- end
- if not debug then
- local okay
- okay,debug=pcall(require,"debug")
- end
- if type(debug)~="table" then
- return
- end
- getinfo=debug.getinfo
- sethook=debug.sethook
- if type(getinfo)~="function" then
- getinfo=nil
- end
- if type(sethook)~="function" then
- sethook=nil
- end
+ if sethook and getinfo then
+ return
+ end
+ if not debug then
+ local okay
+ okay,debug=pcall(require,"debug")
+ end
+ if type(debug)~="table" then
+ return
+ end
+ getinfo=debug.getinfo
+ sethook=debug.sethook
+ if type(getinfo)~="function" then
+ getinfo=nil
+ end
+ if type(sethook)~="function" then
+ sethook=nil
+ end
end
function debugger.savestats(filename,threshold)
- local f=io.open(filename,'w')
- if f then
- debugger.showstats(function(str) f:write(str,"\n") end,threshold)
- f:close()
- end
+ local f=io.open(filename,'w')
+ if f then
+ debugger.showstats(function(str) f:write(str,"\n") end,threshold)
+ f:close()
+ end
end
function debugger.enable()
- getdebug()
- if sethook and getinfo and nesting==0 then
- running=true
- if initialize then
- initialize()
- end
- sethook(hook,"cr")
- local function dummy() end
- local t=ticks()
- for i=1,dummycalls do
- dummy()
- end
- overhead=ticks()-t
- end
- if nesting>0 then
- nesting=nesting+1
- end
+ getdebug()
+ if sethook and getinfo and nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
end
function debugger.disable()
- if nesting>0 then
- nesting=nesting-1
- end
- if sethook and getinfo and nesting==0 then
- sethook()
- end
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if sethook and getinfo and nesting==0 then
+ sethook()
+ end
end
local function showtraceback(rep)
- getdebug()
- if getinfo then
- local level=2
- local reporter=rep or report
- while true do
- local info=getinfo(level,"Sl")
- if not info then
- break
- elseif info.what=="C" then
- reporter("%2i : %s",level-1,"C function")
- else
- reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
- end
- level=level+1
- end
+ getdebug()
+ if getinfo then
+ local level=2
+ local reporter=rep or report
+ while true do
+ local info=getinfo(level,"Sl")
+ if not info then
+ break
+ elseif info.what=="C" then
+ reporter("%2i : %s",level-1,"C function")
+ else
+ reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
+ end
+ level=level+1
end
+ end
end
debugger.showtraceback=showtraceback
@@ -14264,91 +14271,91 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
--- original size: 7112, stripped down to: 3988
+-- original size: 7112, stripped down to: 3887
if not modules then modules={} end modules ['util-tpl']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities.templates=utilities.templates or {}
local templates=utilities.templates
-local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
+local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
local report_template=logs.reporter("template")
local tostring,next=tostring,next
local format,sub,byte=string.format,string.sub,string.byte
local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
local replacer
local function replacekey(k,t,how,recursive)
- local v=t[k]
- if not v then
- if trace_template then
- report_template("unknown key %a",k)
- end
- return ""
+ local v=t[k]
+ if not v then
+ if trace_template then
+ report_template("unknown key %a",k)
+ end
+ return ""
+ else
+ v=tostring(v)
+ if trace_template then
+ report_template("setting key %a to value %a",k,v)
+ end
+ if recursive then
+ return lpegmatch(replacer,v,1,t,how,recursive)
else
- v=tostring(v)
- if trace_template then
- report_template("setting key %a to value %a",k,v)
- end
- if recursive then
- return lpegmatch(replacer,v,1,t,how,recursive)
- else
- return v
- end
+ return v
end
+ end
end
local sqlescape=lpeg.replacer {
- { "'","''" },
- { "\\","\\\\" },
- { "\r\n","\\n" },
- { "\r","\\n" },
+ { "'","''" },
+ { "\\","\\\\" },
+ { "\r\n","\\n" },
+ { "\r","\\n" },
}
local sqlquoted=Cs(Cc("'")*sqlescape*Cc("'"))
lpegpatterns.sqlescape=sqlescape
lpegpatterns.sqlquoted=sqlquoted
local luaescape=lpegpatterns.luaescape
local escapers={
- lua=function(s)
- return lpegmatch(luaescape,s)
- end,
- sql=function(s)
- return lpegmatch(sqlescape,s)
- end,
+ lua=function(s)
+ return lpegmatch(luaescape,s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlescape,s)
+ end,
}
local quotedescapers={
- lua=function(s)
- return format("%q",s)
- end,
- sql=function(s)
- return lpegmatch(sqlquoted,s)
- end,
+ lua=function(s)
+ return format("%q",s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlquoted,s)
+ end,
}
local luaescaper=escapers.lua
local quotedluaescaper=quotedescapers.lua
local function replacekeyunquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and escapers[how] or luaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and escapers[how] or luaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replacekeyquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and quotedescapers[how] or quotedluaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and quotedescapers[how] or quotedluaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replaceoptional(l,m,r,t,how,recurse)
- local v=t[l]
- return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
+ local v=t[l]
+ return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
end
-local single=P("%")
+local single=P("%")
local double=P("%%")
local lquoted=P("%[")
local rquoted=P("]%")
@@ -14365,41 +14372,41 @@ local noloptional=P("%?")/''
local noroptional=P("?%")/''
local nomoptional=P(":")/''
local args=Carg(1)*Carg(2)*Carg(3)
-local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
-local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
-local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
+local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
+local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
+local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
local optional=noloptional*((C((1-nomoptional)^1)*nomoptional*C((1-noroptional)^1)*args)/replaceoptional)*noroptional
local any=P(1)
replacer=Cs((unquoted+quoted+escape+optional+key+any)^0)
local function replace(str,mapping,how,recurse)
- if mapping and str then
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
- return str
- end
+ if mapping and str then
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ else
+ return str
+ end
end
templates.replace=replace
function templates.replacer(str,how,recurse)
- return function(mapping)
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- end
+ return function(mapping)
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ end
end
function templates.load(filename,mapping,how,recurse)
- local data=io.loaddata(filename) or ""
- if mapping and next(mapping) then
- return replace(data,mapping,how,recurse)
- else
- return data
- end
+ local data=io.loaddata(filename) or ""
+ if mapping and next(mapping) then
+ return replace(data,mapping,how,recurse)
+ else
+ return data
+ end
end
function templates.resolve(t,mapping,how,recurse)
- if not mapping then
- mapping=t
- end
- for k,v in next,t do
- t[k]=replace(v,mapping,how,recurse)
- end
- return t
+ if not mapping then
+ mapping=t
+ end
+ for k,v in next,t do
+ t[k]=replace(v,mapping,how,recurse)
+ end
+ return t
end
@@ -14409,14 +14416,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sbx"] = package.loaded["util-sbx"] or true
--- original size: 20393, stripped down to: 13924
+-- original size: 20393, stripped down to: 13121
if not modules then modules={} end modules ['util-sbx']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not sandbox then require("l-sandbox") end
local next,type=next,type
@@ -14449,144 +14456,144 @@ local report=logs.reporter("sandbox")
trackers.register("sandbox",function(v) trace=v end)
sandbox.setreporter(report)
sandbox.finalizer {
- category="files",
- action=function()
- finalized=true
- end
+ category="files",
+ action=function()
+ finalized=true
+ end
}
local function registerroot(root,what)
- if finalized then
- report("roots are already finalized")
- else
- if type(root)=="table" then
- root,what=root[1],root[2]
- end
- if type(root)=="string" and root~="" then
- root=collapsepath(expandname(root))
- if what=="r" or what=="ro" or what=="readable" then
- what="read"
- elseif what=="w" or what=="wo" or what=="writable" then
- what="write"
- end
- validroots[root]=what=="write" or false
- end
+ if finalized then
+ report("roots are already finalized")
+ else
+ if type(root)=="table" then
+ root,what=root[1],root[2]
+ end
+ if type(root)=="string" and root~="" then
+ root=collapsepath(expandname(root))
+ if what=="r" or what=="ro" or what=="readable" then
+ what="read"
+ elseif what=="w" or what=="wo" or what=="writable" then
+ what="write"
+ end
+ validroots[root]=what=="write" or false
end
+ end
end
sandbox.finalizer {
- category="files",
- action=function()
+ category="files",
+ action=function()
+ if p_validroot then
+ report("roots are already initialized")
+ else
+ sandbox.registerroot(".","write")
+ for name in sortedhash(validroots) do
if p_validroot then
- report("roots are already initialized")
+ p_validroot=P(name)+p_validroot
else
- sandbox.registerroot(".","write")
- for name in sortedhash(validroots) do
- if p_validroot then
- p_validroot=P(name)+p_validroot
- else
- p_validroot=P(name)
- end
- end
- p_validroot=p_validroot/validroots
+ p_validroot=P(name)
end
+ end
+ p_validroot=p_validroot/validroots
end
+ end
}
local function registerbinary(name)
- if finalized then
- report("binaries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validbinaries then
- return
- end
- if validbinaries==true then
- validbinaries={ [name]=true }
- else
- validbinaries[name]=true
- end
- elseif name==true then
- validbinaries={}
+ if finalized then
+ report("binaries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validbinaries then
+ return
end
+ if validbinaries==true then
+ validbinaries={ [name]=true }
+ else
+ validbinaries[name]=true
+ end
+ elseif name==true then
+ validbinaries={}
+ end
end
local function registerlibrary(name)
- if finalized then
- report("libraries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validlibraries then
- return
- end
- if validlibraries==true then
- validlibraries={ [nameonly(name)]=true }
- else
- validlibraries[nameonly(name)]=true
- end
- elseif name==true then
- validlibraries={}
+ if finalized then
+ report("libraries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validlibraries then
+ return
end
+ if validlibraries==true then
+ validlibraries={ [nameonly(name)]=true }
+ else
+ validlibraries[nameonly(name)]=true
+ end
+ elseif name==true then
+ validlibraries={}
+ end
end
local p_write=S("wa") p_write=(1-p_write)^0*p_write
-local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
+local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
local function normalized(name)
- if platform=="windows" then
- name=gsub(name,"/","\\")
- end
- return name
+ if platform=="windows" then
+ name=gsub(name,"/","\\")
+ end
+ return name
end
function sandbox.possiblepath(name)
- return lpegmatch(p_path,name) and true or false
+ return lpegmatch(p_path,name) and true or false
end
local filenamelogger=false
function sandbox.setfilenamelogger(l)
- filenamelogger=type(l)=="function" and l or false
+ filenamelogger=type(l)=="function" and l or false
end
local function validfilename(name,what)
- if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
- local asked=collapsepath(expandname(name))
- local okay=lpegmatch(p_validroot,asked)
- if okay==true then
- if filenamelogger then
- filenamelogger(name,"w",asked,true)
- end
- return name
- elseif okay==false then
- if not what then
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- elseif lpegmatch(p_write,what) then
- if filenamelogger then
- filenamelogger(name,"w",asked,false)
- end
- return
- else
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- end
- elseif filenamelogger then
- filenamelogger(name,"*",name,false)
+ if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
+ local asked=collapsepath(expandname(name))
+ local okay=lpegmatch(p_validroot,asked)
+ if okay==true then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,true)
+ end
+ return name
+ elseif okay==false then
+ if not what then
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
+ end
+ return name
+ elseif lpegmatch(p_write,what) then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,false)
+ end
+ return
+ else
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
end
- else
return name
+ end
+ elseif filenamelogger then
+ filenamelogger(name,"*",name,false)
end
+ else
+ return name
+ end
end
local function readable(name,finalized)
- return validfilename(name,"r")
+ return validfilename(name,"r")
end
local function normalizedreadable(name,finalized)
- local valid=validfilename(name,"r")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"r")
+ if valid then
+ return normalized(valid)
+ end
end
local function writeable(name,finalized)
- return validfilename(name,"w")
+ return validfilename(name,"w")
end
local function normalizedwriteable(name,finalized)
- local valid=validfilename(name,"w")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"w")
+ if valid then
+ return normalized(valid)
+ end
end
validators.readable=readable
validators.writeable=normalizedwriteable
@@ -14594,316 +14601,316 @@ validators.normalizedreadable=normalizedreadable
validators.normalizedwriteable=writeable
validators.filename=readable
table.setmetatableindex(validators,function(t,k)
- if k then
- t[k]=readable
- end
- return readable
+ if k then
+ t[k]=readable
+ end
+ return readable
end)
function validators.string(s,finalized)
- if finalized and suspicious(s) then
- return ""
- else
- return s
- end
+ if finalized and suspicious(s) then
+ return ""
+ else
+ return s
+ end
end
function validators.cache(s)
- if finalized then
- return basename(s)
- else
- return s
- end
+ if finalized then
+ return basename(s)
+ else
+ return s
+ end
end
function validators.url(s)
- if finalized and find("^file:") then
- return ""
- else
- return s
- end
+ if finalized and find("^file:") then
+ return ""
+ else
+ return s
+ end
end
local function filehandlerone(action,one,...)
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
+ else
+ end
end
local function filehandlertwo(action,one,two,...)
- local checkedone=validfilename(one)
- if checkedone then
- local checkedtwo=validfilename(two)
- if checkedtwo then
- return action(one,two,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ local checkedtwo=validfilename(two)
+ if checkedtwo then
+ return action(one,two,...)
else
end
+ else
+ end
end
local function iohandler(action,one,...)
- if type(one)=="string" then
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- end
- elseif one then
- return action(one,...)
- else
- return action()
+ if type(one)=="string" then
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
end
+ elseif one then
+ return action(one,...)
+ else
+ return action()
+ end
end
local osexecute=sandbox.original(os.execute)
local iopopen=sandbox.original(io.popen)
local reported={}
local function validcommand(name,program,template,checkers,defaults,variables,reporter,strict)
- if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
- if variables then
- for variable,value in next,variables do
- local checker=validators[checkers[variable]]
- if checker then
- value=checker(unquoted(value),strict)
- if value then
- variables[variable]=optionalquoted(value)
- else
- report("variable %a with value %a fails the check",variable,value)
- return
- end
- else
- report("variable %a has no checker",variable)
- return
- end
- end
- for variable,default in next,defaults do
- local value=variables[variable]
- if not value or value=="" then
- local checker=validators[checkers[variable]]
- if checker then
- default=checker(unquoted(default),strict)
- if default then
- variables[variable]=optionalquoted(default)
- else
- report("variable %a with default %a fails the check",variable,default)
- return
- end
- end
- end
- end
- end
- local command=program.." "..replace(template,variables)
- if reporter then
- reporter("executing runner %a: %s",name,command)
- elseif trace then
- report("executing runner %a: %s",name,command)
- end
- return command
- elseif not reported[name] then
- report("executing program %a of runner %a is not permitted",program,name)
- reported[name]=true
- end
-end
-local runners={
- resultof=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("resultof: %s",command)
- end
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- end
- end
- end,
- execute=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("execute: %s",command)
- end
- return osexecute(command)
+ if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
+ if variables then
+ for variable,value in next,variables do
+ local checker=validators[checkers[variable]]
+ if checker then
+ value=checker(unquoted(value),strict)
+ if value then
+ variables[variable]=optionalquoted(value)
+ else
+ report("variable %a with value %a fails the check",variable,value)
+ return
+ end
+ else
+ report("variable %a has no checker",variable)
+ return
end
- end,
- pipeto=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("pipeto: %s",command)
+ end
+ for variable,default in next,defaults do
+ local value=variables[variable]
+ if not value or value=="" then
+ local checker=validators[checkers[variable]]
+ if checker then
+ default=checker(unquoted(default),strict)
+ if default then
+ variables[variable]=optionalquoted(default)
+ else
+ report("variable %a with default %a fails the check",variable,default)
+ return
end
- return iopopen(command,"w")
- end
- end,
-}
-function sandbox.registerrunner(specification)
- if type(specification)=="string" then
- local wrapped=validrunners[specification]
- inspect(table.sortedkeys(validrunners))
- if wrapped then
- return wrapped
- else
- report("unknown predefined runner %a",specification)
- return
+ end
end
+ end
end
- if type(specification)~="table" then
- report("specification should be a table (or string)")
- return
- end
- local name=specification.name
- if type(name)~="string" then
- report("invalid name, string expected",name)
- return
- end
- if validrunners[name] then
- report("invalid name, runner %a already defined")
- return
- end
- local program=specification.program
- if type(program)=="string" then
- elseif type(program)=="table" then
- program=program[platform] or program.default or program.unix
- end
- if type(program)~="string" or program=="" then
- report("invalid runner %a specified for platform %a",name,platform)
- return
+ local command=program.." "..replace(template,variables)
+ if reporter then
+ reporter("executing runner %a: %s",name,command)
+ elseif trace then
+ report("executing runner %a: %s",name,command)
end
- local template=specification.template
- if not template then
- report("missing template for runner %a",name)
- return
+ return command
+ elseif not reported[name] then
+ report("executing program %a of runner %a is not permitted",program,name)
+ reported[name]=true
+ end
+end
+local runners={
+ resultof=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("resultof: %s",command)
+ end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ end
end
- local method=specification.method or "execute"
- local checkers=specification.checkers or {}
- local defaults=specification.defaults or {}
- local runner=runners[method]
- if runner then
- local finalized=finalized
- local wrapped=function(variables)
- return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
- end
- validrunners[name]=wrapped
- return wrapped
- else
- validrunners[name]=nil
- report("invalid method for runner %a",name)
+ end,
+ execute=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("execute: %s",command)
+ end
+ return osexecute(command)
+ end
+ end,
+ pipeto=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("pipeto: %s",command)
+ end
+ return iopopen(command,"w")
end
+ end,
+}
+function sandbox.registerrunner(specification)
+ if type(specification)=="string" then
+ local wrapped=validrunners[specification]
+ inspect(table.sortedkeys(validrunners))
+ if wrapped then
+ return wrapped
+ else
+ report("unknown predefined runner %a",specification)
+ return
+ end
+ end
+ if type(specification)~="table" then
+ report("specification should be a table (or string)")
+ return
+ end
+ local name=specification.name
+ if type(name)~="string" then
+ report("invalid name, string expected",name)
+ return
+ end
+ if validrunners[name] then
+ report("invalid name, runner %a already defined")
+ return
+ end
+ local program=specification.program
+ if type(program)=="string" then
+ elseif type(program)=="table" then
+ program=program[platform] or program.default or program.unix
+ end
+ if type(program)~="string" or program=="" then
+ report("invalid runner %a specified for platform %a",name,platform)
+ return
+ end
+ local template=specification.template
+ if not template then
+ report("missing template for runner %a",name)
+ return
+ end
+ local method=specification.method or "execute"
+ local checkers=specification.checkers or {}
+ local defaults=specification.defaults or {}
+ local runner=runners[method]
+ if runner then
+ local finalized=finalized
+ local wrapped=function(variables)
+ return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
+ end
+ validrunners[name]=wrapped
+ return wrapped
+ else
+ validrunners[name]=nil
+ report("invalid method for runner %a",name)
+ end
end
function sandbox.getrunner(name)
- return name and validrunners[name]
+ return name and validrunners[name]
end
local function suspicious(str)
- return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
+ return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
end
local function binaryrunner(action,command,...)
- if validbinaries==false then
- report("no binaries permitted, ignoring command: %s",command)
- return
- end
- if type(command)~="string" then
- report("command should be a string")
- return
- end
- local program=lpegmatch(p_split,command)
- if not program or program=="" then
- report("unable to filter binary from command: %s",command)
- return
- end
- if validbinaries==true then
- elseif not validbinaries[program] then
- report("binary not permitted, ignoring command: %s",command)
- return
- elseif suspicious(command) then
- report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
- return
- end
- return action(command,...)
+ if validbinaries==false then
+ report("no binaries permitted, ignoring command: %s",command)
+ return
+ end
+ if type(command)~="string" then
+ report("command should be a string")
+ return
+ end
+ local program=lpegmatch(p_split,command)
+ if not program or program=="" then
+ report("unable to filter binary from command: %s",command)
+ return
+ end
+ if validbinaries==true then
+ elseif not validbinaries[program] then
+ report("binary not permitted, ignoring command: %s",command)
+ return
+ elseif suspicious(command) then
+ report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
+ return
+ end
+ return action(command,...)
end
local function dummyrunner(action,command,...)
- if type(command)=="table" then
- command=concat(command," ",command[0] and 0 or 1)
- end
- report("ignoring command: %s",command)
+ if type(command)=="table" then
+ command=concat(command," ",command[0] and 0 or 1)
+ end
+ report("ignoring command: %s",command)
end
sandbox.filehandlerone=filehandlerone
sandbox.filehandlertwo=filehandlertwo
sandbox.iohandler=iohandler
function sandbox.disablerunners()
- validbinaries=false
+ validbinaries=false
end
function sandbox.disablelibraries()
- validlibraries=false
+ validlibraries=false
end
if FFISUPPORTED and ffi then
- function sandbox.disablelibraries()
- validlibraries=false
- for k,v in next,ffi do
- if k~="gc" then
- ffi[k]=nil
- end
- end
+ function sandbox.disablelibraries()
+ validlibraries=false
+ for k,v in next,ffi do
+ if k~="gc" then
+ ffi[k]=nil
+ end
end
- local fiiload=ffi.load
- if fiiload then
- local reported={}
- function ffi.load(name,...)
- if validlibraries==false then
- elseif validlibraries==true then
- return fiiload(name,...)
- elseif validlibraries[nameonly(name)] then
- return fiiload(name,...)
- else
- end
- if not reported[name] then
- report("using library %a is not permitted",name)
- reported[name]=true
- end
- return nil
- end
+ end
+ local fiiload=ffi.load
+ if fiiload then
+ local reported={}
+ function ffi.load(name,...)
+ if validlibraries==false then
+ elseif validlibraries==true then
+ return fiiload(name,...)
+ elseif validlibraries[nameonly(name)] then
+ return fiiload(name,...)
+ else
+ end
+ if not reported[name] then
+ report("using library %a is not permitted",name)
+ reported[name]=true
+ end
+ return nil
end
+ end
end
local overload=sandbox.overload
local register=sandbox.register
- overload(loadfile,filehandlerone,"loadfile")
+ overload(loadfile,filehandlerone,"loadfile")
if io then
- overload(io.open,filehandlerone,"io.open")
- overload(io.popen,binaryrunner,"io.popen")
- overload(io.input,iohandler,"io.input")
- overload(io.output,iohandler,"io.output")
- overload(io.lines,filehandlerone,"io.lines")
+ overload(io.open,filehandlerone,"io.open")
+ overload(io.popen,binaryrunner,"io.popen")
+ overload(io.input,iohandler,"io.input")
+ overload(io.output,iohandler,"io.output")
+ overload(io.lines,filehandlerone,"io.lines")
end
if os then
- overload(os.execute,binaryrunner,"os.execute")
- overload(os.spawn,dummyrunner,"os.spawn")
- overload(os.exec,dummyrunner,"os.exec")
- overload(os.resultof,binaryrunner,"os.resultof")
- overload(os.pipeto,binaryrunner,"os.pipeto")
- overload(os.rename,filehandlertwo,"os.rename")
- overload(os.remove,filehandlerone,"os.remove")
+ overload(os.execute,binaryrunner,"os.execute")
+ overload(os.spawn,dummyrunner,"os.spawn")
+ overload(os.exec,dummyrunner,"os.exec")
+ overload(os.resultof,binaryrunner,"os.resultof")
+ overload(os.pipeto,binaryrunner,"os.pipeto")
+ overload(os.rename,filehandlertwo,"os.rename")
+ overload(os.remove,filehandlerone,"os.remove")
end
if lfs then
- overload(lfs.chdir,filehandlerone,"lfs.chdir")
- overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
- overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
- overload(lfs.isfile,filehandlerone,"lfs.isfile")
- overload(lfs.isdir,filehandlerone,"lfs.isdir")
- overload(lfs.attributes,filehandlerone,"lfs.attributes")
- overload(lfs.dir,filehandlerone,"lfs.dir")
- overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
- overload(lfs.touch,filehandlerone,"lfs.touch")
- overload(lfs.link,filehandlertwo,"lfs.link")
- overload(lfs.setmode,filehandlerone,"lfs.setmode")
- overload(lfs.readlink,filehandlerone,"lfs.readlink")
- overload(lfs.shortname,filehandlerone,"lfs.shortname")
- overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
+ overload(lfs.chdir,filehandlerone,"lfs.chdir")
+ overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
+ overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
+ overload(lfs.isfile,filehandlerone,"lfs.isfile")
+ overload(lfs.isdir,filehandlerone,"lfs.isdir")
+ overload(lfs.attributes,filehandlerone,"lfs.attributes")
+ overload(lfs.dir,filehandlerone,"lfs.dir")
+ overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
+ overload(lfs.touch,filehandlerone,"lfs.touch")
+ overload(lfs.link,filehandlertwo,"lfs.link")
+ overload(lfs.setmode,filehandlerone,"lfs.setmode")
+ overload(lfs.readlink,filehandlerone,"lfs.readlink")
+ overload(lfs.shortname,filehandlerone,"lfs.shortname")
+ overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
end
if zip then
- zip.open=register(zip.open,filehandlerone,"zip.open")
+ zip.open=register(zip.open,filehandlerone,"zip.open")
end
if fontloader then
- fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
- fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
+ fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
+ fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
end
if epdf then
- epdf.open=register(epdf.open,filehandlerone,"epdf.open")
+ epdf.open=register(epdf.open,filehandlerone,"epdf.open")
end
sandbox.registerroot=registerroot
sandbox.registerbinary=registerbinary
@@ -14917,14 +14924,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-mrg"] = package.loaded["util-mrg"] or true
--- original size: 7757, stripped down to: 6015
+-- original size: 7819, stripped down to: 5881
if not modules then modules={} end modules ['util-mrg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local gsub,format=string.gsub,string.format
local concat=table.concat
@@ -14952,19 +14959,19 @@ local m_report=[[
]]
local m_preloaded=[[package.loaded[%q] = package.loaded[%q] or true]]
local function self_fake()
- return m_faked
+ return m_faked
end
local function self_nothing()
- return ""
+ return ""
end
local function self_load(name)
- local data=io.loaddata(name) or ""
- if data=="" then
- report("unknown file %a",name)
- else
- report("inserting file %a",name)
- end
- return data or ""
+ local data=io.loaddata(name) or ""
+ if data=="" then
+ report("unknown file %a",name)
+ else
+ report("inserting file %a",name)
+ end
+ return data or ""
end
local space=patterns.space
local eol=patterns.newline
@@ -14993,98 +15000,99 @@ local mandatespacing=(eol+space)^1/""
local pack=digit*space^1*operator4*optionalspacing+optionalspacing*operator1*optionalspacing+optionalspacing*operator2*optionalspaces+mandatespacing*operator3*mandatespaces+optionalspaces*separator*optionalspaces
local lines=emptyline^2/"\n"
local spaces=(space*space)/" "
+local spaces=(space*space*space*space)/" "
local compact=Cs ((
- ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
+ ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
)^1 )
local strip=Cs((emptyline^2/"\n"+1)^0)
local stripreturn=Cs((1-P("return")*space^1*P(1-space-eol)^1*(space+eol)^0*P(-1))^1)
function merger.compact(data)
- return lpegmatch(strip,lpegmatch(compact,data))
+ return lpegmatch(strip,lpegmatch(compact,data))
end
local function self_compact(data)
- local delta=0
- if merger.strip_comment then
- local before=#data
- data=lpegmatch(compact,data)
- data=lpegmatch(strip,data)
- local after=#data
- delta=before-after
- report("original size %s, compacted to %s, stripped %s",before,after,delta)
- data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
- end
- return lpegmatch(stripreturn,data) or data,delta
+ local delta=0
+ if merger.strip_comment then
+ local before=#data
+ data=lpegmatch(compact,data)
+ data=lpegmatch(strip,data)
+ local after=#data
+ delta=before-after
+ report("original size %s, compacted to %s, stripped %s",before,after,delta)
+ data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
+ end
+ return lpegmatch(stripreturn,data) or data,delta
end
local function self_save(name,data)
- if data~="" then
- io.savedata(name,data)
- report("saving %s with size %s",name,#data)
- end
+ if data~="" then
+ io.savedata(name,data)
+ report("saving %s with size %s",name,#data)
+ end
end
local function self_swap(data,code)
- return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
+ return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
end
local function self_libs(libs,list)
- local result,f,frozen,foundpath={},nil,false,nil
- result[#result+1]="\n"
- if type(libs)=='string' then libs={ libs } end
- if type(list)=='string' then list={ list } end
+ local result,f,frozen,foundpath={},nil,false,nil
+ result[#result+1]="\n"
+ if type(libs)=='string' then libs={ libs } end
+ if type(list)=='string' then list={ list } end
+ for i=1,#libs do
+ local lib=libs[i]
+ for j=1,#list do
+ local pth=gsub(list[j],"\\","/")
+ report("checking library path %a",pth)
+ local name=pth.."/"..lib
+ if lfs.isfile(name) then
+ foundpath=pth
+ end
+ end
+ if foundpath then break end
+ end
+ if foundpath then
+ report("using library path %a",foundpath)
+ local right,wrong,original,stripped={},{},0,0
for i=1,#libs do
- local lib=libs[i]
- for j=1,#list do
- local pth=gsub(list[j],"\\","/")
- report("checking library path %a",pth)
- local name=pth.."/"..lib
- if lfs.isfile(name) then
- foundpath=pth
- end
- end
- if foundpath then break end
- end
- if foundpath then
- report("using library path %a",foundpath)
- local right,wrong,original,stripped={},{},0,0
- for i=1,#libs do
- local lib=libs[i]
- local fullname=foundpath.."/"..lib
- if lfs.isfile(fullname) then
- report("using library %a",fullname)
- local preloaded=file.nameonly(lib)
- local data=io.loaddata(fullname,true)
- original=original+#data
- local data,delta=self_compact(data)
- right[#right+1]=lib
- result[#result+1]=m_begin_closure
- result[#result+1]=format(m_preloaded,preloaded,preloaded)
- result[#result+1]=data
- result[#result+1]=m_end_closure
- stripped=stripped+delta
- else
- report("skipping library %a",fullname)
- wrong[#wrong+1]=lib
- end
- end
- right=#right>0 and concat(right," ") or "-"
- wrong=#wrong>0 and concat(wrong," ") or "-"
- report("used libraries: %a",right)
- report("skipped libraries: %a",wrong)
- report("original bytes: %a",original)
- report("stripped bytes: %a",stripped)
- result[#result+1]=format(m_report,right,wrong,original,stripped)
- else
- report("no valid library path found")
+ local lib=libs[i]
+ local fullname=foundpath.."/"..lib
+ if lfs.isfile(fullname) then
+ report("using library %a",fullname)
+ local preloaded=file.nameonly(lib)
+ local data=io.loaddata(fullname,true)
+ original=original+#data
+ local data,delta=self_compact(data)
+ right[#right+1]=lib
+ result[#result+1]=m_begin_closure
+ result[#result+1]=format(m_preloaded,preloaded,preloaded)
+ result[#result+1]=data
+ result[#result+1]=m_end_closure
+ stripped=stripped+delta
+ else
+ report("skipping library %a",fullname)
+ wrong[#wrong+1]=lib
+ end
end
- return concat(result,"\n\n")
+ right=#right>0 and concat(right," ") or "-"
+ wrong=#wrong>0 and concat(wrong," ") or "-"
+ report("used libraries: %a",right)
+ report("skipped libraries: %a",wrong)
+ report("original bytes: %a",original)
+ report("stripped bytes: %a",stripped)
+ result[#result+1]=format(m_report,right,wrong,original,stripped)
+ else
+ report("no valid library path found")
+ end
+ return concat(result,"\n\n")
end
function merger.selfcreate(libs,list,target)
- if target then
- self_save(target,self_swap(self_fake(),self_libs(libs,list)))
- end
+ if target then
+ self_save(target,self_swap(self_fake(),self_libs(libs,list)))
+ end
end
function merger.selfmerge(name,libs,list,target)
- self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
+ self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
end
function merger.selfclean(name)
- self_save(name,self_swap(self_load(name),self_nothing()))
+ self_save(name,self_swap(self_load(name),self_nothing()))
end
@@ -15094,14 +15102,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-env"] = package.loaded["util-env"] or true
--- original size: 9634, stripped down to: 5673
+-- original size: 9634, stripped down to: 5360
if not modules then modules={} end modules ['util-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate,mark=utilities.storage.allocate,utilities.storage.mark
local format,sub,match,gsub,find=string.format,string.sub,string.match,string.gsub,string.find
@@ -15113,185 +15121,185 @@ local setlocale=os.setlocale
setlocale(nil,nil)
local report=logs.reporter("system")
function os.setlocale(a,b)
- if a or b then
- if report then
- report()
- report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
- report("now on are on your own and without support. Crashes or unexpected side effects")
- report("can happen but don't bother the luatex and context developer team with it.")
- report()
- report=nil
- end
- setlocale(a,b)
- end
+ if a or b then
+ if report then
+ report()
+ report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
+ report("now on are on your own and without support. Crashes or unexpected side effects")
+ report("can happen but don't bother the luatex and context developer team with it.")
+ report()
+ report=nil
+ end
+ setlocale(a,b)
+ end
end
local validengines=allocate {
- ["luatex"]=true,
- ["luajittex"]=true,
+ ["luatex"]=true,
+ ["luajittex"]=true,
}
local basicengines=allocate {
- ["luatex"]="luatex",
- ["texlua"]="luatex",
- ["texluac"]="luatex",
- ["luajittex"]="luajittex",
- ["texluajit"]="luajittex",
+ ["luatex"]="luatex",
+ ["texlua"]="luatex",
+ ["texluac"]="luatex",
+ ["luajittex"]="luajittex",
+ ["texluajit"]="luajittex",
}
local luaengines=allocate {
- ["lua"]=true,
- ["luajit"]=true,
+ ["lua"]=true,
+ ["luajit"]=true,
}
environment.validengines=validengines
environment.basicengines=basicengines
if not arg then
- environment.used_as_library=true
+ environment.used_as_library=true
elseif luaengines[file.removesuffix(arg[-1])] then
elseif validengines[file.removesuffix(arg[0])] then
- if arg[1]=="--luaonly" then
- arg[-1]=arg[0]
- arg[ 0]=arg[2]
- for k=3,#arg do
- arg[k-2]=arg[k]
- end
- remove(arg)
- remove(arg)
- else
- end
- local originalzero=file.basename(arg[0])
- local specialmapping={ luatools=="base" }
- if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
+ if arg[1]=="--luaonly" then
+ arg[-1]=arg[0]
+ arg[ 0]=arg[2]
+ for k=3,#arg do
+ arg[k-2]=arg[k]
+ end
+ remove(arg)
+ remove(arg)
+ else
+ end
+ local originalzero=file.basename(arg[0])
+ local specialmapping={ luatools=="base" }
+ if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
arg[0]=specialmapping[originalzero] or originalzero
insert(arg,0,"--script")
insert(arg,0,"mtxrun")
- end
+ end
end
environment.arguments=allocate()
environment.files=allocate()
environment.sortedflags=nil
function environment.initializearguments(arg)
- local arguments,files={},{}
- environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
- for index=1,#arg do
- local argument=arg[index]
- if index>0 then
- local flag,value=match(argument,"^%-+(.-)=(.-)$")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=unquoted(value or "")
- else
- flag=match(argument,"^%-+(.+)")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=true
- else
- files[#files+1]=argument
- end
- end
+ local arguments,files={},{}
+ environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
+ for index=1,#arg do
+ local argument=arg[index]
+ if index>0 then
+ local flag,value=match(argument,"^%-+(.-)=(.-)$")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=unquoted(value or "")
+ else
+ flag=match(argument,"^%-+(.+)")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=true
+ else
+ files[#files+1]=argument
end
+ end
end
- environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
+ end
+ environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
end
function environment.setargument(name,value)
- environment.arguments[name]=value
+ environment.arguments[name]=value
end
function environment.getargument(name,partial)
- local arguments,sortedflags=environment.arguments,environment.sortedflags
- if arguments[name] then
- return arguments[name]
- elseif partial then
- if not sortedflags then
- sortedflags=allocate(table.sortedkeys(arguments))
- for k=1,#sortedflags do
- sortedflags[k]="^"..sortedflags[k]
- end
- environment.sortedflags=sortedflags
- end
- for k=1,#sortedflags do
- local v=sortedflags[k]
- if find(name,v) then
- return arguments[sub(v,2,#v)]
- end
- end
+ local arguments,sortedflags=environment.arguments,environment.sortedflags
+ if arguments[name] then
+ return arguments[name]
+ elseif partial then
+ if not sortedflags then
+ sortedflags=allocate(table.sortedkeys(arguments))
+ for k=1,#sortedflags do
+ sortedflags[k]="^"..sortedflags[k]
+ end
+ environment.sortedflags=sortedflags
end
- return nil
+ for k=1,#sortedflags do
+ local v=sortedflags[k]
+ if find(name,v) then
+ return arguments[sub(v,2,#v)]
+ end
+ end
+ end
+ return nil
end
environment.argument=environment.getargument
function environment.splitarguments(separator)
- local done,before,after=false,{},{}
- local originalarguments=environment.originalarguments
- for k=1,#originalarguments do
- local v=originalarguments[k]
- if not done and v==separator then
- done=true
- elseif done then
- after[#after+1]=v
- else
- before[#before+1]=v
- end
+ local done,before,after=false,{},{}
+ local originalarguments=environment.originalarguments
+ for k=1,#originalarguments do
+ local v=originalarguments[k]
+ if not done and v==separator then
+ done=true
+ elseif done then
+ after[#after+1]=v
+ else
+ before[#before+1]=v
end
- return before,after
+ end
+ return before,after
end
function environment.reconstructcommandline(arg,noquote)
- local resolveprefix=resolvers.resolve
- arg=arg or environment.originalarguments
- if noquote and #arg==1 then
- return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
- elseif #arg>0 then
- local result={}
- for i=1,#arg do
- result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
- end
- return concat(result," ")
- else
- return ""
+ local resolveprefix=resolvers.resolve
+ arg=arg or environment.originalarguments
+ if noquote and #arg==1 then
+ return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
+ elseif #arg>0 then
+ local result={}
+ for i=1,#arg do
+ result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
end
+ return concat(result," ")
+ else
+ return ""
+ end
end
function environment.relativepath(path,root)
- if not path then
- path=""
+ if not path then
+ path=""
+ end
+ if not file.is_rootbased_path(path) then
+ if not root then
+ root=file.pathpart(environment.ownscript or environment.ownname or ".")
end
- if not file.is_rootbased_path(path) then
- if not root then
- root=file.pathpart(environment.ownscript or environment.ownname or ".")
- end
- if root=="" then
- root="."
- end
- path=root.."/"..path
+ if root=="" then
+ root="."
end
- return file.collapsepath(path,true)
+ path=root.."/"..path
+ end
+ return file.collapsepath(path,true)
end
if arg then
- local newarg,instring={},false
- for index=1,#arg do
- local argument=arg[index]
- if find(argument,"^\"") then
- if find(argument,"\"$") then
- newarg[#newarg+1]=gsub(argument,"^\"(.-)\"$","%1")
- instring=false
- else
- newarg[#newarg+1]=gsub(argument,"^\"","")
- instring=true
- end
- elseif find(argument,"\"$") then
- if instring then
- newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
- instring=false
- else
- newarg[#newarg+1]=argument
- end
- elseif instring then
- newarg[#newarg]=newarg[#newarg].." "..argument
- else
- newarg[#newarg+1]=argument
- end
- end
- for i=1,-5,-1 do
- newarg[i]=arg[i]
+ local newarg,instring={},false
+ for index=1,#arg do
+ local argument=arg[index]
+ if find(argument,"^\"") then
+ if find(argument,"\"$") then
+ newarg[#newarg+1]=gsub(argument,"^\"(.-)\"$","%1")
+ instring=false
+ else
+ newarg[#newarg+1]=gsub(argument,"^\"","")
+ instring=true
+ end
+ elseif find(argument,"\"$") then
+ if instring then
+ newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
+ instring=false
+ else
+ newarg[#newarg+1]=argument
+ end
+ elseif instring then
+ newarg[#newarg]=newarg[#newarg].." "..argument
+ else
+ newarg[#newarg+1]=argument
end
- environment.initializearguments(newarg)
- environment.originalarguments=mark(newarg)
- environment.rawarguments=mark(arg)
- arg={}
+ end
+ for i=1,-5,-1 do
+ newarg[i]=arg[i]
+ end
+ environment.initializearguments(newarg)
+ environment.originalarguments=mark(newarg)
+ environment.rawarguments=mark(arg)
+ arg={}
end
@@ -15301,18 +15309,18 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-env"] = package.loaded["luat-env"] or true
--- original size: 6134, stripped down to: 4402
+-- original size: 6134, stripped down to: 4118
if not modules then modules={} end modules ['luat-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local rawset,rawget,loadfile=rawset,rawget,loadfile
local gsub=string.gsub
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_lua=logs.reporter("resolvers","lua")
local luautilities=utilities.lua
local luasuffixes=luautilities.suffixes
@@ -15320,145 +15328,145 @@ local texgettoks=tex and tex.gettoks
environment=environment or {}
local environment=environment
local mt={
- __index=function(_,k)
- if k=="version" then
- local version=texgettoks and texgettoks("contextversiontoks")
- if version and version~="" then
- rawset(environment,"version",version)
- return version
- else
- return "unknown"
- end
- elseif k=="kind" then
- local kind=texgettoks and texgettoks("contextkindtoks")
- if kind and kind~="" then
- rawset(environment,"kind",kind)
- return kind
- else
- return "unknown"
- end
- elseif k=="jobname" or k=="formatname" then
- local name=tex and tex[k]
- if name or name=="" then
- rawset(environment,k,name)
- return name
- else
- return "unknown"
- end
- elseif k=="outputfilename" then
- local name=environment.jobname
- rawset(environment,k,name)
- return name
- end
+ __index=function(_,k)
+ if k=="version" then
+ local version=texgettoks and texgettoks("contextversiontoks")
+ if version and version~="" then
+ rawset(environment,"version",version)
+ return version
+ else
+ return "unknown"
+ end
+ elseif k=="kind" then
+ local kind=texgettoks and texgettoks("contextkindtoks")
+ if kind and kind~="" then
+ rawset(environment,"kind",kind)
+ return kind
+ else
+ return "unknown"
+ end
+ elseif k=="jobname" or k=="formatname" then
+ local name=tex and tex[k]
+ if name or name=="" then
+ rawset(environment,k,name)
+ return name
+ else
+ return "unknown"
+ end
+ elseif k=="outputfilename" then
+ local name=environment.jobname
+ rawset(environment,k,name)
+ return name
end
+ end
}
setmetatable(environment,mt)
function environment.texfile(filename)
- return resolvers.findfile(filename,'tex')
+ return resolvers.findfile(filename,'tex')
end
function environment.luafile(filename)
- local resolved=resolvers.findfile(filename,'tex') or ""
- if resolved~="" then
- return resolved
- end
- resolved=resolvers.findfile(filename,'texmfscripts') or ""
- if resolved~="" then
- return resolved
- end
- return resolvers.findfile(filename,'luatexlibs') or ""
-end
-local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
+ local resolved=resolvers.findfile(filename,'tex') or ""
+ if resolved~="" then
+ return resolved
+ end
+ resolved=resolvers.findfile(filename,'texmfscripts') or ""
+ if resolved~="" then
+ return resolved
+ end
+ return resolvers.findfile(filename,'luatexlibs') or ""
+end
+local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
local function strippable(filename)
- if stripindeed then
- local modu=modules[file.nameonly(filename)]
- return modu and modu.dataonly
- else
- return false
- end
+ if stripindeed then
+ local modu=modules[file.nameonly(filename)]
+ return modu and modu.dataonly
+ else
+ return false
+ end
end
function environment.luafilechunk(filename,silent,macros)
- filename=file.replacesuffix(filename,"lua")
- local fullname=environment.luafile(filename)
- if fullname and fullname~="" then
- local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
- if not silent then
- report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
- end
- return data
- else
- if not silent then
- report_lua("unknown file %a",filename)
- end
- return nil
+ filename=file.replacesuffix(filename,"lua")
+ local fullname=environment.luafile(filename)
+ if fullname and fullname~="" then
+ local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
+ if not silent then
+ report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
+ end
+ return data
+ else
+ if not silent then
+ report_lua("unknown file %a",filename)
end
+ return nil
+ end
end
function environment.loadluafile(filename,version)
- local lucname,luaname,chunk
- local basename=file.removesuffix(filename)
- if basename==filename then
- luaname=file.addsuffix(basename,luasuffixes.lua)
- lucname=file.addsuffix(basename,luasuffixes.luc)
- else
- luaname=filename
- lucname=nil
- end
- local fullname=(lucname and environment.luafile(lucname)) or ""
- if fullname~="" then
+ local lucname,luaname,chunk
+ local basename=file.removesuffix(filename)
+ if basename==filename then
+ luaname=file.addsuffix(basename,luasuffixes.lua)
+ lucname=file.addsuffix(basename,luasuffixes.luc)
+ else
+ luaname=filename
+ lucname=nil
+ end
+ local fullname=(lucname and environment.luafile(lucname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
+ end
+ chunk=loadfile(fullname)
+ end
+ if chunk then
+ chunk()
+ if version then
+ local v=version
+ if modules and modules[filename] then
+ v=modules[filename].version
+ elseif versions and versions[filename] then
+ v=versions[filename]
+ end
+ if v==version then
+ return true
+ else
if trace_locating then
- report_lua("loading %a",fullname)
+ report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
end
- chunk=loadfile(fullname)
+ environment.loadluafile(filename)
+ end
+ else
+ return true
end
- if chunk then
- chunk()
- if version then
- local v=version
- if modules and modules[filename] then
- v=modules[filename].version
- elseif versions and versions[filename] then
- v=versions[filename]
- end
- if v==version then
- return true
- else
- if trace_locating then
- report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
- end
- environment.loadluafile(filename)
- end
- else
- return true
- end
+ end
+ fullname=(luaname and environment.luafile(luaname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
end
- fullname=(luaname and environment.luafile(luaname)) or ""
- if fullname~="" then
- if trace_locating then
- report_lua("loading %a",fullname)
- end
- chunk=loadfile(fullname)
- if not chunk then
- if trace_locating then
- report_lua("unknown file %a",filename)
- end
- else
- chunk()
- return true
- end
+ chunk=loadfile(fullname)
+ if not chunk then
+ if trace_locating then
+ report_lua("unknown file %a",filename)
+ end
+ else
+ chunk()
+ return true
end
- return false
+ end
+ return false
end
environment.filenames=setmetatable({},{
- __index=function(t,k)
- local v=environment.files[k]
- if v then
- return (gsub(v,"%.+$",""))
- end
- end,
- __newindex=function(t,k)
- end,
- __len=function(t)
- return #environment.files
- end,
+ __index=function(t,k)
+ local v=environment.files[k]
+ if v then
+ return (gsub(v,"%.+$",""))
+ end
+ end,
+ __newindex=function(t,k)
+ end,
+ __len=function(t)
+ return #environment.files
+ end,
} )
@@ -15468,16 +15476,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true
--- original size: 60383, stripped down to: 38562
+-- original size: 60383, stripped down to: 35698
if not modules then modules={} end modules ['lxml-tab']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
+local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end
if lpeg.setmaxstack then lpeg.setmaxstack(1000) end
xml=xml or {}
@@ -15495,17 +15503,17 @@ xml.xmlns=xml.xmlns or {}
local check=P(false)
local parse=check
function xml.registerns(namespace,pattern)
- check=check+C(P(lower(pattern)))/namespace
- parse=P { P(check)+1*V(1) }
+ check=check+C(P(lower(pattern)))/namespace
+ parse=P { P(check)+1*V(1) }
end
function xml.checkns(namespace,url)
- local ns=lpegmatch(parse,lower(url))
- if ns and namespace~=ns then
- xml.xmlns[namespace]=ns
- end
+ local ns=lpegmatch(parse,lower(url))
+ if ns and namespace~=ns then
+ xml.xmlns[namespace]=ns
+ end
end
function xml.resolvens(url)
- return lpegmatch(parse,lower(url)) or ""
+ return lpegmatch(parse,lower(url)) or ""
end
end
local nsremap,resolvens=xml.xmlns,xml.resolvens
@@ -15523,661 +15531,661 @@ local handle_dec_entity
local handle_any_entity_dtd
local handle_any_entity_text
local function preparexmlstate(settings)
- if settings then
- linenumbers=settings.linenumbers
- stack={}
- level=0
- top={}
- at={}
- mt={}
- dt={}
- nt=0
- xmlns={}
- errorstr=nil
- strip=settings.strip_cm_and_dt
- utfize=settings.utfize_entities
- resolve=settings.resolve_entities
- resolve_predefined=settings.resolve_predefined_entities
- unify_predefined=settings.unify_predefined_entities
- cleanup=settings.text_cleanup
- entities=settings.entities or {}
- currentfilename=settings.currentresource
- currentline=1
- parameters={}
- reported_at_errors={}
- dcache={}
- hcache={}
- acache={}
- if utfize==nil then
- settings.utfize_entities=true
- utfize=true
- end
- if resolve_predefined==nil then
- settings.resolve_predefined_entities=true
- resolve_predefined=true
- end
- else
- linenumbers=false
- stack=nil
- level=nil
- top=nil
- at=nil
- mt=nil
- dt=nil
- nt=nil
- xmlns=nil
- errorstr=nil
- strip=nil
- utfize=nil
- resolve=nil
- resolve_predefined=nil
- unify_predefined=nil
- cleanup=nil
- entities=nil
- parameters=nil
- reported_at_errors=nil
- dcache=nil
- hcache=nil
- acache=nil
- currentfilename=nil
- currentline=1
- end
+ if settings then
+ linenumbers=settings.linenumbers
+ stack={}
+ level=0
+ top={}
+ at={}
+ mt={}
+ dt={}
+ nt=0
+ xmlns={}
+ errorstr=nil
+ strip=settings.strip_cm_and_dt
+ utfize=settings.utfize_entities
+ resolve=settings.resolve_entities
+ resolve_predefined=settings.resolve_predefined_entities
+ unify_predefined=settings.unify_predefined_entities
+ cleanup=settings.text_cleanup
+ entities=settings.entities or {}
+ currentfilename=settings.currentresource
+ currentline=1
+ parameters={}
+ reported_at_errors={}
+ dcache={}
+ hcache={}
+ acache={}
+ if utfize==nil then
+ settings.utfize_entities=true
+ utfize=true
+ end
+ if resolve_predefined==nil then
+ settings.resolve_predefined_entities=true
+ resolve_predefined=true
+ end
+ else
+ linenumbers=false
+ stack=nil
+ level=nil
+ top=nil
+ at=nil
+ mt=nil
+ dt=nil
+ nt=nil
+ xmlns=nil
+ errorstr=nil
+ strip=nil
+ utfize=nil
+ resolve=nil
+ resolve_predefined=nil
+ unify_predefined=nil
+ cleanup=nil
+ entities=nil
+ parameters=nil
+ reported_at_errors=nil
+ dcache=nil
+ hcache=nil
+ acache=nil
+ currentfilename=nil
+ currentline=1
+ end
end
local function initialize_mt(root)
- mt={ __index=root }
+ mt={ __index=root }
end
function xml.setproperty(root,k,v)
- getmetatable(root).__index[k]=v
+ getmetatable(root).__index[k]=v
end
function xml.checkerror(top,toclose)
- return ""
+ return ""
end
local checkns=xml.checkns
local function add_attribute(namespace,tag,value)
- if cleanup and value~="" then
- value=cleanup(value)
- end
- if tag=="xmlns" then
- xmlns[#xmlns+1]=resolvens(value)
- at[tag]=value
- elseif namespace=="" then
- at[tag]=value
- elseif namespace=="xmlns" then
- checkns(tag,value)
- at["xmlns:"..tag]=value
- else
- at[namespace..":"..tag]=value
- end
+ if cleanup and value~="" then
+ value=cleanup(value)
+ end
+ if tag=="xmlns" then
+ xmlns[#xmlns+1]=resolvens(value)
+ at[tag]=value
+ elseif namespace=="" then
+ at[tag]=value
+ elseif namespace=="xmlns" then
+ checkns(tag,value)
+ at["xmlns:"..tag]=value
+ else
+ at[namespace..":"..tag]=value
+ end
end
local function add_empty(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- top=stack[level]
- dt=top.dt
- nt=#dt+1
- local t=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- cf=currentfilename,
- cl=currentline,
- __p__=top,
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- __p__=top,
- }
- dt[nt]=t
- setmetatable(t,mt)
- if at.xmlns then
- remove(xmlns)
- end
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ top=stack[level]
+ dt=top.dt
+ nt=#dt+1
+ local t=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=top,
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ __p__=top,
+ }
+ dt[nt]=t
+ setmetatable(t,mt)
+ if at.xmlns then
+ remove(xmlns)
+ end
+ at={}
end
local function add_begin(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- dt={}
- top=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- cf=currentfilename,
- cl=currentline,
- __p__=stack[level],
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- __p__=stack[level],
- }
- setmetatable(top,mt)
- nt=0
- level=level+1
- stack[level]=top
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ dt={}
+ top=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=stack[level],
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ __p__=stack[level],
+ }
+ setmetatable(top,mt)
+ nt=0
+ level=level+1
+ stack[level]=top
+ at={}
end
local function add_end(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local toclose=stack[level]
- level=level-1
- top=stack[level]
- if level<1 then
- errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- elseif toclose.tg~=tag then
- errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- end
- dt=top.dt
- nt=#dt+1
- dt[nt]=toclose
- toclose.ni=nt
- if toclose.at.xmlns then
- remove(xmlns)
- end
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local toclose=stack[level]
+ level=level-1
+ top=stack[level]
+ if level<1 then
+ errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ elseif toclose.tg~=tag then
+ errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ end
+ dt=top.dt
+ nt=#dt+1
+ dt[nt]=toclose
+ toclose.ni=nt
+ if toclose.at.xmlns then
+ remove(xmlns)
+ end
end
local function add_text(text)
- if text=="" then
- return
- end
- if cleanup then
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..cleanup(text)
- else
- nt=nt+1
- dt[nt]=cleanup(text)
- end
- else
- nt=1
- dt[1]=cleanup(text)
- end
+ if text=="" then
+ return
+ end
+ if cleanup then
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..cleanup(text)
+ else
+ nt=nt+1
+ dt[nt]=cleanup(text)
+ end
else
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..text
- else
- nt=nt+1
- dt[nt]=text
- end
- else
- nt=1
- dt[1]=text
- end
+ nt=1
+ dt[1]=cleanup(text)
end
-end
-local function add_special(what,spacing,text)
- if spacing~="" then
+ else
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..text
+ else
nt=nt+1
- dt[nt]=spacing
- end
- if strip and (what=="@cm@" or what=="@dt@") then
+ dt[nt]=text
+ end
else
- nt=nt+1
- dt[nt]=linenumbers and {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- cf=currentfilename,
- cl=currentline,
- } or {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- }
+ nt=1
+ dt[1]=text
end
+ end
+end
+local function add_special(what,spacing,text)
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ if strip and (what=="@cm@" or what=="@dt@") then
+ else
+ nt=nt+1
+ dt[nt]=linenumbers and {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ cf=currentfilename,
+ cl=currentline,
+ } or {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ }
+ end
end
local function set_message(txt)
- errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
+ errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
end
local function attribute_value_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute value %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute value %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
local function attribute_specification_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute specification %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute specification %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
do
- local badentity="&"
- xml.placeholders={
- unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
- unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
- unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
- }
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return utfchar(n)
- else
- return formatters["h:%s"](s),true
+ local badentity="&"
+ xml.placeholders={
+ unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
+ unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
+ unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
+ }
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local p_rest=(1-P(";"))^0
+ local p_many=P(1)^0
+ local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
+ xml.parsedentitylpeg=parsedentity
+ local predefined_unified={
+ [38]="&amp;",
+ [42]="&quot;",
+ [47]="&apos;",
+ [74]="&lt;",
+ [76]="&gt;",
+ }
+ local predefined_simplified={
+ [38]="&",amp="&",
+ [42]='"',quot='"',
+ [47]="'",apos="'",
+ [74]="<",lt="<",
+ [76]=">",gt=">",
+ }
+ local nofprivates=0xF0000
+ local privates_u={
+ [ [[&]] ]="&amp;",
+ [ [["]] ]="&quot;",
+ [ [[']] ]="&apos;",
+ [ [[<]] ]="&lt;",
+ [ [[>]] ]="&gt;",
+ }
+ local privates_p={
+ }
+ local privates_s={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[&]] ]="&U+26;",
+ [ [[']] ]="&U+27;",
+ [ [[<]] ]="&U+3C;",
+ [ [[>]] ]="&U+3E;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_x={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[']] ]="&U+27;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_n={
+ }
+ local escaped=utf.remapper(privates_u,"dynamic")
+ local unprivatized=utf.remapper(privates_p,"dynamic")
+ local unspecialized=utf.remapper(privates_s,"dynamic")
+ local despecialized=utf.remapper(privates_x,"dynamic")
+ xml.unprivatized=unprivatized
+ xml.unspecialized=unspecialized
+ xml.despecialized=despecialized
+ xml.escaped=escaped
+ local function unescaped(s)
+ local p=privates_n[s]
+ if not p then
+ nofprivates=nofprivates+1
+ p=utfchar(nofprivates)
+ privates_n[s]=p
+ s="&"..s..";"
+ privates_u[p]=s
+ privates_p[p]=s
+ privates_s[p]=s
+ end
+ return p
+ end
+ xml.privatetoken=unescaped
+ xml.privatecodes=privates_n
+ xml.specialcodes=privates_s
+ function xml.addspecialcode(key,value)
+ privates_s[key]=value or "&"..s..";"
+ end
+ handle_hex_entity=function(str)
+ local h=hcache[str]
+ if not h then
+ local n=tonumber(str,16)
+ h=unify_predefined and predefined_unified[n]
+ if h then
+ if trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+ end
+ elseif utfize then
+ h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring hex entity &#x%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
end
+ else
+ if trace_entities then
+ report_xml("found entity &#x%s;",str)
+ end
+ h="&#x"..str..";"
+ end
+ hcache[str]=h
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return utfchar(n)
- else
- return formatters["d:%s"](s),true
- end
- end
- local p_rest=(1-P(";"))^0
- local p_many=P(1)^0
- local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
- xml.parsedentitylpeg=parsedentity
- local predefined_unified={
- [38]="&amp;",
- [42]="&quot;",
- [47]="&apos;",
- [74]="&lt;",
- [76]="&gt;",
- }
- local predefined_simplified={
- [38]="&",amp="&",
- [42]='"',quot='"',
- [47]="'",apos="'",
- [74]="<",lt="<",
- [76]=">",gt=">",
- }
- local nofprivates=0xF0000
- local privates_u={
- [ [[&]] ]="&amp;",
- [ [["]] ]="&quot;",
- [ [[']] ]="&apos;",
- [ [[<]] ]="&lt;",
- [ [[>]] ]="&gt;",
- }
- local privates_p={
- }
- local privates_s={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[&]] ]="&U+26;",
- [ [[']] ]="&U+27;",
- [ [[<]] ]="&U+3C;",
- [ [[>]] ]="&U+3E;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_x={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[']] ]="&U+27;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_n={
- }
- local escaped=utf.remapper(privates_u,"dynamic")
- local unprivatized=utf.remapper(privates_p,"dynamic")
- local unspecialized=utf.remapper(privates_s,"dynamic")
- local despecialized=utf.remapper(privates_x,"dynamic")
- xml.unprivatized=unprivatized
- xml.unspecialized=unspecialized
- xml.despecialized=despecialized
- xml.escaped=escaped
- local function unescaped(s)
- local p=privates_n[s]
- if not p then
- nofprivates=nofprivates+1
- p=utfchar(nofprivates)
- privates_n[s]=p
- s="&"..s..";"
- privates_u[p]=s
- privates_p[p]=s
- privates_s[p]=s
- end
- return p
- end
- xml.privatetoken=unescaped
- xml.privatecodes=privates_n
- xml.specialcodes=privates_s
- function xml.addspecialcode(key,value)
- privates_s[key]=value or "&"..s..";"
- end
- handle_hex_entity=function(str)
- local h=hcache[str]
- if not h then
- local n=tonumber(str,16)
- h=unify_predefined and predefined_unified[n]
- if h then
- if trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- elseif utfize then
- h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring hex entity &#x%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- else
- if trace_entities then
- report_xml("found entity &#x%s;",str)
- end
- h="&#x"..str..";"
- end
- hcache[str]=h
- end
- return h
- end
- handle_dec_entity=function(str)
- local d=dcache[str]
- if not d then
- local n=tonumber(str)
- d=unify_predefined and predefined_unified[n]
- if d then
- if trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- elseif utfize then
- d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring dec entity &#%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- else
- if trace_entities then
- report_xml("found entity &#%s;",str)
- end
- d="&#"..str..";"
- end
- dcache[str]=d
+ return h
+ end
+ handle_dec_entity=function(str)
+ local d=dcache[str]
+ if not d then
+ local n=tonumber(str)
+ d=unify_predefined and predefined_unified[n]
+ if d then
+ if trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ elseif utfize then
+ d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring dec entity &#%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ else
+ if trace_entities then
+ report_xml("found entity &#%s;",str)
end
- return d
+ d="&#"..str..";"
+ end
+ dcache[str]=d
end
- handle_any_entity_dtd=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
- end
- return a
+ return d
+ end
+ handle_any_entity_dtd=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
- end
- return a
+ a=entities[str]
end
- end
- handle_any_entity_text=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(grammar_parsed_text_two,a) or a
- if type(a)=="number" then
- return ""
- else
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- end
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
end
- return a
+ a=a(str) or ""
+ end
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
end
- return a
- end
- end
- local p_rest=(1-P(";"))^1
- local spec={
- [0x23]="\\Ux{23}",
- [0x24]="\\Ux{24}",
- [0x25]="\\Ux{25}",
- [0x5C]="\\Ux{5C}",
- [0x7B]="\\Ux{7B}",
- [0x7C]="\\Ux{7C}",
- [0x7D]="\\Ux{7D}",
- [0x7E]="\\Ux{7E}",
- }
- local hash=table.setmetatableindex(spec,function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
- else
- return formatters["u:%s"](s),true
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
- end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
+ end
+ return a
+ end
+ end
+ handle_any_entity_text=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- return formatters["d:%s"](s),true
+ a=entities[str]
end
- end
- local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- local hash=table.setmetatableindex(function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
+ end
+ a=a(str) or ""
+ end
+ a=lpegmatch(grammar_parsed_text_two,a) or a
+ if type(a)=="number" then
+ return ""
+ else
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
+ end
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- return formatters["u:%s"](s),true
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
+ end
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
+ end
+ return a
+ end
+ end
+ local p_rest=(1-P(";"))^1
+ local spec={
+ [0x23]="\\Ux{23}",
+ [0x24]="\\Ux{24}",
+ [0x25]="\\Ux{25}",
+ [0x5C]="\\Ux{5C}",
+ [0x7B]="\\Ux{7B}",
+ [0x7C]="\\Ux{7C}",
+ [0x7D]="\\Ux{7D}",
+ [0x7E]="\\Ux{7E}",
+ }
+ local hash=table.setmetatableindex(spec,function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
- else
- return formatters["d:%s"](s),true
- end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ local hash=table.setmetatableindex(function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
+ end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
end
- local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- xml.reparsedentitylpeg=reparsedentity
- xml.unescapedentitylpeg=unescapedentity
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ xml.reparsedentitylpeg=reparsedentity
+ xml.unescapedentitylpeg=unescapedentity
end
local escaped=xml.escaped
local unescaped=xml.unescaped
local placeholders=xml.placeholders
local function handle_end_entity(str)
- report_xml("error in entity, %a found without ending %a",str,";")
- return str
+ report_xml("error in entity, %a found without ending %a",str,";")
+ return str
end
local function handle_crap_error(chr)
- report_xml("error in parsing, unexpected %a found ",chr)
- add_text(chr)
- return chr
+ report_xml("error in parsing, unexpected %a found ",chr)
+ add_text(chr)
+ return chr
end
local function handlenewline()
- currentline=currentline+1
+ currentline=currentline+1
end
local spacetab=S(' \t')
local space=S(' \r\n\t')
@@ -16202,141 +16210,141 @@ local space_nl=spacetab+newline
local spacing_nl=Cs((space_nl)^0)
local anything_nl=newline+P(1)
local function weirdentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","weird",k,v)
- end
- parameters[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","weird",k,v)
+ end
+ parameters[k]=v
end
local function normalentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","normal",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","normal",k,v)
+ end
+ entities[k]=v
end
local function systementity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","system",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","system",k,v)
+ end
+ entities[k]=v
end
local function publicentity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","public",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","public",k,v)
+ end
+ entities[k]=v
end
local function entityfile(pattern,k,v,n)
- if n then
- local okay,data
- if resolvers then
- okay,data=resolvers.loadbinfile(n)
- else
- data=io.loaddata(n)
- okay=data and data~=""
- end
- if okay then
- if trace_entities then
- report_xml("loading public entities %a as %a from %a",k,v,n)
- end
- lpegmatch(pattern,data)
- return
- end
+ if n then
+ local okay,data
+ if resolvers then
+ okay,data=resolvers.loadbinfile(n)
+ else
+ data=io.loaddata(n)
+ okay=data and data~=""
end
- report_xml("ignoring public entities %a as %a from %a",k,v,n)
+ if okay then
+ if trace_entities then
+ report_xml("loading public entities %a as %a from %a",k,v,n)
+ end
+ lpegmatch(pattern,data)
+ return
+ end
+ end
+ report_xml("ignoring public entities %a as %a from %a",k,v,n)
end
local function install(spacenewline,spacing,anything)
- local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
- local hexentitycontent=R("AF","af","09")^1
- local decentitycontent=R("09")^1
- local parsedentity=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_dtd)
- local parsedentity_text=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_text)
- local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local text_unparsed=Cs((anything-open)^1)
- local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
- local somespace=(spacenewline)^1
- local optionalspace=(spacenewline)^0
- local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
- local endofattributes=slash*close+close
- local whatever=space*name*optionalspace*equal
- local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
- local attributevalue=value+wrongvalue
- local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
- local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
- local parsedtext=text_parsed
- local unparsedtext=text_unparsed/add_text
- local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
- local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
- local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
- local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
- local begincomment=open*P("!--")
- local endcomment=P("--")*close
- local begininstruction=open*P("?")
- local endinstruction=P("?")*close
- local begincdata=open*P("![CDATA[")
- local endcdata=P("]]")*close
- local someinstruction=C((anything-endinstruction)^0)
- local somecomment=C((anything-endcomment )^0)
- local somecdata=C((anything-endcdata )^0)
- local begindoctype=open*P("!DOCTYPE")
- local enddoctype=close
- local beginset=P("[")
- local endset=P("]")
- local wrdtypename=C((anything-somespace-P(";"))^1)
- local doctypename=C((anything-somespace-close)^0)
- local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
- local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
- local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
- local normalentitytype=(doctypename*somespace*value)/normalentity
- local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
- local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
- local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
- local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
- entityfile(entitydoctype,...)
- end
- local function weirdresolve(s)
- lpegmatch(entitydoctype,parameters[s])
- end
- local function normalresolve(s)
- lpegmatch(entitydoctype,entities[s])
- end
- local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
- entitydoctype=entitydoctype+entityresolve
- local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
- local definitiondoctype=doctypename*somespace*doctypeset
- local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
- local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
- local simpledoctype=(anything-close)^1
- local somedoctype=C((somespace*(
+ local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
+ local hexentitycontent=R("AF","af","09")^1
+ local decentitycontent=R("09")^1
+ local parsedentity=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_dtd)
+ local parsedentity_text=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_text)
+ local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local text_unparsed=Cs((anything-open)^1)
+ local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
+ local somespace=(spacenewline)^1
+ local optionalspace=(spacenewline)^0
+ local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
+ local endofattributes=slash*close+close
+ local whatever=space*name*optionalspace*equal
+ local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
+ local attributevalue=value+wrongvalue
+ local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
+ local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
+ local parsedtext=text_parsed
+ local unparsedtext=text_unparsed/add_text
+ local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
+ local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
+ local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
+ local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
+ local begincomment=open*P("!--")
+ local endcomment=P("--")*close
+ local begininstruction=open*P("?")
+ local endinstruction=P("?")*close
+ local begincdata=open*P("![CDATA[")
+ local endcdata=P("]]")*close
+ local someinstruction=C((anything-endinstruction)^0)
+ local somecomment=C((anything-endcomment )^0)
+ local somecdata=C((anything-endcdata )^0)
+ local begindoctype=open*P("!DOCTYPE")
+ local enddoctype=close
+ local beginset=P("[")
+ local endset=P("]")
+ local wrdtypename=C((anything-somespace-P(";"))^1)
+ local doctypename=C((anything-somespace-close)^0)
+ local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
+ local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
+ local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
+ local normalentitytype=(doctypename*somespace*value)/normalentity
+ local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
+ local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
+ local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
+ local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
+ entityfile(entitydoctype,...)
+ end
+ local function weirdresolve(s)
+ lpegmatch(entitydoctype,parameters[s])
+ end
+ local function normalresolve(s)
+ lpegmatch(entitydoctype,entities[s])
+ end
+ local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
+ entitydoctype=entitydoctype+entityresolve
+ local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
+ local definitiondoctype=doctypename*somespace*doctypeset
+ local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
+ local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
+ local simpledoctype=(anything-close)^1
+ local somedoctype=C((somespace*(
publicentityfile+publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0)
- local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
- local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
- local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
- local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
- local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
- local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
- local trailer=space^0*(text_unparsed/set_message)^0
- local grammar_parsed_text_one=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
- }
- local grammar_parsed_text_two=P { "followup",
- followup=V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
- }
- local grammar_unparsed_text=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
- }
- return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
+ local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
+ local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
+ local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
+ local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
+ local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
+ local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
+ local trailer=space^0*(text_unparsed/set_message)^0
+ local grammar_parsed_text_one=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
+ }
+ local grammar_parsed_text_two=P { "followup",
+ followup=V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
+ }
+ local grammar_unparsed_text=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
+ }
+ return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
end
grammar_parsed_text_one_nop,
grammar_parsed_text_two_nop,
@@ -16345,576 +16353,576 @@ grammar_parsed_text_one_yes,
grammar_parsed_text_two_yes,
grammar_unparsed_text_yes=install(space_nl,spacing_nl,anything_nl)
local function _xmlconvert_(data,settings,detail)
- settings=settings or {}
- preparexmlstate(settings)
- if settings.linenumbers then
- grammar_parsed_text_one=grammar_parsed_text_one_yes
- grammar_parsed_text_two=grammar_parsed_text_two_yes
- grammar_unparsed_text=grammar_unparsed_text_yes
- else
- grammar_parsed_text_one=grammar_parsed_text_one_nop
- grammar_parsed_text_two=grammar_parsed_text_two_nop
- grammar_unparsed_text=grammar_unparsed_text_nop
- end
- local preprocessor=settings.preprocessor
- if data and data~="" and type(preprocessor)=="function" then
- data=preprocessor(data,settings) or data
+ settings=settings or {}
+ preparexmlstate(settings)
+ if settings.linenumbers then
+ grammar_parsed_text_one=grammar_parsed_text_one_yes
+ grammar_parsed_text_two=grammar_parsed_text_two_yes
+ grammar_unparsed_text=grammar_unparsed_text_yes
+ else
+ grammar_parsed_text_one=grammar_parsed_text_one_nop
+ grammar_parsed_text_two=grammar_parsed_text_two_nop
+ grammar_unparsed_text=grammar_unparsed_text_nop
+ end
+ local preprocessor=settings.preprocessor
+ if data and data~="" and type(preprocessor)=="function" then
+ data=preprocessor(data,settings) or data
+ end
+ if settings.parent_root then
+ mt=getmetatable(settings.parent_root)
+ else
+ initialize_mt(top)
+ end
+ level=level+1
+ stack[level]=top
+ top.dt={}
+ dt=top.dt
+ nt=0
+ if not data or data=="" then
+ errorstr="empty xml file"
+ elseif data==true then
+ errorstr=detail or "problematic xml file"
+ elseif utfize or resolve then
+ local m=lpegmatch(grammar_parsed_text_one,data)
+ if m then
+ m=lpegmatch(grammar_parsed_text_two,data,m)
end
- if settings.parent_root then
- mt=getmetatable(settings.parent_root)
- else
- initialize_mt(top)
- end
- level=level+1
- stack[level]=top
- top.dt={}
- dt=top.dt
- nt=0
- if not data or data=="" then
- errorstr="empty xml file"
- elseif data==true then
- errorstr=detail or "problematic xml file"
- elseif utfize or resolve then
- local m=lpegmatch(grammar_parsed_text_one,data)
- if m then
- m=lpegmatch(grammar_parsed_text_two,data,m)
- end
- if m then
- else
- errorstr="invalid xml file - parsed text"
- end
- elseif type(data)=="string" then
- if lpegmatch(grammar_unparsed_text,data) then
- errorstr=""
- else
- errorstr="invalid xml file - unparsed text"
- end
+ if m then
else
- errorstr="invalid xml file - no text at all"
- end
- local result
- if errorstr and errorstr~="" then
- result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
- setmetatable(result,mt)
- setmetatable(result.dt[1],mt)
- setmetatable(stack,mt)
- local errorhandler=settings.error_handler
- if errorhandler==false then
+ errorstr="invalid xml file - parsed text"
+ end
+ elseif type(data)=="string" then
+ if lpegmatch(grammar_unparsed_text,data) then
+ errorstr=""
+ else
+ errorstr="invalid xml file - unparsed text"
+ end
+ else
+ errorstr="invalid xml file - no text at all"
+ end
+ local result
+ if errorstr and errorstr~="" then
+ result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
+ setmetatable(result,mt)
+ setmetatable(result.dt[1],mt)
+ setmetatable(stack,mt)
+ local errorhandler=settings.error_handler
+ if errorhandler==false then
+ else
+ errorhandler=errorhandler or xml.errorhandler
+ if errorhandler then
+ local currentresource=settings.currentresource
+ if currentresource and currentresource~="" then
+ xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
else
- errorhandler=errorhandler or xml.errorhandler
- if errorhandler then
- local currentresource=settings.currentresource
- if currentresource and currentresource~="" then
- xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
- else
- xml.errorhandler(formatters["load error: %s"](errorstr))
- end
- end
- end
- else
- result=stack[1]
- end
- if not settings.no_root then
- result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
- setmetatable(result,mt)
- local rdt=result.dt
- for k=1,#rdt do
- local v=rdt[k]
- if type(v)=="table" and not v.special then
- result.ri=k
- v.__p__=result
- break
- end
+ xml.errorhandler(formatters["load error: %s"](errorstr))
end
+ end
end
- if errorstr and errorstr~="" then
- result.error=true
- else
- errorstr=nil
- end
- result.statistics={
- errormessage=errorstr,
- entities={
- decimals=dcache,
- hexadecimals=hcache,
- names=acache,
- intermediates=parameters,
- }
+ else
+ result=stack[1]
+ end
+ if not settings.no_root then
+ result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
+ setmetatable(result,mt)
+ local rdt=result.dt
+ for k=1,#rdt do
+ local v=rdt[k]
+ if type(v)=="table" and not v.special then
+ result.ri=k
+ v.__p__=result
+ break
+ end
+ end
+ end
+ if errorstr and errorstr~="" then
+ result.error=true
+ else
+ errorstr=nil
+ end
+ result.statistics={
+ errormessage=errorstr,
+ entities={
+ decimals=dcache,
+ hexadecimals=hcache,
+ names=acache,
+ intermediates=parameters,
}
- preparexmlstate()
- return result
+ }
+ preparexmlstate()
+ return result
end
local function xmlconvert(data,settings)
- local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
- if ok then
- return result
- elseif type(result)=="string" then
- return _xmlconvert_(true,settings,result)
- else
- return _xmlconvert_(true,settings)
- end
+ local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
+ if ok then
+ return result
+ elseif type(result)=="string" then
+ return _xmlconvert_(true,settings,result)
+ else
+ return _xmlconvert_(true,settings)
+ end
end
xml.convert=xmlconvert
function xml.inheritedconvert(data,xmldata)
- local settings=xmldata.settings
- if settings then
- settings.parent_root=xmldata
- end
- local xc=xmlconvert(data,settings)
- return xc
+ local settings=xmldata.settings
+ if settings then
+ settings.parent_root=xmldata
+ end
+ local xc=xmlconvert(data,settings)
+ return xc
end
function xml.is_valid(root)
- return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
+ return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
end
function xml.package(tag,attributes,data)
- local ns,tg=match(tag,"^(.-):?([^:]+)$")
- local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
- setmetatable(t,mt)
- return t
+ local ns,tg=match(tag,"^(.-):?([^:]+)$")
+ local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
+ setmetatable(t,mt)
+ return t
end
function xml.is_valid(root)
- return root and not root.error
+ return root and not root.error
end
xml.errorhandler=report_xml
function xml.load(filename,settings)
- local data=""
- if type(filename)=="string" then
- local f=io.open(filename,'r')
- if f then
- data=f:read("*all")
- f:close()
- end
- elseif filename then
- data=filename:read("*all")
- end
- if settings then
- settings.currentresource=filename
- local result=xmlconvert(data,settings)
- settings.currentresource=nil
- return result
- else
- return xmlconvert(data,{ currentresource=filename })
- end
+ local data=""
+ if type(filename)=="string" then
+ local f=io.open(filename,'r')
+ if f then
+ data=f:read("*all")
+ f:close()
+ end
+ elseif filename then
+ data=filename:read("*all")
+ end
+ if settings then
+ settings.currentresource=filename
+ local result=xmlconvert(data,settings)
+ settings.currentresource=nil
+ return result
+ else
+ return xmlconvert(data,{ currentresource=filename })
+ end
end
local no_root={ no_root=true }
function xml.toxml(data)
- if type(data)=="string" then
- local root={ xmlconvert(data,no_root) }
- return (#root>1 and root) or root[1]
- else
- return data
- end
+ if type(data)=="string" then
+ local root={ xmlconvert(data,no_root) }
+ return (#root>1 and root) or root[1]
+ else
+ return data
+ end
end
local function copy(old,p)
- if old then
- local new={}
- for k,v in next,old do
- local t=type(v)=="table"
- if k=="at" then
- local t={}
- for k,v in next,v do
- t[k]=v
- end
- new[k]=t
- elseif k=="dt" then
- v.__p__=nil
- v=copy(v,new)
- new[k]=v
- v.__p__=p
- else
- new[k]=v
- end
- end
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ local t=type(v)=="table"
+ if k=="at" then
+ local t={}
+ for k,v in next,v do
+ t[k]=v
+ end
+ new[k]=t
+ elseif k=="dt" then
+ v.__p__=nil
+ v=copy(v,new)
+ new[k]=v
+ v.__p__=p
+ else
+ new[k]=v
+ end
+ end
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
end
+ return new
+ else
+ return {}
+ end
end
xml.copy=copy
function xml.checkbom(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@" and find(v.dt[1],"xml.*version=") then
- return
- end
- end
- insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
- insert(dt,2,"\n" )
+ 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@" and find(v.dt[1],"xml.*version=") then
+ return
+ end
end
+ insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
+ insert(dt,2,"\n" )
+ end
end
local f_attribute=formatters['%s=%q']
local function verbose_element(e,handlers,escape)
- local handle=handlers.handle
- local serialize=handlers.serialize
- local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
- local ats=eat and next(eat) and {}
- if ats then
- local n=0
- for k in next,eat do
- n=n+1
- ats[n]=k
- end
- if n==1 then
- local k=ats[1]
- ats=f_attribute(k,escaped(eat[k]))
- else
- sort(ats)
- for i=1,n do
- local k=ats[i]
- ats[i]=f_attribute(k,escaped(eat[k]))
- end
- ats=concat(ats," ")
- end
- end
- if ern and trace_entities and ern~=ens then
- ens=ern
+ local handle=handlers.handle
+ local serialize=handlers.serialize
+ local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
+ local ats=eat and next(eat) and {}
+ if ats then
+ local n=0
+ for k in next,eat do
+ n=n+1
+ ats[n]=k
end
- local n=edt and #edt
- if ens~="" then
- if n and n>0 then
- if ats then
- handle("<",ens,":",etg," ",ats,">")
- else
- handle("<",ens,":",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",ens,":",etg,">")
+ if n==1 then
+ local k=ats[1]
+ ats=f_attribute(k,escaped(eat[k]))
+ else
+ sort(ats)
+ for i=1,n do
+ local k=ats[i]
+ ats[i]=f_attribute(k,escaped(eat[k]))
+ end
+ ats=concat(ats," ")
+ end
+ end
+ if ern and trace_entities and ern~=ens then
+ ens=ern
+ end
+ local n=edt and #edt
+ if ens~="" then
+ if n and n>0 then
+ if ats then
+ handle("<",ens,":",etg," ",ats,">")
+ else
+ handle("<",ens,":",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",ens,":",etg," ",ats,"/>")
- else
- handle("<",ens,":",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",ens,":",etg,">")
else
- if n and n>0 then
- if ats then
- handle("<",etg," ",ats,">")
- else
- handle("<",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",etg,">")
+ if ats then
+ handle("<",ens,":",etg," ",ats,"/>")
+ else
+ handle("<",ens,":",etg,"/>")
+ end
+ end
+ else
+ if n and n>0 then
+ if ats then
+ handle("<",etg," ",ats,">")
+ else
+ handle("<",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",etg," ",ats,"/>")
- else
- handle("<",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",etg,">")
+ else
+ if ats then
+ handle("<",etg," ",ats,"/>")
+ else
+ handle("<",etg,"/>")
+ end
end
+ end
end
local function verbose_pi(e,handlers)
- handlers.handle("<?",e.dt[1],"?>")
+ handlers.handle("<?",e.dt[1],"?>")
end
local function verbose_comment(e,handlers)
- handlers.handle("<!--",e.dt[1],"-->")
+ handlers.handle("<!--",e.dt[1],"-->")
end
local function verbose_cdata(e,handlers)
- handlers.handle("<![CDATA[",e.dt[1],"]]>")
+ handlers.handle("<![CDATA[",e.dt[1],"]]>")
end
local function verbose_doctype(e,handlers)
- handlers.handle("<!DOCTYPE",e.dt[1],">")
+ handlers.handle("<!DOCTYPE",e.dt[1],">")
end
local function verbose_root(e,handlers)
- handlers.serialize(e.dt,handlers)
+ handlers.serialize(e.dt,handlers)
end
local function verbose_text(e,handlers)
- handlers.handle(escaped(e))
+ handlers.handle(escaped(e))
end
local function verbose_document(e,handlers)
- local serialize=handlers.serialize
- local functions=handlers.functions
- for i=1,#e do
- local ei=e[i]
- if type(ei)=="string" then
- functions["@tx@"](ei,handlers)
- else
- serialize(ei,handlers)
- end
+ local serialize=handlers.serialize
+ local functions=handlers.functions
+ for i=1,#e do
+ local ei=e[i]
+ if type(ei)=="string" then
+ functions["@tx@"](ei,handlers)
+ else
+ serialize(ei,handlers)
end
+ end
end
local function serialize(e,handlers,...)
- if e then
- local initialize=handlers.initialize
- local finalize=handlers.finalize
- local functions=handlers.functions
- if initialize then
- local state=initialize(...)
- if not state==true then
- return state
- end
- end
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
- if finalize then
- return finalize()
- end
+ if e then
+ local initialize=handlers.initialize
+ local finalize=handlers.finalize
+ local functions=handlers.functions
+ if initialize then
+ local state=initialize(...)
+ if not state==true then
+ return state
+ end
+ end
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
end
+ if finalize then
+ return finalize()
+ end
+ end
end
local function xserialize(e,handlers)
- if e then
- local functions=handlers.functions
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
+ if e then
+ local functions=handlers.functions
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
end
+ end
end
local handlers={}
local function newhandlers(settings)
- local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
- if settings then
- for k,v in next,settings do
- if type(v)=="table" then
- local tk=t[k] if not tk then tk={} t[k]=tk end
- for kk,vv in next,v do
- tk[kk]=vv
- end
- else
- t[k]=v
- end
- end
- if settings.name then
- handlers[settings.name]=t
- end
+ local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
+ if settings then
+ for k,v in next,settings do
+ if type(v)=="table" then
+ local tk=t[k] if not tk then tk={} t[k]=tk end
+ for kk,vv in next,v do
+ tk[kk]=vv
+ end
+ else
+ t[k]=v
+ end
end
- utilities.storage.mark(t)
- return t
+ if settings.name then
+ handlers[settings.name]=t
+ end
+ end
+ utilities.storage.mark(t)
+ return t
end
local nofunction=function() end
function xml.sethandlersfunction(handler,name,fnc)
- handler.functions[name]=fnc or nofunction
+ handler.functions[name]=fnc or nofunction
end
function xml.gethandlersfunction(handler,name)
- return handler.functions[name]
+ return handler.functions[name]
end
function xml.gethandlers(name)
- return handlers[name]
+ return handlers[name]
end
newhandlers {
- name="verbose",
- initialize=false,
- finalize=false,
- serialize=xserialize,
- handle=print,
- functions={
- ["@dc@"]=verbose_document,
- ["@dt@"]=verbose_doctype,
- ["@rt@"]=verbose_root,
- ["@el@"]=verbose_element,
- ["@pi@"]=verbose_pi,
- ["@cm@"]=verbose_comment,
- ["@cd@"]=verbose_cdata,
- ["@tx@"]=verbose_text,
- }
+ name="verbose",
+ initialize=false,
+ finalize=false,
+ serialize=xserialize,
+ handle=print,
+ functions={
+ ["@dc@"]=verbose_document,
+ ["@dt@"]=verbose_doctype,
+ ["@rt@"]=verbose_root,
+ ["@el@"]=verbose_element,
+ ["@pi@"]=verbose_pi,
+ ["@cm@"]=verbose_comment,
+ ["@cd@"]=verbose_cdata,
+ ["@tx@"]=verbose_text,
+ }
}
local result
local xmlfilehandler=newhandlers {
- name="file",
- initialize=function(name)
- result=io.open(name,"wb")
- return result
- end,
- finalize=function()
- result:close()
- return true
- end,
- handle=function(...)
- result:write(...)
- end,
+ name="file",
+ initialize=function(name)
+ result=io.open(name,"wb")
+ return result
+ end,
+ finalize=function()
+ result:close()
+ return true
+ end,
+ handle=function(...)
+ result:write(...)
+ end,
}
function xml.save(root,name)
- serialize(root,xmlfilehandler,name)
+ serialize(root,xmlfilehandler,name)
end
local result,r,threshold={},0,512
local xmlstringhandler=newhandlers {
- name="string",
- initialize=function()
- r=0
- return result
- end,
- finalize=function()
- local done=concat(result,"",1,r)
- r=0
- if r>threshold then
- result={}
- end
- return done
- end,
- handle=function(...)
- for i=1,select("#",...) do
- r=r+1
- result[r]=select(i,...)
- end
- end,
+ name="string",
+ initialize=function()
+ r=0
+ return result
+ end,
+ finalize=function()
+ local done=concat(result,"",1,r)
+ r=0
+ if r>threshold then
+ result={}
+ end
+ return done
+ end,
+ handle=function(...)
+ for i=1,select("#",...) do
+ r=r+1
+ result[r]=select(i,...)
+ end
+ end,
}
local function xmltostring(root)
- if not root then
- return ""
- elseif type(root)=="string" then
- return root
- else
- return serialize(root,xmlstringhandler) or ""
- end
+ if not root then
+ return ""
+ elseif type(root)=="string" then
+ return root
+ else
+ return serialize(root,xmlstringhandler) or ""
+ end
end
local function __tostring(root)
- return (root and xmltostring(root)) or ""
+ return (root and xmltostring(root)) or ""
end
initialize_mt=function(root)
- mt={ __tostring=__tostring,__index=root }
+ mt={ __tostring=__tostring,__index=root }
end
xml.defaulthandlers=handlers
xml.newhandlers=newhandlers
xml.serialize=serialize
xml.tostring=xmltostring
local function xmlstring(e,handle)
- if not handle or (e.special and e.tg~="@rt@") then
- elseif e.tg then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- xmlstring(edt[i],handle)
- end
- end
- else
- handle(e)
+ if not handle or (e.special and e.tg~="@rt@") then
+ elseif e.tg then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ xmlstring(edt[i],handle)
+ end
end
+ else
+ handle(e)
+ end
end
xml.string=xmlstring
function xml.settings(e)
- while e do
- local s=e.settings
- if s then
- return s
- else
- e=e.__p__
- end
+ while e do
+ local s=e.settings
+ if s then
+ return s
+ else
+ e=e.__p__
end
- return nil
+ end
+ return nil
end
function xml.root(e)
- local r=e
- while e do
- e=e.__p__
- if e then
- r=e
- end
+ local r=e
+ while e do
+ e=e.__p__
+ if e then
+ r=e
end
- return r
+ end
+ return r
end
function xml.parent(root)
- return root.__p__
+ return root.__p__
end
function xml.body(root)
- return root.ri and root.dt[root.ri] or root
+ return root.ri and root.dt[root.ri] or root
end
function xml.name(root)
- if not root then
- return ""
- end
- local ns=root.ns
- local tg=root.tg
- if ns=="" then
- return tg
- else
- return ns..":"..tg
- end
+ if not root then
+ return ""
+ end
+ local ns=root.ns
+ local tg=root.tg
+ if ns=="" then
+ return tg
+ else
+ return ns..":"..tg
+ end
end
function xml.erase(dt,k)
- if dt then
- if k then
- dt[k]=""
- else for k=1,#dt do
- dt[1]={ "" }
- end end
- end
+ if dt then
+ if k then
+ dt[k]=""
+ else for k=1,#dt do
+ dt[1]={ "" }
+ end end
+ end
end
function xml.assign(dt,k,root)
- if dt and k then
- dt[k]=type(root)=="table" and xml.body(root) or root
- return dt[k]
- else
- return xml.body(root)
- end
+ if dt and k then
+ dt[k]=type(root)=="table" and xml.body(root) or root
+ return dt[k]
+ else
+ return xml.body(root)
+ end
end
function xml.tocdata(e,wrapper)
- local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
- if wrapper then
- whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
- end
- local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
- setmetatable(t,getmetatable(e))
- e.dt={ t }
+ local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
+ if wrapper then
+ whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
+ end
+ local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
+ setmetatable(t,getmetatable(e))
+ 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
+ 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
- return root
+ end
+ return root
end
function xml.kind(e)
- local dt=e and e.dt
- if dt then
- local n=#dt
- if n==1 then
- local d=dt[1]
- if d.special then
- local tg=d.tg
- if tg=="@cd@" then
- return "cdata"
- elseif tg=="@cm" then
- return "comment"
- elseif tg=="@pi@" then
- return "instruction"
- elseif tg=="@dt@" then
- return "declaration"
- end
- elseif type(d)=="string" then
- return "text"
- end
- return "element"
- elseif n>0 then
- return "mixed"
- end
+ local dt=e and e.dt
+ if dt then
+ local n=#dt
+ if n==1 then
+ local d=dt[1]
+ if d.special then
+ local tg=d.tg
+ if tg=="@cd@" then
+ return "cdata"
+ elseif tg=="@cm" then
+ return "comment"
+ elseif tg=="@pi@" then
+ return "instruction"
+ elseif tg=="@dt@" then
+ return "declaration"
+ end
+ elseif type(d)=="string" then
+ return "text"
+ end
+ return "element"
+ elseif n>0 then
+ return "mixed"
end
- return "empty"
+ end
+ return "empty"
end
@@ -16924,14 +16932,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true
--- original size: 54551, stripped down to: 33353
+-- original size: 54551, stripped down to: 30745
if not modules then modules={} end modules ['lxml-lpt']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local concat,remove,insert=table.concat,table.remove,table.insert
local type,next,tonumber,tostring,setmetatable,load,select=type,next,tonumber,tostring,setmetatable,load,select
@@ -16944,21 +16952,21 @@ local trace_lparse=false
local trace_lprofile=false
local report_lpath=logs.reporter("xml","lpath")
if trackers then
- trackers.register("xml.path",function(v)
- trace_lpath=v
- end)
- trackers.register("xml.parse",function(v)
- trace_lparse=v
- end)
- trackers.register("xml.profile",function(v)
- trace_lpath=v
- trace_lparse=v
- trace_lprofile=v
- end)
+ trackers.register("xml.path",function(v)
+ trace_lpath=v
+ end)
+ trackers.register("xml.parse",function(v)
+ trace_lparse=v
+ end)
+ trackers.register("xml.profile",function(v)
+ trace_lpath=v
+ trace_lparse=v
+ trace_lprofile=v
+ end)
end
local xml=xml
-local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
-local lpathcached=0 function xml.lpathcached() return lpathcached end
+local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
+local lpathcached=0 function xml.lpathcached() return lpathcached end
xml.functions=xml.functions or {}
local functions=xml.functions
xml.expressions=xml.expressions or {}
@@ -16972,262 +16980,262 @@ local xmlpatterns=lpegpatterns.xml
finalizers.xml=finalizers.xml or {}
finalizers.tex=finalizers.tex or {}
local function fallback (t,name)
- local fn=finalizers[name]
- if fn then
- t[name]=fn
- else
- report_lpath("unknown sub finalizer %a",name)
- fn=function() end
- end
- return fn
+ local fn=finalizers[name]
+ if fn then
+ t[name]=fn
+ else
+ report_lpath("unknown sub finalizer %a",name)
+ fn=function() end
+ end
+ return fn
end
setmetatableindex(finalizers.xml,fallback)
setmetatableindex(finalizers.tex,fallback)
xml.defaultprotocol="xml"
local apply_axis={}
apply_axis['root']=function(list)
- local collected={}
- for l=1,#list do
- local ll=list[l]
- local rt=ll
- while ll do
- ll=ll.__p__
- if ll then
- rt=ll
- end
- end
- collected[l]=rt
+ local collected={}
+ for l=1,#list do
+ local ll=list[l]
+ local rt=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
+ rt=ll
+ end
end
- return collected
+ collected[l]=rt
+ end
+ return collected
end
apply_axis['self']=function(list)
- return list
+ return list
end
apply_axis['child']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local dt=ll.dt
- if dt then
- local n=#dt
- if n==0 then
- ll.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- ll.en=1
- end
- else
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- end
- end
- ll.en=en
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local dt=ll.dt
+ if dt then
+ local n=#dt
+ if n==0 then
+ ll.en=0
+ elseif n==1 then
+ local dk=dt[1]
+ if dk.tg then
+ c=c+1
+ collected[c]=dk
+ dk.ni=1
+ dk.ei=1
+ ll.en=1
+ end
+ else
+ local en=0
+ for k=1,#dt do
+ local dk=dt[k]
+ if dk.tg then
+ c=c+1
+ en=en+1
+ collected[c]=dk
+ dk.ni=k
+ dk.ei=en
+ end
end
+ ll.en=en
+ end
end
- return collected
+ end
+ return collected
end
local function collect(list,collected,c)
- local dt=list.dt
- if dt then
- local n=#dt
- if n==0 then
- list.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- c=collect(dk,collected,c)
- list.en=1
- else
- list.en=0
- end
- else
- local en=0
- for k=1,n do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- c=collect(dk,collected,c)
- end
- end
- list.en=en
+ local dt=list.dt
+ if dt then
+ local n=#dt
+ if n==0 then
+ list.en=0
+ elseif n==1 then
+ local dk=dt[1]
+ if dk.tg then
+ c=c+1
+ collected[c]=dk
+ dk.ni=1
+ dk.ei=1
+ c=collect(dk,collected,c)
+ list.en=1
+ else
+ list.en=0
+ end
+ else
+ local en=0
+ for k=1,n do
+ local dk=dt[k]
+ if dk.tg then
+ c=c+1
+ en=en+1
+ collected[c]=dk
+ dk.ni=k
+ dk.ei=en
+ c=collect(dk,collected,c)
end
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant']=function(list)
- local collected,c={},0
- for l=1,#list do
- c=collect(list[l],collected,c)
- end
- return collected
+ local collected,c={},0
+ for l=1,#list do
+ c=collect(list[l],collected,c)
+ end
+ return collected
end
local function collect(list,collected,c)
- local dt=list.dt
- if dt then
- local n=#dt
- if n==0 then
- list.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- c=collect(dk,collected,c)
- list.en=1
- end
- else
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- c=collect(dk,collected,c)
- end
- end
- list.en=en
+ local dt=list.dt
+ if dt then
+ local n=#dt
+ if n==0 then
+ list.en=0
+ elseif n==1 then
+ local dk=dt[1]
+ if dk.tg then
+ c=c+1
+ collected[c]=dk
+ dk.ni=1
+ dk.ei=1
+ c=collect(dk,collected,c)
+ list.en=1
+ end
+ else
+ local en=0
+ for k=1,#dt do
+ local dk=dt[k]
+ if dk.tg then
+ c=c+1
+ en=en+1
+ collected[c]=dk
+ dk.ni=k
+ dk.ei=en
+ c=collect(dk,collected,c)
end
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- if ll.special~=true then
- c=c+1
- collected[c]=ll
- end
- c=collect(ll,collected,c)
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ if ll.special~=true then
+ c=c+1
+ collected[c]=ll
end
- return collected
+ c=collect(ll,collected,c)
+ end
+ return collected
end
apply_axis['ancestor']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ while ll do
+ ll=ll.__p__
+ if ll then
+ c=c+1
+ collected[c]=ll
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['ancestor-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ c=c+1
+ collected[c]=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
c=c+1
collected[c]=ll
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['parent']=function(list)
- local collected,c={},0
- for l=1,#list do
- local pl=list[l].__p__
- if pl then
- c=c+1
- collected[c]=pl
- end
+ local collected,c={},0
+ for l=1,#list do
+ local pl=list[l].__p__
+ if pl then
+ c=c+1
+ collected[c]=pl
end
- return collected
+ end
+ return collected
end
apply_axis['attribute']=function(list)
- return {}
+ return {}
end
apply_axis['namespace']=function(list)
- return {}
+ return {}
end
apply_axis['following']=function(list)
- return {}
+ return {}
end
apply_axis['preceding']=function(list)
- return {}
+ return {}
end
apply_axis['following-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=ll.ni+1,#d do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=ll.ni+1,#d do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['preceding-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=1,ll.ni-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=1,ll.ni-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['reverse-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=ll.ni-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=ll.ni-1,1,-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['auto-descendant-or-self']=apply_axis['descendant-or-self']
apply_axis['auto-descendant']=apply_axis['descendant']
@@ -17235,130 +17243,130 @@ apply_axis['auto-child']=apply_axis['child']
apply_axis['auto-self']=apply_axis['self']
apply_axis['initial-child']=apply_axis['child']
local function apply_nodes(list,directive,nodes)
- local maxn=#nodes
- if maxn==3 then
- local nns,ntg=nodes[2],nodes[3]
- if not nns and not ntg then
+ local maxn=#nodes
+ if maxn==3 then
+ local nns,ntg=nodes[2],nodes[3]
+ if not nns and not ntg then
+ if directive then
+ return list
+ else
+ return {}
+ end
+ else
+ local collected,c,m,p={},0,0,nil
+ if not nns then
+ for l=1,#list do
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
if directive then
- return list
- else
- return {}
+ if ntg==ltg then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif ntg~=ltg then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
end
- else
- local collected,c,m,p={},0,0,nil
- if not nns then
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- if directive then
- if ntg==ltg then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif ntg~=ltg then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- elseif not ntg then
- for l=1,#list do
- local ll=list[l]
- local lns=ll.rn or ll.ns
- if lns then
- if directive then
- if lns==nns then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif lns~=nns then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- else
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=ltg==ntg and lns==nns
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
+ end
+ end
+ elseif not ntg then
+ for l=1,#list do
+ local ll=list[l]
+ local lns=ll.rn or ll.ns
+ if lns then
+ if directive then
+ if lns==nns then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif lns~=nns then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
end
- return collected
+ end
end
- else
- local collected,c,m,p={},0,0,nil
+ else
for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=false
- for n=1,maxn,3 do
- local nns,ntg=nodes[n+1],nodes[n+2]
- ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
- if ok then
- break
- end
- end
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=ltg==ntg and lns==nns
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
end
+ end
end
- return collected
+ end
+ return collected
end
-end
-local quit_expression=false
-local function apply_expression(list,expression,order)
- local collected,c={},0
- quit_expression=false
+ else
+ local collected,c,m,p={},0,0,nil
for l=1,#list do
- local ll=list[l]
- if expression(list,ll,l,order) then
- c=c+1
- collected[c]=ll
- end
- if quit_expression then
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=false
+ for n=1,maxn,3 do
+ local nns,ntg=nodes[n+1],nodes[n+2]
+ ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
+ if ok then
break
+ end
end
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ end
end
return collected
+ end
end
-local function apply_selector(list,specification)
- if xml.applyselector then
- apply_selector=xml.applyselector
- return apply_selector(list,specification)
- else
- return list
+local quit_expression=false
+local function apply_expression(list,expression,order)
+ local collected,c={},0
+ quit_expression=false
+ for l=1,#list do
+ local ll=list[l]
+ if expression(list,ll,l,order) then
+ c=c+1
+ collected[c]=ll
+ end
+ if quit_expression then
+ break
end
+ end
+ return collected
+end
+local function apply_selector(list,specification)
+ if xml.applyselector then
+ apply_selector=xml.applyselector
+ return apply_selector(list,specification)
+ else
+ return list
+ end
end
local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb
local spaces=S(" \n\r\t\f")^0
@@ -17369,24 +17377,24 @@ local lp_doequal=P("=")/"=="
local lp_or=P("|")/" or "
local lp_and=P("&")/" and "
local builtin={
- text="(ll.dt[1] or '')",
- content="ll.dt",
- name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
- tag="ll.tg",
- position="l",
- firstindex="1",
- firstelement="1",
- first="1",
- lastindex="(#ll.__p__.dt or 1)",
- lastelement="(ll.__p__.en or 1)",
- last="#list",
- rootposition="order",
- order="order",
- element="(ll.ei or 1)",
- index="(ll.ni or 1)",
- match="(ll.mi or 1)",
- namespace="ll.ns",
- ns="ll.ns",
+ text="(ll.dt[1] or '')",
+ content="ll.dt",
+ name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
+ tag="ll.tg",
+ position="l",
+ firstindex="1",
+ firstelement="1",
+ first="1",
+ lastindex="(#ll.__p__.dt or 1)",
+ lastelement="(ll.__p__.en or 1)",
+ last="#list",
+ rootposition="order",
+ order="order",
+ element="(ll.ei or 1)",
+ index="(ll.ni or 1)",
+ match="(ll.mi or 1)",
+ namespace="ll.ns",
+ ns="ll.ns",
}
local lp_builtin=lpeg.utfchartabletopattern(builtin)/builtin*((spaces*P("(")*spaces*P(")"))/"")
local lp_attribute=(P("@")+P("attribute::"))/""*Cc("(ll.at and ll.at['")*((R("az","AZ")+S("-_:"))^1)*Cc("'])")
@@ -17396,11 +17404,11 @@ local lp_fastpos=lp_fastpos_n+lp_fastpos_p
local lp_reserved=C("and")+C("or")+C("not")+C("div")+C("mod")+C("true")+C("false")
local lp_lua_function=Cs((R("az","AZ","__")^1*(P(".")*R("az","AZ","__")^1)^1)*("("))/"%0"
local lp_function=C(R("az","AZ","__")^1)*P("(")/function(t)
- if expressions[t] then
- return "expr."..t.."("
- else
- return "expr.error("
- end
+ if expressions[t] then
+ return "expr."..t.."("
+ else
+ return "expr.error("
+ end
end
local lparent=P("(")
local rparent=P(")")
@@ -17413,24 +17421,24 @@ local lp_string=Cc("'")*R("az","AZ","--","__")^1*Cc("'")
local lp_content=(P("'")*(1-P("'"))^0*P("'")+P('"')*(1-P('"'))^0*P('"'))
local cleaner
local lp_special=(C(P("name")+P("text")+P("tag")+P("count")+P("child")))*value/function(t,s)
- if expressions[t] then
- s=s and s~="" and lpegmatch(cleaner,s)
- if s and s~="" then
- return "expr."..t.."(ll,"..s..")"
- else
- return "expr."..t.."(ll)"
- end
+ if expressions[t] then
+ s=s and s~="" and lpegmatch(cleaner,s)
+ if s and s~="" then
+ return "expr."..t.."(ll,"..s..")"
else
- return "expr.error("..t..")"
+ return "expr."..t.."(ll)"
end
+ else
+ return "expr.error("..t..")"
+ end
end
local content=lp_builtin+lp_attribute+lp_special+lp_noequal+lp_doequal+lp_or+lp_and+lp_reserved+lp_lua_function+lp_function+lp_content+
- lp_child+lp_any
+ lp_child+lp_any
local converter=Cs (
- lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
+ lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
)
cleaner=Cs ((
- lp_reserved+lp_number+lp_string+1 )^1 )
+ lp_reserved+lp_number+lp_string+1 )^1 )
local template_e=[[
local expr = xml.expressions
return function(list,ll,l,order)
@@ -17446,75 +17454,75 @@ local template_f_y=[[
local template_f_n=[[
return xml.finalizers['%s']['%s']
]]
-local register_last_match={ kind="axis",axis="last-match" }
-local register_self={ kind="axis",axis="self" }
-local register_parent={ kind="axis",axis="parent" }
-local register_descendant={ kind="axis",axis="descendant" }
-local register_child={ kind="axis",axis="child" }
+local register_last_match={ kind="axis",axis="last-match" }
+local register_self={ kind="axis",axis="self" }
+local register_parent={ kind="axis",axis="parent" }
+local register_descendant={ kind="axis",axis="descendant" }
+local register_child={ kind="axis",axis="child" }
local register_descendant_or_self={ kind="axis",axis="descendant-or-self" }
-local register_root={ kind="axis",axis="root" }
-local register_ancestor={ kind="axis",axis="ancestor" }
-local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
-local register_attribute={ kind="axis",axis="attribute" }
-local register_namespace={ kind="axis",axis="namespace" }
-local register_following={ kind="axis",axis="following" }
+local register_root={ kind="axis",axis="root" }
+local register_ancestor={ kind="axis",axis="ancestor" }
+local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
+local register_attribute={ kind="axis",axis="attribute" }
+local register_namespace={ kind="axis",axis="namespace" }
+local register_following={ kind="axis",axis="following" }
local register_following_sibling={ kind="axis",axis="following-sibling" }
-local register_preceding={ kind="axis",axis="preceding" }
+local register_preceding={ kind="axis",axis="preceding" }
local register_preceding_sibling={ kind="axis",axis="preceding-sibling" }
-local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
+local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
local register_auto_descendant_or_self={ kind="axis",axis="auto-descendant-or-self" }
-local register_auto_descendant={ kind="axis",axis="auto-descendant" }
-local register_auto_self={ kind="axis",axis="auto-self" }
-local register_auto_child={ kind="axis",axis="auto-child" }
-local register_initial_child={ kind="axis",axis="initial-child" }
+local register_auto_descendant={ kind="axis",axis="auto-descendant" }
+local register_auto_self={ kind="axis",axis="auto-self" }
+local register_auto_child={ kind="axis",axis="auto-child" }
+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)
- if not skip[str] then
- report_lpath("error in expression: %s => %s",str,cnv)
- skip[str]=cnv or str
- end
- return false
+ if not skip[str] then
+ report_lpath("error in expression: %s => %s",str,cnv)
+ skip[str]=cnv or str
+ end
+ return false
end
local function errorrunner_f(str,arg)
- report_lpath("error in finalizer: %s(%s)",str,arg or "")
- return false
+ report_lpath("error in finalizer: %s(%s)",str,arg or "")
+ return false
end
local function register_nodes(nodetest,nodes)
- return { kind="nodes",nodetest=nodetest,nodes=nodes }
+ return { kind="nodes",nodetest=nodetest,nodes=nodes }
end
local function register_selector(specification)
- return { kind="selector",specification=specification }
+ return { kind="selector",specification=specification }
end
local function register_expression(expression)
- local converted=lpegmatch(converter,expression)
- local runner=load(format(template_e,converted))
- runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
- return { kind="expression",expression=expression,converted=converted,evaluator=runner }
+ local converted=lpegmatch(converter,expression)
+ local runner=load(format(template_e,converted))
+ runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
+ return { kind="expression",expression=expression,converted=converted,evaluator=runner }
end
local function register_finalizer(protocol,name,arguments)
- local runner
- if arguments and arguments~="" then
- runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
- else
- runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
- end
- runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
- return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
+ local runner
+ if arguments and arguments~="" then
+ runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
+ else
+ runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
+ end
+ runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
+ return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
end
local expression=P { "ex",
- ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
- sq="'"*(1-S("'"))^0*"'",
- dq='"'*(1-S('"'))^0*'"',
+ ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
+ sq="'"*(1-S("'"))^0*"'",
+ dq='"'*(1-S('"'))^0*'"',
}
local arguments=P { "ar",
- ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
- nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
- sq=P("'")*(1-P("'"))^0*P("'"),
- dq=P('"')*(1-P('"'))^0*P('"'),
+ ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
+ nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
+ sq=P("'")*(1-P("'"))^0*P("'"),
+ dq=P('"')*(1-P('"'))^0*P('"'),
}
local function register_error(str)
- return { kind="error",error=format("unparsed: %s",str) }
+ return { kind="error",error=format("unparsed: %s",str) }
end
local special_1=P("*")*Cc(register_auto_descendant)*Cc(register_all_nodes)
local special_2=P("/")*Cc(register_auto_self)
@@ -17522,367 +17530,367 @@ local special_3=P("")*Cc(register_auto_self)
local no_nextcolon=P(-1)+#(1-P(":"))
local no_nextlparent=P(-1)+#(1-P("("))
local pathparser=Ct { "patterns",
- patterns=spaces*V("protocol")*spaces*(
- (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
- ),
- protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
- step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
- axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
- special=special_1+special_2+special_3,
- initial=(P("/")*spaces*Cc(register_initial_child))^-1,
- error=(P(1)^1)/register_error,
- shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
- shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
- s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
- s_descendant=P("**")*Cc(register_descendant),
- s_child=P("*")*no_nextcolon*Cc(register_child),
- s_parent=P("..")*Cc(register_parent),
- s_self=P("." )*Cc(register_self),
- s_root=P("^^")*Cc(register_root),
- s_ancestor=P("^")*Cc(register_ancestor),
- s_lastmatch=P("=")*Cc(register_last_match),
- descendant=P("descendant::")*Cc(register_descendant),
- child=P("child::")*Cc(register_child),
- parent=P("parent::")*Cc(register_parent),
- self=P("self::")*Cc(register_self),
- root=P('root::')*Cc(register_root),
- ancestor=P('ancestor::')*Cc(register_ancestor),
- descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
- ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
- following=P('following::')*Cc(register_following),
- following_sibling=P('following-sibling::')*Cc(register_following_sibling),
- preceding=P('preceding::')*Cc(register_preceding),
- preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
- reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
- last_match=P('last-match::')*Cc(register_last_match),
- selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
- nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
- expressions=expression/register_expression,
- letters=R("az")^1,
- name=(1-S("/[]()|:*!"))^1,
- negate=P("!")*Cc(false),
- nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
- nodetest=V("negate")+Cc(true),
- nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
- wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
- nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
- finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
+ patterns=spaces*V("protocol")*spaces*(
+ (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
+ ),
+ protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
+ step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
+ axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
+ special=special_1+special_2+special_3,
+ initial=(P("/")*spaces*Cc(register_initial_child))^-1,
+ error=(P(1)^1)/register_error,
+ shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
+ shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
+ s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
+ s_descendant=P("**")*Cc(register_descendant),
+ s_child=P("*")*no_nextcolon*Cc(register_child),
+ s_parent=P("..")*Cc(register_parent),
+ s_self=P("." )*Cc(register_self),
+ s_root=P("^^")*Cc(register_root),
+ s_ancestor=P("^")*Cc(register_ancestor),
+ s_lastmatch=P("=")*Cc(register_last_match),
+ descendant=P("descendant::")*Cc(register_descendant),
+ child=P("child::")*Cc(register_child),
+ parent=P("parent::")*Cc(register_parent),
+ self=P("self::")*Cc(register_self),
+ root=P('root::')*Cc(register_root),
+ ancestor=P('ancestor::')*Cc(register_ancestor),
+ descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
+ ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
+ following=P('following::')*Cc(register_following),
+ following_sibling=P('following-sibling::')*Cc(register_following_sibling),
+ preceding=P('preceding::')*Cc(register_preceding),
+ preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
+ reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
+ last_match=P('last-match::')*Cc(register_last_match),
+ selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
+ nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
+ expressions=expression/register_expression,
+ letters=R("az")^1,
+ name=(1-S("/[]()|:*!"))^1,
+ negate=P("!")*Cc(false),
+ nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
+ nodetest=V("negate")+Cc(true),
+ nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
+ wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
+ nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
+ finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
}
xmlpatterns.pathparser=pathparser
local cache={}
local function nodesettostring(set,nodetest)
- local t={}
- for i=1,#set,3 do
- local directive,ns,tg=set[i],set[i+1],set[i+2]
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- t[#t+1]=(directive and tg) or format("not(%s)",tg)
- end
- if nodetest==false then
- return format("not(%s)",concat(t,"|"))
- else
- return concat(t,"|")
- end
+ local t={}
+ for i=1,#set,3 do
+ local directive,ns,tg=set[i],set[i+1],set[i+2]
+ if not ns or ns=="" then ns="*" end
+ if not tg or tg=="" then tg="*" end
+ tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
+ t[#t+1]=(directive and tg) or format("not(%s)",tg)
+ end
+ if nodetest==false then
+ return format("not(%s)",concat(t,"|"))
+ else
+ return concat(t,"|")
+ end
end
local function tagstostring(list)
- if #list==0 then
- return "no elements"
- else
- local t={}
- for i=1,#list do
- local li=list[i]
- local ns,tg=li.ns,li.tg
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- t[i]=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- end
- return concat(t," ")
+ if #list==0 then
+ return "no elements"
+ else
+ local t={}
+ for i=1,#list do
+ local li=list[i]
+ local ns,tg=li.ns,li.tg
+ if not ns or ns=="" then ns="*" end
+ if not tg or tg=="" then tg="*" end
+ t[i]=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
end
+ return concat(t," ")
+ end
end
xml.nodesettostring=nodesettostring
local lpath
local function lshow(parsed)
- if type(parsed)=="string" then
- parsed=lpath(parsed)
- end
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
- table.serialize(parsed,false))
+ if type(parsed)=="string" then
+ parsed=lpath(parsed)
+ end
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
+ table.serialize(parsed,false))
end
xml.lshow=lshow
local function add_comment(p,str)
- local pc=p.comment
- if not pc then
- p.comment={ str }
- else
- pc[#pc+1]=str
- end
+ local pc=p.comment
+ if not pc then
+ p.comment={ str }
+ else
+ pc[#pc+1]=str
+ end
end
lpath=function (pattern)
- lpathcalls=lpathcalls+1
- if type(pattern)=="table" then
- return pattern
- else
- local parsed=cache[pattern]
- if parsed then
- lpathcached=lpathcached+1
+ lpathcalls=lpathcalls+1
+ if type(pattern)=="table" then
+ return pattern
+ else
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcached=lpathcached+1
+ else
+ parsed=lpegmatch(pathparser,pattern)
+ if parsed then
+ parsed.pattern=pattern
+ local np=#parsed
+ if np==0 then
+ parsed={ pattern=pattern,register_self,state="parsing error" }
+ report_lpath("parsing error in pattern: %s",pattern)
+ lshow(parsed)
else
- parsed=lpegmatch(pathparser,pattern)
- if parsed then
- parsed.pattern=pattern
- local np=#parsed
- if np==0 then
- parsed={ pattern=pattern,register_self,state="parsing error" }
- report_lpath("parsing error in pattern: %s",pattern)
- lshow(parsed)
- else
- local pi=parsed[1]
- if pi.axis=="auto-child" then
- if false then
- add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
- parsed[1]=register_auto_descendant_or_self
- else
- add_comment(parsed,"auto-child replaced by auto-descendant")
- parsed[1]=register_auto_descendant
- end
- elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
- add_comment(parsed,"initial-child removed")
- remove(parsed,1)
- end
- local np=#parsed
- if np>1 then
- local pnp=parsed[np]
- if pnp.kind=="nodes" and pnp.nodetest==true then
- local nodes=pnp.nodes
- if nodes[1]==true and nodes[2]==false and nodes[3]==false then
- add_comment(parsed,"redundant final wildcard filter removed")
- remove(parsed,np)
- end
- end
- end
- end
+ local pi=parsed[1]
+ if pi.axis=="auto-child" then
+ if false then
+ add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
+ parsed[1]=register_auto_descendant_or_self
else
- parsed={ pattern=pattern }
+ add_comment(parsed,"auto-child replaced by auto-descendant")
+ parsed[1]=register_auto_descendant
end
- cache[pattern]=parsed
- if trace_lparse and not trace_lprofile then
- lshow(parsed)
+ elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
+ add_comment(parsed,"initial-child removed")
+ remove(parsed,1)
+ end
+ local np=#parsed
+ if np>1 then
+ local pnp=parsed[np]
+ if pnp.kind=="nodes" and pnp.nodetest==true then
+ local nodes=pnp.nodes
+ if nodes[1]==true and nodes[2]==false and nodes[3]==false then
+ add_comment(parsed,"redundant final wildcard filter removed")
+ remove(parsed,np)
+ end
end
+ end
end
- return parsed
+ else
+ parsed={ pattern=pattern }
+ end
+ cache[pattern]=parsed
+ if trace_lparse and not trace_lprofile then
+ lshow(parsed)
+ end
end
+ return parsed
+ end
end
xml.lpath=lpath
do
- local profiled={}
- xml.profiled=profiled
- local lastmatch=nil
- local keepmatch=nil
- if directives then
- directives.register("xml.path.keeplastmatch",function(v)
- keepmatch=v
- lastmatch=nil
- end)
- end
- apply_axis["last-match"]=function()
- return lastmatch or {}
- end
- local function profiled_apply(list,parsed,nofparsed,order)
- local p=profiled[parsed.pattern]
- if p then
- p.tested=p.tested+1
- else
- p={ tested=1,matched=0,finalized=0 }
- profiled[parsed.pattern]=p
- end
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- p.matched=p.matched+1
- p.finalized=p.finalized+1
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- p.finalized=p.finalized+1
- return collected
- end
- return nil
- end
- end
- if collected then
- p.matched=p.matched+1
- end
- return collected
- end
- local function traced_apply(list,parsed,nofparsed,order)
- if trace_lparse then
- lshow(parsed)
- end
- report_lpath("collecting: %s",parsed.pattern)
- report_lpath("root tags : %s",tagstostring(list))
- report_lpath("order : %s",order or "unset")
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
- return collected
- end
- return nil
- end
- end
+ local profiled={}
+ xml.profiled=profiled
+ local lastmatch=nil
+ local keepmatch=nil
+ if directives then
+ directives.register("xml.path.keeplastmatch",function(v)
+ keepmatch=v
+ lastmatch=nil
+ end)
+ end
+ apply_axis["last-match"]=function()
+ return lastmatch or {}
+ end
+ local function profiled_apply(list,parsed,nofparsed,order)
+ local p=profiled[parsed.pattern]
+ if p then
+ p.tested=p.tested+1
+ else
+ p={ tested=1,matched=0,finalized=0 }
+ profiled[parsed.pattern]=p
+ end
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ p.matched=p.matched+1
+ p.finalized=p.finalized+1
return collected
- end
- local function normal_apply(list,parsed,nofparsed,order)
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- local axis=pi.axis
- if axis~="self" then
- collected=apply_axis[axis](collected)
- end
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- return pi.finalizer(collected)
- end
- if not collected or #collected==0 then
- local pf=i<nofparsed and parsed[nofparsed].finalizer
- if pf then
- return pf(collected)
- end
- return nil
- end
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ p.finalized=p.finalized+1
+ return collected
end
- return collected
+ return nil
+ end
end
- local apply=normal_apply
- if trackers then
- trackers.register("xml.path,xml.parse,xml.profile",function()
- if trace_lprofile then
- apply=profiled_apply
- elseif trace_lpath then
- apply=traced_apply
- else
- apply=normal_apply
- end
- end)
+ if collected then
+ p.matched=p.matched+1
end
- function xml.applylpath(list,pattern)
- if not list then
- lastmatch=nil
- return
- end
- local parsed=cache[pattern]
- if parsed then
- lpathcalls=lpathcalls+1
- lpathcached=lpathcached+1
- elseif type(pattern)=="table" then
- lpathcalls=lpathcalls+1
- parsed=pattern
- else
- parsed=lpath(pattern) or pattern
- end
- if not parsed then
- lastmatch=nil
- return
- end
- local nofparsed=#parsed
- if nofparsed==0 then
- lastmatch=nil
- return
- end
- local collected=apply({ list },parsed,nofparsed,list.mi)
- lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ local function traced_apply(list,parsed,nofparsed,order)
+ if trace_lparse then
+ lshow(parsed)
+ end
+ report_lpath("collecting: %s",parsed.pattern)
+ report_lpath("root tags : %s",tagstostring(list))
+ report_lpath("order : %s",order or "unset")
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
return collected
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
+ return collected
+ end
+ return nil
+ end
end
- function xml.lastmatch()
- return lastmatch
- end
- local stack={}
- function xml.pushmatch()
- insert(stack,lastmatch)
- end
- function xml.popmatch()
- lastmatch=remove(stack)
+ return collected
+ end
+ local function normal_apply(list,parsed,nofparsed,order)
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ local axis=pi.axis
+ if axis~="self" then
+ collected=apply_axis[axis](collected)
+ end
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ return pi.finalizer(collected)
+ end
+ if not collected or #collected==0 then
+ local pf=i<nofparsed and parsed[nofparsed].finalizer
+ if pf then
+ return pf(collected)
+ end
+ return nil
+ end
end
+ return collected
+ end
+ local apply=normal_apply
+ if trackers then
+ trackers.register("xml.path,xml.parse,xml.profile",function()
+ if trace_lprofile then
+ apply=profiled_apply
+ elseif trace_lpath then
+ apply=traced_apply
+ else
+ apply=normal_apply
+ end
+ end)
+ end
+ function xml.applylpath(list,pattern)
+ if not list then
+ lastmatch=nil
+ return
+ end
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcalls=lpathcalls+1
+ lpathcached=lpathcached+1
+ elseif type(pattern)=="table" then
+ lpathcalls=lpathcalls+1
+ parsed=pattern
+ else
+ parsed=lpath(pattern) or pattern
+ end
+ if not parsed then
+ lastmatch=nil
+ return
+ end
+ local nofparsed=#parsed
+ if nofparsed==0 then
+ lastmatch=nil
+ return
+ end
+ local collected=apply({ list },parsed,nofparsed,list.mi)
+ lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ function xml.lastmatch()
+ return lastmatch
+ end
+ local stack={}
+ function xml.pushmatch()
+ insert(stack,lastmatch)
+ end
+ function xml.popmatch()
+ lastmatch=remove(stack)
+ end
end
local applylpath=xml.applylpath
function xml.filter(root,pattern)
- return applylpath(root,pattern)
+ return applylpath(root,pattern)
end
expressions.child=function(e,pattern)
- return applylpath(e,pattern)
+ return applylpath(e,pattern)
end
expressions.count=function(e,pattern)
- local collected=applylpath(e,pattern)
- return pattern and (collected and #collected) or 0
+ local collected=applylpath(e,pattern)
+ return pattern and (collected and #collected) or 0
end
expressions.oneof=function(s,...)
- for i=1,select("#",...) do
- if s==select(i,...) then
- return true
- end
+ for i=1,select("#",...) do
+ if s==select(i,...) then
+ return true
end
- return false
+ end
+ return false
end
expressions.error=function(str)
- xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
- return false
+ xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
+ return false
end
expressions.undefined=function(s)
- return s==nil
+ return s==nil
end
expressions.quit=function(s)
- if s or s==nil then
- quit_expression=true
- end
- return true
+ if s or s==nil then
+ quit_expression=true
+ end
+ return true
end
expressions.print=function(...)
- print(...)
- return true
+ print(...)
+ return true
end
expressions.find=find
expressions.upper=upper
@@ -17890,233 +17898,233 @@ expressions.lower=lower
expressions.number=tonumber
expressions.boolean=toboolean
function expressions.contains(str,pattern)
- local t=type(str)
- if t=="string" then
- if find(str,pattern) then
- return true
- end
- elseif t=="table" then
- for i=1,#str do
- local d=str[i]
- if type(d)=="string" and find(d,pattern) then
- return true
- end
- end
+ local t=type(str)
+ if t=="string" then
+ if find(str,pattern) then
+ return true
end
- return false
+ elseif t=="table" then
+ for i=1,#str do
+ local d=str[i]
+ if type(d)=="string" and find(d,pattern) then
+ return true
+ end
+ end
+ end
+ return false
end
function xml.expressions.idstring(str)
- return type(str)=="string" and gsub(str,"^#","") or ""
+ return type(str)=="string" and gsub(str,"^#","") or ""
end
local function traverse(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local r=e.__p__
- handle(r,r.dt,e.ni)
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local r=e.__p__
+ handle(r,r.dt,e.ni)
end
+ end
end
local function selection(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- if handle then
- for c=1,#collected do
- handle(collected[c])
- end
- else
- return collected
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ if handle then
+ for c=1,#collected do
+ handle(collected[c])
+ end
+ else
+ return collected
end
+ end
end
-xml.traverse=traverse
+xml.traverse=traverse
xml.selection=selection
local function dofunction(collected,fnc,...)
- if collected then
- local f=functions[fnc]
- if f then
- for c=1,#collected do
- f(collected[c],...)
- end
- else
- report_lpath("unknown function %a",fnc)
- end
+ if collected then
+ local f=functions[fnc]
+ if f then
+ for c=1,#collected do
+ f(collected[c],...)
+ end
+ else
+ report_lpath("unknown function %a",fnc)
end
+ end
end
finalizers.xml["function"]=dofunction
finalizers.tex["function"]=dofunction
expressions.text=function(e,n)
- local rdt=e.__p__.dt
- return rdt and rdt[n] or ""
+ local rdt=e.__p__.dt
+ return rdt and rdt[n] or ""
end
expressions.name=function(e,n)
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=type(e)=="table" and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=type(e)=="table" and e
+ elseif n<0 then
+ local d,k=e.__p__.dt,e.ni
+ for i=k-1,1,-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
end
+ end
end
- if found then
- local ns,tg=found.rn or found.ns or "",found.tg
- if ns~="" then
- return ns..":"..tg
+ else
+ local d,k=e.__p__.dt,e.ni
+ for i=k+1,#d,1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==1 then
+ found=di
+ break
else
- return tg
+ n=n-1
end
+ end
+ end
+ end
+ if found then
+ local ns,tg=found.rn or found.ns or "",found.tg
+ if ns~="" then
+ return ns..":"..tg
else
- return ""
+ return tg
end
+ else
+ return ""
+ end
end
expressions.tag=function(e,n)
- if not e then
- return ""
+ if not e then
+ return ""
+ else
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=(type(e)=="table") and e
+ elseif n<0 then
+ local d,k=e.__p__.dt,e.ni
+ for i=k-1,1,-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
+ end
+ end
+ end
else
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=(type(e)=="table") and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
- end
+ local d,k=e.__p__.dt,e.ni
+ for i=k+1,#d,1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==1 then
+ found=di
+ break
+ else
+ n=n-1
+ end
end
- return (found and found.tg) or ""
+ end
end
+ return (found and found.tg) or ""
+ end
end
local dummy=function() end
function xml.elements(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
+ end
end
function xml.collected(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ return collected[c]
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- return collected[c]
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- return collected[c]
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ return collected[c]
+ end
end
+ end
end
function xml.inspect(collection,pattern)
- pattern=pattern or "."
- for e in xml.collected(collection,pattern or ".") do
- report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
- end
+ pattern=pattern or "."
+ for e in xml.collected(collection,pattern or ".") do
+ report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
+ end
end
local function split(e)
- local dt=e.dt
- if dt then
- for i=1,#dt do
- local dti=dt[i]
- if type(dti)=="string" then
- dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
- dti=gsub(dti,"[\n\r]+","\n\n")
- dt[i]=dti
- else
- split(dti)
- end
- end
+ local dt=e.dt
+ if dt then
+ for i=1,#dt do
+ local dti=dt[i]
+ if type(dti)=="string" then
+ dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
+ dti=gsub(dti,"[\n\r]+","\n\n")
+ dt[i]=dti
+ else
+ split(dti)
+ end
end
- return e
+ end
+ return e
end
function xml.finalizers.paragraphs(c)
- for i=1,#c do
- split(c[i])
- end
- return c
+ for i=1,#c do
+ split(c[i])
+ end
+ return c
end
@@ -18126,14 +18134,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-mis"] = package.loaded["lxml-mis"] or true
--- original size: 3574, stripped down to: 1863
+-- original size: 3574, stripped down to: 1808
if not modules then modules={} end modules ['lxml-mis']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local xml,lpeg,string=xml,lpeg,string
local type=type
@@ -18144,26 +18152,26 @@ local P,S,R,C,V,Cc,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.Cc,lpeg.Cs
lpegpatterns.xml=lpegpatterns.xml or {}
local xmlpatterns=lpegpatterns.xml
local function xmlgsub(t,old,new)
- local dt=t.dt
- if dt then
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="string" then
- dt[k]=gsub(v,old,new)
- else
- xmlgsub(v,old,new)
- end
- end
+ local dt=t.dt
+ if dt then
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="string" then
+ dt[k]=gsub(v,old,new)
+ else
+ xmlgsub(v,old,new)
+ end
end
+ end
end
function xml.stripleadingspaces(dk,d,k)
- if d and k then
- local dkm=d[k-1]
- if dkm and type(dkm)=="string" then
- local s=match(dkm,"\n(%s+)")
- xmlgsub(dk,"\n"..rep(" ",#s),"\n")
- end
+ if d and k then
+ local dkm=d[k-1]
+ if dkm and type(dkm)=="string" then
+ local s=match(dkm,"\n(%s+)")
+ xmlgsub(dk,"\n"..rep(" ",#s),"\n")
end
+ end
end
local normal=(1-S("<&>"))^0
local special=P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"
@@ -18175,17 +18183,17 @@ local cleansed=Cs(((P("<")*(1-P(">"))^0*P(">"))/""+1)^0)
xmlpatterns.escaped=escaped
xmlpatterns.unescaped=unescaped
xmlpatterns.cleansed=cleansed
-function xml.escaped (str) return lpegmatch(escaped,str) end
+function xml.escaped (str) return lpegmatch(escaped,str) end
function xml.unescaped(str) return lpegmatch(unescaped,str) end
-function xml.cleansed (str) return lpegmatch(cleansed,str) end
+function xml.cleansed (str) return lpegmatch(cleansed,str) end
function xml.fillin(root,pattern,str,check)
- local e=xml.first(root,pattern)
- if e then
- local n=#e.dt
- if not check or n==0 or (n==1 and e.dt[1]=="") then
- e.dt={ str }
- end
+ local e=xml.first(root,pattern)
+ if e then
+ local n=#e.dt
+ if not check or n==0 or (n==1 and e.dt[1]=="") then
+ e.dt={ str }
end
+ end
end
@@ -18195,17 +18203,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-aux"] = package.loaded["lxml-aux"] or true
--- original size: 30650, stripped down to: 21793
+-- original size: 30650, stripped down to: 19621
if not modules then modules={} end modules ['lxml-aux']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
-local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
+local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
+local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
local report_xml=logs.reporter("xml")
local xml=xml
local xmlcopy,xmlname=xml.copy,xml.name
@@ -18218,308 +18226,308 @@ local utfbyte=utf.byte
local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
local striplinepatterns=utilities.strings.striplinepatterns
local function report(what,pattern,c,e)
- report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
+ report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
end
local function withelements(e,handle,depth)
- if e and handle then
- local edt=e.dt
- if edt then
- depth=depth or 0
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- handle(e,depth)
- withelements(e,handle,depth+1)
- end
- end
+ if e and handle then
+ local edt=e.dt
+ if edt then
+ depth=depth or 0
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ handle(e,depth)
+ withelements(e,handle,depth+1)
end
+ end
end
+ end
end
xml.withelements=withelements
function xml.withelement(e,n,handle)
- if e and n~=0 and handle then
- local edt=e.dt
- if edt then
- if n>0 then
- for i=1,#edt do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==1 then
- handle(ei)
- return
- else
- n=n-1
- end
- end
- end
- elseif n<0 then
- for i=#edt,1,-1 do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==-1 then
- handle(ei)
- return
- else
- n=n+1
- end
- end
- end
+ if e and n~=0 and handle then
+ local edt=e.dt
+ if edt then
+ if n>0 then
+ for i=1,#edt do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==1 then
+ handle(ei)
+ return
+ else
+ n=n-1
end
+ end
end
- end
-end
-function xml.each(root,pattern,handle,reverse)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- if handle then
- if reverse then
- for c=#collected,1,-1 do
- handle(collected[c])
- end
+ elseif n<0 then
+ for i=#edt,1,-1 do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==-1 then
+ handle(ei)
+ return
else
- for c=1,#collected do
- handle(collected[c])
- end
+ n=n+1
end
+ end
end
- return collected
+ end
end
+ end
end
-function xml.processattributes(root,pattern,handle)
- local collected=xmlapplylpath(root,pattern)
- if collected and handle then
+function xml.each(root,pattern,handle,reverse)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ if handle then
+ if reverse then
+ for c=#collected,1,-1 do
+ handle(collected[c])
+ end
+ else
for c=1,#collected do
- handle(collected[c].at)
+ handle(collected[c])
end
+ end
end
return collected
+ end
+end
+function xml.processattributes(root,pattern,handle)
+ local collected=xmlapplylpath(root,pattern)
+ if collected and handle then
+ for c=1,#collected do
+ handle(collected[c].at)
+ end
+ end
+ return collected
end
function xml.collect(root,pattern)
- return xmlapplylpath(root,pattern)
+ return xmlapplylpath(root,pattern)
end
function xml.collecttexts(root,pattern,flatten)
- local collected=xmlapplylpath(root,pattern)
- if collected and flatten then
- local xmltostring=xml.tostring
- for c=1,#collected do
- collected[c]=xmltostring(collected[c].dt)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected and flatten then
+ local xmltostring=xml.tostring
+ for c=1,#collected do
+ collected[c]=xmltostring(collected[c].dt)
end
- return collected or {}
+ end
+ return collected or {}
end
function xml.collect_tags(root,pattern,nonamespace)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- local t,n={},0
- for c=1,#collected do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace then
- t[n]=tg
- elseif ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
- end
- return t
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ local t,n={},0
+ for c=1,#collected do
+ local e=collected[c]
+ local ns,tg=e.ns,e.tg
+ n=n+1
+ if nonamespace then
+ t[n]=tg
+ elseif ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
+ end
end
+ return t
+ end
end
local no_root={ no_root=true }
local function redo_ni(d)
- for k=1,#d do
- local dk=d[k]
- if type(dk)=="table" then
- dk.ni=k
- end
+ for k=1,#d do
+ local dk=d[k]
+ if type(dk)=="table" then
+ dk.ni=k
end
+ end
end
xml.reindex=redo_ni
local function xmltoelement(whatever,root)
- if not whatever then
- return nil
- end
- local element
- if type(whatever)=="string" then
- element=xmlinheritedconvert(whatever,root)
- else
- element=whatever
- end
- if element.error then
- return whatever
- end
- if element then
- end
- return element
+ if not whatever then
+ return nil
+ end
+ local element
+ if type(whatever)=="string" then
+ element=xmlinheritedconvert(whatever,root)
+ else
+ element=whatever
+ end
+ if element.error then
+ return whatever
+ end
+ if element then
+ end
+ return element
end
xml.toelement=xmltoelement
local function copiedelement(element,newparent)
- if type(element)=="string" then
- return element
- else
- element=xmlcopy(element).dt
- if newparent and type(element)=="table" then
- element.__p__=newparent
- end
- return element
+ if type(element)=="string" then
+ return element
+ else
+ element=xmlcopy(element).dt
+ if newparent and type(element)=="table" then
+ element.__p__=newparent
end
+ return element
+ end
end
function xml.delete(root,pattern)
- if not pattern or pattern=="" then
- local p=root.__p__
+ if not pattern or pattern=="" then
+ local p=root.__p__
+ if p then
+ if trace_manipulations then
+ report('deleting',"--",c,root)
+ end
+ local d=p.dt
+ remove(d,root.ni)
+ redo_ni(d)
+ end
+ else
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
if p then
- if trace_manipulations then
- report('deleting',"--",c,root)
- end
- local d=p.dt
- remove(d,root.ni)
- redo_ni(d)
- end
- else
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('deleting',pattern,c,e)
- end
- local d=p.dt
- local ni=e.ni
- if ni<=#d then
- if false then
- p.dt[ni]=""
- else
- remove(d,ni)
- redo_ni(d)
- end
- else
- end
- end
+ if trace_manipulations then
+ report('deleting',pattern,c,e)
+ end
+ local d=p.dt
+ local ni=e.ni
+ if ni<=#d then
+ if false then
+ p.dt[ni]=""
+ else
+ remove(d,ni)
+ redo_ni(d)
end
+ else
+ end
end
+ end
end
+ end
end
function xml.replace(root,pattern,whatever)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('replacing',pattern,c,e)
- end
- local d=p.dt
- local n=e.ni
- local t=copiedelement(element,p)
- if type(t)=="table" then
- d[n]=t[1]
- for i=2,#t do
- n=n+1
- insert(d,n,t[i])
- end
- else
- d[n]=t
- end
- redo_ni(d)
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
+ if p then
+ if trace_manipulations then
+ report('replacing',pattern,c,e)
end
+ local d=p.dt
+ local n=e.ni
+ local t=copiedelement(element,p)
+ if type(t)=="table" then
+ d[n]=t[1]
+ for i=2,#t do
+ n=n+1
+ insert(d,n,t[i])
+ end
+ else
+ d[n]=t
+ end
+ redo_ni(d)
+ end
end
+ end
end
local function wrap(e,wrapper)
- local t={
- rn=e.rn,
- tg=e.tg,
- ns=e.ns,
- at=e.at,
- dt=e.dt,
- __p__=e,
- }
- setmetatable(t,getmetatable(e))
- e.rn=wrapper.rn or e.rn or ""
- e.tg=wrapper.tg or e.tg or ""
- e.ns=wrapper.ns or e.ns or ""
- e.at=fastcopy(wrapper.at)
- e.dt={ t }
+ local t={
+ rn=e.rn,
+ tg=e.tg,
+ ns=e.ns,
+ at=e.at,
+ dt=e.dt,
+ __p__=e,
+ }
+ setmetatable(t,getmetatable(e))
+ e.rn=wrapper.rn or e.rn or ""
+ e.tg=wrapper.tg or e.tg or ""
+ e.ns=wrapper.ns or e.ns or ""
+ e.at=fastcopy(wrapper.at)
+ e.dt={ t }
end
function xml.wrap(root,pattern,whatever)
- if whatever then
- local wrapper=xmltoelement(whatever,root)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if trace_manipulations then
- report('wrapping',pattern,c,e)
- end
- wrap(e,wrapper)
- end
+ if whatever then
+ local wrapper=xmltoelement(whatever,root)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if trace_manipulations then
+ report('wrapping',pattern,c,e)
end
- else
- wrap(root,xmltoelement(pattern))
+ wrap(e,wrapper)
+ end
end
+ else
+ wrap(root,xmltoelement(pattern))
+ end
end
local function inject_element(root,pattern,whatever,prepend)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function inject_e(e)
- local r=e.__p__
- local d,k,rri=r.dt,e.ni,r.ri
- local edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
- if edt then
- local be,af
- local cp=copiedelement(element,e)
- if prepend then
- be,af=cp,edt
- else
- be,af=edt,cp
- end
- local bn=#be
- for i=1,#af do
- bn=bn+1
- be[bn]=af[i]
- end
- if rri then
- r.dt[rri].dt=be
- else
- d[k].dt=be
- end
- redo_ni(d)
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ local function inject_e(e)
+ local r=e.__p__
+ local d,k,rri=r.dt,e.ni,r.ri
+ local edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
+ if edt then
+ local be,af
+ local cp=copiedelement(element,e)
+ if prepend then
+ be,af=cp,edt
+ else
+ be,af=edt,cp
+ end
+ local bn=#be
+ for i=1,#af do
+ bn=bn+1
+ be[bn]=af[i]
+ end
+ if rri then
+ r.dt[rri].dt=be
+ else
+ d[k].dt=be
+ end
+ redo_ni(d)
end
- if not collected then
- elseif collected.tg then
- inject_e(collected)
- else
- for c=1,#collected do
- inject_e(collected[c])
- end
+ end
+ if not collected then
+ elseif collected.tg then
+ inject_e(collected)
+ else
+ for c=1,#collected do
+ inject_e(collected[c])
end
+ end
end
local function insert_element(root,pattern,whatever,before)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function insert_e(e)
- local r=e.__p__
- local d,k=r.dt,e.ni
- if not before then
- k=k+1
- end
- insert(d,k,copiedelement(element,r))
- redo_ni(d)
- end
- if not collected then
- elseif collected.tg then
- insert_e(collected)
- else
- for c=1,#collected do
- insert_e(collected[c])
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ local function insert_e(e)
+ local r=e.__p__
+ local d,k=r.dt,e.ni
+ if not before then
+ k=k+1
+ end
+ insert(d,k,copiedelement(element,r))
+ redo_ni(d)
+ end
+ if not collected then
+ elseif collected.tg then
+ insert_e(collected)
+ else
+ for c=1,#collected do
+ insert_e(collected[c])
end
+ end
end
xml.insert_element=insert_element
xml.insertafter=insert_element
@@ -18527,124 +18535,124 @@ xml.insertbefore=function(r,p,e) insert_element(r,p,e,true) end
xml.injectafter=inject_element
xml.injectbefore=function(r,p,e) inject_element(r,p,e,true) end
local function include(xmldata,pattern,attribute,recursive,loaddata,level)
- pattern=pattern or 'include'
- loaddata=loaddata or io.loaddata
- local collected=xmlapplylpath(xmldata,pattern)
- if collected then
- if not level then
- level=1
- end
- for c=1,#collected do
- local ek=collected[c]
- local name=nil
- local ekdt=ek.dt
- if ekdt then
- local ekat=ek.at
- local ekrt=ek.__p__
- if ekrt then
- local epdt=ekrt.dt
- if not attribute or attribute=="" then
- name=(type(ekdt)=="table" and ekdt[1]) or ekdt
- end
- if not name then
- for a in gmatch(attribute or "href","([^|]+)") do
- name=ekat[a]
- if name then
- break
- end
- end
- end
- local data=nil
- if name and name~="" then
- local d,n=loaddata(name)
- data=d or ""
- name=n or name
- if trace_inclusions then
- report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
- end
- end
- if not data or data=="" then
- epdt[ek.ni]=""
- elseif ekat["parse"]=="text" then
- epdt[ek.ni]=xml.escaped(data)
- else
+ pattern=pattern or 'include'
+ loaddata=loaddata or io.loaddata
+ local collected=xmlapplylpath(xmldata,pattern)
+ if collected then
+ if not level then
+ level=1
+ end
+ for c=1,#collected do
+ local ek=collected[c]
+ local name=nil
+ local ekdt=ek.dt
+ if ekdt then
+ local ekat=ek.at
+ local ekrt=ek.__p__
+ if ekrt then
+ local epdt=ekrt.dt
+ if not attribute or attribute=="" then
+ name=(type(ekdt)=="table" and ekdt[1]) or ekdt
+ end
+ if not name then
+ for a in gmatch(attribute or "href","([^|]+)") do
+ name=ekat[a]
+ if name then
+ break
+ end
+ end
+ end
+ local data=nil
+ if name and name~="" then
+ local d,n=loaddata(name)
+ data=d or ""
+ name=n or name
+ if trace_inclusions then
+ report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
+ end
+ end
+ if not data or data=="" then
+ epdt[ek.ni]=""
+ elseif ekat["parse"]=="text" then
+ epdt[ek.ni]=xml.escaped(data)
+ else
local settings=xmldata.settings
local savedresource=settings.currentresource
settings.currentresource=name
- local xi=xmlinheritedconvert(data,xmldata)
- if not xi then
- epdt[ek.ni]=""
- else
- if recursive then
- include(xi,pattern,attribute,recursive,loaddata,level+1)
- end
- local child=xml.body(xi)
- child.__p__=ekrt
- child.__f__=name
+ local xi=xmlinheritedconvert(data,xmldata)
+ if not xi then
+ epdt[ek.ni]=""
+ else
+ if recursive then
+ include(xi,pattern,attribute,recursive,loaddata,level+1)
+ end
+ local child=xml.body(xi)
+ child.__p__=ekrt
+ child.__f__=name
child.cf=name
- epdt[ek.ni]=child
- local settings=xmldata.settings
- local inclusions=settings and settings.inclusions
- if inclusions then
- inclusions[#inclusions+1]=name
- elseif settings then
- settings.inclusions={ name }
- else
- settings={ inclusions={ name } }
- xmldata.settings=settings
- end
- if child.er then
- local badinclusions=settings.badinclusions
- if badinclusions then
- badinclusions[#badinclusions+1]=name
- else
- settings.badinclusions={ name }
- end
- end
- end
-settings.currentresource=savedresource
- end
+ epdt[ek.ni]=child
+ local settings=xmldata.settings
+ local inclusions=settings and settings.inclusions
+ if inclusions then
+ inclusions[#inclusions+1]=name
+ elseif settings then
+ settings.inclusions={ name }
+ else
+ settings={ inclusions={ name } }
+ xmldata.settings=settings
+ end
+ if child.er then
+ local badinclusions=settings.badinclusions
+ if badinclusions then
+ badinclusions[#badinclusions+1]=name
+ else
+ settings.badinclusions={ name }
end
+ end
end
+settings.currentresource=savedresource
+ end
end
+ end
end
+ end
end
xml.include=include
function xml.inclusion(e,default)
- while e do
- local f=e.__f__
- if f then
- return f
- else
- e=e.__p__
- end
+ while e do
+ local f=e.__f__
+ if f then
+ return f
+ else
+ e=e.__p__
end
- return default
+ end
+ return default
end
local function getinclusions(key,e,sorted)
- while e do
- local settings=e.settings
- if settings then
- local inclusions=settings[key]
- if inclusions then
- inclusions=table.unique(inclusions)
- if sorted then
- table.sort(inclusions)
- end
- return inclusions
- else
- e=e.__p__
- end
- else
- e=e.__p__
- end
+ while e do
+ local settings=e.settings
+ if settings then
+ local inclusions=settings[key]
+ if inclusions then
+ inclusions=table.unique(inclusions)
+ if sorted then
+ table.sort(inclusions)
+ end
+ return inclusions
+ else
+ e=e.__p__
+ end
+ else
+ e=e.__p__
end
+ end
end
function xml.inclusions(e,sorted)
- return getinclusions("inclusions",e,sorted)
+ return getinclusions("inclusions",e,sorted)
end
function xml.badinclusions(e,sorted)
- return getinclusions("badinclusions",e,sorted)
+ return getinclusions("badinclusions",e,sorted)
end
local b_collapser=lpegpatterns.b_collapser
local m_collapser=lpegpatterns.m_collapser
@@ -18653,194 +18661,194 @@ local b_stripper=lpegpatterns.b_stripper
local m_stripper=lpegpatterns.m_stripper
local e_stripper=lpegpatterns.e_stripper
local function stripelement(e,nolines,anywhere)
- local edt=e.dt
- if edt then
- local n=#edt
- if n==0 then
- return e
- elseif anywhere then
- local t={}
- local m=0
- for e=1,n do
- local str=edt[e]
- if type(str)~="string" then
- m=m+1
- t[m]=str
- elseif str~="" then
- if nolines then
- str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
- else
- str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
- end
- if str~="" then
- m=m+1
- t[m]=str
- end
- end
- end
- e.dt=t
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==0 then
+ return e
+ elseif anywhere then
+ local t={}
+ local m=0
+ for e=1,n do
+ local str=edt[e]
+ if type(str)~="string" then
+ m=m+1
+ t[m]=str
+ elseif str~="" then
+ if nolines then
+ str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
+ else
+ str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
+ end
+ if str~="" then
+ m=m+1
+ t[m]=str
+ end
+ end
+ end
+ e.dt=t
+ else
+ local str=edt[1]
+ if type(str)=="string" then
+ if str~="" then
+ str=lpegmatch(nolines and b_collapser or b_stripper,str)
+ end
+ if str=="" then
+ remove(edt,1)
+ n=n-1
else
- local str=edt[1]
- if type(str)=="string" then
- if str~="" then
- str=lpegmatch(nolines and b_collapser or b_stripper,str)
- end
- if str=="" then
- remove(edt,1)
- n=n-1
- else
- edt[1]=str
- end
- end
- if n>0 then
- str=edt[n]
- if type(str)=="string" then
- if str=="" then
- remove(edt)
- else
- str=lpegmatch(nolines and e_collapser or e_stripper,str)
- if str=="" then
- remove(edt)
- else
- edt[n]=str
- end
- end
- end
+ edt[1]=str
+ end
+ end
+ if n>0 then
+ str=edt[n]
+ if type(str)=="string" then
+ if str=="" then
+ remove(edt)
+ else
+ str=lpegmatch(nolines and e_collapser or e_stripper,str)
+ if str=="" then
+ remove(edt)
+ else
+ edt[n]=str
end
+ end
end
+ end
end
- return e
+ end
+ return e
end
xml.stripelement=stripelement
function xml.strip(root,pattern,nolines,anywhere)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for i=1,#collected do
- stripelement(collected[i],nolines,anywhere)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for i=1,#collected do
+ stripelement(collected[i],nolines,anywhere)
end
+ end
end
local function renamespace(root,oldspace,newspace)
- local ndt=#root.dt
- for i=1,ndt or 0 do
- local e=root[i]
- if type(e)=="table" then
- if e.ns==oldspace then
- e.ns=newspace
- if e.rn then
- e.rn=newspace
- end
- end
- local edt=e.dt
- if edt then
- renamespace(edt,oldspace,newspace)
- end
+ local ndt=#root.dt
+ for i=1,ndt or 0 do
+ local e=root[i]
+ if type(e)=="table" then
+ if e.ns==oldspace then
+ e.ns=newspace
+ if e.rn then
+ e.rn=newspace
end
+ end
+ local edt=e.dt
+ if edt then
+ renamespace(edt,oldspace,newspace)
+ end
end
+ end
end
xml.renamespace=renamespace
function xml.remaptag(root,pattern,newtg)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].tg=newtg
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].tg=newtg
end
+ end
end
function xml.remapnamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].ns=newns
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].ns=newns
end
+ end
end
function xml.checknamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if (not e.rn or e.rn=="") and e.ns=="" then
- e.rn=newns
- end
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if (not e.rn or e.rn=="") and e.ns=="" then
+ e.rn=newns
+ end
end
+ end
end
function xml.remapname(root,pattern,newtg,newns,newrn)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- e.tg,e.ns,e.rn=newtg,newns,newrn
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ e.tg,e.ns,e.rn=newtg,newns,newrn
end
+ end
end
function xml.cdatatotext(e)
- local dt=e.dt
- if #dt==1 then
- local first=dt[1]
- if first.tg=="@cd@" then
- e.dt=first.dt
- end
- else
+ local dt=e.dt
+ if #dt==1 then
+ local first=dt[1]
+ if first.tg=="@cd@" then
+ e.dt=first.dt
end
+ else
+ end
end
function xml.texttocdata(e)
- local dt=e.dt
- local s=xml.tostring(dt)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(dt)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
function xml.elementtocdata(e)
- local dt=e.dt
- local s=xml.tostring(e)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(e)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
xml.builtinentities=table.tohash { "amp","quot","apos","lt","gt" }
local entities=characters and characters.entities or nil
local builtinentities=xml.builtinentities
function xml.addentitiesdoctype(root,option)
- if not entities then
- require("char-ent")
- entities=characters.entities
- end
- if entities and root and root.tg=="@rt@" and root.statistics then
- local list={}
- local hexify=option=="hexadecimal"
- for k,v in table.sortedhash(root.statistics.entities.names) do
- if not builtinentities[k] then
- local e=entities[k]
- if not e then
- e=format("[%s]",k)
- elseif hexify then
- e=format("&#%05X;",utfbyte(k))
- end
- list[#list+1]=format(" <!ENTITY %s %q >",k,e)
- end
- end
- local dt=root.dt
- local n=dt[1].tg=="@pi@" and 2 or 1
- if #list>0 then
- insert(dt,n,{ "\n" })
- insert(dt,n,{
- tg="@dt@",
- dt={ format("Something [\n%s\n] ",concat(list)) },
- ns="",
- special=true,
- })
- insert(dt,n,{ "\n\n" })
- else
- end
+ if not entities then
+ require("char-ent")
+ entities=characters.entities
+ end
+ if entities and root and root.tg=="@rt@" and root.statistics then
+ local list={}
+ local hexify=option=="hexadecimal"
+ for k,v in table.sortedhash(root.statistics.entities.names) do
+ if not builtinentities[k] then
+ local e=entities[k]
+ if not e then
+ e=format("[%s]",k)
+ elseif hexify then
+ e=format("&#%05X;",utfbyte(k))
+ end
+ list[#list+1]=format(" <!ENTITY %s %q >",k,e)
+ end
end
+ local dt=root.dt
+ local n=dt[1].tg=="@pi@" and 2 or 1
+ if #list>0 then
+ insert(dt,n,{ "\n" })
+ insert(dt,n,{
+ tg="@dt@",
+ dt={ format("Something [\n%s\n] ",concat(list)) },
+ ns="",
+ special=true,
+ })
+ insert(dt,n,{ "\n\n" })
+ else
+ end
+ end
end
xml.all=xml.each
xml.insert=xml.insertafter
@@ -18850,239 +18858,239 @@ xml.before=xml.insertbefore
xml.process=xml.each
xml.obsolete=xml.obsolete or {}
local obsolete=xml.obsolete
-xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
-xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
-xml.delete_element=xml.delete obsolete.delete_element=xml.delete
-xml.replace_element=xml.replace obsolete.replace_element=xml.replace
-xml.each_element=xml.each obsolete.each_element=xml.each
-xml.process_elements=xml.process obsolete.process_elements=xml.process
-xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
-xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
-xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
-xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
-xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
-xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
-xml.inject_element=xml.inject obsolete.inject_element=xml.inject
-xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
-xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
-xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
+xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
+xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
+xml.delete_element=xml.delete obsolete.delete_element=xml.delete
+xml.replace_element=xml.replace obsolete.replace_element=xml.replace
+xml.each_element=xml.each obsolete.each_element=xml.each
+xml.process_elements=xml.process obsolete.process_elements=xml.process
+xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
+xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
+xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
+xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
+xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
+xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
+xml.inject_element=xml.inject obsolete.inject_element=xml.inject
+xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
+xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
+xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
function xml.cdata(e)
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
end
- return ""
+ end
+ return ""
end
function xml.finalizers.xml.cdata(collected)
- if collected then
- local e=collected[1]
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
- end
+ if collected then
+ local e=collected[1]
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
+ end
end
- return ""
+ end
+ return ""
end
function xml.insertcomment(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.insertcdata(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.setcomment(e,str,n)
- e.dt={ {
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.setcdata(e,str)
- e.dt={ {
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.separate(x,pattern)
- local collected=xmlapplylpath(x,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local d=e.dt
- if d==x then
- report_xml("warning: xml.separate changes root")
- x=d
- end
- local t,n={ "\n" },1
- local i,nd=1,#d
- while i<=nd do
- while i<=nd do
- local di=d[i]
- if type(di)=="string" then
- if di=="\n" or find(di,"^%s+$") then
- i=i+1
- else
- d[i]=strip(di)
- break
- end
- else
- break
- end
- end
- if i>nd then
- break
- end
- t[n+1]="\n"
- t[n+2]=d[i]
- t[n+3]="\n"
- n=n+3
- i=i+1
+ local collected=xmlapplylpath(x,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local d=e.dt
+ if d==x then
+ report_xml("warning: xml.separate changes root")
+ x=d
+ end
+ local t,n={ "\n" },1
+ local i,nd=1,#d
+ while i<=nd do
+ while i<=nd do
+ local di=d[i]
+ if type(di)=="string" then
+ if di=="\n" or find(di,"^%s+$") then
+ i=i+1
+ else
+ d[i]=strip(di)
+ break
end
- t[n+1]="\n"
- setmetatable(t,getmetatable(d))
- e.dt=t
+ else
+ break
+ end
end
+ if i>nd then
+ break
+ end
+ t[n+1]="\n"
+ t[n+2]=d[i]
+ t[n+3]="\n"
+ n=n+3
+ i=i+1
+ end
+ t[n+1]="\n"
+ setmetatable(t,getmetatable(d))
+ e.dt=t
end
- return x
+ end
+ return x
end
local helpers=xml.helpers or {}
xml.helpers=helpers
local function normal(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)=="string" and str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)=="string" and str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
local function recurse(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)~="string" then
- recurse(str,action)
- elseif str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)~="string" then
+ recurse(str,action)
+ elseif str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
function helpers.recursetext(collected,action,recursive)
- if recursive then
- for i=1,#collected do
- recurse(collected[i],action)
- end
- else
- for i=1,#collected do
- normal(collected[i],action)
- end
+ if recursive then
+ for i=1,#collected do
+ recurse(collected[i],action)
+ end
+ else
+ for i=1,#collected do
+ normal(collected[i],action)
end
+ end
end
local specials={
- ["@rt@"]="root",
- ["@pi@"]="instruction",
- ["@cm@"]="comment",
- ["@dt@"]="declaration",
- ["@cd@"]="cdata",
+ ["@rt@"]="root",
+ ["@pi@"]="instruction",
+ ["@cm@"]="comment",
+ ["@dt@"]="declaration",
+ ["@cd@"]="cdata",
}
local function convert(x,strip,flat)
- local ns=x.ns
- local tg=x.tg
- local at=x.at
- local dt=x.dt
- local node=flat and {
- [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
- } or {
- _namespace=ns~="" and ns or nil,
- _tag=not x.special and tg or nil,
- _type=specials[tg] or "_element",
- }
- if at then
- for k,v in next,at do
- node[k]=v
+ local ns=x.ns
+ local tg=x.tg
+ local at=x.at
+ local dt=x.dt
+ local node=flat and {
+ [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
+ } or {
+ _namespace=ns~="" and ns or nil,
+ _tag=not x.special and tg or nil,
+ _type=specials[tg] or "_element",
+ }
+ if at then
+ for k,v in next,at do
+ node[k]=v
+ end
+ end
+ local n=0
+ for i=1,#dt do
+ local di=dt[i]
+ if type(di)=="table" then
+ if flat and di.special then
+ else
+ di=convert(di,strip,flat)
+ if di then
+ n=n+1
+ node[n]=di
end
+ end
+ elseif strip then
+ di=lpegmatch(strip,di)
+ if di~="" then
+ n=n+1
+ node[n]=di
+ end
+ else
+ n=n+1
+ node[n]=di
end
- local n=0
- for i=1,#dt do
- local di=dt[i]
- if type(di)=="table" then
- if flat and di.special then
- else
- di=convert(di,strip,flat)
- if di then
- n=n+1
- node[n]=di
- end
- end
- elseif strip then
- di=lpegmatch(strip,di)
- if di~="" then
- n=n+1
- node[n]=di
- end
- else
- n=n+1
- node[n]=di
- end
- end
- if next(node) then
- return node
- end
+ end
+ if next(node) then
+ return node
+ end
end
function xml.totable(x,strip,flat)
- if type(x)=="table" then
- if strip then
- strip=striplinepatterns[strip]
- end
- return convert(x,strip,flat)
+ if type(x)=="table" then
+ if strip then
+ strip=striplinepatterns[strip]
end
+ return convert(x,strip,flat)
+ end
end
function xml.rename(e,namespace,name,attributes)
- if type(e)~="table" or not e.tg then
- return
- end
- if type(name)=="table" then
- attributes=name
- name=namespace
- namespace=""
- elseif type(name)~="string" then
- attributes={}
- name=namespace
- namespace=""
- end
- if type(attributes)~="table" then
- attributes={}
- end
- e.ns=namespace
- e.rn=namespace
- e.tg=name
- e.at=attributes
+ if type(e)~="table" or not e.tg then
+ return
+ end
+ if type(name)=="table" then
+ attributes=name
+ name=namespace
+ namespace=""
+ elseif type(name)~="string" then
+ attributes={}
+ name=namespace
+ namespace=""
+ end
+ if type(attributes)~="table" then
+ attributes={}
+ end
+ e.ns=namespace
+ e.rn=namespace
+ e.tg=name
+ e.at=attributes
end
@@ -19092,14 +19100,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
--- original size: 11096, stripped down to: 8243
+-- original size: 11096, stripped down to: 7702
if not modules then modules={} end modules ['lxml-xml']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber,next=tonumber,next
local concat=table.concat
@@ -19111,241 +19119,241 @@ local xmltostring=xml.tostring
local xmlserialize=xml.serialize
local xmlcollected=xml.collected
local xmlnewhandlers=xml.newhandlers
-local reparsedentity=xml.reparsedentitylpeg
+local reparsedentity=xml.reparsedentitylpeg
local unescapedentity=xml.unescapedentitylpeg
local parsedentity=reparsedentity
local function first(collected)
- return collected and collected[1]
+ return collected and collected[1]
end
local function last(collected)
- return collected and collected[#collected]
+ return collected and collected[#collected]
end
local function all(collected)
- return collected
+ return collected
end
local reverse=table.reversed
local function attribute(collected,name)
- if collected and #collected>0 then
- local at=collected[1].at
- return at and at[name]
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ return at and at[name]
+ end
end
local function att(id,name)
- local at=id.at
- return at and at[name]
+ local at=id.at
+ return at and at[name]
end
local function count(collected)
- return collected and #collected or 0
+ return collected and #collected or 0
end
local function position(collected,n)
- if not collected then
- return 0
- end
- local nc=#collected
- if nc==0 then
- return 0
- end
- n=tonumber(n) or 0
- if n<0 then
- return collected[nc+n+1]
- elseif n>0 then
- return collected[n]
- else
- return collected[1].mi or 0
- end
+ if not collected then
+ return 0
+ end
+ local nc=#collected
+ if nc==0 then
+ return 0
+ end
+ n=tonumber(n) or 0
+ if n<0 then
+ return collected[nc+n+1]
+ elseif n>0 then
+ return collected[n]
+ else
+ return collected[1].mi or 0
+ end
end
local function match(collected)
- return collected and #collected>0 and collected[1].mi or 0
+ return collected and #collected>0 and collected[1].mi or 0
end
local function index(collected)
- return collected and #collected>0 and collected[1].ni or 0
+ return collected and #collected>0 and collected[1].ni or 0
end
local function attributes(collected,arguments)
- if collected and #collected>0 then
- local at=collected[1].at
- if arguments then
- return at[arguments]
- elseif next(at) then
- return at
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ if arguments then
+ return at[arguments]
+ elseif next(at) then
+ return at
end
+ end
end
local function chainattribute(collected,arguments)
- if collected and #collected>0 then
- local e=collected[1]
- while e do
- local at=e.at
- if at then
- local a=at[arguments]
- if a then
- return a
- end
- else
- break
- end
- e=e.__p__
+ if collected and #collected>0 then
+ local e=collected[1]
+ while e do
+ local at=e.at
+ if at then
+ local a=at[arguments]
+ if a then
+ return a
end
+ else
+ break
+ end
+ e=e.__p__
end
- return ""
+ end
+ return ""
end
local function raw(collected)
- if collected and #collected>0 then
- local e=collected[1] or collected
- return e and xmltostring(e) or ""
- else
- return ""
- end
+ if collected and #collected>0 then
+ local e=collected[1] or collected
+ return e and xmltostring(e) or ""
+ else
+ return ""
+ end
end
local xmltexthandler=xmlnewhandlers {
- name="string",
- initialize=function()
- result={}
- return result
- end,
- finalize=function()
- return concat(result)
- end,
- handle=function(...)
- result[#result+1]=concat {... }
- end,
- escape=false,
+ name="string",
+ initialize=function()
+ result={}
+ return result
+ end,
+ finalize=function()
+ return concat(result)
+ end,
+ handle=function(...)
+ result[#result+1]=concat {... }
+ end,
+ escape=false,
}
local function xmltotext(root)
- local dt=root.dt
- if not dt then
- return ""
- end
- local nt=#dt
- if nt==0 then
- return ""
- elseif nt==1 and type(dt[1])=="string" then
- return dt[1]
- else
- return xmlserialize(root,xmltexthandler) or ""
- end
+ local dt=root.dt
+ if not dt then
+ return ""
+ end
+ local nt=#dt
+ if nt==0 then
+ return ""
+ elseif nt==1 and type(dt[1])=="string" then
+ return dt[1]
+ else
+ return xmlserialize(root,xmltexthandler) or ""
+ end
end
function xml.serializetotext(root)
- return root and xmlserialize(root,xmltexthandler) or ""
+ return root and xmlserialize(root,xmltexthandler) or ""
end
local function text(collected)
- if collected then
- local e=collected[1] or collected
- return e and xmltotext(e) or ""
- else
- return ""
- end
+ if collected then
+ local e=collected[1] or collected
+ return e and xmltotext(e) or ""
+ else
+ return ""
+ end
end
local function texts(collected)
- if not collected then
- return {}
- end
- local nc=#collected
- if nc==0 then
- return {}
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- if e and e.dt then
- n=n+1
- t[n]=e.dt
- end
- end
- return t
+ if not collected then
+ return {}
+ end
+ local nc=#collected
+ if nc==0 then
+ return {}
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ if e and e.dt then
+ n=n+1
+ t[n]=e.dt
+ end
+ end
+ return t
end
local function tag(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- return c and c.tg
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ return c and c.tg
end
local function name(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- if not c then
- elseif c.ns=="" then
- return c.tg
- else
- return c.ns..":"..c.tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ if not c then
+ elseif c.ns=="" then
+ return c.tg
+ else
+ return c.ns..":"..c.tg
+ end
end
local function tags(collected,nonamespace)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace or ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ local ns,tg=e.ns,e.tg
+ n=n+1
+ if nonamespace or ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
end
- return t
+ end
+ return t
end
local function empty(collected,spacesonly)
- if not collected then
- return true
- end
- local nc=#collected
- if nc==0 then
- return true
- end
- for c=1,nc do
- local e=collected[c]
- if e then
- local edt=e.dt
- if edt then
- local n=#edt
- if n==1 then
- local edk=edt[1]
- local typ=type(edk)
- if typ=="table" then
- return false
- elseif edk~="" then
- return false
- elseif spacesonly and not find(edk,"%S") then
- return false
- end
- elseif n>1 then
- return false
- end
- end
+ if not collected then
+ return true
+ end
+ local nc=#collected
+ if nc==0 then
+ return true
+ end
+ for c=1,nc do
+ local e=collected[c]
+ if e then
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==1 then
+ local edk=edt[1]
+ local typ=type(edk)
+ if typ=="table" then
+ return false
+ elseif edk~="" then
+ return false
+ elseif spacesonly and not find(edk,"%S") then
+ return false
+ end
+ elseif n>1 then
+ return false
end
+ end
end
- return true
+ end
+ return true
end
finalizers.first=first
finalizers.last=last
@@ -19368,124 +19376,124 @@ finalizers.name=name
finalizers.tags=tags
finalizers.empty=empty
function xml.first(id,pattern)
- return first(xmlfilter(id,pattern))
+ return first(xmlfilter(id,pattern))
end
function xml.last(id,pattern)
- return last(xmlfilter(id,pattern))
+ return last(xmlfilter(id,pattern))
end
function xml.count(id,pattern)
- return count(xmlfilter(id,pattern))
+ return count(xmlfilter(id,pattern))
end
function xml.attribute(id,pattern,a,default)
- return attribute(xmlfilter(id,pattern),a,default)
+ return attribute(xmlfilter(id,pattern),a,default)
end
function xml.raw(id,pattern)
- if pattern then
- return raw(xmlfilter(id,pattern))
- else
- return raw(id)
- end
+ if pattern then
+ return raw(xmlfilter(id,pattern))
+ else
+ return raw(id)
+ end
end
function xml.text(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- return collected and #collected>0 and xmltotext(collected[1]) or ""
- elseif id then
- return xmltotext(id) or ""
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ return collected and #collected>0 and xmltotext(collected[1]) or ""
+ elseif id then
+ return xmltotext(id) or ""
+ else
+ return ""
+ end
end
function xml.pure(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- if collected and #collected>0 then
- parsedentity=unescapedentity
- local s=collected and #collected>0 and xmltotext(collected[1]) or ""
- parsedentity=reparsedentity
- return s
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ if collected and #collected>0 then
+ parsedentity=unescapedentity
+ local s=collected and #collected>0 and xmltotext(collected[1]) or ""
+ parsedentity=reparsedentity
+ return s
else
- parsedentity=unescapedentity
- local s=xmltotext(id) or ""
- parsedentity=reparsedentity
- return s
+ return ""
end
+ else
+ parsedentity=unescapedentity
+ local s=xmltotext(id) or ""
+ parsedentity=reparsedentity
+ return s
+ end
end
xml.content=text
function xml.position(id,pattern,n)
- return position(xmlfilter(id,pattern),n)
+ return position(xmlfilter(id,pattern),n)
end
function xml.match(id,pattern)
- return match(xmlfilter(id,pattern))
+ return match(xmlfilter(id,pattern))
end
function xml.empty(id,pattern,spacesonly)
- return empty(xmlfilter(id,pattern),spacesonly)
+ return empty(xmlfilter(id,pattern),spacesonly)
end
xml.all=xml.filter
xml.index=xml.position
xml.found=xml.filter
local function totable(x)
- local t={}
- for e in xmlcollected(x[1] or x,"/*") do
- t[e.tg]=xmltostring(e.dt) or ""
- end
- return next(t) and t or nil
+ local t={}
+ for e in xmlcollected(x[1] or x,"/*") do
+ t[e.tg]=xmltostring(e.dt) or ""
+ end
+ return next(t) and t or nil
end
xml.table=totable
finalizers.table=totable
local function textonly(e,t)
- if e then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- textonly(e,t)
- else
- t[#t+1]=e
- end
- end
+ if e then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ textonly(e,t)
+ else
+ t[#t+1]=e
end
+ end
end
- return t
+ end
+ return t
end
function xml.textonly(e)
- return concat(textonly(e,{}))
+ return concat(textonly(e,{}))
end
function finalizers.lowerall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=lower(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[lower(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=lower(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[lower(k)]=v
end
+ e.at=t
+ end
end
+ end
end
function finalizers.upperall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=upper(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[upper(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=upper(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[upper(k)]=v
end
+ e.at=t
+ end
end
+ end
end
@@ -19495,14 +19503,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-xml"] = package.loaded["trac-xml"] or true
--- original size: 6407, stripped down to: 4965
+-- original size: 6407, stripped down to: 4640
if not modules then modules={} end modules ['trac-xml']={
- version=1.001,
- comment="companion to trac-log.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local formatters=string.formatters
local reporters=logs.reporters
@@ -19511,152 +19519,152 @@ local xmlcollected=xml.collected
local xmltext=xml.text
local xmlfirst=xml.first
local function showhelp(specification,...)
- local root=xml.convert(specification.helpinfo or "")
- if not root then
- return
- end
- local xs=xml.gethandlers("string")
- xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
- xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
- local wantedcategories=select("#",...)==0 and true or table.tohash {... }
- local nofcategories=xml.count(root,"/application/flags/category")
- local report=specification.report
- for category in xmlcollected(root,"/application/flags/category") do
- local categoryname=category.at.name or ""
- if wantedcategories==true or wantedcategories[categoryname] then
- if nofcategories>1 then
- report("%s options:",categoryname)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for flag in xmlcollected(subcategory,"/flag") do
- local name=flag.at.name
- local value=flag.at.value
- local short=xmltext(xmlfirst(flag,"/short"))
- if value then
- report("--%-20s %s",formatters["%s=%s"](name,value),short)
- else
- report("--%-20s %s",name,short)
- end
- end
- report()
- end
- end
- end
- for category in xmlcollected(root,"/application/examples/category") do
- local title=xmltext(xmlfirst(category,"/title"))
- if title and title~="" then
- report()
- report(title)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for example in xmlcollected(subcategory,"/example") do
- local command=xmltext(xmlfirst(example,"/command"))
- local comment=xmltext(xmlfirst(example,"/comment"))
- report(command)
- end
- report()
- end
- end
- for comment in xmlcollected(root,"/application/comments/comment") do
- local comment=xmltext(comment)
+ local root=xml.convert(specification.helpinfo or "")
+ if not root then
+ return
+ end
+ local xs=xml.gethandlers("string")
+ xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
+ xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
+ local wantedcategories=select("#",...)==0 and true or table.tohash {... }
+ local nofcategories=xml.count(root,"/application/flags/category")
+ local report=specification.report
+ for category in xmlcollected(root,"/application/flags/category") do
+ local categoryname=category.at.name or ""
+ if wantedcategories==true or wantedcategories[categoryname] then
+ if nofcategories>1 then
+ report("%s options:",categoryname)
report()
- report(comment)
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for flag in xmlcollected(subcategory,"/flag") do
+ local name=flag.at.name
+ local value=flag.at.value
+ local short=xmltext(xmlfirst(flag,"/short"))
+ if value then
+ report("--%-20s %s",formatters["%s=%s"](name,value),short)
+ else
+ report("--%-20s %s",name,short)
+ end
+ end
report()
+ end
+ end
+ end
+ for category in xmlcollected(root,"/application/examples/category") do
+ local title=xmltext(xmlfirst(category,"/title"))
+ if title and title~="" then
+ report()
+ report(title)
+ report()
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for example in xmlcollected(subcategory,"/example") do
+ local command=xmltext(xmlfirst(example,"/command"))
+ local comment=xmltext(xmlfirst(example,"/comment"))
+ report(command)
+ end
+ report()
end
+ end
+ for comment in xmlcollected(root,"/application/comments/comment") do
+ local comment=xmltext(comment)
+ report()
+ report(comment)
+ report()
+ end
end
local reporthelp=reporters.help
local exporthelp=reporters.export
local function xmlfound(t)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="table" then
- return false
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="table" then
+ return false
+ end
+ if type(helpinfo)~="string" then
+ helpinfo="Warning: no helpinfo found."
+ t.helpinfo=helpinfo
+ return false
+ end
+ if string.find(helpinfo,".xml$") then
+ local ownscript=environment.ownscript
+ local helpdata=false
+ if ownscript then
+ local helpfile=file.join(file.pathpart(ownscript),helpinfo)
+ helpdata=io.loaddata(helpfile)
+ if helpdata=="" then
+ helpdata=false
+ end
end
- if type(helpinfo)~="string" then
- helpinfo="Warning: no helpinfo found."
- t.helpinfo=helpinfo
- return false
+ if not helpdata then
+ local helpfile=resolvers.findfile(helpinfo,"tex")
+ helpdata=helpfile and io.loaddata(helpfile)
end
- if string.find(helpinfo,".xml$") then
- local ownscript=environment.ownscript
- local helpdata=false
- if ownscript then
- local helpfile=file.join(file.pathpart(ownscript),helpinfo)
- helpdata=io.loaddata(helpfile)
- if helpdata=="" then
- helpdata=false
- end
- end
- if not helpdata then
- local helpfile=resolvers.findfile(helpinfo,"tex")
- helpdata=helpfile and io.loaddata(helpfile)
- end
- if helpdata and helpdata~="" then
- helpinfo=helpdata
- else
- helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
- end
+ if helpdata and helpdata~="" then
+ helpinfo=helpdata
+ else
+ helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
end
- t.helpinfo=helpinfo
- return string.find(t.helpinfo,"^<%?xml") and true or false
+ end
+ t.helpinfo=helpinfo
+ return string.find(t.helpinfo,"^<%?xml") and true or false
end
function reporters.help(t,...)
- if xmlfound(t) then
- showhelp(t,...)
- else
- reporthelp(t,...)
- end
+ if xmlfound(t) then
+ showhelp(t,...)
+ else
+ reporthelp(t,...)
+ end
end
function reporters.export(t,methods,filename)
- if not xmlfound(t) then
- return exporthelp(t)
- end
- if not methods or methods=="" then
- methods=environment.arguments["exporthelp"]
- end
- if not filename or filename=="" then
- filename=environment.files[1]
- end
- dofile(resolvers.findfile("trac-exp.lua","tex"))
- local exporters=logs.exporters
- if not exporters or not methods then
- return exporthelp(t)
- end
- if methods=="all" then
- methods=table.keys(exporters)
- elseif type(methods)=="string" then
- methods=utilities.parsers.settings_to_array(methods)
- else
- return exporthelp(t)
- end
- if type(filename)~="string" or filename=="" then
- filename=false
- elseif file.pathpart(filename)=="" then
- t.report("export file %a will not be saved on the current path (safeguard)",filename)
- return
- end
- for i=1,#methods do
- local method=methods[i]
- local exporter=exporters[method]
- if exporter then
- local result=exporter(t,method)
- if result and result~="" then
- if filename then
- local fullname=file.replacesuffix(filename,method)
- t.report("saving export in %a",fullname)
- dir.mkdirs(file.pathpart(fullname))
- io.savedata(fullname,result)
- else
- reporters.lines(t,result)
- end
- else
- t.report("no output from exporter %a",method)
- end
+ if not xmlfound(t) then
+ return exporthelp(t)
+ end
+ if not methods or methods=="" then
+ methods=environment.arguments["exporthelp"]
+ end
+ if not filename or filename=="" then
+ filename=environment.files[1]
+ end
+ dofile(resolvers.findfile("trac-exp.lua","tex"))
+ local exporters=logs.exporters
+ if not exporters or not methods then
+ return exporthelp(t)
+ end
+ if methods=="all" then
+ methods=table.keys(exporters)
+ elseif type(methods)=="string" then
+ methods=utilities.parsers.settings_to_array(methods)
+ else
+ return exporthelp(t)
+ end
+ if type(filename)~="string" or filename=="" then
+ filename=false
+ elseif file.pathpart(filename)=="" then
+ t.report("export file %a will not be saved on the current path (safeguard)",filename)
+ return
+ end
+ for i=1,#methods do
+ local method=methods[i]
+ local exporter=exporters[method]
+ if exporter then
+ local result=exporter(t,method)
+ if result and result~="" then
+ if filename then
+ local fullname=file.replacesuffix(filename,method)
+ t.report("saving export in %a",fullname)
+ dir.mkdirs(file.pathpart(fullname))
+ io.savedata(fullname,result)
else
- t.report("unknown exporter %a",method)
+ reporters.lines(t,result)
end
+ else
+ t.report("no output from exporter %a",method)
+ end
+ else
+ t.report("unknown exporter %a",method)
end
+ end
end
@@ -19666,149 +19674,149 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-ini"] = package.loaded["data-ini"] or true
--- original size: 11099, stripped down to: 7516
+-- original size: 11099, stripped down to: 7152
if not modules then modules={} end modules ['data-ini']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local next,type,getmetatable,rawset=next,type,getmetatable,rawset
local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char
local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join
local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv
local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
local report_initialization=logs.reporter("resolvers","initialization")
resolvers=resolvers or {}
local resolvers=resolvers
texconfig.kpse_init=false
texconfig.shell_escape='t'
if not (environment and environment.default_texmfcnf) and kpse and kpse.default_texmfcnf then
- local default_texmfcnf=kpse.default_texmfcnf()
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
- default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
- environment.default_texmfcnf=default_texmfcnf
+ local default_texmfcnf=kpse.default_texmfcnf()
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
+ default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
+ environment.default_texmfcnf=default_texmfcnf
end
kpse={ original=kpse }
setmetatable(kpse,{
- __index=function(kp,name)
- report_initialization("fatal error: kpse library is accessed (key: %s)",name)
- os.exit()
- end
+ __index=function(kp,name)
+ report_initialization("fatal error: kpse library is accessed (key: %s)",name)
+ os.exit()
+ end
} )
do
- local osfontdir=osgetenv("OSFONTDIR")
- if osfontdir and osfontdir~="" then
- elseif osname=="windows" then
- ossetenv("OSFONTDIR","c:/windows/fonts//")
- elseif osname=="macosx" then
- ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
- end
+ local osfontdir=osgetenv("OSFONTDIR")
+ if osfontdir and osfontdir~="" then
+ elseif osname=="windows" then
+ ossetenv("OSFONTDIR","c:/windows/fonts//")
+ elseif osname=="macosx" then
+ ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
+ end
end
do
- local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
- if not homedir or homedir=="" then
- homedir=char(127)
- end
- homedir=file.collapsepath(homedir)
- ossetenv("HOME",homedir)
- ossetenv("USERPROFILE",homedir)
- environment.homedir=homedir
+ local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
+ if not homedir or homedir=="" then
+ homedir=char(127)
+ end
+ homedir=file.collapsepath(homedir)
+ ossetenv("HOME",homedir)
+ ossetenv("USERPROFILE",homedir)
+ environment.homedir=homedir
end
do
- local args=environment.originalarguments or arg
- if not environment.ownmain then
- environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
- end
- local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
- local ownpath=environment.ownpath or os.selfdir
- ownbin=file.collapsepath(ownbin)
- ownpath=file.collapsepath(ownpath)
- if not ownpath or ownpath=="" or ownpath=="unset" then
- ownpath=args[-1] or arg[-1]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- if not ownpath or ownpath=="" then
- ownpath=args[-0] or arg[-0]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- end
- local binary=ownbin
- if not ownpath or ownpath=="" then
- ownpath=ownpath and filedirname(binary)
- end
- if not ownpath or ownpath=="" then
- if os.binsuffix~="" then
- binary=file.replacesuffix(binary,os.binsuffix)
- end
- local path=osgetenv("PATH")
- if path then
- for p in gmatch(path,"[^"..io.pathseparator.."]+") do
- local b=filejoin(p,binary)
- if lfs.isfile(b) then
- local olddir=lfs.currentdir()
- if lfs.chdir(p) then
- local pp=lfs.currentdir()
- if trace_locating and p~=pp then
- report_initialization("following symlink %a to %a",p,pp)
- end
- ownpath=pp
- lfs.chdir(olddir)
- else
- if trace_locating then
- report_initialization("unable to check path %a",p)
- end
- ownpath=p
- end
- break
- end
- end
+ local args=environment.originalarguments or arg
+ if not environment.ownmain then
+ environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
+ end
+ local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
+ local ownpath=environment.ownpath or os.selfdir
+ ownbin=file.collapsepath(ownbin)
+ ownpath=file.collapsepath(ownpath)
+ if not ownpath or ownpath=="" or ownpath=="unset" then
+ ownpath=args[-1] or arg[-1]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ if not ownpath or ownpath=="" then
+ ownpath=args[-0] or arg[-0]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ end
+ local binary=ownbin
+ if not ownpath or ownpath=="" then
+ ownpath=ownpath and filedirname(binary)
+ end
+ if not ownpath or ownpath=="" then
+ if os.binsuffix~="" then
+ binary=file.replacesuffix(binary,os.binsuffix)
+ end
+ local path=osgetenv("PATH")
+ if path then
+ for p in gmatch(path,"[^"..io.pathseparator.."]+") do
+ local b=filejoin(p,binary)
+ if lfs.isfile(b) then
+ local olddir=lfs.currentdir()
+ if lfs.chdir(p) then
+ local pp=lfs.currentdir()
+ if trace_locating and p~=pp then
+ report_initialization("following symlink %a to %a",p,pp)
+ end
+ ownpath=pp
+ lfs.chdir(olddir)
+ else
+ if trace_locating then
+ report_initialization("unable to check path %a",p)
+ end
+ ownpath=p
end
+ break
+ end
end
- if not ownpath or ownpath=="" then
- ownpath="."
- report_initialization("forcing fallback to ownpath %a",ownpath)
- elseif trace_locating then
- report_initialization("using ownpath %a",ownpath)
- end
+ end
end
- environment.ownbin=ownbin
- environment.ownpath=ownpath
+ if not ownpath or ownpath=="" then
+ ownpath="."
+ report_initialization("forcing fallback to ownpath %a",ownpath)
+ elseif trace_locating then
+ report_initialization("using ownpath %a",ownpath)
+ end
+ end
+ environment.ownbin=ownbin
+ environment.ownpath=ownpath
end
resolvers.ownpath=environment.ownpath
function resolvers.getownpath()
- return environment.ownpath
+ return environment.ownpath
end
do
- local ownpath=environment.ownpath or dir.current()
- if ownpath then
- ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
- ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
- ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
- else
- report_initialization("error: unable to locate ownpath")
- os.exit()
- end
-end
-local texos=environment.texos or osgetenv("TEXOS")
+ local ownpath=environment.ownpath or dir.current()
+ if ownpath then
+ ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
+ ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
+ ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
+ else
+ report_initialization("error: unable to locate ownpath")
+ os.exit()
+ end
+end
+local texos=environment.texos or osgetenv("TEXOS")
local texmfos=environment.texmfos or osgetenv('SELFAUTODIR')
if not texos or texos=="" then
- texos=file.basename(texmfos)
+ texos=file.basename(texmfos)
end
ossetenv('TEXMFOS',texmfos)
-ossetenv('TEXOS',texos)
-ossetenv('SELFAUTOSYSTEM',os.platform)
+ossetenv('TEXOS',texos)
+ossetenv('SELFAUTOSYSTEM',os.platform)
environment.texos=texos
environment.texmfos=texmfos
local texroot=environment.texroot or osgetenv("TEXROOT")
if not texroot or texroot=="" then
- texroot=osgetenv('SELFAUTOPARENT')
- ossetenv('TEXROOT',texroot)
+ texroot=osgetenv('SELFAUTOPARENT')
+ ossetenv('TEXROOT',texroot)
end
environment.texroot=file.collapsepath(texroot)
local prefixes=utilities.storage.allocate()
@@ -19817,30 +19825,30 @@ local resolved={}
local abstract={}
local dynamic={}
function resolvers.resetresolve(str)
- resolved,abstract={},{}
+ resolved,abstract={},{}
end
function resolvers.allprefixes(separator)
- local all=table.sortedkeys(prefixes)
- if separator then
- for i=1,#all do
- all[i]=all[i]..":"
- end
+ local all=table.sortedkeys(prefixes)
+ if separator then
+ for i=1,#all do
+ all[i]=all[i]..":"
end
- return all
+ end
+ return all
end
local function _resolve_(method,target)
- local action=prefixes[method]
- if action then
- return action(target)
- else
- return method..":"..target
- end
+ local action=prefixes[method]
+ if action then
+ return action(target)
+ else
+ return method..":"..target
+ end
end
function resolvers.unresolve(str)
- return abstract[str] or str
+ return abstract[str] or str
end
function resolvers.setdynamic(str)
- dynamic[str]=true
+ dynamic[str]=true
end
local pattern=Cs((C(R("az")^2)*P(":")*C((1-S(" \"\';,"))^1)/_resolve_+P(1))^0)
local prefix=C(R("az")^2)*P(":")
@@ -19849,65 +19857,65 @@ local notarget=(#S(";,")+P(-1))*Cc("")
local p_resolve=Cs(((prefix*(target+notarget))/_resolve_+P(1))^0)
local p_simple=prefix*P(-1)
local function resolve(str)
- if type(str)=="table" then
- local res={}
- for i=1,#str do
- res[i]=resolve(str[i])
- end
- return res
- end
- local res=resolved[str]
- if res then
- return res
+ if type(str)=="table" then
+ local res={}
+ for i=1,#str do
+ res[i]=resolve(str[i])
end
- local simple=lpegmatch(p_simple,str)
- local action=prefixes[simple]
- if action then
- local res=action(res)
- if not dynamic[simple] then
- resolved[simple]=res
- abstract[res]=simple
- end
- return res
+ return res
+ end
+ local res=resolved[str]
+ if res then
+ return res
+ end
+ local simple=lpegmatch(p_simple,str)
+ local action=prefixes[simple]
+ if action then
+ local res=action(res)
+ if not dynamic[simple] then
+ resolved[simple]=res
+ abstract[res]=simple
end
- res=lpegmatch(p_resolve,str)
- resolved[str]=res
- abstract[res]=str
return res
+ end
+ res=lpegmatch(p_resolve,str)
+ resolved[str]=res
+ abstract[res]=str
+ return res
end
resolvers.resolve=resolve
if type(osuname)=="function" then
- for k,v in next,osuname() do
- if not prefixes[k] then
- prefixes[k]=function() return v end
- end
+ for k,v in next,osuname() do
+ if not prefixes[k] then
+ prefixes[k]=function() return v end
end
+ end
end
if ostype=="unix" then
- local pattern
- local function makepattern(t,k,v)
- if t then
- rawset(t,k,v)
- end
- local colon=P(":")
- for k,v in table.sortedpairs(prefixes) do
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- pattern=Cs((p*colon+colon/";"+P(1))^0)
- end
- makepattern()
- table.setmetatablenewindex(prefixes,makepattern)
- function resolvers.repath(str)
- return lpegmatch(pattern,str)
+ local pattern
+ local function makepattern(t,k,v)
+ if t then
+ rawset(t,k,v)
+ end
+ local colon=P(":")
+ for k,v in table.sortedpairs(prefixes) do
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
end
+ pattern=Cs((p*colon+colon/";"+P(1))^0)
+ end
+ makepattern()
+ table.setmetatablenewindex(prefixes,makepattern)
+ function resolvers.repath(str)
+ return lpegmatch(pattern,str)
+ end
else
- function resolvers.repath(str)
- return str
- end
+ function resolvers.repath(str)
+ return str
+ end
end
@@ -19917,14 +19925,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-exp"] = package.loaded["data-exp"] or true
--- original size: 18105, stripped down to: 11207
+-- original size: 18105, stripped down to: 10389
if not modules then modules={} end modules ['data-exp']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub
local concat,sort=table.concat,table.sort
@@ -19934,21 +19942,21 @@ local Ct,Cs,Cc,Carg,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.P,lpeg.C,lpeg.S
local type,next=type,next
local isdir=lfs.isdir
local collapsepath,joinpath,basename=file.collapsepath,file.join,file.basename
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
local report_expansions=logs.reporter("resolvers","expansions")
local report_globbing=logs.reporter("resolvers","globbing")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
local function f_both(a,b)
- local t,n={},0
- for sb in gmatch(b,"[^,]+") do
- for sa in gmatch(a,"[^,]+") do
- n=n+1;t[n]=sa..sb
- end
+ local t,n={},0
+ for sb in gmatch(b,"[^,]+") do
+ for sa in gmatch(a,"[^,]+") do
+ n=n+1;t[n]=sa..sb
end
- return concat(t,",")
+ end
+ return concat(t,",")
end
local comma=P(",")
local nocomma=(1-comma)^1
@@ -19958,7 +19966,7 @@ local after=Cs((Carg(1)*nocomma+docomma)^0)
local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0)
local function f_first (a,b) return lpegmatch(after,b,1,a) end
local function f_second(a,b) return lpegmatch(before,a,1,b) end
-local function f_both (a,b) return lpegmatch(both,b,1,a) end
+local function f_both (a,b) return lpegmatch(both,b,1,a) end
local left=P("{")
local right=P("}")
local var=P((1-S("{}" ))^0)
@@ -19971,141 +19979,141 @@ local l_rest=Cs((left*var*(left/"")*var*(right/"")*var*right+other )^0 )
local stripper_1=lpeg.stripper ("{}@")
local replacer_1=lpeg.replacer { { ",}",",@}" },{ "{,","{@," },}
local function splitpathexpr(str,newlist,validate)
- if trace_expansions then
- report_expansions("expanding variable %a",str)
- end
- local t,ok,done=newlist or {},false,false
- local n=#t
- str=lpegmatch(replacer_1,str)
+ if trace_expansions then
+ report_expansions("expanding variable %a",str)
+ end
+ local t,ok,done=newlist or {},false,false
+ local n=#t
+ str=lpegmatch(replacer_1,str)
+ repeat
+ local old=str
repeat
- local old=str
- repeat
- local old=str
- str=lpegmatch(l_first,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_second,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_both,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_rest,str)
- until old==str
- until old==str
- str=lpegmatch(stripper_1,str)
- if validate then
- for s in gmatch(str,"[^,]+") do
- s=validate(s)
- if s then
- n=n+1
- t[n]=s
- end
- end
- else
- for s in gmatch(str,"[^,]+") do
- n=n+1
- t[n]=s
- end
+ local old=str
+ str=lpegmatch(l_first,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_second,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_both,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_rest,str)
+ until old==str
+ until old==str
+ str=lpegmatch(stripper_1,str)
+ if validate then
+ for s in gmatch(str,"[^,]+") do
+ s=validate(s)
+ if s then
+ n=n+1
+ t[n]=s
+ end
end
- if trace_expansions then
- for k=1,#t do
- report_expansions("% 4i: %s",k,t[k])
- end
+ else
+ for s in gmatch(str,"[^,]+") do
+ n=n+1
+ t[n]=s
end
- return t
+ end
+ if trace_expansions then
+ for k=1,#t do
+ report_expansions("% 4i: %s",k,t[k])
+ end
+ end
+ return t
end
local function validate(s)
- s=collapsepath(s)
- return s~="" and not find(s,"^!*unset/*$") and s
+ s=collapsepath(s)
+ return s~="" and not find(s,"^!*unset/*$") and s
end
resolvers.validatedpath=validate
function resolvers.expandedpathfromlist(pathlist)
- local newlist={}
- for k=1,#pathlist do
- splitpathexpr(pathlist[k],newlist,validate)
- end
- return newlist
+ local newlist={}
+ for k=1,#pathlist do
+ splitpathexpr(pathlist[k],newlist,validate)
+ end
+ return newlist
end
local usedhomedir=nil
-local donegation=(P("!")/"" )^0
+local donegation=(P("!")/"" )^0
local doslashes=(P("\\")/"/"+1)^0
local function expandedhome()
- if not usedhomedir then
- usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
- if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
- if trace_expansions then
- report_expansions("no home dir set, ignoring dependent path using current path")
- end
- usedhomedir="."
- end
+ if not usedhomedir then
+ usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
+ if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
+ if trace_expansions then
+ report_expansions("no home dir set, ignoring dependent path using current path")
+ end
+ usedhomedir="."
end
- return usedhomedir
+ end
+ return usedhomedir
end
local dohome=((P("~")+P("$HOME")+P("%HOME%"))/expandedhome)^0
local cleanup=Cs(donegation*dohome*doslashes)
resolvers.cleanpath=function(str)
- return str and lpegmatch(cleanup,str) or ""
+ return str and lpegmatch(cleanup,str) or ""
end
local expandhome=P("~")/"$HOME"
local dodouble=P('"')/""*(expandhome+(1-P('"')))^0*P('"')/""
local dosingle=P("'")/""*(expandhome+(1-P("'")))^0*P("'")/""
-local dostring=(expandhome+1 )^0
+local dostring=(expandhome+1 )^0
local stripper=Cs(
- lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
+ lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
)
function resolvers.checkedvariable(str)
- return type(str)=="string" and lpegmatch(stripper,str) or str
+ return type(str)=="string" and lpegmatch(stripper,str) or str
end
local cache={}
local splitter=lpeg.tsplitat(";")
local backslashswapper=lpeg.replacer("\\","/")
local function splitconfigurationpath(str)
- if str then
- local found=cache[str]
- if not found then
- if str=="" then
- found={}
- else
- local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
- found={}
- local noffound=0
- for i=1,#split do
- local s=split[i]
- if not find(s,"^{*unset}*") then
- noffound=noffound+1
- found[noffound]=s
- end
- end
- if trace_expansions then
- report_expansions("splitting path specification %a",str)
- for k=1,noffound do
- report_expansions("% 4i: %s",k,found[k])
- end
- end
- cache[str]=found
- end
+ if str then
+ local found=cache[str]
+ if not found then
+ if str=="" then
+ found={}
+ else
+ local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
+ found={}
+ local noffound=0
+ for i=1,#split do
+ local s=split[i]
+ if not find(s,"^{*unset}*") then
+ noffound=noffound+1
+ found[noffound]=s
+ end
end
- return found
+ if trace_expansions then
+ report_expansions("splitting path specification %a",str)
+ for k=1,noffound do
+ report_expansions("% 4i: %s",k,found[k])
+ end
+ end
+ cache[str]=found
+ end
end
+ return found
+ end
end
resolvers.splitconfigurationpath=splitconfigurationpath
function resolvers.splitpath(str)
- if type(str)=='table' then
- return str
- else
- return splitconfigurationpath(str)
- end
+ if type(str)=='table' then
+ return str
+ else
+ return splitconfigurationpath(str)
+ end
end
function resolvers.joinpath(str)
- if type(str)=='table' then
- return joinpath(str)
- else
- return str
- end
+ if type(str)=='table' then
+ return joinpath(str)
+ else
+ return str
+ end
end
local attributes,directory=lfs.attributes,lfs.dir
local weird=P(".")^1+lpeg.anywhere(S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t"))
@@ -20118,201 +20126,201 @@ local fullcache={}
local nofsharedscans=0
local addcasecraptoo=true
local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant)
- local full=path=="" and spec or (spec..path..'/')
- local dirlist={}
- local nofdirs=0
- local pattern=tolerant and lessweird or weird
- local filelist={}
- local noffiles=0
- for name in directory(full) do
- if not lpegmatch(pattern,name) then
- local mode=attributes(full..name,"mode")
- if mode=="file" then
- n=n+1
- noffiles=noffiles+1
- filelist[noffiles]=name
- elseif mode=="directory" then
- m=m+1
- nofdirs=nofdirs+1
- if path~="" then
- dirlist[nofdirs]=path.."/"..name
- else
- dirlist[nofdirs]=name
- end
- end
+ local full=path=="" and spec or (spec..path..'/')
+ local dirlist={}
+ local nofdirs=0
+ local pattern=tolerant and lessweird or weird
+ local filelist={}
+ local noffiles=0
+ for name in directory(full) do
+ if not lpegmatch(pattern,name) then
+ local mode=attributes(full..name,"mode")
+ if mode=="file" then
+ n=n+1
+ noffiles=noffiles+1
+ filelist[noffiles]=name
+ elseif mode=="directory" then
+ m=m+1
+ nofdirs=nofdirs+1
+ if path~="" then
+ dirlist[nofdirs]=path.."/"..name
+ else
+ dirlist[nofdirs]=name
end
+ end
end
- if noffiles>0 then
- sort(filelist)
- for i=1,noffiles do
- local name=filelist[i]
- local lower=lower(name)
- local paths=files[lower]
- if paths then
- if onlyone then
- else
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- if addcasecraptoo then
- local paths=files[name]
- if not paths then
- files[name]=path
- elseif type(paths)=="string" then
- files[name]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- end
- if type(paths)=="string" then
- files[lower]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- else
- files[lower]=path
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- end
+ end
+ if noffiles>0 then
+ sort(filelist)
+ for i=1,noffiles do
+ local name=filelist[i]
+ local lower=lower(name)
+ local paths=files[lower]
+ if paths then
+ if onlyone then
+ else
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
+ if addcasecraptoo then
+ local paths=files[name]
+ if not paths then
+ files[name]=path
+ elseif type(paths)=="string" then
+ files[name]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
+ end
+ if type(paths)=="string" then
+ files[lower]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
- end
- if nofdirs>0 then
- sort(dirlist)
- for i=1,nofdirs do
- files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
+ else
+ files[lower]=path
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
end
+ end
+ end
+ end
+ if nofdirs>0 then
+ sort(dirlist)
+ for i=1,nofdirs do
+ files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
end
- scancache[sub(full,1,-2)]=files
- return files,remap,n,m,r
+ end
+ scancache[sub(full,1,-2)]=files
+ return files,remap,n,m,r
end
function resolvers.scanfiles(path,branch,usecache,onlyonce,tolerant)
- local realpath=resolveprefix(path)
- if usecache then
- local content=fullcache[realpath]
- if content then
- if trace_locating then
- report_expansions("using cached scan of path %a, branch %a",path,branch or path)
- end
- nofsharedscans=nofsharedscans+1
- return content
- end
- end
- statistics.starttiming(timer)
+ local realpath=resolveprefix(path)
+ if usecache then
+ local content=fullcache[realpath]
+ if content then
+ if trace_locating then
+ report_expansions("using cached scan of path %a, branch %a",path,branch or path)
+ end
+ nofsharedscans=nofsharedscans+1
+ return content
+ end
+ end
+ statistics.starttiming(timer)
+ if trace_locating then
+ report_expansions("scanning path %a, branch %a",path,branch or path)
+ end
+ local content
+ if isdir(realpath) then
+ local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
+ content={
+ metadata={
+ path=path,
+ files=n,
+ directories=m,
+ remappings=r,
+ },
+ files=files,
+ remap=remap,
+ }
if trace_locating then
- report_expansions("scanning path %a, branch %a",path,branch or path)
+ report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
end
- local content
- if isdir(realpath) then
- local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
- content={
- metadata={
- path=path,
- files=n,
- directories=m,
- remappings=r,
- },
- files=files,
- remap=remap,
- }
- if trace_locating then
- report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
- end
- else
- content={
- metadata={
- path=path,
- files=0,
- directories=0,
- remappings=0,
- },
- files={},
- remap={},
- }
- if trace_locating then
- report_expansions("invalid path %a",realpath)
- end
- end
- if usecache then
- scanned[#scanned+1]=realpath
- fullcache[realpath]=content
+ else
+ content={
+ metadata={
+ path=path,
+ files=0,
+ directories=0,
+ remappings=0,
+ },
+ files={},
+ remap={},
+ }
+ if trace_locating then
+ report_expansions("invalid path %a",realpath)
end
- nofscans=nofscans+1
- statistics.stoptiming(timer)
- return content
+ end
+ if usecache then
+ scanned[#scanned+1]=realpath
+ fullcache[realpath]=content
+ end
+ nofscans=nofscans+1
+ statistics.stoptiming(timer)
+ return content
end
function resolvers.simplescanfiles(path,branch,usecache)
- return resolvers.scanfiles(path,branch,usecache,true,true)
+ return resolvers.scanfiles(path,branch,usecache,true,true)
end
function resolvers.scandata()
- table.sort(scanned)
- return {
- n=nofscans,
- shared=nofsharedscans,
- time=statistics.elapsedtime(timer),
- paths=scanned,
- }
+ table.sort(scanned)
+ return {
+ n=nofscans,
+ shared=nofsharedscans,
+ time=statistics.elapsedtime(timer),
+ paths=scanned,
+ }
end
function resolvers.get_from_content(content,path,name)
- if not content then
- return
- end
- local files=content.files
- if not files then
- return
- end
- local remap=content.remap
- if not remap then
- return
- end
- if name then
- local used=lower(name)
- return path,remap[used] or used
- else
- local name=path
- local used=lower(name)
- local path=files[used]
- if path then
- return path,remap[used] or used
- end
- end
+ if not content then
+ return
+ end
+ local files=content.files
+ if not files then
+ return
+ end
+ local remap=content.remap
+ if not remap then
+ return
+ end
+ if name then
+ local used=lower(name)
+ return path,remap[used] or used
+ else
+ local name=path
+ local used=lower(name)
+ local path=files[used]
+ if path then
+ return path,remap[used] or used
+ end
+ end
end
local nothing=function() end
function resolvers.filtered_from_content(content,pattern)
- if content and type(pattern)=="string" then
- local pattern=lower(pattern)
- local files=content.files
- local remap=content.remap
- if files and remap then
- local f=sortedkeys(files)
- local n=#f
- local i=0
- local function iterator()
- while i<n do
- i=i+1
- local k=f[i]
- if find(k,pattern) then
- return files[k],remap and remap[k] or k
- end
- end
- end
- return iterator
+ if content and type(pattern)=="string" then
+ local pattern=lower(pattern)
+ local files=content.files
+ local remap=content.remap
+ if files and remap then
+ local f=sortedkeys(files)
+ local n=#f
+ local i=0
+ local function iterator()
+ while i<n do
+ i=i+1
+ local k=f[i]
+ if find(k,pattern) then
+ return files[k],remap and remap[k] or k
+ end
end
+ end
+ return iterator
end
- return nothing
+ end
+ return nothing
end
@@ -20322,14 +20330,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-env"] = package.loaded["data-env"] or true
--- original size: 9360, stripped down to: 6903
+-- original size: 9360, stripped down to: 6312
if not modules then modules={} end modules ['data-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local lower,gsub=string.lower,string.gsub
local next=next
@@ -20349,255 +20357,255 @@ resolvers.suffixmap=suffixmap
resolvers.usertypes=usertypes
local luasuffixes=utilities.lua.suffixes
local relations=allocate {
- core={
- ofm={
- names={ "ofm","omega font metric","omega font metrics" },
- variable='OFMFONTS',
- suffixes={ 'ofm','tfm' },
- },
- ovf={
- names={ "ovf","omega virtual font","omega virtual fonts" },
- variable='OVFFONTS',
- suffixes={ 'ovf','vf' },
- },
- tfm={
- names={ "tfm","tex font metric","tex font metrics" },
- variable='TFMFONTS',
- suffixes={ 'tfm' },
- },
- vf={
- names={ "vf","virtual font","virtual fonts" },
- variable='VFFONTS',
- suffixes={ 'vf' },
- },
- otf={
- names={ "otf","opentype","opentype font","opentype fonts"},
- variable='OPENTYPEFONTS',
- suffixes={ 'otf' },
- },
- ttf={
- names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
- variable='TTFONTS',
- suffixes={ 'ttf','ttc','dfont' },
- },
- afm={
- names={ "afm","adobe font metric","adobe font metrics" },
- variable="AFMFONTS",
- suffixes={ "afm" },
- },
- pfb={
- names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
- variable='T1FONTS',
- suffixes={ 'pfb','pfa' },
- },
- fea={
- names={ "fea","font feature","font features","font feature file","font feature files" },
- variable='FONTFEATURES',
- suffixes={ 'fea' },
- },
- cid={
- names={ "cid","cid map","cid maps","cid file","cid files" },
- variable='FONTCIDMAPS',
- suffixes={ 'cid','cidmap' },
- },
- fmt={
- names={ "fmt","format","tex format" },
- variable='TEXFORMATS',
- suffixes={ 'fmt' },
- },
- mem={
- names={ 'mem',"metapost format" },
- variable='MPMEMS',
- suffixes={ 'mem' },
- },
- mp={
- names={ "mp" },
- variable='MPINPUTS',
- suffixes={ 'mp','mpvi','mpiv','mpii' },
- usertype=true,
- },
- tex={
- names={ "tex" },
- variable='TEXINPUTS',
- suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
- usertype=true,
- },
- icc={
- names={ "icc","icc profile","icc profiles" },
- variable='ICCPROFILES',
- suffixes={ 'icc' },
- },
- texmfscripts={
- names={ "texmfscript","texmfscripts","script","scripts" },
- variable='TEXMFSCRIPTS',
- suffixes={ 'lua','rb','pl','py' },
- },
- lua={
- names={ "lua" },
- variable='LUAINPUTS',
- suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
- usertype=true,
- },
- lib={
- names={ "lib" },
- variable='CLUAINPUTS',
- suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
- },
- bib={
- names={ 'bib' },
- variable='BIBINPUTS',
- suffixes={ 'bib' },
- usertype=true,
- },
- bst={
- names={ 'bst' },
- variable='BSTINPUTS',
- suffixes={ 'bst' },
- usertype=true,
- },
- fontconfig={
- names={ 'fontconfig','fontconfig file','fontconfig files' },
- variable='FONTCONFIG_PATH',
- },
- pk={
- names={ "pk" },
- variable='PKFONTS',
- suffixes={ 'pk' },
- },
+ core={
+ ofm={
+ names={ "ofm","omega font metric","omega font metrics" },
+ variable='OFMFONTS',
+ suffixes={ 'ofm','tfm' },
+ },
+ ovf={
+ names={ "ovf","omega virtual font","omega virtual fonts" },
+ variable='OVFFONTS',
+ suffixes={ 'ovf','vf' },
+ },
+ tfm={
+ names={ "tfm","tex font metric","tex font metrics" },
+ variable='TFMFONTS',
+ suffixes={ 'tfm' },
},
- obsolete={
- enc={
- names={ "enc","enc files","enc file","encoding files","encoding file" },
- variable='ENCFONTS',
- suffixes={ 'enc' },
- },
- map={
- names={ "map","map files","map file" },
- variable='TEXFONTMAPS',
- suffixes={ 'map' },
- },
- lig={
- names={ "lig files","lig file","ligature file","ligature files" },
- variable='LIGFONTS',
- suffixes={ 'lig' },
- },
- opl={
- names={ "opl" },
- variable='OPLFONTS',
- suffixes={ 'opl' },
- },
- ovp={
- names={ "ovp" },
- variable='OVPFONTS',
- suffixes={ 'ovp' },
- },
+ vf={
+ names={ "vf","virtual font","virtual fonts" },
+ variable='VFFONTS',
+ suffixes={ 'vf' },
},
- kpse={
- base={
- names={ 'base',"metafont format" },
- variable='MFBASES',
- suffixes={ 'base','bas' },
- },
- cmap={
- names={ 'cmap','cmap files','cmap file' },
- variable='CMAPFONTS',
- suffixes={ 'cmap' },
- },
- cnf={
- names={ 'cnf' },
- suffixes={ 'cnf' },
- },
- web={
- names={ 'web' },
- suffixes={ 'web','ch' }
- },
- cweb={
- names={ 'cweb' },
- suffixes={ 'w','web','ch' },
- },
- gf={
- names={ 'gf' },
- suffixes={ '<resolution>gf' },
- },
- mf={
- names={ 'mf' },
- variable='MFINPUTS',
- suffixes={ 'mf' },
- },
- mft={
- names={ 'mft' },
- suffixes={ 'mft' },
- },
- pk={
- names={ 'pk' },
- suffixes={ '<resolution>pk' },
- },
+ otf={
+ names={ "otf","opentype","opentype font","opentype fonts"},
+ variable='OPENTYPEFONTS',
+ suffixes={ 'otf' },
},
+ ttf={
+ names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
+ variable='TTFONTS',
+ suffixes={ 'ttf','ttc','dfont' },
+ },
+ afm={
+ names={ "afm","adobe font metric","adobe font metrics" },
+ variable="AFMFONTS",
+ suffixes={ "afm" },
+ },
+ pfb={
+ names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
+ variable='T1FONTS',
+ suffixes={ 'pfb','pfa' },
+ },
+ fea={
+ names={ "fea","font feature","font features","font feature file","font feature files" },
+ variable='FONTFEATURES',
+ suffixes={ 'fea' },
+ },
+ cid={
+ names={ "cid","cid map","cid maps","cid file","cid files" },
+ variable='FONTCIDMAPS',
+ suffixes={ 'cid','cidmap' },
+ },
+ fmt={
+ names={ "fmt","format","tex format" },
+ variable='TEXFORMATS',
+ suffixes={ 'fmt' },
+ },
+ mem={
+ names={ 'mem',"metapost format" },
+ variable='MPMEMS',
+ suffixes={ 'mem' },
+ },
+ mp={
+ names={ "mp" },
+ variable='MPINPUTS',
+ suffixes={ 'mp','mpvi','mpiv','mpii' },
+ usertype=true,
+ },
+ tex={
+ names={ "tex" },
+ variable='TEXINPUTS',
+ suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
+ usertype=true,
+ },
+ icc={
+ names={ "icc","icc profile","icc profiles" },
+ variable='ICCPROFILES',
+ suffixes={ 'icc' },
+ },
+ texmfscripts={
+ names={ "texmfscript","texmfscripts","script","scripts" },
+ variable='TEXMFSCRIPTS',
+ suffixes={ 'lua','rb','pl','py' },
+ },
+ lua={
+ names={ "lua" },
+ variable='LUAINPUTS',
+ suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
+ usertype=true,
+ },
+ lib={
+ names={ "lib" },
+ variable='CLUAINPUTS',
+ suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
+ },
+ bib={
+ names={ 'bib' },
+ variable='BIBINPUTS',
+ suffixes={ 'bib' },
+ usertype=true,
+ },
+ bst={
+ names={ 'bst' },
+ variable='BSTINPUTS',
+ suffixes={ 'bst' },
+ usertype=true,
+ },
+ fontconfig={
+ names={ 'fontconfig','fontconfig file','fontconfig files' },
+ variable='FONTCONFIG_PATH',
+ },
+ pk={
+ names={ "pk" },
+ variable='PKFONTS',
+ suffixes={ 'pk' },
+ },
+ },
+ obsolete={
+ enc={
+ names={ "enc","enc files","enc file","encoding files","encoding file" },
+ variable='ENCFONTS',
+ suffixes={ 'enc' },
+ },
+ map={
+ names={ "map","map files","map file" },
+ variable='TEXFONTMAPS',
+ suffixes={ 'map' },
+ },
+ lig={
+ names={ "lig files","lig file","ligature file","ligature files" },
+ variable='LIGFONTS',
+ suffixes={ 'lig' },
+ },
+ opl={
+ names={ "opl" },
+ variable='OPLFONTS',
+ suffixes={ 'opl' },
+ },
+ ovp={
+ names={ "ovp" },
+ variable='OVPFONTS',
+ suffixes={ 'ovp' },
+ },
+ },
+ kpse={
+ base={
+ names={ 'base',"metafont format" },
+ variable='MFBASES',
+ suffixes={ 'base','bas' },
+ },
+ cmap={
+ names={ 'cmap','cmap files','cmap file' },
+ variable='CMAPFONTS',
+ suffixes={ 'cmap' },
+ },
+ cnf={
+ names={ 'cnf' },
+ suffixes={ 'cnf' },
+ },
+ web={
+ names={ 'web' },
+ suffixes={ 'web','ch' }
+ },
+ cweb={
+ names={ 'cweb' },
+ suffixes={ 'w','web','ch' },
+ },
+ gf={
+ names={ 'gf' },
+ suffixes={ '<resolution>gf' },
+ },
+ mf={
+ names={ 'mf' },
+ variable='MFINPUTS',
+ suffixes={ 'mf' },
+ },
+ mft={
+ names={ 'mft' },
+ suffixes={ 'mft' },
+ },
+ pk={
+ names={ 'pk' },
+ suffixes={ '<resolution>pk' },
+ },
+ },
}
resolvers.relations=relations
function resolvers.updaterelations()
- for category,categories in next,relations do
- for name,relation in next,categories do
- local rn=relation.names
- local rv=relation.variable
- if rn and rv then
- local rs=relation.suffixes
- local ru=relation.usertype
- for i=1,#rn do
- local rni=lower(gsub(rn[i]," ",""))
- formats[rni]=rv
- if rs then
- suffixes[rni]=rs
- for i=1,#rs do
- local rsi=rs[i]
- suffixmap[rsi]=rni
- end
- end
- end
- if ru then
- usertypes[name]=true
- end
+ for category,categories in next,relations do
+ for name,relation in next,categories do
+ local rn=relation.names
+ local rv=relation.variable
+ if rn and rv then
+ local rs=relation.suffixes
+ local ru=relation.usertype
+ for i=1,#rn do
+ local rni=lower(gsub(rn[i]," ",""))
+ formats[rni]=rv
+ if rs then
+ suffixes[rni]=rs
+ for i=1,#rs do
+ local rsi=rs[i]
+ suffixmap[rsi]=rni
end
+ end
+ end
+ if ru then
+ usertypes[name]=true
end
+ end
end
+ end
end
resolvers.updaterelations()
local function simplified(t,k)
- return k and rawget(t,lower(gsub(k," ",""))) or nil
+ return k and rawget(t,lower(gsub(k," ",""))) or nil
end
setmetatableindex(formats,simplified)
setmetatableindex(suffixes,simplified)
setmetatableindex(suffixmap,simplified)
function resolvers.suffixofformat(str)
- local s=suffixes[str]
- return s and s[1] or ""
+ local s=suffixes[str]
+ return s and s[1] or ""
end
function resolvers.suffixofformat(str)
- return suffixes[str] or {}
+ return suffixes[str] or {}
end
for name,format in next,formats do
- dangerous[name]=true
+ dangerous[name]=true
end
dangerous.tex=nil
function resolvers.formatofvariable(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.formatofsuffix(str)
- return suffixmap[suffixonly(str)] or 'tex'
+ return suffixmap[suffixonly(str)] or 'tex'
end
function resolvers.variableofformat(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.variableofformatorsuffix(str)
- local v=formats[str]
- if v then
- return v
- end
- v=suffixmap[suffixonly(str)]
- if v then
- return formats[v]
- end
- return ''
+ local v=formats[str]
+ if v then
+ return v
+ end
+ v=suffixmap[suffixonly(str)]
+ if v then
+ return formats[v]
+ end
+ return ''
end
@@ -20607,14 +20615,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16116, stripped down to: 11459
+-- original size: 16116, stripped down to: 10782
if not modules then modules={} end modules ['data-tmp']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub,concat=string.format,string.lower,string.gsub,table.concat
local concat=table.concat
@@ -20622,19 +20630,19 @@ local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile
local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
local formatters=string.formatters
local next,type=next,type
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
local report_caches=logs.reporter("resolvers","caches")
local report_resolvers=logs.reporter("resolvers","caching")
local resolvers=resolvers
local cleanpath=resolvers.cleanpath
-local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
-local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
+local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
+local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
local compile=utilities.lua.compile
function utilities.lua.compile(luafile,lucfile,cleanup,strip)
- if cleanup==nil then cleanup=directive_cleanup end
- if strip==nil then strip=directive_strip end
- return compile(luafile,lucfile,cleanup,strip)
+ if cleanup==nil then cleanup=directive_cleanup end
+ if strip==nil then strip=directive_strip end
+ return compile(luafile,lucfile,cleanup,strip)
end
caches=caches or {}
local caches=caches
@@ -20649,324 +20657,324 @@ caches.relocate=false
caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
local writable,readables,usedreadables=nil,{},{}
local function identify()
- local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- cachepath=file.collapsepath(cachepath)
- local valid=isdir(cachepath)
- if valid then
- if is_readable(cachepath) then
- readables[#readables+1]=cachepath
- if not writable and is_writable(cachepath) then
- writable=cachepath
- end
- end
- elseif not writable and caches.force then
- local cacheparent=file.dirname(cachepath)
- if is_writable(cacheparent) and true then
- if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
- mkdirs(cachepath)
- if isdir(cachepath) and is_writable(cachepath) then
- report_caches("path %a created",cachepath)
- writable=cachepath
- readables[#readables+1]=cachepath
- end
- end
- end
- end
+ local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ cachepath=file.collapsepath(cachepath)
+ local valid=isdir(cachepath)
+ if valid then
+ if is_readable(cachepath) then
+ readables[#readables+1]=cachepath
+ if not writable and is_writable(cachepath) then
+ writable=cachepath
end
- end
- end
- local texmfcaches=caches.defaults
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- cachepath=resolvers.expansion(cachepath)
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- local valid=isdir(cachepath)
- if valid and is_readable(cachepath) then
- if not writable and is_writable(cachepath) then
- readables[#readables+1]=cachepath
- writable=cachepath
- break
- end
- end
+ end
+ elseif not writable and caches.force then
+ local cacheparent=file.dirname(cachepath)
+ if is_writable(cacheparent) and true then
+ if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
+ mkdirs(cachepath)
+ if isdir(cachepath) and is_writable(cachepath) then
+ report_caches("path %a created",cachepath)
+ writable=cachepath
+ readables[#readables+1]=cachepath
+ end
end
+ end
end
+ end
end
- if not writable then
- report_caches("fatal error: there is no valid writable cache path defined")
- os.exit()
- elseif #readables==0 then
- report_caches("fatal error: there is no valid readable cache path defined")
- os.exit()
- end
- writable=dir.expandname(resolvers.cleanpath(writable))
- local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
- if tree then
- caches.tree=tree
- writable=mkdirs(writable,base,more,tree)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more,tree)
- end
- else
- writable=mkdirs(writable,base,more)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more)
+ end
+ local texmfcaches=caches.defaults
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ cachepath=resolvers.expansion(cachepath)
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ local valid=isdir(cachepath)
+ if valid and is_readable(cachepath) then
+ if not writable and is_writable(cachepath) then
+ readables[#readables+1]=cachepath
+ writable=cachepath
+ break
+ end
end
+ end
end
- if trace_cache then
- for i=1,#readables do
- report_caches("using readable path %a (order %s)",readables[i],i)
- end
- report_caches("using writable path %a",writable)
+ end
+ if not writable then
+ report_caches("fatal error: there is no valid writable cache path defined")
+ os.exit()
+ elseif #readables==0 then
+ report_caches("fatal error: there is no valid readable cache path defined")
+ os.exit()
+ end
+ writable=dir.expandname(resolvers.cleanpath(writable))
+ local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
+ if tree then
+ caches.tree=tree
+ writable=mkdirs(writable,base,more,tree)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more,tree)
end
- identify=function()
- return writable,readables
+ else
+ writable=mkdirs(writable,base,more)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more)
+ end
+ end
+ if trace_cache then
+ for i=1,#readables do
+ report_caches("using readable path %a (order %s)",readables[i],i)
end
+ report_caches("using writable path %a",writable)
+ end
+ identify=function()
return writable,readables
+ end
+ return writable,readables
end
function caches.usedpaths(separator)
- local writable,readables=identify()
- if #readables>1 then
- local result={}
- local done={}
- for i=1,#readables do
- local readable=readables[i]
- if readable==writable then
- done[readable]=true
- result[#result+1]=formatters["readable+writable: %a"](readable)
- elseif usedreadables[i] then
- done[readable]=true
- result[#result+1]=formatters["readable: %a"](readable)
- end
- end
- if not done[writable] then
- result[#result+1]=formatters["writable: %a"](writable)
- end
- return concat(result,separator or " | ")
- else
- return writable or "?"
+ local writable,readables=identify()
+ if #readables>1 then
+ local result={}
+ local done={}
+ for i=1,#readables do
+ local readable=readables[i]
+ if readable==writable then
+ done[readable]=true
+ result[#result+1]=formatters["readable+writable: %a"](readable)
+ elseif usedreadables[i] then
+ done[readable]=true
+ result[#result+1]=formatters["readable: %a"](readable)
+ end
+ end
+ if not done[writable] then
+ result[#result+1]=formatters["writable: %a"](writable)
end
+ return concat(result,separator or " | ")
+ else
+ return writable or "?"
+ end
end
function caches.configfiles()
- return concat(resolvers.configurationfiles(),";")
+ return concat(resolvers.configurationfiles(),";")
end
function caches.hashed(tree)
- tree=gsub(tree,"[\\/]+$","")
- tree=lower(tree)
- local hash=md5.hex(tree)
- if trace_cache or trace_locating then
- report_caches("hashing tree %a, hash %a",tree,hash)
- end
- return hash
+ tree=gsub(tree,"[\\/]+$","")
+ tree=lower(tree)
+ local hash=md5.hex(tree)
+ if trace_cache or trace_locating then
+ report_caches("hashing tree %a, hash %a",tree,hash)
+ end
+ return hash
end
function caches.treehash()
- local tree=caches.configfiles()
- if not tree or tree=="" then
- return false
- else
- return caches.hashed(tree)
- end
+ local tree=caches.configfiles()
+ if not tree or tree=="" then
+ return false
+ else
+ return caches.hashed(tree)
+ end
end
local r_cache,w_cache={},{}
local function getreadablepaths(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=r_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done={}
- for i=1,#readables do
- done[i]=file.join(readables[i],...)
- end
- else
- done=readables
- end
- r_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=r_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done={}
+ for i=1,#readables do
+ done[i]=file.join(readables[i],...)
+ end
+ else
+ done=readables
end
- return done
+ r_cache[hash]=done
+ end
+ return done
end
local function getwritablepath(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=w_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done=mkdirs(writable,...)
- else
- done=writable
- end
- w_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=w_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done=mkdirs(writable,...)
+ else
+ done=writable
end
- return done
+ w_cache[hash]=done
+ end
+ return done
end
caches.getreadablepaths=getreadablepaths
caches.getwritablepath=getwritablepath
function caches.getfirstreadablefile(filename,...)
- local fullname,path=caches.setfirstwritablefile(filename,...)
+ local fullname,path=caches.setfirstwritablefile(filename,...)
+ if is_readable(fullname) then
+ return fullname,path
+ end
+ local rd=getreadablepaths(...)
+ for i=1,#rd do
+ local path=rd[i]
+ local fullname=file.join(path,filename)
if is_readable(fullname) then
- return fullname,path
- end
- local rd=getreadablepaths(...)
- for i=1,#rd do
- local path=rd[i]
- local fullname=file.join(path,filename)
- if is_readable(fullname) then
- usedreadables[i]=true
- return fullname,path
- end
+ usedreadables[i]=true
+ return fullname,path
end
- return fullname,path
+ end
+ return fullname,path
end
function caches.setfirstwritablefile(filename,...)
- local wr=getwritablepath(...)
- local fullname=file.join(wr,filename)
- return fullname,wr
+ local wr=getwritablepath(...)
+ local fullname=file.join(wr,filename)
+ return fullname,wr
end
function caches.define(category,subcategory)
- return function()
- return getwritablepath(category,subcategory)
- end
+ return function()
+ return getwritablepath(category,subcategory)
+ end
end
function caches.setluanames(path,name)
- return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
+ return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
end
function caches.loaddata(readables,name,writable)
- if type(readables)=="string" then
- readables={ readables }
+ if type(readables)=="string" then
+ readables={ readables }
+ end
+ for i=1,#readables do
+ local path=readables[i]
+ local loader=false
+ local tmaname,tmcname=caches.setluanames(path,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader and isfile(tmaname) then
+ local tmacrap,tmcname=caches.setluanames(writable,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ utilities.lua.compile(tmaname,tmcname)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader then
+ loader=loadfile(tmaname)
+ end
end
- for i=1,#readables do
- local path=readables[i]
- local loader=false
- local tmaname,tmcname=caches.setluanames(path,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader and isfile(tmaname) then
- local tmacrap,tmcname=caches.setluanames(writable,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- utilities.lua.compile(tmaname,tmcname)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader then
- loader=loadfile(tmaname)
- end
- end
- if loader then
- loader=loader()
- collectgarbage("step")
- return loader
- end
+ if loader then
+ loader=loader()
+ collectgarbage("step")
+ return loader
end
- return false
+ end
+ return false
end
function caches.is_writable(filepath,filename)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- return is_writable(tmaname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ return is_writable(tmaname)
end
local saveoptions={ compact=true }
function caches.savedata(filepath,filename,data,raw)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- data.cache_uuid=os.uuid()
- if caches.direct then
- file.savedata(tmaname,table.serialize(data,true,saveoptions))
- else
- table.tofile(tmaname,data,true,saveoptions)
- end
- utilities.lua.compile(tmaname,tmcname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ data.cache_uuid=os.uuid()
+ if caches.direct then
+ file.savedata(tmaname,table.serialize(data,true,saveoptions))
+ else
+ table.tofile(tmaname,data,true,saveoptions)
+ end
+ utilities.lua.compile(tmaname,tmcname)
end
local content_state={}
function caches.contentstate()
- return content_state or {}
+ return content_state or {}
end
function caches.loadcontent(cachename,dataname,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
- if blob then
- local data=blob()
- if data and data.content then
- if data.type==dataname then
- if data.version==resolvers.cacheversion then
- content_state[#content_state+1]=data.uuid
- if trace_locating then
- report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
- end
- return data.content
- else
- report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
- end
- else
- report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
- end
- elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
+ if blob then
+ local data=blob()
+ if data and data.content then
+ if data.type==dataname then
+ if data.version==resolvers.cacheversion then
+ content_state[#content_state+1]=data.uuid
+ if trace_locating then
+ report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
+ end
+ return data.content
+ else
+ report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
end
+ else
+ report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
+ end
elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
end
+ elseif trace_locating then
+ report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ end
end
function caches.collapsecontent(content)
- for k,v in next,content do
- if type(v)=="table" and #v==1 then
- content[k]=v[1]
- end
+ for k,v in next,content do
+ if type(v)=="table" and #v==1 then
+ content[k]=v[1]
end
+ end
end
function caches.savecontent(cachename,dataname,content,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local luaname=addsuffix(filename,luasuffixes.lua)
- local lucname=addsuffix(filename,luasuffixes.luc)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local luaname=addsuffix(filename,luasuffixes.lua)
+ local lucname=addsuffix(filename,luasuffixes.luc)
+ if trace_locating then
+ report_resolvers("preparing %a for %a",dataname,cachename)
+ end
+ local data={
+ type=dataname,
+ root=cachename,
+ version=resolvers.cacheversion,
+ date=os.date("%Y-%m-%d"),
+ time=os.date("%H:%M:%S"),
+ content=content,
+ uuid=os.uuid(),
+ }
+ local ok=io.savedata(luaname,table.serialize(data,true))
+ if ok then
if trace_locating then
- report_resolvers("preparing %a for %a",dataname,cachename)
- end
- local data={
- type=dataname,
- root=cachename,
- version=resolvers.cacheversion,
- date=os.date("%Y-%m-%d"),
- time=os.date("%H:%M:%S"),
- content=content,
- uuid=os.uuid(),
- }
- local ok=io.savedata(luaname,table.serialize(data,true))
- if ok then
- if trace_locating then
- report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
- end
- if utilities.lua.compile(luaname,lucname) then
- if trace_locating then
- report_resolvers("%a compiled to %a",dataname,lucname)
- end
- return true
- else
- if trace_locating then
- report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
- end
- os.remove(lucname)
- end
- elseif trace_locating then
- report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
end
+ if utilities.lua.compile(luaname,lucname) then
+ if trace_locating then
+ report_resolvers("%a compiled to %a",dataname,lucname)
+ end
+ return true
+ else
+ if trace_locating then
+ report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
+ end
+ os.remove(lucname)
+ end
+ elseif trace_locating then
+ report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ end
end
@@ -20976,14 +20984,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-met"] = package.loaded["data-met"] or true
--- original size: 5310, stripped down to: 3980
+-- original size: 5310, stripped down to: 3784
if not modules then modules={} end modules ['data-met']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local find,format=string.find,string.format
local sequenced=table.sequenced
@@ -20997,86 +21005,86 @@ local allocate=utilities.storage.allocate
local resolvers=resolvers
local registered={}
local function splitmethod(filename)
- if not filename then
- return { scheme="unknown",original=filename }
- end
- if type(filename)=="table" then
- return filename
- end
- filename=file.collapsepath(filename,".")
- if not find(filename,"://",1,true) then
- return { scheme="file",path=filename,original=filename,filename=filename }
- end
- local specification=url.hashed(filename)
- if not specification.scheme or specification.scheme=="" then
- return { scheme="file",path=filename,original=filename,filename=filename }
- else
- return specification
- end
+ if not filename then
+ return { scheme="unknown",original=filename }
+ end
+ if type(filename)=="table" then
+ return filename
+ end
+ filename=file.collapsepath(filename,".")
+ if not find(filename,"://",1,true) then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ end
+ local specification=url.hashed(filename)
+ if not specification.scheme or specification.scheme=="" then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ else
+ return specification
+ end
end
resolvers.splitmethod=splitmethod
local function methodhandler(what,first,...)
- local method=registered[what]
- if method then
- local how,namespace=method.how,method.namespace
- if how=="uri" or how=="url" then
- local specification=splitmethod(first)
- local scheme=specification.scheme
- local resolver=namespace and namespace[scheme]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
- end
- return resolver(specification,...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
- end
- return resolver(specification,...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
- end
- end
- elseif how=="tag" then
- local resolver=namespace and namespace[first]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,first)
- end
- return resolver(...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
- end
- return resolver(...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
- end
- end
+ local method=registered[what]
+ if method then
+ local how,namespace=method.how,method.namespace
+ if how=="uri" or how=="url" then
+ local specification=splitmethod(first)
+ local scheme=specification.scheme
+ local resolver=namespace and namespace[scheme]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
+ end
+ return resolver(specification,...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
+ end
+ return resolver(specification,...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
end
- else
- report_methods("resolving, invalid method %a")
+ end
+ elseif how=="tag" then
+ local resolver=namespace and namespace[first]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,first)
+ end
+ return resolver(...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
+ end
+ return resolver(...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
+ end
+ end
end
+ else
+ report_methods("resolving, invalid method %a")
+ end
end
resolvers.methodhandler=methodhandler
function resolvers.registermethod(name,namespace,how)
- registered[name]={ how=how or "tag",namespace=namespace }
- namespace["byscheme"]=function(scheme,filename,...)
- if scheme=="file" then
- return methodhandler(name,filename,...)
- else
- return methodhandler(name,addurlscheme(filename,scheme),...)
- end
+ registered[name]={ how=how or "tag",namespace=namespace }
+ namespace["byscheme"]=function(scheme,filename,...)
+ if scheme=="file" then
+ return methodhandler(name,filename,...)
+ else
+ return methodhandler(name,addurlscheme(filename,scheme),...)
end
+ end
end
-local concatinators=allocate { notfound=file.join }
-local locators=allocate { notfound=function() end }
-local hashers=allocate { notfound=function() end }
-local generators=allocate { notfound=function() end }
+local concatinators=allocate { notfound=file.join }
+local locators=allocate { notfound=function() end }
+local hashers=allocate { notfound=function() end }
+local generators=allocate { notfound=function() end }
resolvers.concatinators=concatinators
resolvers.locators=locators
resolvers.hashers=hashers
@@ -21094,14 +21102,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-res"] = package.loaded["data-res"] or true
--- original size: 68195, stripped down to: 47727
+-- original size: 68195, stripped down to: 43680
if not modules then modules={} end modules ['data-res']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local gsub,find,lower,upper,match,gmatch=string.gsub,string.find,string.lower,string.upper,string.match,string.gmatch
local concat,insert,remove=table.concat,table.insert,table.remove
@@ -21126,11 +21134,11 @@ local isfile=lfs.isfile
local isdir=lfs.isdir
local setmetatableindex=table.setmetatableindex
local luasuffixes=utilities.lua.suffixes
-local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
-local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
+local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
+local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
local report_resolving=logs.reporter("resolvers","resolving")
local resolvers=resolvers
local expandedpathfromlist=resolvers.expandedpathfromlist
@@ -21151,15 +21159,15 @@ resolvers.luacnfname="texmfcnf.lua"
resolvers.luacnffallback="contextcnf.lua"
resolvers.luacnfstate="unknown"
if environment.default_texmfcnf then
- resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
+ resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
else
- resolvers.luacnfspec=concat ({
- "home:texmf/web2c",
- "selfautoparent:/texmf-local/web2c",
- "selfautoparent:/texmf-context/web2c",
- "selfautoparent:/texmf-dist/web2c",
- "selfautoparent:/texmf/web2c",
- },";")
+ resolvers.luacnfspec=concat ({
+ "home:texmf/web2c",
+ "selfautoparent:/texmf-local/web2c",
+ "selfautoparent:/texmf-context/web2c",
+ "selfautoparent:/texmf-dist/web2c",
+ "selfautoparent:/texmf/web2c",
+ },";")
end
local unset_variable="unset"
local formats=resolvers.formats
@@ -21170,24 +21178,24 @@ local suffixmap=resolvers.suffixmap
resolvers.defaultsuffixes={ "tex" }
local instance=nil
function resolvers.setenv(key,value,raw)
- if instance then
- instance.environment[key]=value
- ossetenv(key,raw and value or resolveprefix(value))
- end
+ if instance then
+ instance.environment[key]=value
+ ossetenv(key,raw and value or resolveprefix(value))
+ end
end
local function getenv(key)
- local value=rawget(instance.environment,key)
- if value and value~="" then
- return value
- else
- local e=osgetenv(key)
- return e~=nil and e~="" and checkedvariable(e) or ""
- end
+ local value=rawget(instance.environment,key)
+ if value and value~="" then
+ return value
+ else
+ local e=osgetenv(key)
+ return e~=nil and e~="" and checkedvariable(e) or ""
+ end
end
resolvers.getenv=getenv
resolvers.env=getenv
local function resolvevariable(k)
- return instance.expansions[k]
+ return instance.expansions[k]
end
local dollarstripper=lpeg.stripper("$")
local inhibitstripper=P("!")^0*Cs(P(1)^0)
@@ -21201,1506 +21209,1506 @@ local somevariable=R("az","AZ","09","__","--")^1/resolvevariable
local variable=(P("$")/"")*(somevariable+(P("{")/"")*somevariable*(P("}")/""))
local variableresolver=Cs((variable+P(1))^0)
local function expandedvariable(var)
- return lpegmatch(variableexpander,var) or var
+ return lpegmatch(variableexpander,var) or var
end
function resolvers.reset()
- if trace_locating then
- report_resolving("creating instance")
- end
- local environment={}
- local variables={}
- local expansions={}
- local order={}
- instance={
- environment=environment,
- variables=variables,
- expansions=expansions,
- order=order,
- files={},
- setups={},
- found={},
- foundintrees={},
- hashes={},
- hashed={},
- pathlists=false,
- specification={},
- lists={},
- data={},
- fakepaths={},
- remember=true,
- diskcache=true,
- renewcache=false,
- renewtree=false,
- loaderror=false,
- savelists=true,
- pattern=nil,
- force_suffixes=true,
- pathstack={},
- }
- setmetatableindex(variables,function(t,k)
- local v
- for i=1,#order do
- v=order[i][k]
- if v~=nil then
- t[k]=v
- return v
- end
- end
- if v==nil then
- v=""
- end
+ if trace_locating then
+ report_resolving("creating instance")
+ end
+ local environment={}
+ local variables={}
+ local expansions={}
+ local order={}
+ instance={
+ environment=environment,
+ variables=variables,
+ expansions=expansions,
+ order=order,
+ files={},
+ setups={},
+ found={},
+ foundintrees={},
+ hashes={},
+ hashed={},
+ pathlists=false,
+ specification={},
+ lists={},
+ data={},
+ fakepaths={},
+ remember=true,
+ diskcache=true,
+ renewcache=false,
+ renewtree=false,
+ loaderror=false,
+ savelists=true,
+ pattern=nil,
+ force_suffixes=true,
+ pathstack={},
+ }
+ setmetatableindex(variables,function(t,k)
+ local v
+ for i=1,#order do
+ v=order[i][k]
+ if v~=nil then
t[k]=v
return v
- end)
- setmetatableindex(environment,function(t,k)
- local v=osgetenv(k)
- if v==nil then
- v=variables[k]
- end
- if v~=nil then
- v=checkedvariable(v) or ""
- end
- v=resolvers.repath(v)
- t[k]=v
- return v
- end)
- setmetatableindex(expansions,function(t,k)
- local v=environment[k]
- if type(v)=="string" then
- v=lpegmatch(variableresolver,v)
- v=lpegmatch(variablecleaner,v)
- end
- t[k]=v
- return v
- end)
+ end
+ end
+ if v==nil then
+ v=""
+ end
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(environment,function(t,k)
+ local v=osgetenv(k)
+ if v==nil then
+ v=variables[k]
+ end
+ if v~=nil then
+ v=checkedvariable(v) or ""
+ end
+ v=resolvers.repath(v)
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(expansions,function(t,k)
+ local v=environment[k]
+ if type(v)=="string" then
+ v=lpegmatch(variableresolver,v)
+ v=lpegmatch(variablecleaner,v)
+ end
+ t[k]=v
+ return v
+ end)
end
function resolvers.initialized()
- return instance~=nil
+ return instance~=nil
end
local function reset_hashes()
- instance.lists={}
- instance.pathlists=false
- instance.found={}
+ instance.lists={}
+ instance.pathlists=false
+ instance.found={}
end
local function reset_caches()
- instance.lists={}
- instance.pathlists=false
+ instance.lists={}
+ instance.pathlists=false
end
local slash=P("/")
local pathexpressionpattern=Cs (
- Cc("^")*(
- Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+ Cc("^")*(
+ Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+slash^2/"/"+(1-slash)*P(-1)*Cc("/")+P(1)
- )^1*Cc("$")
+ )^1*Cc("$")
)
local cache={}
local function makepathexpression(str)
- if str=="." then
- return "^%./$"
- else
- local c=cache[str]
- if not c then
- c=lpegmatch(pathexpressionpattern,str)
- cache[str]=c
- end
- return c
+ if str=="." then
+ return "^%./$"
+ else
+ local c=cache[str]
+ if not c then
+ c=lpegmatch(pathexpressionpattern,str)
+ cache[str]=c
end
+ return c
+ end
end
local function reportcriticalvariables(cnfspec)
- if trace_locating then
- for i=1,#resolvers.criticalvars do
- local k=resolvers.criticalvars[i]
- local v=resolvers.getenv(k) or "unknown"
- report_resolving("variable %a set to %a",k,v)
- end
- report_resolving()
- if cnfspec then
- report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
- end
- report_resolving()
+ if trace_locating then
+ for i=1,#resolvers.criticalvars do
+ local k=resolvers.criticalvars[i]
+ local v=resolvers.getenv(k) or "unknown"
+ report_resolving("variable %a set to %a",k,v)
+ end
+ report_resolving()
+ if cnfspec then
+ report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
end
- reportcriticalvariables=function() end
+ report_resolving()
+ end
+ reportcriticalvariables=function() end
end
local function identify_configuration_files()
- local specification=instance.specification
- if #specification==0 then
- local cnfspec=getenv("TEXMFCNF")
- if cnfspec=="" then
- cnfspec=resolvers.luacnfspec
- resolvers.luacnfstate="default"
- else
- resolvers.luacnfstate="environment"
- end
- reportcriticalvariables(cnfspec)
- local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
- local function locatecnf(luacnfname,kind)
- for i=1,#cnfpaths do
- local filepath=cnfpaths[i]
- local filename=collapsepath(filejoin(filepath,luacnfname))
- local realname=resolveprefix(filename)
- if trace_locating then
- local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
- local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
- report_resolving("looking for %s %a on %s path %a from specification %a",
- kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
- end
- if isfile(realname) then
- specification[#specification+1]=filename
- if trace_locating then
- report_resolving("found %s configuration file %a",kind,realname)
- end
- end
- end
- end
- locatecnf(resolvers.luacnfname,"regular")
- if #specification==0 then
- locatecnf(resolvers.luacnffallback,"fallback")
- end
+ local specification=instance.specification
+ if #specification==0 then
+ local cnfspec=getenv("TEXMFCNF")
+ if cnfspec=="" then
+ cnfspec=resolvers.luacnfspec
+ resolvers.luacnfstate="default"
+ else
+ resolvers.luacnfstate="environment"
+ end
+ reportcriticalvariables(cnfspec)
+ local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
+ local function locatecnf(luacnfname,kind)
+ for i=1,#cnfpaths do
+ local filepath=cnfpaths[i]
+ local filename=collapsepath(filejoin(filepath,luacnfname))
+ local realname=resolveprefix(filename)
if trace_locating then
- report_resolving()
+ local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
+ local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
+ report_resolving("looking for %s %a on %s path %a from specification %a",
+ kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
+ end
+ if isfile(realname) then
+ specification[#specification+1]=filename
+ if trace_locating then
+ report_resolving("found %s configuration file %a",kind,realname)
+ end
end
- elseif trace_locating then
- report_resolving("configuration files already identified")
+ end
end
+ locatecnf(resolvers.luacnfname,"regular")
+ if #specification==0 then
+ locatecnf(resolvers.luacnffallback,"fallback")
+ end
+ if trace_locating then
+ report_resolving()
+ end
+ elseif trace_locating then
+ report_resolving("configuration files already identified")
+ end
end
local function load_configuration_files()
- local specification=instance.specification
- if #specification>0 then
- local luacnfname=resolvers.luacnfname
- for i=1,#specification do
- local filename=specification[i]
- local pathname=filedirname(filename)
- local filename=filejoin(pathname,luacnfname)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local setups=instance.setups
- local data=blob()
- local parent=data and data.parent
- if parent then
- local filename=filejoin(pathname,parent)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local parentdata=blob()
- if parentdata then
- report_resolving("loading configuration file %a",filename)
- data=table.merged(parentdata,data)
- end
- end
- end
- data=data and data.content
- if data then
- if trace_locating then
- report_resolving("loading configuration file %a",filename)
- report_resolving()
- end
- local variables=data.variables or {}
- local warning=false
- for k,v in next,data do
- local variant=type(v)
- if variant=="table" then
- initializesetter(filename,k,v)
- elseif variables[k]==nil then
- if trace_locating and not warning then
- report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
- k,resolveprefix(filename))
- warning=true
- end
- variables[k]=v
- end
- end
- setups[pathname]=variables
- if resolvers.luacnfstate=="default" then
- local cnfspec=variables["TEXMFCNF"]
- if cnfspec then
- if trace_locating then
- report_resolving("reloading configuration due to TEXMF redefinition")
- end
- resolvers.setenv("TEXMFCNF",cnfspec)
- instance.specification={}
- identify_configuration_files()
- load_configuration_files()
- resolvers.luacnfstate="configuration"
- break
- end
- end
- else
- if trace_locating then
- report_resolving("skipping configuration file %a (no content)",filename)
- end
- setups[pathname]={}
- instance.loaderror=true
- end
- elseif trace_locating then
- report_resolving("skipping configuration file %a (no valid format)",filename)
+ local specification=instance.specification
+ if #specification>0 then
+ local luacnfname=resolvers.luacnfname
+ for i=1,#specification do
+ local filename=specification[i]
+ local pathname=filedirname(filename)
+ local filename=filejoin(pathname,luacnfname)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local setups=instance.setups
+ local data=blob()
+ local parent=data and data.parent
+ if parent then
+ local filename=filejoin(pathname,parent)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local parentdata=blob()
+ if parentdata then
+ report_resolving("loading configuration file %a",filename)
+ data=table.merged(parentdata,data)
end
- instance.order[#instance.order+1]=instance.setups[pathname]
- if instance.loaderror then
- break
+ end
+ end
+ data=data and data.content
+ if data then
+ if trace_locating then
+ report_resolving("loading configuration file %a",filename)
+ report_resolving()
+ end
+ local variables=data.variables or {}
+ local warning=false
+ for k,v in next,data do
+ local variant=type(v)
+ if variant=="table" then
+ initializesetter(filename,k,v)
+ elseif variables[k]==nil then
+ if trace_locating and not warning then
+ report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
+ k,resolveprefix(filename))
+ warning=true
+ end
+ variables[k]=v
+ end
+ end
+ setups[pathname]=variables
+ if resolvers.luacnfstate=="default" then
+ local cnfspec=variables["TEXMFCNF"]
+ if cnfspec then
+ if trace_locating then
+ report_resolving("reloading configuration due to TEXMF redefinition")
+ end
+ resolvers.setenv("TEXMFCNF",cnfspec)
+ instance.specification={}
+ identify_configuration_files()
+ load_configuration_files()
+ resolvers.luacnfstate="configuration"
+ break
end
+ end
+ else
+ if trace_locating then
+ report_resolving("skipping configuration file %a (no content)",filename)
+ end
+ setups[pathname]={}
+ instance.loaderror=true
end
- elseif trace_locating then
- report_resolving("warning: no lua configuration files found")
+ elseif trace_locating then
+ report_resolving("skipping configuration file %a (no valid format)",filename)
+ end
+ instance.order[#instance.order+1]=instance.setups[pathname]
+ if instance.loaderror then
+ break
+ end
end
+ elseif trace_locating then
+ report_resolving("warning: no lua configuration files found")
+ end
end
function resolvers.configurationfiles()
- return instance.specification or {}
+ return instance.specification or {}
end
local function load_file_databases()
- instance.loaderror=false
- instance.files={}
- if not instance.renewcache then
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- resolvers.hashers.byscheme(hash.type,hash.name)
- if instance.loaderror then break end
- end
+ instance.loaderror=false
+ instance.files={}
+ if not instance.renewcache then
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ resolvers.hashers.byscheme(hash.type,hash.name)
+ if instance.loaderror then break end
end
+ end
end
local function locate_file_databases()
- local texmfpaths=resolvers.expandedpathlist("TEXMF")
- if #texmfpaths>0 then
- for i=1,#texmfpaths do
- local path=collapsepath(texmfpaths[i])
- path=gsub(path,"/+$","")
- local stripped=lpegmatch(inhibitstripper,path)
- if stripped~="" then
- local runtime=stripped==path
- path=cleanpath(path)
- local spec=resolvers.splitmethod(stripped)
- if runtime and (spec.noscheme or spec.scheme=="file") then
- stripped="tree:///"..stripped
- elseif spec.scheme=="cache" or spec.scheme=="file" then
- stripped=spec.path
- end
- if trace_locating then
- if runtime then
- report_resolving("locating list of %a (runtime) (%s)",path,stripped)
- else
- report_resolving("locating list of %a (cached)",path)
- end
- end
- methodhandler('locators',stripped)
- end
+ local texmfpaths=resolvers.expandedpathlist("TEXMF")
+ if #texmfpaths>0 then
+ for i=1,#texmfpaths do
+ local path=collapsepath(texmfpaths[i])
+ path=gsub(path,"/+$","")
+ local stripped=lpegmatch(inhibitstripper,path)
+ if stripped~="" then
+ local runtime=stripped==path
+ path=cleanpath(path)
+ local spec=resolvers.splitmethod(stripped)
+ if runtime and (spec.noscheme or spec.scheme=="file") then
+ stripped="tree:///"..stripped
+ elseif spec.scheme=="cache" or spec.scheme=="file" then
+ stripped=spec.path
end
if trace_locating then
- report_resolving()
+ if runtime then
+ report_resolving("locating list of %a (runtime) (%s)",path,stripped)
+ else
+ report_resolving("locating list of %a (cached)",path)
+ end
end
- elseif trace_locating then
- report_resolving("no texmf paths are defined (using TEXMF)")
- end
-end
-local function generate_file_databases()
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- methodhandler('generators',hash.name)
+ methodhandler('locators',stripped)
+ end
end
if trace_locating then
- report_resolving()
+ report_resolving()
end
+ elseif trace_locating then
+ report_resolving("no texmf paths are defined (using TEXMF)")
+ end
+end
+local function generate_file_databases()
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ methodhandler('generators',hash.name)
+ end
+ if trace_locating then
+ report_resolving()
+ end
end
local function save_file_databases()
- for i=1,#instance.hashes do
- local hash=instance.hashes[i]
- local cachename=hash.name
- if hash.cache then
- local content=instance.files[cachename]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",cachename)
- end
- caches.savecontent(cachename,"files",content)
- elseif trace_locating then
- report_resolving("not saving runtime tree %a",cachename)
- end
+ for i=1,#instance.hashes do
+ local hash=instance.hashes[i]
+ local cachename=hash.name
+ if hash.cache then
+ local content=instance.files[cachename]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",cachename)
+ end
+ caches.savecontent(cachename,"files",content)
+ elseif trace_locating then
+ report_resolving("not saving runtime tree %a",cachename)
end
+ end
end
function resolvers.renew(hashname)
- if hashname and hashname~="" then
- local expanded=resolvers.expansion(hashname) or ""
- if expanded~="" then
- if trace_locating then
- report_resolving("identifying tree %a from %a",expanded,hashname)
- end
- hashname=expanded
- else
- if trace_locating then
- report_resolving("identifying tree %a",hashname)
- end
- end
- local realpath=resolveprefix(hashname)
- if isdir(realpath) then
- if trace_locating then
- report_resolving("using path %a",realpath)
- end
- methodhandler('generators',hashname)
- local content=instance.files[hashname]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",hashname)
- end
- caches.savecontent(hashname,"files",content)
- else
- report_resolving("invalid path %a",realpath)
- end
+ if hashname and hashname~="" then
+ local expanded=resolvers.expansion(hashname) or ""
+ if expanded~="" then
+ if trace_locating then
+ report_resolving("identifying tree %a from %a",expanded,hashname)
+ end
+ hashname=expanded
+ else
+ if trace_locating then
+ report_resolving("identifying tree %a",hashname)
+ end
end
+ local realpath=resolveprefix(hashname)
+ if isdir(realpath) then
+ if trace_locating then
+ report_resolving("using path %a",realpath)
+ end
+ methodhandler('generators',hashname)
+ local content=instance.files[hashname]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",hashname)
+ end
+ caches.savecontent(hashname,"files",content)
+ else
+ report_resolving("invalid path %a",realpath)
+ end
+ end
end
local function load_databases()
- locate_file_databases()
- if instance.diskcache and not instance.renewcache then
- load_file_databases()
- if instance.loaderror then
- generate_file_databases()
- save_file_databases()
- end
- else
- generate_file_databases()
- if instance.renewcache then
- save_file_databases()
- end
+ locate_file_databases()
+ if instance.diskcache and not instance.renewcache then
+ load_file_databases()
+ if instance.loaderror then
+ generate_file_databases()
+ save_file_databases()
+ end
+ else
+ generate_file_databases()
+ if instance.renewcache then
+ save_file_databases()
end
+ end
end
function resolvers.appendhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a appended",name)
- end
- insert(instance.hashes,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a appended",name)
end
+ insert(instance.hashes,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.prependhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a prepended",name)
- end
- insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a prepended",name)
end
+ insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.extendtexmfvariable(specification)
- local t=resolvers.splitpath(getenv("TEXMF"))
- insert(t,1,specification)
- local newspec=concat(t,",")
- if instance.environment["TEXMF"] then
- instance.environment["TEXMF"]=newspec
- elseif instance.variables["TEXMF"] then
- instance.variables["TEXMF"]=newspec
- else
- end
- reset_hashes()
+ local t=resolvers.splitpath(getenv("TEXMF"))
+ insert(t,1,specification)
+ local newspec=concat(t,",")
+ if instance.environment["TEXMF"] then
+ instance.environment["TEXMF"]=newspec
+ elseif instance.variables["TEXMF"] then
+ instance.variables["TEXMF"]=newspec
+ else
+ end
+ reset_hashes()
end
function resolvers.splitexpansions()
- local ie=instance.expansions
- for k,v in next,ie do
- local t,tn,h,p={},0,{},splitconfigurationpath(v)
- for kk=1,#p do
- local vv=p[kk]
- if vv~="" and not h[vv] then
- tn=tn+1
- t[tn]=vv
- h[vv]=true
- end
- end
- if #t>1 then
- ie[k]=t
- else
- ie[k]=t[1]
- end
+ local ie=instance.expansions
+ for k,v in next,ie do
+ local t,tn,h,p={},0,{},splitconfigurationpath(v)
+ for kk=1,#p do
+ local vv=p[kk]
+ if vv~="" and not h[vv] then
+ tn=tn+1
+ t[tn]=vv
+ h[vv]=true
+ end
end
+ if #t>1 then
+ ie[k]=t
+ else
+ ie[k]=t[1]
+ end
+ end
end
function resolvers.datastate()
- return caches.contentstate()
+ return caches.contentstate()
end
function resolvers.variable(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.variables[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.variables[name]
+ return result~=nil and result or ""
end
function resolvers.expansion(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.expansions[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.expansions[name]
+ return result~=nil and result or ""
end
function resolvers.unexpandedpathlist(str)
- local pth=resolvers.variable(str)
- local lst=resolvers.splitpath(pth)
- return expandedpathfromlist(lst)
+ local pth=resolvers.variable(str)
+ local lst=resolvers.splitpath(pth)
+ return expandedpathfromlist(lst)
end
function resolvers.unexpandedpath(str)
- return joinpath(resolvers.unexpandedpathlist(str))
+ return joinpath(resolvers.unexpandedpathlist(str))
end
function resolvers.pushpath(name)
- local pathstack=instance.pathstack
- local lastpath=pathstack[#pathstack]
- local pluspath=filedirname(name)
- if lastpath then
- lastpath=collapsepath(filejoin(lastpath,pluspath))
- else
- lastpath=collapsepath(pluspath)
- end
- insert(pathstack,lastpath)
- if trace_paths then
- report_resolving("pushing path %a",lastpath)
- end
+ local pathstack=instance.pathstack
+ local lastpath=pathstack[#pathstack]
+ local pluspath=filedirname(name)
+ if lastpath then
+ lastpath=collapsepath(filejoin(lastpath,pluspath))
+ else
+ lastpath=collapsepath(pluspath)
+ end
+ insert(pathstack,lastpath)
+ if trace_paths then
+ report_resolving("pushing path %a",lastpath)
+ end
end
function resolvers.poppath()
- local pathstack=instance.pathstack
- if trace_paths and #pathstack>0 then
- report_resolving("popping path %a",pathstack[#pathstack])
- end
- remove(pathstack)
+ local pathstack=instance.pathstack
+ if trace_paths and #pathstack>0 then
+ report_resolving("popping path %a",pathstack[#pathstack])
+ end
+ remove(pathstack)
end
function resolvers.stackpath()
- local pathstack=instance.pathstack
- local currentpath=pathstack[#pathstack]
- return currentpath~="" and currentpath or nil
+ local pathstack=instance.pathstack
+ local currentpath=pathstack[#pathstack]
+ return currentpath~="" and currentpath or nil
end
local done={}
function resolvers.resetextrapaths()
- local ep=instance.extra_paths
- if not ep then
- done={}
- instance.extra_paths={}
- elseif #ep>0 then
- done={}
- reset_caches()
- end
+ local ep=instance.extra_paths
+ if not ep then
+ done={}
+ instance.extra_paths={}
+ elseif #ep>0 then
+ done={}
+ reset_caches()
+ end
end
function resolvers.getextrapaths()
- return instance.extra_paths or {}
+ return instance.extra_paths or {}
end
function resolvers.registerextrapath(paths,subpaths)
- if not subpaths or subpaths=="" then
- if not paths or path=="" then
- return
- elseif done[paths] then
- return
- end
- end
- local paths=settings_to_array(paths)
- local subpaths=settings_to_array(subpaths)
- local ep=instance.extra_paths or {}
- local oldn=#ep
- local newn=oldn
- local nofpaths=#paths
- local nofsubpaths=#subpaths
- if nofpaths>0 then
- if nofsubpaths>0 then
- for i=1,nofpaths do
- local p=paths[i]
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=p.."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
- end
- else
- for i=1,nofpaths do
- local p=paths[i]
- if not done[p] then
- newn=newn+1
- ep[newn]=cleanpath(p)
- done[p]=true
- end
- end
+ if not subpaths or subpaths=="" then
+ if not paths or path=="" then
+ return
+ elseif done[paths] then
+ return
+ end
+ end
+ local paths=settings_to_array(paths)
+ local subpaths=settings_to_array(subpaths)
+ local ep=instance.extra_paths or {}
+ local oldn=#ep
+ local newn=oldn
+ local nofpaths=#paths
+ local nofsubpaths=#subpaths
+ if nofpaths>0 then
+ if nofsubpaths>0 then
+ for i=1,nofpaths do
+ local p=paths[i]
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=p.."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
end
- elseif nofsubpaths>0 then
- for i=1,oldn do
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=ep[i].."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
+ end
+ else
+ for i=1,nofpaths do
+ local p=paths[i]
+ if not done[p] then
+ newn=newn+1
+ ep[newn]=cleanpath(p)
+ done[p]=true
end
+ end
end
- if newn>0 then
- instance.extra_paths=ep
- end
- if newn~=oldn then
- reset_caches()
+ elseif nofsubpaths>0 then
+ for i=1,oldn do
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=ep[i].."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
+ end
end
+ end
+ if newn>0 then
+ instance.extra_paths=ep
+ end
+ if newn~=oldn then
+ reset_caches()
+ end
end
function resolvers.pushextrapath(path)
- local paths=settings_to_array(path)
- if instance.extra_stack then
- insert(instance.extra_stack,1,paths)
- else
- instance.extra_stack={ paths }
- end
- reset_caches()
+ local paths=settings_to_array(path)
+ if instance.extra_stack then
+ insert(instance.extra_stack,1,paths)
+ else
+ instance.extra_stack={ paths }
+ end
+ reset_caches()
end
function resolvers.popextrapath()
- if instance.extra_stack then
- reset_caches()
- return remove(instance.extra_stack,1)
- end
+ if instance.extra_stack then
+ reset_caches()
+ return remove(instance.extra_stack,1)
+ end
end
local function made_list(instance,list,extra_too)
- local done={}
- local new={}
- local newn=0
- local function add(p)
- for k=1,#p do
- local v=p[k]
- if not done[v] then
- done[v]=true
- newn=newn+1
- new[newn]=v
- end
- end
+ local done={}
+ local new={}
+ local newn=0
+ local function add(p)
+ for k=1,#p do
+ local v=p[k]
+ if not done[v] then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ end
end
- for k=1,#list do
- local v=list[k]
- if done[v] then
- elseif find(v,"^[%.%/]$") then
- done[v]=true
- newn=newn+1
- new[newn]=v
- else
- break
- end
+ end
+ for k=1,#list do
+ local v=list[k]
+ if done[v] then
+ elseif find(v,"^[%.%/]$") then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ else
+ break
+ end
+ end
+ if extra_too then
+ local es=instance.extra_stack
+ if es and #es>0 then
+ for k=1,#es do
+ add(es[k])
+ end
end
- if extra_too then
- local es=instance.extra_stack
- if es and #es>0 then
- for k=1,#es do
- add(es[k])
- end
- end
- local ep=instance.extra_paths
- if ep and #ep>0 then
- add(ep)
- end
+ local ep=instance.extra_paths
+ if ep and #ep>0 then
+ add(ep)
end
- add(list)
- return new
+ end
+ add(list)
+ return new
end
function resolvers.cleanpathlist(str)
- local t=resolvers.expandedpathlist(str)
- if t then
- for i=1,#t do
- t[i]=collapsepath(cleanpath(t[i]))
- end
+ local t=resolvers.expandedpathlist(str)
+ if t then
+ for i=1,#t do
+ t[i]=collapsepath(cleanpath(t[i]))
end
- return t
+ end
+ return t
end
function resolvers.expandpath(str)
- return joinpath(resolvers.expandedpathlist(str))
+ return joinpath(resolvers.expandedpathlist(str))
end
function resolvers.expandedpathlist(str,extra_too)
- if not str then
- return {}
- elseif instance.savelists then
- str=lpegmatch(dollarstripper,str)
- local lists=instance.lists
- local lst=lists[str]
- if not lst then
- local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
- lst=expandedpathfromlist(l)
- lists[str]=lst
- end
- return lst
- else
- local lst=resolvers.splitpath(resolvers.expansion(str))
- return made_list(instance,expandedpathfromlist(lst),extra_too)
+ if not str then
+ return {}
+ elseif instance.savelists then
+ str=lpegmatch(dollarstripper,str)
+ local lists=instance.lists
+ local lst=lists[str]
+ if not lst then
+ local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
+ lst=expandedpathfromlist(l)
+ lists[str]=lst
end
+ return lst
+ else
+ local lst=resolvers.splitpath(resolvers.expansion(str))
+ return made_list(instance,expandedpathfromlist(lst),extra_too)
+ end
end
function resolvers.expandedpathlistfromvariable(str)
- str=lpegmatch(dollarstripper,str)
- local tmp=resolvers.variableofformatorsuffix(str)
- return resolvers.expandedpathlist(tmp~="" and tmp or str)
+ str=lpegmatch(dollarstripper,str)
+ local tmp=resolvers.variableofformatorsuffix(str)
+ return resolvers.expandedpathlist(tmp~="" and tmp or str)
end
function resolvers.expandpathfromvariable(str)
- return joinpath(resolvers.expandedpathlistfromvariable(str))
+ return joinpath(resolvers.expandedpathlistfromvariable(str))
end
function resolvers.cleanedpathlist(v)
- local t=resolvers.expandedpathlist(v)
- for i=1,#t do
- t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
- end
- return t
+ local t=resolvers.expandedpathlist(v)
+ for i=1,#t do
+ t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
+ end
+ return t
end
function resolvers.expandbraces(str)
- local pth=expandedpathfromlist(resolvers.splitpath(str))
- return joinpath(pth)
+ local pth=expandedpathfromlist(resolvers.splitpath(str))
+ return joinpath(pth)
end
function resolvers.registerfilehash(name,content,someerror)
- if content then
- instance.files[name]=content
- else
- instance.files[name]={}
- if somerror==true then
- instance.loaderror=someerror
- end
+ if content then
+ instance.files[name]=content
+ else
+ instance.files[name]={}
+ if somerror==true then
+ instance.loaderror=someerror
end
+ end
end
function resolvers.getfilehashes()
- return instance and instance.files or {}
+ return instance and instance.files or {}
end
function resolvers.gethashes()
- return instance and instance.hashes or {}
+ return instance and instance.hashes or {}
end
function resolvers.renewcache()
- if instance then
- instance.renewcache=true
- end
+ if instance then
+ instance.renewcache=true
+ end
end
local function isreadable(name)
- local readable=isfile(name)
- if trace_detail then
- if readable then
- report_resolving("file %a is readable",name)
- else
- report_resolving("file %a is not readable",name)
- end
+ local readable=isfile(name)
+ if trace_detail then
+ if readable then
+ report_resolving("file %a is readable",name)
+ else
+ report_resolving("file %a is not readable",name)
end
- return readable
+ end
+ return readable
end
local function collect_files(names)
- local filelist={}
- local noffiles=0
- local function check(hash,root,pathname,path,basename,name)
- if not pathname or find(path,pathname) then
- local variant=hash.type
- local search=filejoin(root,path,name)
- local result=methodhandler('concatinators',variant,root,path,name)
- if trace_detail then
- report_resolving("match: variant %a, search %a, result %a",variant,search,result)
- end
- noffiles=noffiles+1
- filelist[noffiles]={ variant,search,result }
- end
+ local filelist={}
+ local noffiles=0
+ local function check(hash,root,pathname,path,basename,name)
+ if not pathname or find(path,pathname) then
+ local variant=hash.type
+ local search=filejoin(root,path,name)
+ local result=methodhandler('concatinators',variant,root,path,name)
+ if trace_detail then
+ report_resolving("match: variant %a, search %a, result %a",variant,search,result)
+ end
+ noffiles=noffiles+1
+ filelist[noffiles]={ variant,search,result }
end
- for k=1,#names do
- local filename=names[k]
+ end
+ for k=1,#names do
+ local filename=names[k]
+ if trace_detail then
+ report_resolving("checking name %a",filename)
+ end
+ local basename=filebasename(filename)
+ local pathname=filedirname(filename)
+ if pathname=="" or find(pathname,"^%.") then
+ pathname=false
+ else
+ pathname=gsub(pathname,"%*",".*")
+ pathname="/"..pathname.."$"
+ end
+ local hashes=instance.hashes
+ for h=1,#hashes do
+ local hash=hashes[h]
+ local hashname=hash.name
+ local content=hashname and instance.files[hashname]
+ if content then
if trace_detail then
- report_resolving("checking name %a",filename)
+ report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
end
- local basename=filebasename(filename)
- local pathname=filedirname(filename)
- if pathname=="" or find(pathname,"^%.") then
- pathname=false
- else
- pathname=gsub(pathname,"%*",".*")
- pathname="/"..pathname.."$"
- end
- local hashes=instance.hashes
- for h=1,#hashes do
- local hash=hashes[h]
- local hashname=hash.name
- local content=hashname and instance.files[hashname]
- if content then
- if trace_detail then
- report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
- end
- local path,name=lookup(content,basename)
- if path then
- local metadata=content.metadata
- local realroot=metadata and metadata.path or hashname
- if type(path)=="string" then
- check(hash,realroot,pathname,path,basename,name)
- else
- for i=1,#path do
- check(hash,realroot,pathname,path[i],basename,name)
- end
- end
- end
- elseif trace_locating then
- report_resolving("no match in %a (%s)",hashname,basename)
+ local path,name=lookup(content,basename)
+ if path then
+ local metadata=content.metadata
+ local realroot=metadata and metadata.path or hashname
+ if type(path)=="string" then
+ check(hash,realroot,pathname,path,basename,name)
+ else
+ for i=1,#path do
+ check(hash,realroot,pathname,path[i],basename,name)
end
+ end
end
+ elseif trace_locating then
+ report_resolving("no match in %a (%s)",hashname,basename)
+ end
end
- return noffiles>0 and filelist or nil
+ end
+ return noffiles>0 and filelist or nil
end
local fit={}
function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname)
- local foundintrees=instance.foundintrees
- if usedmethod=="direct" and filename==foundname and fit[foundname] then
- else
- local collapsed=collapsepath(foundname,true)
- local t={
- filename=filename,
- format=format~="" and format or nil,
- filetype=filetype~="" and filetype or nil,
- usedmethod=usedmethod,
- foundname=foundname,
- fullname=collapsed,
- }
- fit[foundname]=t
- foundintrees[#foundintrees+1]=t
- end
+ local foundintrees=instance.foundintrees
+ if usedmethod=="direct" and filename==foundname and fit[foundname] then
+ else
+ local collapsed=collapsepath(foundname,true)
+ local t={
+ filename=filename,
+ format=format~="" and format or nil,
+ filetype=filetype~="" and filetype or nil,
+ usedmethod=usedmethod,
+ foundname=foundname,
+ fullname=collapsed,
+ }
+ fit[foundname]=t
+ foundintrees[#foundintrees+1]=t
+ end
end
function resolvers.foundintrees()
- return instance.foundintrees or {}
+ return instance.foundintrees or {}
end
function resolvers.foundintree(fullname)
- local f=fit[fullname]
- return f and f.usedmethod=="database"
+ local f=fit[fullname]
+ return f and f.usedmethod=="database"
end
local function can_be_dir(name)
- local fakepaths=instance.fakepaths
- if not fakepaths[name] then
- if isdir(name) then
- fakepaths[name]=1
- else
- fakepaths[name]=2
- end
+ local fakepaths=instance.fakepaths
+ if not fakepaths[name] then
+ if isdir(name) then
+ fakepaths[name]=1
+ else
+ fakepaths[name]=2
end
- return fakepaths[name]==1
+ end
+ return fakepaths[name]==1
end
local preparetreepattern=Cs((P(".")/"%%."+P("-")/"%%-"+P(1))^0*Cc("$"))
local collect_instance_files
local function find_analyze(filename,askedformat,allresults)
- local filetype=''
- local filesuffix=suffixonly(filename)
- local wantedfiles={}
- wantedfiles[#wantedfiles+1]=filename
- if askedformat=="" then
- if filesuffix=="" or not suffixmap[filesuffix] then
- local defaultsuffixes=resolvers.defaultsuffixes
- local formatofsuffix=resolvers.formatofsuffix
- for i=1,#defaultsuffixes do
- local forcedname=filename..'.'..defaultsuffixes[i]
- wantedfiles[#wantedfiles+1]=forcedname
- filetype=formatofsuffix(forcedname)
- if trace_locating then
- report_resolving("forcing filetype %a",filetype)
- end
- end
- else
- filetype=resolvers.formatofsuffix(filename)
- if trace_locating then
- report_resolving("using suffix based filetype %a",filetype)
- end
+ local filetype=''
+ local filesuffix=suffixonly(filename)
+ local wantedfiles={}
+ wantedfiles[#wantedfiles+1]=filename
+ if askedformat=="" then
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local defaultsuffixes=resolvers.defaultsuffixes
+ local formatofsuffix=resolvers.formatofsuffix
+ for i=1,#defaultsuffixes do
+ local forcedname=filename..'.'..defaultsuffixes[i]
+ wantedfiles[#wantedfiles+1]=forcedname
+ filetype=formatofsuffix(forcedname)
+ if trace_locating then
+ report_resolving("forcing filetype %a",filetype)
end
+ end
else
- if filesuffix=="" or not suffixmap[filesuffix] then
- local format_suffixes=suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
- end
- end
- end
- filetype=askedformat
- if trace_locating then
- report_resolving("using given filetype %a",filetype)
+ filetype=resolvers.formatofsuffix(filename)
+ if trace_locating then
+ report_resolving("using suffix based filetype %a",filetype)
+ end
+ end
+ else
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local format_suffixes=suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
end
+ end
end
- return filetype,wantedfiles
+ filetype=askedformat
+ if trace_locating then
+ report_resolving("using given filetype %a",filetype)
+ end
+ end
+ return filetype,wantedfiles
end
local function find_direct(filename,allresults)
- if not dangerous[askedformat] and isreadable(filename) then
- if trace_detail then
- report_resolving("file %a found directly",filename)
- end
- return "direct",{ filename }
+ if not dangerous[askedformat] and isreadable(filename) then
+ if trace_detail then
+ report_resolving("file %a found directly",filename)
end
+ return "direct",{ filename }
+ end
end
local function find_wildcard(filename,allresults)
- if find(filename,'*',1,true) then
- if trace_locating then
- report_resolving("checking wildcard %a",filename)
- end
- local result=resolvers.findwildcardfiles(filename)
- if result then
- return "wildcard",result
- end
- end
-end
-local function find_qualified(filename,allresults,askedformat,alsostripped)
- if not is_qualified_path(filename) then
- return
- end
+ if find(filename,'*',1,true) then
if trace_locating then
- report_resolving("checking qualified name %a",filename)
+ report_resolving("checking wildcard %a",filename)
end
- if isreadable(filename) then
- if trace_detail then
- report_resolving("qualified file %a found",filename)
- end
- return "qualified",{ filename }
+ local result=resolvers.findwildcardfiles(filename)
+ if result then
+ return "wildcard",result
end
+ end
+end
+local function find_qualified(filename,allresults,askedformat,alsostripped)
+ if not is_qualified_path(filename) then
+ return
+ end
+ if trace_locating then
+ report_resolving("checking qualified name %a",filename)
+ end
+ if isreadable(filename) then
if trace_detail then
- report_resolving("locating qualified file %a",filename)
- end
- local forcedname,suffix="",suffixonly(filename)
- if suffix=="" then
- local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- local s=format_suffixes[i]
- forcedname=filename.."."..s
- if isreadable(forcedname) then
- if trace_locating then
- report_resolving("no suffix, forcing format filetype %a",s)
- end
- return "qualified",{ forcedname }
- end
- end
+ report_resolving("qualified file %a found",filename)
+ end
+ return "qualified",{ filename }
+ end
+ if trace_detail then
+ report_resolving("locating qualified file %a",filename)
+ end
+ local forcedname,suffix="",suffixonly(filename)
+ if suffix=="" then
+ local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ local s=format_suffixes[i]
+ forcedname=filename.."."..s
+ if isreadable(forcedname) then
+ if trace_locating then
+ report_resolving("no suffix, forcing format filetype %a",s)
+ end
+ return "qualified",{ forcedname }
end
+ end
end
- if alsostripped and suffix and suffix~="" then
- local basename=filebasename(filename)
- local pattern=lpegmatch(preparetreepattern,filename)
- local savedformat=askedformat
- local format=savedformat or ""
- if format=="" then
- askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if alsostripped and suffix and suffix~="" then
+ local basename=filebasename(filename)
+ local pattern=lpegmatch(preparetreepattern,filename)
+ local savedformat=askedformat
+ local format=savedformat or ""
+ if format=="" then
+ askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if not format then
+ askedformat="othertextfiles"
+ end
+ if basename~=filename then
+ local resolved=collect_instance_files(basename,askedformat,allresults)
+ if #resolved==0 then
+ local lowered=lower(basename)
+ if filename~=lowered then
+ resolved=collect_instance_files(lowered,askedformat,allresults)
end
- if not format then
- askedformat="othertextfiles"
+ end
+ resolvers.format=savedformat
+ if #resolved>0 then
+ local result={}
+ for r=1,#resolved do
+ local rr=resolved[r]
+ if find(rr,pattern) then
+ result[#result+1]=rr
+ end
end
- if basename~=filename then
- local resolved=collect_instance_files(basename,askedformat,allresults)
- if #resolved==0 then
- local lowered=lower(basename)
- if filename~=lowered then
- resolved=collect_instance_files(lowered,askedformat,allresults)
- end
- end
- resolvers.format=savedformat
- if #resolved>0 then
- local result={}
- for r=1,#resolved do
- local rr=resolved[r]
- if find(rr,pattern) then
- result[#result+1]=rr
- end
- end
- if #result>0 then
- return "qualified",result
- end
- end
+ if #result>0 then
+ return "qualified",result
end
+ end
end
+ end
end
local function check_subpath(fname)
- if isreadable(fname) then
- if trace_detail then
- report_resolving("found %a by deep scanning",fname)
- end
- return fname
+ if isreadable(fname) then
+ if trace_detail then
+ report_resolving("found %a by deep scanning",fname)
end
+ return fname
+ end
end
local function makepathlist(list,filetype)
- local typespec=resolvers.variableofformat(filetype)
- local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
- local entry={}
- if pathlist and #pathlist>0 then
- for k=1,#pathlist do
- local path=pathlist[k]
- local prescanned=find(path,'^!!')
- local resursive=find(path,'//$')
- local pathname=lpegmatch(inhibitstripper,path)
- local expression=makepathexpression(pathname)
- local barename=gsub(pathname,"/+$","")
- barename=resolveprefix(barename)
- local scheme=url.hasscheme(barename)
- local schemename=gsub(barename,"%.%*$",'')
- entry[k]={
- path=path,
- pathname=pathname,
- prescanned=prescanned,
- recursive=recursive,
- expression=expression,
- barename=barename,
- scheme=scheme,
- schemename=schemename,
- }
- end
- entry.typespec=typespec
- list[filetype]=entry
- else
- list[filetype]=false
- end
- return entry
+ local typespec=resolvers.variableofformat(filetype)
+ local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
+ local entry={}
+ if pathlist and #pathlist>0 then
+ for k=1,#pathlist do
+ local path=pathlist[k]
+ local prescanned=find(path,'^!!')
+ local resursive=find(path,'//$')
+ local pathname=lpegmatch(inhibitstripper,path)
+ local expression=makepathexpression(pathname)
+ local barename=gsub(pathname,"/+$","")
+ barename=resolveprefix(barename)
+ local scheme=url.hasscheme(barename)
+ local schemename=gsub(barename,"%.%*$",'')
+ entry[k]={
+ path=path,
+ pathname=pathname,
+ prescanned=prescanned,
+ recursive=recursive,
+ expression=expression,
+ barename=barename,
+ scheme=scheme,
+ schemename=schemename,
+ }
+ end
+ entry.typespec=typespec
+ list[filetype]=entry
+ else
+ list[filetype]=false
+ end
+ return entry
end
local function find_intree(filename,filetype,wantedfiles,allresults)
- local pathlists=instance.pathlists
- if not pathlists then
- pathlists=setmetatableindex({},makepathlist)
- instance.pathlists=pathlists
- end
- local pathlist=pathlists[filetype]
- if pathlist then
- local method="intree"
- local filelist=collect_files(wantedfiles)
- local dirlist={}
- local result={}
- if filelist then
- for i=1,#filelist do
- dirlist[i]=filedirname(filelist[i][3]).."/"
+ local pathlists=instance.pathlists
+ if not pathlists then
+ pathlists=setmetatableindex({},makepathlist)
+ instance.pathlists=pathlists
+ end
+ local pathlist=pathlists[filetype]
+ if pathlist then
+ local method="intree"
+ local filelist=collect_files(wantedfiles)
+ local dirlist={}
+ local result={}
+ if filelist then
+ for i=1,#filelist do
+ dirlist[i]=filedirname(filelist[i][3]).."/"
+ end
+ end
+ if trace_detail then
+ report_resolving("checking filename %a in tree",filename)
+ end
+ for k=1,#pathlist do
+ local entry=pathlist[k]
+ local path=entry.path
+ local pathname=entry.pathname
+ local done=false
+ if filelist then
+ local expression=entry.expression
+ if trace_detail then
+ report_resolving("using pattern %a for path %a",expression,pathname)
+ end
+ for k=1,#filelist do
+ local fl=filelist[k]
+ local f=fl[2]
+ local d=dirlist[k]
+ if find(d,expression) or find(resolveprefix(d),expression) then
+ result[#result+1]=resolveprefix(fl[3])
+ done=true
+ if allresults then
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
+ end
+ else
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
+ end
+ break
end
+ elseif trace_detail then
+ report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ end
end
- if trace_detail then
- report_resolving("checking filename %a in tree",filename)
- end
- for k=1,#pathlist do
- local entry=pathlist[k]
- local path=entry.path
- local pathname=entry.pathname
- local done=false
- if filelist then
- local expression=entry.expression
+ end
+ if done then
+ method="database"
+ else
+ method="filesystem"
+ local scheme=entry.scheme
+ if not scheme or scheme=="file" then
+ local pname=entry.schemename
+ if not find(pname,"*",1,true) then
+ if can_be_dir(pname) then
+ if not done and not entry.prescanned then
if trace_detail then
- report_resolving("using pattern %a for path %a",expression,pathname)
+ report_resolving("quick root scan for %a",pname)
end
- for k=1,#filelist do
- local fl=filelist[k]
- local f=fl[2]
- local d=dirlist[k]
- if find(d,expression) or find(resolveprefix(d),expression) then
- result[#result+1]=resolveprefix(fl[3])
- done=true
- if allresults then
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
- end
- else
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
- end
- break
- end
- elseif trace_detail then
- report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local fname=check_subpath(filejoin(pname,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
- end
- end
- if done then
- method="database"
- else
- method="filesystem"
- local scheme=entry.scheme
- if not scheme or scheme=="file" then
- local pname=entry.schemename
- if not find(pname,"*",1,true) then
- if can_be_dir(pname) then
- if not done and not entry.prescanned then
- if trace_detail then
- report_resolving("quick root scan for %a",pname)
- end
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local fname=check_subpath(filejoin(pname,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- if not done and entry.recursive then
- if trace_detail then
- report_resolving("scanning filesystem for %a",pname)
- end
- local files=resolvers.simplescanfiles(pname,false,true)
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local subpath=files[w]
- if not subpath or subpath=="" then
- elseif type(subpath)=="string" then
- local fname=check_subpath(filejoin(pname,subpath,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- else
- for i=1,#subpath do
- local sp=subpath[i]
- if sp=="" then
- else
- local fname=check_subpath(filejoin(pname,sp,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- end
- if done and not allresults then
- break
- end
- end
- end
- end
- end
+ end
+ end
+ if not done and entry.recursive then
+ if trace_detail then
+ report_resolving("scanning filesystem for %a",pname)
+ end
+ local files=resolvers.simplescanfiles(pname,false,true)
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local subpath=files[w]
+ if not subpath or subpath=="" then
+ elseif type(subpath)=="string" then
+ local fname=check_subpath(filejoin(pname,subpath,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
+ end
else
- end
- else
- for k=1,#wantedfiles do
- local pname=entry.barename
- local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
- if fname then
+ for i=1,#subpath do
+ local sp=subpath[i]
+ if sp=="" then
+ else
+ local fname=check_subpath(filejoin(pname,sp,w))
+ if fname then
result[#result+1]=fname
done=true
if not allresults then
- break
+ break
end
+ end
end
+ end
+ if done and not allresults then
+ break
+ end
end
+ end
end
+ end
end
- if done and not allresults then
+ else
+ end
+ else
+ for k=1,#wantedfiles do
+ local pname=entry.barename
+ local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
break
+ end
end
+ end
end
- if #result>0 then
- return method,result
- end
+ end
+ if done and not allresults then
+ break
+ end
end
+ if #result>0 then
+ return method,result
+ end
+ end
end
local function find_onpath(filename,filetype,wantedfiles,allresults)
- if trace_detail then
- report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
- end
- local result={}
- for k=1,#wantedfiles do
- local fname=wantedfiles[k]
- if fname and isreadable(fname) then
- filename=fname
- result[#result+1]=filejoin('.',fname)
- if not allresults then
- break
- end
- end
- end
- if #result>0 then
- return "onpath",result
+ if trace_detail then
+ report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
+ end
+ local result={}
+ for k=1,#wantedfiles do
+ local fname=wantedfiles[k]
+ if fname and isreadable(fname) then
+ filename=fname
+ result[#result+1]=filejoin('.',fname)
+ if not allresults then
+ break
+ end
end
+ end
+ if #result>0 then
+ return "onpath",result
+ end
end
local function find_otherwise(filename,filetype,wantedfiles,allresults)
- local filelist=collect_files(wantedfiles)
- local fl=filelist and filelist[1]
- if fl then
- return "otherwise",{ resolveprefix(fl[3]) }
- end
+ local filelist=collect_files(wantedfiles)
+ local fl=filelist and filelist[1]
+ if fl then
+ return "otherwise",{ resolveprefix(fl[3]) }
+ end
end
collect_instance_files=function(filename,askedformat,allresults)
- if not filename or filename=="" then
- return {}
- end
- askedformat=askedformat or ""
- filename=collapsepath(filename,".")
- filename=gsub(filename,"^%./",getcurrentdir().."/")
- if allresults then
- local filetype,wantedfiles=find_analyze(filename,askedformat)
- local results={
- { find_direct (filename,true) },
- { find_wildcard (filename,true) },
- { find_qualified(filename,true,askedformat) },
- { find_intree (filename,filetype,wantedfiles,true) },
- { find_onpath (filename,filetype,wantedfiles,true) },
- { find_otherwise(filename,filetype,wantedfiles,true) },
- }
- local result,status,done={},{},{}
- for k,r in next,results do
- local method,list=r[1],r[2]
- if method and list then
- for i=1,#list do
- local c=collapsepath(list[i])
- if not done[c] then
- result[#result+1]=c
- done[c]=true
- end
- status[#status+1]=formatters["%-10s: %s"](method,c)
- end
- end
- end
- if trace_detail then
- report_resolving("lookup status: %s",table.serialize(status,filename))
+ if not filename or filename=="" then
+ return {}
+ end
+ askedformat=askedformat or ""
+ filename=collapsepath(filename,".")
+ filename=gsub(filename,"^%./",getcurrentdir().."/")
+ if allresults then
+ local filetype,wantedfiles=find_analyze(filename,askedformat)
+ local results={
+ { find_direct (filename,true) },
+ { find_wildcard (filename,true) },
+ { find_qualified(filename,true,askedformat) },
+ { find_intree (filename,filetype,wantedfiles,true) },
+ { find_onpath (filename,filetype,wantedfiles,true) },
+ { find_otherwise(filename,filetype,wantedfiles,true) },
+ }
+ local result,status,done={},{},{}
+ for k,r in next,results do
+ local method,list=r[1],r[2]
+ if method and list then
+ for i=1,#list do
+ local c=collapsepath(list[i])
+ if not done[c] then
+ result[#result+1]=c
+ done[c]=true
+ end
+ status[#status+1]=formatters["%-10s: %s"](method,c)
end
- return result,status
- else
- local method,result,stamp,filetype,wantedfiles
- if instance.remember then
- if askedformat=="" then
- stamp=formatters["%s::%s"](suffixonly(filename),filename)
- else
- stamp=formatters["%s::%s"](askedformat,filename)
- end
- result=stamp and instance.found[stamp]
- if result then
- if trace_locating then
- report_resolving("remembered file %a",filename)
- end
- return result
- end
+ end
+ end
+ if trace_detail then
+ report_resolving("lookup status: %s",table.serialize(status,filename))
+ end
+ return result,status
+ else
+ local method,result,stamp,filetype,wantedfiles
+ if instance.remember then
+ if askedformat=="" then
+ stamp=formatters["%s::%s"](suffixonly(filename),filename)
+ else
+ stamp=formatters["%s::%s"](askedformat,filename)
+ end
+ result=stamp and instance.found[stamp]
+ if result then
+ if trace_locating then
+ report_resolving("remembered file %a",filename)
end
- method,result=find_direct(filename)
+ return result
+ end
+ end
+ method,result=find_direct(filename)
+ if not result then
+ method,result=find_wildcard(filename)
+ if not result then
+ method,result=find_qualified(filename,false,askedformat)
if not result then
- method,result=find_wildcard(filename)
- if not result then
- method,result=find_qualified(filename,false,askedformat)
- if not result then
- filetype,wantedfiles=find_analyze(filename,askedformat)
- method,result=find_intree(filename,filetype,wantedfiles)
- if not result then
- method,result=find_onpath(filename,filetype,wantedfiles)
- if resolve_otherwise and not result then
- method,result=find_otherwise(filename,filetype,wantedfiles)
- end
- end
- end
- end
- end
- if result and #result>0 then
- local foundname=collapsepath(result[1])
- resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
- result={ foundname }
- else
- result={}
- end
- if stamp then
- if trace_locating then
- report_resolving("remembering file %a using hash %a",filename,stamp)
+ filetype,wantedfiles=find_analyze(filename,askedformat)
+ method,result=find_intree(filename,filetype,wantedfiles)
+ if not result then
+ method,result=find_onpath(filename,filetype,wantedfiles)
+ if resolve_otherwise and not result then
+ method,result=find_otherwise(filename,filetype,wantedfiles)
end
- instance.found[stamp]=result
+ end
end
- return result
+ end
+ end
+ if result and #result>0 then
+ local foundname=collapsepath(result[1])
+ resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
+ result={ foundname }
+ else
+ result={}
end
+ if stamp then
+ if trace_locating then
+ report_resolving("remembering file %a using hash %a",filename,stamp)
+ end
+ instance.found[stamp]=result
+ end
+ return result
+ end
end
local function findfiles(filename,filetype,allresults)
- if not filename or filename=="" then
- return {}
- end
- local result,status=collect_instance_files(filename,filetype or "",allresults)
- if not result or #result==0 then
- local lowered=lower(filename)
- if filename~=lowered then
- result,status=collect_instance_files(lowered,filetype or "",allresults)
- end
+ if not filename or filename=="" then
+ return {}
+ end
+ local result,status=collect_instance_files(filename,filetype or "",allresults)
+ if not result or #result==0 then
+ local lowered=lower(filename)
+ if filename~=lowered then
+ result,status=collect_instance_files(lowered,filetype or "",allresults)
end
- return result or {},status
+ end
+ return result or {},status
end
function resolvers.findfiles(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,true)
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,true)
+ end
end
function resolvers.findfile(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,false)[1] or ""
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,false)[1] or ""
+ end
end
function resolvers.findpath(filename,filetype)
- return filedirname(findfiles(filename,filetype,false)[1] or "")
+ return filedirname(findfiles(filename,filetype,false)[1] or "")
end
local function findgivenfiles(filename,allresults)
- local base=filebasename(filename)
- local result={}
- local hashes=instance.hashes
- local function okay(hash,path,name)
- local found=methodhandler('concatinators',hash.type,hash.name,path,name)
- if found and found~="" then
- result[#result+1]=resolveprefix(found)
- return not allresults
- end
- end
- for k=1,#hashes do
- local hash=hashes[k]
- local content=instance.files[hash.name]
- if content then
- local path,name=lookup(content,base)
- if not path then
- elseif type(path)=="string" then
- if okay(hash,path,name) then
- return result
- end
- else
- for i=1,#path do
- if okay(hash,path[i],name) then
- return result
- end
- end
- end
+ local base=filebasename(filename)
+ local result={}
+ local hashes=instance.hashes
+ local function okay(hash,path,name)
+ local found=methodhandler('concatinators',hash.type,hash.name,path,name)
+ if found and found~="" then
+ result[#result+1]=resolveprefix(found)
+ return not allresults
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local content=instance.files[hash.name]
+ if content then
+ local path,name=lookup(content,base)
+ if not path then
+ elseif type(path)=="string" then
+ if okay(hash,path,name) then
+ return result
+ end
+ else
+ for i=1,#path do
+ if okay(hash,path[i],name) then
+ return result
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findgivenfiles(filename)
- return findgivenfiles(filename,true)
+ return findgivenfiles(filename,true)
end
function resolvers.findgivenfile(filename)
- return findgivenfiles(filename,false)[1] or ""
+ return findgivenfiles(filename,false)[1] or ""
end
local makewildcard=Cs(
- (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
+ (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
)
function resolvers.wildcardpattern(pattern)
- return lpegmatch(makewildcard,pattern) or pattern
+ return lpegmatch(makewildcard,pattern) or pattern
end
local function findwildcardfiles(filename,allresults,result)
- local result=result or {}
- local base=filebasename(filename)
- local dirn=filedirname(filename)
- local path=lower(lpegmatch(makewildcard,dirn) or dirn)
- local name=lower(lpegmatch(makewildcard,base) or base)
- local files=instance.files
- if find(name,"*",1,true) then
- local hashes=instance.hashes
- local function okay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
- end
+ local result=result or {}
+ local base=filebasename(filename)
+ local dirn=filedirname(filename)
+ local path=lower(lpegmatch(makewildcard,dirn) or dirn)
+ local name=lower(lpegmatch(makewildcard,base) or base)
+ local files=instance.files
+ if find(name,"*",1,true) then
+ local hashes=instance.hashes
+ local function okay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
end
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- for found,base in filtered(files[hashname],name) do
- if type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
- end
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ for found,base in filtered(files[hashname],name) do
+ if type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
end
- end
- else
- local function okayokay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
+ end
end
+ end
end
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- local found,base=lookup(content,base)
- if not found then
- elseif type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
+ end
+ end
+ else
+ local function okayokay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
+ end
+ end
+ end
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ local found,base=lookup(content,base)
+ if not found then
+ elseif type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
+ end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
end
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findwildcardfiles(filename,result)
- return findwildcardfiles(filename,true,result)
+ return findwildcardfiles(filename,true,result)
end
function resolvers.findwildcardfile(filename)
- return findwildcardfiles(filename,false)[1] or ""
+ return findwildcardfiles(filename,false)[1] or ""
end
function resolvers.automount()
end
function resolvers.starttiming()
- statistics.starttiming(instance)
+ statistics.starttiming(instance)
end
function resolvers.stoptiming()
- statistics.stoptiming(instance)
+ statistics.stoptiming(instance)
end
function resolvers.load(option)
- resolvers.starttiming()
- identify_configuration_files()
- load_configuration_files()
- if option~="nofiles" then
- load_databases()
- resolvers.automount()
- end
- resolvers.stoptiming()
- local files=instance.files
- return files and next(files) and true
+ resolvers.starttiming()
+ identify_configuration_files()
+ load_configuration_files()
+ if option~="nofiles" then
+ load_databases()
+ resolvers.automount()
+ end
+ resolvers.stoptiming()
+ local files=instance.files
+ return files and next(files) and true
end
function resolvers.loadtime()
- return statistics.elapsedtime(instance)
+ return statistics.elapsedtime(instance)
end
local function report(str)
- if trace_locating then
- report_resolving(str)
- else
- print(str)
- end
+ if trace_locating then
+ report_resolving(str)
+ else
+ print(str)
+ end
end
function resolvers.dowithfilesandreport(command,files,...)
- if files and #files>0 then
- if trace_locating then
- report('')
- end
- if type(files)=="string" then
- files={ files }
- end
- for f=1,#files do
- local file=files[f]
- local result=command(file,...)
- if type(result)=='string' then
- report(result)
- else
- for i=1,#result do
- report(result[i])
- end
- end
+ if files and #files>0 then
+ if trace_locating then
+ report('')
+ end
+ if type(files)=="string" then
+ files={ files }
+ end
+ for f=1,#files do
+ local file=files[f]
+ local result=command(file,...)
+ if type(result)=='string' then
+ report(result)
+ else
+ for i=1,#result do
+ report(result[i])
end
+ end
end
+ end
end
-function resolvers.showpath(str)
- return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
+function resolvers.showpath(str)
+ return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
end
function resolvers.registerfile(files,name,path)
- if files[name] then
- if type(files[name])=='string' then
- files[name]={ files[name],path }
- else
- files[name]=path
- end
+ if files[name] then
+ if type(files[name])=='string' then
+ files[name]={ files[name],path }
else
- files[name]=path
+ files[name]=path
end
+ else
+ files[name]=path
+ end
end
function resolvers.dowithpath(name,func)
- local pathlist=resolvers.expandedpathlist(name)
- for i=1,#pathlist do
- func("^"..cleanpath(pathlist[i]))
- end
+ local pathlist=resolvers.expandedpathlist(name)
+ for i=1,#pathlist do
+ func("^"..cleanpath(pathlist[i]))
+ end
end
function resolvers.dowithvariable(name,func)
- func(expandedvariable(name))
+ func(expandedvariable(name))
end
function resolvers.locateformat(name)
- local engine=environment.ownmain or "luatex"
- local barename=removesuffix(name)
- local fullname=addsuffix(barename,"fmt")
- local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
- if fmtname=="" then
- fmtname=resolvers.findfile(fullname)
- fmtname=cleanpath(fmtname)
- end
- if fmtname~="" then
- local barename=removesuffix(fmtname)
- local luaname=addsuffix(barename,luasuffixes.lua)
- local lucname=addsuffix(barename,luasuffixes.luc)
- local luiname=addsuffix(barename,luasuffixes.lui)
- if isfile(luiname) then
- return barename,luiname
- elseif isfile(lucname) then
- return barename,lucname
- elseif isfile(luaname) then
- return barename,luaname
- end
- end
- return nil,nil
+ local engine=environment.ownmain or "luatex"
+ local barename=removesuffix(name)
+ local fullname=addsuffix(barename,"fmt")
+ local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
+ if fmtname=="" then
+ fmtname=resolvers.findfile(fullname)
+ fmtname=cleanpath(fmtname)
+ end
+ if fmtname~="" then
+ local barename=removesuffix(fmtname)
+ local luaname=addsuffix(barename,luasuffixes.lua)
+ local lucname=addsuffix(barename,luasuffixes.luc)
+ local luiname=addsuffix(barename,luasuffixes.lui)
+ if isfile(luiname) then
+ return barename,luiname
+ elseif isfile(lucname) then
+ return barename,lucname
+ elseif isfile(luaname) then
+ return barename,luaname
+ end
+ end
+ return nil,nil
end
function resolvers.booleanvariable(str,default)
- local b=resolvers.expansion(str)
- if b=="" then
- return default
- else
- b=toboolean(b)
- return (b==nil and default) or b
- end
+ local b=resolvers.expansion(str)
+ if b=="" then
+ return default
+ else
+ b=toboolean(b)
+ return (b==nil and default) or b
+ end
end
function resolvers.dowithfilesintree(pattern,handle,before,after)
- local hashes=instance.hashes
- for i=1,#hashes do
- local hash=hashes[i]
- local blobtype=hash.type
- local blobpath=hash.name
- if blobtype and blobpath then
- local total=0
- local checked=0
- local done=0
- if before then
- before(blobtype,blobpath,pattern)
- end
- for path,name in filtered(instance.files[blobpath],pattern) do
- if type(path)=="string" then
- checked=checked+1
- if handle(blobtype,blobpath,path,name) then
- done=done+1
- end
- else
- checked=checked+#path
- for i=1,#path do
- if handle(blobtype,blobpath,path[i],name) then
- done=done+1
- end
- end
- end
- end
- if after then
- after(blobtype,blobpath,pattern,checked,done)
+ local hashes=instance.hashes
+ for i=1,#hashes do
+ local hash=hashes[i]
+ local blobtype=hash.type
+ local blobpath=hash.name
+ if blobtype and blobpath then
+ local total=0
+ local checked=0
+ local done=0
+ if before then
+ before(blobtype,blobpath,pattern)
+ end
+ for path,name in filtered(instance.files[blobpath],pattern) do
+ if type(path)=="string" then
+ checked=checked+1
+ if handle(blobtype,blobpath,path,name) then
+ done=done+1
+ end
+ else
+ checked=checked+#path
+ for i=1,#path do
+ if handle(blobtype,blobpath,path[i],name) then
+ done=done+1
end
+ end
end
+ end
+ if after then
+ after(blobtype,blobpath,pattern,checked,done)
+ end
end
+ end
end
local obsolete=resolvers.obsolete or {}
resolvers.obsolete=obsolete
-resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
-resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
+resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
+resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
function resolvers.knownvariables(pattern)
- if instance then
- local environment=instance.environment
- local variables=instance.variables
- local expansions=instance.expansions
- local order=instance.order
- local pattern=upper(pattern or "")
- local result={}
- for i=1,#order do
- for key in next,order[i] do
- if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
- result[key]={
- environment=rawget(environment,key),
- variable=key,
- expansion=expansions[key],
- resolved=resolveprefix(expansions[key]),
- }
- end
- end
+ if instance then
+ local environment=instance.environment
+ local variables=instance.variables
+ local expansions=instance.expansions
+ local order=instance.order
+ local pattern=upper(pattern or "")
+ local result={}
+ for i=1,#order do
+ for key in next,order[i] do
+ if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
+ result[key]={
+ environment=rawget(environment,key),
+ variable=key,
+ expansion=expansions[key],
+ resolved=resolveprefix(expansions[key]),
+ }
end
- return result
- else
- return {}
+ end
end
+ return result
+ else
+ return {}
+ end
end
@@ -22710,14 +22718,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-pre"] = package.loaded["data-pre"] or true
--- original size: 4854, stripped down to: 2993
+-- original size: 4854, stripped down to: 2889
if not modules then modules={} end modules ['data-pre']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local resolvers=resolvers
local prefixes=resolvers.prefixes
@@ -22730,64 +22738,64 @@ local dirname=file.dirname
local joinpath=file.join
local isfile=lfs.isfile
prefixes.environment=function(str)
- return cleanpath(expansion(str))
+ return cleanpath(expansion(str))
end
local function relative(str,n)
- if not isfile(str) then
- local pstr="./"..str
+ if not isfile(str) then
+ local pstr="./"..str
+ if isfile(pstr) then
+ str=pstr
+ else
+ local p="../"
+ for i=1,n or 2 do
+ local pstr=p..str
if isfile(pstr) then
- str=pstr
+ str=pstr
+ break
else
- local p="../"
- for i=1,n or 2 do
- local pstr=p..str
- if isfile(pstr) then
- str=pstr
- break
- else
- p=p.."../"
- end
- end
+ p=p.."../"
end
+ end
end
- return cleanpath(str)
+ end
+ return cleanpath(str)
end
local function locate(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(fullname~="" and fullname or str)
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(fullname~="" and fullname or str)
end
prefixes.relative=relative
prefixes.locate=locate
prefixes.auto=function(str)
- local fullname=relative(str)
- if not isfile(fullname) then
- fullname=locate(str)
- end
- return fullname
+ local fullname=relative(str)
+ if not isfile(fullname) then
+ fullname=locate(str)
+ end
+ return fullname
end
prefixes.filename=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(basename((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(basename((fullname~="" and fullname) or str))
end
prefixes.pathname=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(dirname((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(dirname((fullname~="" and fullname) or str))
end
prefixes.selfautoloc=function(str)
- local pth=getenv('SELFAUTOLOC')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOLOC')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautoparent=function(str)
- local pth=getenv('SELFAUTOPARENT')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOPARENT')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautodir=function(str)
- local pth=getenv('SELFAUTODIR')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTODIR')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.home=function(str)
- local pth=getenv('HOME')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('HOME')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.env=prefixes.environment
prefixes.rel=prefixes.relative
@@ -22797,24 +22805,24 @@ prefixes.full=prefixes.locate
prefixes.file=prefixes.filename
prefixes.path=prefixes.pathname
local function toppath()
- local inputstack=resolvers.inputstack
- if not inputstack then
- return "."
- end
- local pathname=dirname(inputstack[#inputstack] or "")
- if pathname=="" then
- return "."
- else
- return pathname
- end
+ local inputstack=resolvers.inputstack
+ if not inputstack then
+ return "."
+ end
+ local pathname=dirname(inputstack[#inputstack] or "")
+ if pathname=="" then
+ return "."
+ else
+ return pathname
+ end
end
local function jobpath()
- local path=resolvers.stackpath()
- if not path or path=="" then
- return "."
- else
- return path
- end
+ local path=resolvers.stackpath()
+ if not path or path=="" then
+ return "."
+ else
+ return path
+ end
end
resolvers.toppath=toppath
resolvers.jobpath=jobpath
@@ -22830,14 +22838,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-inp"] = package.loaded["data-inp"] or true
--- original size: 910, stripped down to: 823
+-- original size: 910, stripped down to: 818
if not modules then modules={} end modules ['data-inp']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -22860,14 +22868,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-out"] = package.loaded["data-out"] or true
--- original size: 530, stripped down to: 475
+-- original size: 530, stripped down to: 470
if not modules then modules={} end modules ['data-out']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -22883,16 +22891,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-fil"] = package.loaded["data-fil"] or true
--- original size: 3863, stripped down to: 3310
+-- original size: 3863, stripped down to: 3170
if not modules then modules={} end modules ['data-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_files=logs.reporter("resolvers","files")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -22900,88 +22908,88 @@ local finders,openers,loaders,savers=resolvers.finders,resolvers.openers,resolve
local locators,hashers,generators,concatinators=resolvers.locators,resolvers.hashers,resolvers.generators,resolvers.concatinators
local checkgarbage=utilities.garbagecollector and utilities.garbagecollector.check
function locators.file(specification)
- local filename=specification.filename
- local realname=resolveprefix(filename)
- if realname and realname~='' and lfs.isdir(realname) then
- if trace_locating then
- report_files("file locator %a found as %a",filename,realname)
- end
- resolvers.appendhash('file',filename,true)
- elseif trace_locating then
- report_files("file locator %a not found",filename)
+ local filename=specification.filename
+ local realname=resolveprefix(filename)
+ if realname and realname~='' and lfs.isdir(realname) then
+ if trace_locating then
+ report_files("file locator %a found as %a",filename,realname)
end
+ resolvers.appendhash('file',filename,true)
+ elseif trace_locating then
+ report_files("file locator %a not found",filename)
+ end
end
function hashers.file(specification)
- local pathname=specification.filename
- local content=caches.loadcontent(pathname,'files')
- resolvers.registerfilehash(pathname,content,content==nil)
+ local pathname=specification.filename
+ local content=caches.loadcontent(pathname,'files')
+ resolvers.registerfilehash(pathname,content,content==nil)
end
function generators.file(specification)
- local pathname=specification.filename
- local content=resolvers.scanfiles(pathname,false,true)
- resolvers.registerfilehash(pathname,content,true)
+ local pathname=specification.filename
+ local content=resolvers.scanfiles(pathname,false,true)
+ resolvers.registerfilehash(pathname,content,true)
end
concatinators.file=file.join
function finders.file(specification,filetype)
- local filename=specification.filename
- local foundname=resolvers.findfile(filename,filetype)
- if foundname and foundname~="" then
- if trace_locating then
- report_files("file finder: %a found",filename)
- end
- return foundname
- else
- if trace_locating then
- report_files("file finder: %a not found",filename)
- end
- return finders.notfound()
+ local filename=specification.filename
+ local foundname=resolvers.findfile(filename,filetype)
+ if foundname and foundname~="" then
+ if trace_locating then
+ report_files("file finder: %a found",filename)
+ end
+ return foundname
+ else
+ if trace_locating then
+ report_files("file finder: %a not found",filename)
end
+ return finders.notfound()
+ end
end
function openers.helpers.textopener(tag,filename,f)
- return {
- reader=function() return f:read () end,
- close=function() logs.show_close(filename) return f:close() end,
- }
+ return {
+ reader=function() return f:read () end,
+ close=function() logs.show_close(filename) return f:close() end,
+ }
end
function openers.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"r")
- if f then
- if trace_locating then
- report_files("file opener: %a opened",filename)
- end
- return openers.helpers.textopener("file",filename,f)
- end
- end
- if trace_locating then
- report_files("file opener: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"r")
+ if f then
+ if trace_locating then
+ report_files("file opener: %a opened",filename)
+ end
+ return openers.helpers.textopener("file",filename,f)
end
- return openers.notfound()
+ end
+ if trace_locating then
+ report_files("file opener: %a not found",filename)
+ end
+ return openers.notfound()
end
function loaders.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"rb")
- if f then
- logs.show_load(filename)
- if trace_locating then
- report_files("file loader: %a loaded",filename)
- end
- local s=f:read("*a")
- if checkgarbage then
- checkgarbage(#s)
- end
- f:close()
- if s then
- return true,s,#s
- end
- end
- end
- if trace_locating then
- report_files("file loader: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"rb")
+ if f then
+ logs.show_load(filename)
+ if trace_locating then
+ report_files("file loader: %a loaded",filename)
+ end
+ local s=f:read("*a")
+ if checkgarbage then
+ checkgarbage(#s)
+ end
+ f:close()
+ if s then
+ return true,s,#s
+ end
end
- return loaders.notfound()
+ end
+ if trace_locating then
+ report_files("file loader: %a not found",filename)
+ end
+ return loaders.notfound()
end
@@ -22991,116 +22999,116 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-con"] = package.loaded["data-con"] or true
--- original size: 5029, stripped down to: 3607
+-- original size: 5029, stripped down to: 3432
if not modules then modules={} end modules ['data-con']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub=string.format,string.lower,string.gsub
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
-local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
-local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
+local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
containers=containers or {}
local containers=containers
containers.usecache=true
local report_containers=logs.reporter("resolvers","containers")
local allocated={}
local mt={
- __index=function(t,k)
- if k=="writable" then
- local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
- t.writable=writable
- return writable
- elseif k=="readables" then
- local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
- t.readables=readables
- return readables
- end
- end,
- __storage__=true
+ __index=function(t,k)
+ if k=="writable" then
+ local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
+ t.writable=writable
+ return writable
+ elseif k=="readables" then
+ local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
+ t.readables=readables
+ return readables
+ end
+ end,
+ __storage__=true
}
function containers.define(category,subcategory,version,enabled)
- if category and subcategory then
- local c=allocated[category]
- if not c then
- c={}
- allocated[category]=c
- end
- local s=c[subcategory]
- if not s then
- s={
- category=category,
- subcategory=subcategory,
- storage={},
- enabled=enabled,
- version=version or math.pi,
- trace=false,
- }
- setmetatable(s,mt)
- c[subcategory]=s
- end
- return s
+ if category and subcategory then
+ local c=allocated[category]
+ if not c then
+ c={}
+ allocated[category]=c
+ end
+ local s=c[subcategory]
+ if not s then
+ s={
+ category=category,
+ subcategory=subcategory,
+ storage={},
+ enabled=enabled,
+ version=version or math.pi,
+ trace=false,
+ }
+ setmetatable(s,mt)
+ c[subcategory]=s
end
+ return s
+ end
end
function containers.is_usable(container,name)
- return container.enabled and caches and caches.is_writable(container.writable,name)
+ return container.enabled and caches and caches.is_writable(container.writable,name)
end
function containers.is_valid(container,name)
- if name and name~="" then
- local storage=container.storage[name]
- return storage and storage.cache_version==container.version
- else
- return false
- end
+ if name and name~="" then
+ local storage=container.storage[name]
+ return storage and storage.cache_version==container.version
+ else
+ return false
+ end
end
function containers.read(container,name)
- local storage=container.storage
- local stored=storage[name]
- if not stored and container.enabled and caches and containers.usecache then
- stored=caches.loaddata(container.readables,name,container.writable)
- if stored and stored.cache_version==container.version then
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","load",container.subcategory,name)
- end
- else
- stored=nil
- end
- storage[name]=stored
- elseif stored then
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
- end
+ local storage=container.storage
+ local stored=storage[name]
+ if not stored and container.enabled and caches and containers.usecache then
+ stored=caches.loaddata(container.readables,name,container.writable)
+ if stored and stored.cache_version==container.version then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","load",container.subcategory,name)
+ end
+ else
+ stored=nil
end
- return stored
+ storage[name]=stored
+ elseif stored then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
+ end
+ end
+ return stored
end
function containers.write(container,name,data)
- if data then
- data.cache_version=container.version
- if container.enabled and caches then
- local unique,shared=data.unique,data.shared
- data.unique,data.shared=nil,nil
- caches.savedata(container.writable,name,data)
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","save",container.subcategory,name)
- end
- data.unique,data.shared=unique,shared
- end
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","store",container.subcategory,name)
- end
- container.storage[name]=data
+ if data then
+ data.cache_version=container.version
+ if container.enabled and caches then
+ local unique,shared=data.unique,data.shared
+ data.unique,data.shared=nil,nil
+ caches.savedata(container.writable,name,data)
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","save",container.subcategory,name)
+ end
+ data.unique,data.shared=unique,shared
end
- return data
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","store",container.subcategory,name)
+ end
+ container.storage[name]=data
+ end
+ return data
end
function containers.content(container,name)
- return container.storage[name]
+ return container.storage[name]
end
function containers.cleanname(name)
- return (gsub(lower(name),"[^%w\128-\255]+","-"))
+ return (gsub(lower(name),"[^%w\128-\255]+","-"))
end
@@ -23110,97 +23118,97 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-use"] = package.loaded["data-use"] or true
--- original size: 4272, stripped down to: 3289
+-- original size: 4272, stripped down to: 3060
if not modules then modules={} end modules ['data-use']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub,find=string.format,string.lower,string.gsub,string.find
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_mounts=logs.reporter("resolvers","mounts")
local resolvers=resolvers
resolvers.automounted=resolvers.automounted or {}
function resolvers.automount(usecache)
- local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
- if (not mountpaths or #mountpaths==0) and usecache then
- mountpaths=caches.getreadablepaths("mount")
- end
- if mountpaths and #mountpaths>0 then
- resolvers.starttiming()
- for k=1,#mountpaths do
- local root=mountpaths[k]
- local f=io.open(root.."/url.tmi")
- if f then
- for line in f:lines() do
- if line then
- if find(line,"^[%%#%-]") then
- elseif find(line,"^zip://") then
- if trace_locating then
- report_mounts("mounting %a",line)
- end
- table.insert(resolvers.automounted,line)
- resolvers.usezipfile(line)
- end
- end
- end
- f:close()
+ local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
+ if (not mountpaths or #mountpaths==0) and usecache then
+ mountpaths=caches.getreadablepaths("mount")
+ end
+ if mountpaths and #mountpaths>0 then
+ resolvers.starttiming()
+ for k=1,#mountpaths do
+ local root=mountpaths[k]
+ local f=io.open(root.."/url.tmi")
+ if f then
+ for line in f:lines() do
+ if line then
+ if find(line,"^[%%#%-]") then
+ elseif find(line,"^zip://") then
+ if trace_locating then
+ report_mounts("mounting %a",line)
+ end
+ table.insert(resolvers.automounted,line)
+ resolvers.usezipfile(line)
end
+ end
end
- resolvers.stoptiming()
+ f:close()
+ end
end
+ resolvers.stoptiming()
+ end
end
statistics.register("used config file",function() return caches.configfiles() end)
statistics.register("used cache path",function() return caches.usedpaths() end)
function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner)
- local enginebanner=status.banner
- if formatbanner and enginebanner and sourcefile then
- local luvname=file.replacesuffix(texname,"luv")
- local luvdata={
- enginebanner=enginebanner,
- formatbanner=formatbanner,
- sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
- sourcefile=sourcefile,
- luaversion=LUAVERSION,
- }
- io.savedata(luvname,table.serialize(luvdata,true))
- lua.registerfinalizer(function()
- logs.report("format banner","%s",banner)
- logs.newline()
- end)
- end
+ local enginebanner=status.banner
+ if formatbanner and enginebanner and sourcefile then
+ local luvname=file.replacesuffix(texname,"luv")
+ local luvdata={
+ enginebanner=enginebanner,
+ formatbanner=formatbanner,
+ sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
+ sourcefile=sourcefile,
+ luaversion=LUAVERSION,
+ }
+ io.savedata(luvname,table.serialize(luvdata,true))
+ lua.registerfinalizer(function()
+ logs.report("format banner","%s",banner)
+ logs.newline()
+ end)
+ end
end
function statistics.checkfmtstatus(texname)
- local enginebanner=status.banner
- if enginebanner and texname then
- local luvname=file.replacesuffix(texname,"luv")
- if lfs.isfile(luvname) then
- local luv=dofile(luvname)
- if luv and luv.sourcefile then
- local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
- local luvbanner=luv.enginebanner or "?"
- if luvbanner~=enginebanner then
- return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
- end
- local luvhash=luv.sourcehash or "?"
- if luvhash~=sourcehash then
- return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
- end
- local luvluaversion=luv.luaversion or 0
- if luvluaversion~=LUAVERSION then
- return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
- end
- else
- return "invalid status file"
- end
- else
- return "missing status file"
- end
+ local enginebanner=status.banner
+ if enginebanner and texname then
+ local luvname=file.replacesuffix(texname,"luv")
+ if lfs.isfile(luvname) then
+ local luv=dofile(luvname)
+ if luv and luv.sourcefile then
+ local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
+ local luvbanner=luv.enginebanner or "?"
+ if luvbanner~=enginebanner then
+ return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
+ end
+ local luvhash=luv.sourcehash or "?"
+ if luvhash~=sourcehash then
+ return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
+ end
+ local luvluaversion=luv.luaversion or 0
+ if luvluaversion~=LUAVERSION then
+ return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
+ end
+ else
+ return "invalid status file"
+ end
+ else
+ return "missing status file"
end
- return true
+ end
+ return true
end
@@ -23210,17 +23218,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-zip"] = package.loaded["data-zip"] or true
--- original size: 8700, stripped down to: 6781
+-- original size: 8700, stripped down to: 6313
if not modules then modules={} end modules ['data-zip']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,find,match=string.format,string.find,string.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_zip=logs.reporter("resolvers","zip")
local resolvers=resolvers
zip=zip or {}
@@ -23230,213 +23238,213 @@ zip.archives=archives
local registeredfiles=zip.registeredfiles or {}
zip.registeredfiles=registeredfiles
local function validzip(str)
- if not find(str,"^zip://") then
- return "zip:///"..str
- else
- return str
- end
+ if not find(str,"^zip://") then
+ return "zip:///"..str
+ else
+ return str
+ end
end
function zip.openarchive(name)
- if not name or name=="" then
- return nil
- else
- local arch=archives[name]
- if not arch then
- local full=resolvers.findfile(name) or ""
- arch=full~="" and zip.open(full) or false
- archives[name]=arch
- end
- return arch
+ if not name or name=="" then
+ return nil
+ else
+ local arch=archives[name]
+ if not arch then
+ local full=resolvers.findfile(name) or ""
+ arch=full~="" and zip.open(full) or false
+ archives[name]=arch
end
+ return arch
+ end
end
function zip.closearchive(name)
- if not name or (name=="" and archives[name]) then
- zip.close(archives[name])
- archives[name]=nil
- end
+ if not name or (name=="" and archives[name]) then
+ zip.close(archives[name])
+ archives[name]=nil
+ end
end
function resolvers.locators.zip(specification)
- local archive=specification.filename
- local zipfile=archive and archive~="" and zip.openarchive(archive)
- if trace_locating then
- if zipfile then
- report_zip("locator: archive %a found",archive)
- else
- report_zip("locator: archive %a not found",archive)
- end
+ local archive=specification.filename
+ local zipfile=archive and archive~="" and zip.openarchive(archive)
+ if trace_locating then
+ if zipfile then
+ report_zip("locator: archive %a found",archive)
+ else
+ report_zip("locator: archive %a not found",archive)
end
+ end
end
function resolvers.hashers.zip(specification)
- local archive=specification.filename
- if trace_locating then
- report_zip("loading file %a",archive)
- end
- resolvers.usezipfile(specification.original)
+ local archive=specification.filename
+ if trace_locating then
+ report_zip("loading file %a",archive)
+ end
+ resolvers.usezipfile(specification.original)
end
function resolvers.concatinators.zip(zipfile,path,name)
- if not path or path=="" then
- return format('%s?name=%s',zipfile,name)
- else
- return format('%s?name=%s/%s',zipfile,path,name)
- end
+ if not path or path=="" then
+ return format('%s?name=%s',zipfile,name)
+ else
+ return format('%s?name=%s/%s',zipfile,path,name)
+ end
end
function resolvers.finders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("finder: archive %a found",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- dfile:close()
- if trace_locating then
- report_zip("finder: file %a found",queryname)
- end
- return specification.original
- elseif trace_locating then
- report_zip("finder: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("finder: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("finder: archive %a found",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ dfile:close()
+ if trace_locating then
+ report_zip("finder: file %a found",queryname)
+ end
+ return specification.original
+ elseif trace_locating then
+ report_zip("finder: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("finder: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("finder: %a not found",original)
- end
- return resolvers.finders.notfound()
+ end
+ if trace_locating then
+ report_zip("finder: %a not found",original)
+ end
+ return resolvers.finders.notfound()
end
function resolvers.openers.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("opener; archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- if trace_locating then
- report_zip("opener: file %a found",queryname)
- end
- return resolvers.openers.helpers.textopener('zip',original,dfile)
- elseif trace_locating then
- report_zip("opener: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("opener: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("opener; archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ if trace_locating then
+ report_zip("opener: file %a found",queryname)
+ end
+ return resolvers.openers.helpers.textopener('zip',original,dfile)
+ elseif trace_locating then
+ report_zip("opener: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("opener: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("opener: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("opener: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.loaders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("loader: archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- logs.show_load(original)
- if trace_locating then
- report_zip("loader; file %a loaded",original)
- end
- local s=dfile:read("*all")
- dfile:close()
- return true,s,#s
- elseif trace_locating then
- report_zip("loader: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("loader; unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("loader: archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ logs.show_load(original)
+ if trace_locating then
+ report_zip("loader; file %a loaded",original)
+ end
+ local s=dfile:read("*all")
+ dfile:close()
+ return true,s,#s
+ elseif trace_locating then
+ report_zip("loader: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("loader; unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("loader: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("loader: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.usezipfile(archive)
- local specification=resolvers.splitmethod(archive)
- local archive=specification.filename
- if archive and not registeredfiles[archive] then
- local z=zip.openarchive(archive)
- if z then
- local tree=url.query(specification.query).tree or ""
- if trace_locating then
- report_zip("registering: archive %a",archive)
- end
- resolvers.starttiming()
- resolvers.prependhash('zip',archive)
- resolvers.extendtexmfvariable(archive)
- registeredfiles[archive]=z
- resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
- resolvers.stoptiming()
- elseif trace_locating then
- report_zip("registering: unknown archive %a",archive)
- end
+ local specification=resolvers.splitmethod(archive)
+ local archive=specification.filename
+ if archive and not registeredfiles[archive] then
+ local z=zip.openarchive(archive)
+ if z then
+ local tree=url.query(specification.query).tree or ""
+ if trace_locating then
+ report_zip("registering: archive %a",archive)
+ end
+ resolvers.starttiming()
+ resolvers.prependhash('zip',archive)
+ resolvers.extendtexmfvariable(archive)
+ registeredfiles[archive]=z
+ resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
+ resolvers.stoptiming()
elseif trace_locating then
- report_zip("registering: archive %a not found",archive)
+ report_zip("registering: unknown archive %a",archive)
end
+ elseif trace_locating then
+ report_zip("registering: archive %a not found",archive)
+ end
end
function resolvers.registerzipfile(z,tree)
- local names={}
- local files={}
- local remap={}
- local n=0
- local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
- local register=resolvers.registerfile
- if trace_locating then
- report_zip("registering: using filter %a",filter)
- end
- for i in z:files() do
- local filename=i.filename
- local path,name=match(filename,filter)
- if not path then
- n=n+1
- register(names,filename,"")
- local usedname=lower(filename)
- files[usedname]=""
- if usedname~=filename then
- remap[usedname]=filename
- end
- elseif name and name~="" then
- n=n+1
- register(names,name,path)
- local usedname=lower(name)
- files[usedname]=path
- if usedname~=name then
- remap[usedname]=name
- end
- else
- end
+ local names={}
+ local files={}
+ local remap={}
+ local n=0
+ local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
+ local register=resolvers.registerfile
+ if trace_locating then
+ report_zip("registering: using filter %a",filter)
+ end
+ for i in z:files() do
+ local filename=i.filename
+ local path,name=match(filename,filter)
+ if not path then
+ n=n+1
+ register(names,filename,"")
+ local usedname=lower(filename)
+ files[usedname]=""
+ if usedname~=filename then
+ remap[usedname]=filename
+ end
+ elseif name and name~="" then
+ n=n+1
+ register(names,name,path)
+ local usedname=lower(name)
+ files[usedname]=path
+ if usedname~=name then
+ remap[usedname]=name
+ end
+ else
end
- report_zip("registering: %s files registered",n)
- return {
- files=files,
- remap=remap,
- }
+ end
+ report_zip("registering: %s files registered",n)
+ return {
+ files=files,
+ remap=remap,
+ }
end
@@ -23446,20 +23454,20 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tre"] = package.loaded["data-tre"] or true
--- original size: 8478, stripped down to: 5611
+-- original size: 8478, stripped down to: 5223
if not modules then modules={} end modules ['data-tre']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local find,gsub,lower=string.find,string.gsub,string.lower
-local basename,dirname,joinname=file.basename,file.dirname,file .join
+local basename,dirname,joinname=file.basename,file.dirname,file .join
local globdir,isdir,isfile=dir.glob,lfs.isdir,lfs.isfile
local P,lpegmatch=lpeg.P,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_trees=logs.reporter("resolvers","trees")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -23468,167 +23476,167 @@ local lookup=resolvers.get_from_content
local collectors={}
local found={}
function resolvers.finders.tree(specification)
- local spec=specification.filename
- local okay=found[spec]
- if okay==nil then
- if spec~="" then
- local path=dirname(spec)
- local name=basename(spec)
- if path=="" then
- path="."
- end
- local names=collectors[path]
- if not names then
- local pattern=find(path,"/%*+$") and path or (path.."/*")
- names=globdir(pattern)
- collectors[path]=names
- end
- local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
- for i=1,#names do
- local fullname=names[i]
- if find(fullname,pattern) then
- found[spec]=fullname
- return fullname
- end
- end
- local pattern=lower(pattern)
- for i=1,#names do
- local fullname=lower(names[i])
- if find(fullname,pattern) then
- if isfile(fullname) then
- found[spec]=fullname
- return fullname
- else
- break
- end
- end
- end
+ local spec=specification.filename
+ local okay=found[spec]
+ if okay==nil then
+ if spec~="" then
+ local path=dirname(spec)
+ local name=basename(spec)
+ if path=="" then
+ path="."
+ end
+ local names=collectors[path]
+ if not names then
+ local pattern=find(path,"/%*+$") and path or (path.."/*")
+ names=globdir(pattern)
+ collectors[path]=names
+ end
+ local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
+ for i=1,#names do
+ local fullname=names[i]
+ if find(fullname,pattern) then
+ found[spec]=fullname
+ return fullname
+ end
+ end
+ local pattern=lower(pattern)
+ for i=1,#names do
+ local fullname=lower(names[i])
+ if find(fullname,pattern) then
+ if isfile(fullname) then
+ found[spec]=fullname
+ return fullname
+ else
+ break
+ end
end
- okay=notfound()
- found[spec]=okay
+ end
end
- return okay
+ okay=notfound()
+ found[spec]=okay
+ end
+ return okay
end
function resolvers.locators.tree(specification)
- local name=specification.filename
- local realname=resolveprefix(name)
- if realname and realname~='' and isdir(realname) then
- if trace_locating then
- report_trees("locator %a found",realname)
- end
- resolvers.appendhash('tree',name,false)
- elseif trace_locating then
- report_trees("locator %a not found",name)
+ local name=specification.filename
+ local realname=resolveprefix(name)
+ if realname and realname~='' and isdir(realname) then
+ if trace_locating then
+ report_trees("locator %a found",realname)
end
+ resolvers.appendhash('tree',name,false)
+ elseif trace_locating then
+ report_trees("locator %a not found",name)
+ end
end
function resolvers.hashers.tree(specification)
- local name=specification.filename
- if trace_locating then
- report_trees("analyzing %a",name)
- end
- resolvers.methodhandler("hashers",name)
- resolvers.generators.file(specification)
+ local name=specification.filename
+ if trace_locating then
+ report_trees("analyzing %a",name)
+ end
+ resolvers.methodhandler("hashers",name)
+ resolvers.generators.file(specification)
end
local collectors={}
local splitter=lpeg.splitat("/**/")
local stripper=lpeg.replacer { [P("/")*P("*")^1*P(-1)]="" }
table.setmetatableindex(collectors,function(t,k)
- local rootname=lpegmatch(stripper,k)
- local dataname=joinname(rootname,"dirlist")
- local content=caches.loadcontent(dataname,"files",dataname)
- if not content then
- content=resolvers.scanfiles(rootname,nil,nil,false,true)
- caches.savecontent(dataname,"files",content,dataname)
- end
- t[k]=content
- return content
+ local rootname=lpegmatch(stripper,k)
+ local dataname=joinname(rootname,"dirlist")
+ local content=caches.loadcontent(dataname,"files",dataname)
+ if not content then
+ content=resolvers.scanfiles(rootname,nil,nil,false,true)
+ caches.savecontent(dataname,"files",content,dataname)
+ end
+ t[k]=content
+ return content
end)
local function checked(root,p,n)
- if p then
- if type(p)=="table" then
- for i=1,#p do
- local fullname=joinname(root,p[i],n)
- if isfile(fullname) then
- return fullname
- end
- end
- else
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
+ if p then
+ if type(p)=="table" then
+ for i=1,#p do
+ local fullname=joinname(root,p[i],n)
+ if isfile(fullname) then
+ return fullname
end
+ end
+ else
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- return notfound()
+ end
+ return notfound()
end
local function resolve(specification)
- local filename=specification.filename
- if filename~="" then
- local root,rest=lpegmatch(splitter,filename)
- if root and rest then
- local path,name=dirname(rest),basename(rest)
- if name~=rest then
- local content=collectors[root]
- local p,n=lookup(content,name)
- if not p then
- return notfound()
- end
- local pattern=".*/"..path.."$"
- local istable=type(p)=="table"
- if istable then
- for i=1,#p do
- local pi=p[i]
- if pi==path or find(pi,pattern) then
- local fullname=joinname(root,pi,n)
- if isfile(fullname) then
- return fullname
- end
- end
- end
- elseif p==path or find(p,pattern) then
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
- end
- local queries=specification.queries
- if queries and queries.option=="fileonly" then
- return checked(root,p,n)
- else
- return notfound()
- end
+ local filename=specification.filename
+ if filename~="" then
+ local root,rest=lpegmatch(splitter,filename)
+ if root and rest then
+ local path,name=dirname(rest),basename(rest)
+ if name~=rest then
+ local content=collectors[root]
+ local p,n=lookup(content,name)
+ if not p then
+ return notfound()
+ end
+ local pattern=".*/"..path.."$"
+ local istable=type(p)=="table"
+ if istable then
+ for i=1,#p do
+ local pi=p[i]
+ if pi==path or find(pi,pattern) then
+ local fullname=joinname(root,pi,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
+ end
+ elseif p==path or find(p,pattern) then
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- local path,name=dirname(filename),basename(filename)
- local root=lpegmatch(stripper,path)
- local content=collectors[path]
- local p,n=lookup(content,name)
- if p then
- return checked(root,p,n)
+ local queries=specification.queries
+ if queries and queries.option=="fileonly" then
+ return checked(root,p,n)
+ else
+ return notfound()
end
+ end
+ end
+ local path,name=dirname(filename),basename(filename)
+ local root=lpegmatch(stripper,path)
+ local content=collectors[path]
+ local p,n=lookup(content,name)
+ if p then
+ return checked(root,p,n)
end
- return notfound()
+ end
+ return notfound()
end
-resolvers.finders .dirlist=resolve
-resolvers.locators .dirlist=resolvers.locators .tree
-resolvers.hashers .dirlist=resolvers.hashers .tree
+resolvers.finders .dirlist=resolve
+resolvers.locators .dirlist=resolvers.locators .tree
+resolvers.hashers .dirlist=resolvers.hashers .tree
resolvers.generators.dirlist=resolvers.generators.file
-resolvers.openers .dirlist=resolvers.openers .file
-resolvers.loaders .dirlist=resolvers.loaders .file
+resolvers.openers .dirlist=resolvers.openers .file
+resolvers.loaders .dirlist=resolvers.loaders .file
function resolvers.finders.dirfile(specification)
- local queries=specification.queries
- if queries then
- queries.option="fileonly"
- else
- specification.queries={ option="fileonly" }
- end
- return resolve(specification)
-end
-resolvers.locators .dirfile=resolvers.locators .dirlist
-resolvers.hashers .dirfile=resolvers.hashers .dirlist
+ local queries=specification.queries
+ if queries then
+ queries.option="fileonly"
+ else
+ specification.queries={ option="fileonly" }
+ end
+ return resolve(specification)
+end
+resolvers.locators .dirfile=resolvers.locators .dirlist
+resolvers.hashers .dirfile=resolvers.hashers .dirlist
resolvers.generators.dirfile=resolvers.generators.dirlist
-resolvers.openers .dirfile=resolvers.openers .dirlist
-resolvers.loaders .dirfile=resolvers.loaders .dirlist
+resolvers.openers .dirfile=resolvers.openers .dirlist
+resolvers.loaders .dirfile=resolvers.loaders .dirlist
end -- of closure
@@ -23637,19 +23645,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-sch"] = package.loaded["data-sch"] or true
--- original size: 6753, stripped down to: 5511
+-- original size: 6753, stripped down to: 5268
if not modules then modules={} end modules ['data-sch']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local load,tonumber=load,tonumber
local gsub,concat,format=string.gsub,table.concat,string.format
local finders,openers,loaders=resolvers.finders,resolvers.openers,resolvers.loaders
-local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
+local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
local report_schemes=logs.reporter("resolvers","schemes")
local http=require("socket.http")
local ltn12=require("ltn12")
@@ -23662,27 +23670,27 @@ schemes.cleaners=cleaners
local threshold=24*60*60
directives.register("schemes.threshold",function(v) threshold=tonumber(v) or threshold end)
function cleaners.none(specification)
- return specification.original
+ return specification.original
end
function cleaners.strip(specification)
- local path,name=file.splitbase(specification.original)
- if path=="" then
- return (gsub(name,"[^%a%d%.]+","-"))
- else
- return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
- end
+ local path,name=file.splitbase(specification.original)
+ if path=="" then
+ return (gsub(name,"[^%a%d%.]+","-"))
+ else
+ return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
+ end
end
function cleaners.md5(specification)
- return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
+ return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
end
local cleaner=cleaners.strip
directives.register("schemes.cleanmethod",function(v) cleaner=cleaners[v] or cleaners.strip end)
function resolvers.schemes.cleanname(specification)
- local hash=cleaner(specification)
- if trace_schemes then
- report_schemes("hashing %a to %a",specification.original,hash)
- end
- return hash
+ local hash=cleaner(specification)
+ if trace_schemes then
+ report_schemes("hashing %a to %a",specification.original,hash)
+ end
+ return hash
end
local cached={}
local loaded={}
@@ -23690,139 +23698,139 @@ local reused={}
local thresholds={}
local handlers={}
local runner=sandbox.registerrunner {
- name="curl resolver",
- method="execute",
- program="curl",
- template="--silent --insecure --create-dirs --output %cachename% %original%",
- checkers={
- cachename="cache",
- original="url",
- }
+ name="curl resolver",
+ method="execute",
+ program="curl",
+ template="--silent --insecure --create-dirs --output %cachename% %original%",
+ checkers={
+ cachename="cache",
+ original="url",
+ }
}
local function fetch(specification)
- local original=specification.original
- local scheme=specification.scheme
- local cleanname=schemes.cleanname(specification)
- local cachename=caches.setfirstwritablefile(cleanname,"schemes")
- if not cached[original] then
- statistics.starttiming(schemes)
- if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
- cached[original]=cachename
- local handler=handlers[scheme]
- if handler then
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
- end
- logs.flush()
- handler(specification,cachename)
- else
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
- end
- logs.flush()
- runner {
- original=original,
- cachename=cachename,
- }
- end
- end
- if io.exists(cachename) then
- cached[original]=cachename
- if trace_schemes then
- report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
- end
- else
- cached[original]=""
- if trace_schemes then
- report_schemes("using missing %a, protocol %a",original,scheme)
- end
+ local original=specification.original
+ local scheme=specification.scheme
+ local cleanname=schemes.cleanname(specification)
+ local cachename=caches.setfirstwritablefile(cleanname,"schemes")
+ if not cached[original] then
+ statistics.starttiming(schemes)
+ if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
+ cached[original]=cachename
+ local handler=handlers[scheme]
+ if handler then
+ if trace_schemes then
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
end
- loaded[scheme]=loaded[scheme]+1
- statistics.stoptiming(schemes)
- else
+ logs.flush()
+ handler(specification,cachename)
+ else
if trace_schemes then
- report_schemes("reusing %a, protocol %a",original,scheme)
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
end
- reused[scheme]=reused[scheme]+1
+ logs.flush()
+ runner {
+ original=original,
+ cachename=cachename,
+ }
+ end
end
- return cached[original]
+ if io.exists(cachename) then
+ cached[original]=cachename
+ if trace_schemes then
+ report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
+ end
+ else
+ cached[original]=""
+ if trace_schemes then
+ report_schemes("using missing %a, protocol %a",original,scheme)
+ end
+ end
+ loaded[scheme]=loaded[scheme]+1
+ statistics.stoptiming(schemes)
+ else
+ if trace_schemes then
+ report_schemes("reusing %a, protocol %a",original,scheme)
+ end
+ reused[scheme]=reused[scheme]+1
+ end
+ return cached[original]
end
local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
+ return resolvers.methodhandler("finders",fetch(specification),filetype)
end
local opener=openers.file
local loader=loaders.file
local function install(scheme,handler,newthreshold)
- handlers [scheme]=handler
- loaded [scheme]=0
- reused [scheme]=0
- finders [scheme]=finder
- openers [scheme]=opener
- loaders [scheme]=loader
- thresholds[scheme]=newthreshold or threshold
+ handlers [scheme]=handler
+ loaded [scheme]=0
+ reused [scheme]=0
+ finders [scheme]=finder
+ openers [scheme]=opener
+ loaders [scheme]=loader
+ thresholds[scheme]=newthreshold or threshold
end
schemes.install=install
local function http_handler(specification,cachename)
- local tempname=cachename..".tmp"
- local f=io.open(tempname,"wb")
- local status,message=http.request {
- url=specification.original,
- sink=ltn12.sink.file(f)
- }
- if not status then
- os.remove(tempname)
- else
- os.remove(cachename)
- os.rename(tempname,cachename)
- end
- return cachename
+ local tempname=cachename..".tmp"
+ local f=io.open(tempname,"wb")
+ local status,message=http.request {
+ url=specification.original,
+ sink=ltn12.sink.file(f)
+ }
+ if not status then
+ os.remove(tempname)
+ else
+ os.remove(cachename)
+ os.rename(tempname,cachename)
+ end
+ return cachename
end
install('http',http_handler)
install('https')
install('ftp')
statistics.register("scheme handling time",function()
- local l,r,nl,nr={},{},0,0
- for k,v in table.sortedhash(loaded) do
- if v>0 then
- nl=nl+1
- l[nl]=k..":"..v
- end
- end
- for k,v in table.sortedhash(reused) do
- if v>0 then
- nr=nr+1
- r[nr]=k..":"..v
- end
- end
- local n=nl+nr
- if n>0 then
- l=nl>0 and concat(l) or "none"
- r=nr>0 and concat(r) or "none"
- return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
- statistics.elapsedtime(schemes),n,threshold,l,r)
- else
- return nil
- end
+ local l,r,nl,nr={},{},0,0
+ for k,v in table.sortedhash(loaded) do
+ if v>0 then
+ nl=nl+1
+ l[nl]=k..":"..v
+ end
+ end
+ for k,v in table.sortedhash(reused) do
+ if v>0 then
+ nr=nr+1
+ r[nr]=k..":"..v
+ end
+ end
+ local n=nl+nr
+ if n>0 then
+ l=nl>0 and concat(l) or "none"
+ r=nr>0 and concat(r) or "none"
+ return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
+ statistics.elapsedtime(schemes),n,threshold,l,r)
+ else
+ return nil
+ end
end)
local httprequest=http.request
local toquery=url.toquery
local function fetchstring(url,data)
- local q=data and toquery(data)
- if q then
- url=url.."?"..q
- end
- local reply=httprequest(url)
- return reply
+ local q=data and toquery(data)
+ if q then
+ url=url.."?"..q
+ end
+ local reply=httprequest(url)
+ return reply
end
schemes.fetchstring=fetchstring
function schemes.fetchtable(url,data)
- local reply=fetchstring(url,data)
- if reply then
- local s=load("return "..reply)
- if s then
- return s()
- end
+ local reply=fetchstring(url,data)
+ if reply then
+ local s=load("return "..reply)
+ if s then
+ return s()
end
+ end
end
@@ -23832,14 +23840,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lua"] = package.loaded["data-lua"] or true
--- original size: 4207, stripped down to: 3137
+-- original size: 4207, stripped down to: 3041
if not modules then modules={} end modules ['data-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local package,lpeg=package,lpeg
local gsub=string.gsub
@@ -23858,20 +23866,20 @@ helpers.report=logs.reporter("resolvers","libraries")
trackers.register("resolvers.libraries",function(v) helpers.trace=v end)
trackers.register("resolvers.locating",function(v) helpers.trace=v end)
helpers.sequence={
- "already loaded",
- "preload table",
- "lua variable format",
- "lib variable format",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
+ "already loaded",
+ "preload table",
+ "lua variable format",
+ "lib variable format",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
}
local pattern=Cs(P("!")^0/""*(P("/")*P(-1)/"/"+P("/")^1/"/"+1)^0)
function helpers.cleanpath(path)
- return resolveprefix(lpegmatch(pattern,path))
+ return resolveprefix(lpegmatch(pattern,path))
end
local loadedaslib=helpers.loadedaslib
local registerpath=helpers.registerpath
@@ -23879,56 +23887,56 @@ local lualibfile=helpers.lualibfile
local luaformatpaths
local libformatpaths
local function getluaformatpaths()
- if not luaformatpaths then
- luaformatpaths={}
- for i=1,#luaformats do
- registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
- end
+ if not luaformatpaths then
+ luaformatpaths={}
+ for i=1,#luaformats do
+ registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
end
- return luaformatpaths
+ end
+ return luaformatpaths
end
local function getlibformatpaths()
- if not libformatpaths then
- libformatpaths={}
- for i=1,#libformats do
- registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
- end
+ if not libformatpaths then
+ libformatpaths={}
+ for i=1,#libformats do
+ registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
end
- return libformatpaths
+ end
+ return libformatpaths
end
local function loadedbyformat(name,rawname,suffixes,islib,what)
- local trace=helpers.trace
- local report=helpers.report
- for i=1,#suffixes do
- local format=suffixes[i]
- local resolved=resolvers.findfile(name,format) or ""
- if trace then
- report("%s format, identifying %a using format %a",what,name,format)
- end
- if resolved~="" then
- if trace then
- report("%s format, %a found on %a",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ local report=helpers.report
+ for i=1,#suffixes do
+ local format=suffixes[i]
+ local resolved=resolvers.findfile(name,format) or ""
+ if trace then
+ report("%s format, identifying %a using format %a",what,name,format)
end
+ if resolved~="" then
+ if trace then
+ report("%s format, %a found on %a",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
+ end
+ end
end
helpers.loadedbyformat=loadedbyformat
methods["lua variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
end
methods["lib variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
end
resolvers.loadlualib=require
@@ -23939,64 +23947,64 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-aux"] = package.loaded["data-aux"] or true
--- original size: 2438, stripped down to: 2003
+-- original size: 2438, stripped down to: 1863
if not modules then modules={} end modules ['data-aux']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local find=string.find
local type,next=type,next
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local resolvers=resolvers
local report_scripts=logs.reporter("resolvers","scripts")
function resolvers.updatescript(oldname,newname)
- local scriptpath="context/lua"
- newname=file.addsuffix(newname,"lua")
- local oldscript=resolvers.cleanpath(oldname)
+ local scriptpath="context/lua"
+ newname=file.addsuffix(newname,"lua")
+ local oldscript=resolvers.cleanpath(oldname)
+ if trace_locating then
+ report_scripts("to be replaced old script %a",oldscript)
+ end
+ local newscripts=resolvers.findfiles(newname) or {}
+ if #newscripts==0 then
if trace_locating then
- report_scripts("to be replaced old script %a",oldscript)
+ report_scripts("unable to locate new script")
end
- local newscripts=resolvers.findfiles(newname) or {}
- if #newscripts==0 then
+ else
+ for i=1,#newscripts do
+ local newscript=resolvers.cleanpath(newscripts[i])
+ if trace_locating then
+ report_scripts("checking new script %a",newscript)
+ end
+ if oldscript==newscript then
if trace_locating then
- report_scripts("unable to locate new script")
+ report_scripts("old and new script are the same")
end
- else
- for i=1,#newscripts do
- local newscript=resolvers.cleanpath(newscripts[i])
- if trace_locating then
- report_scripts("checking new script %a",newscript)
- end
- if oldscript==newscript then
- if trace_locating then
- report_scripts("old and new script are the same")
- end
- elseif not find(newscript,scriptpath,1,true) then
- if trace_locating then
- report_scripts("new script should come from %a",scriptpath)
- end
- elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
- if trace_locating then
- report_scripts("invalid new script name")
- end
- else
- local newdata=io.loaddata(newscript)
- if newdata then
- if trace_locating then
- report_scripts("old script content replaced by new content")
- end
- io.savedata(oldscript,newdata)
- break
- elseif trace_locating then
- report_scripts("unable to load new script")
- end
- end
+ elseif not find(newscript,scriptpath,1,true) then
+ if trace_locating then
+ report_scripts("new script should come from %a",scriptpath)
+ end
+ elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
+ if trace_locating then
+ report_scripts("invalid new script name")
end
+ else
+ local newdata=io.loaddata(newscript)
+ if newdata then
+ if trace_locating then
+ report_scripts("old script content replaced by new content")
+ end
+ io.savedata(oldscript,newdata)
+ break
+ elseif trace_locating then
+ report_scripts("unable to load new script")
+ end
+ end
end
+ end
end
@@ -24006,53 +24014,53 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmf"] = package.loaded["data-tmf"] or true
--- original size: 2601, stripped down to: 1627
+-- original size: 2601, stripped down to: 1549
if not modules then modules={} end modules ['data-tmf']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local resolvers=resolvers
local report_tds=logs.reporter("resolvers","tds")
function resolvers.load_tree(tree,resolve)
- if type(tree)=="string" and tree~="" then
- local getenv,setenv=resolvers.getenv,resolvers.setenv
- local texos="texmf-"..os.platform
- local oldroot=environment.texroot
- local newroot=file.collapsepath(tree)
- local newtree=file.join(newroot,texos)
- local newpath=file.join(newtree,"bin")
- if not lfs.isdir(newtree) then
- report_tds("no %a under tree %a",texos,tree)
- os.exit()
- end
- if not lfs.isdir(newpath) then
- report_tds("no '%s/bin' under tree %a",texos,tree)
- os.exit()
- end
- local texmfos=newtree
- environment.texroot=newroot
- environment.texos=texos
- environment.texmfos=texmfos
- if resolve then
- resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
- end
- setenv('SELFAUTOPARENT',newroot)
- setenv('SELFAUTODIR',newtree)
- setenv('SELFAUTOLOC',newpath)
- setenv('TEXROOT',newroot)
- setenv('TEXOS',texos)
- setenv('TEXMFOS',texmfos)
- setenv('TEXMFCNF',resolvers.luacnfspec,true)
- setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
- report_tds("changing from root %a to %a",oldroot,newroot)
- report_tds("prepending %a to PATH",newpath)
- report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
- report_tds()
- end
+ if type(tree)=="string" and tree~="" then
+ local getenv,setenv=resolvers.getenv,resolvers.setenv
+ local texos="texmf-"..os.platform
+ local oldroot=environment.texroot
+ local newroot=file.collapsepath(tree)
+ local newtree=file.join(newroot,texos)
+ local newpath=file.join(newtree,"bin")
+ if not lfs.isdir(newtree) then
+ report_tds("no %a under tree %a",texos,tree)
+ os.exit()
+ end
+ if not lfs.isdir(newpath) then
+ report_tds("no '%s/bin' under tree %a",texos,tree)
+ os.exit()
+ end
+ local texmfos=newtree
+ environment.texroot=newroot
+ environment.texos=texos
+ environment.texmfos=texmfos
+ if resolve then
+ resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
+ end
+ setenv('SELFAUTOPARENT',newroot)
+ setenv('SELFAUTODIR',newtree)
+ setenv('SELFAUTOLOC',newpath)
+ setenv('TEXROOT',newroot)
+ setenv('TEXOS',texos)
+ setenv('TEXMFOS',texmfos)
+ setenv('TEXMFCNF',resolvers.luacnfspec,true)
+ setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
+ report_tds("changing from root %a to %a",oldroot,newroot)
+ report_tds("prepending %a to PATH",newpath)
+ report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
+ report_tds()
+ end
end
@@ -24062,14 +24070,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lst"] = package.loaded["data-lst"] or true
--- original size: 1823, stripped down to: 1591
+-- original size: 1823, stripped down to: 1542
if not modules then modules={} end modules ['data-lst']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type=type
local concat,sortedhash=table.concat,table.sortedhash
@@ -24080,37 +24088,37 @@ local resolveprefix=resolvers.resolve
local report_lists=logs.reporter("resolvers","lists")
local report_resolved=logs.reporter("system","resolved")
local function tabstr(str)
- if type(str)=='table' then
- return concat(str," | ")
- else
- return str
- end
+ if type(str)=='table' then
+ return concat(str," | ")
+ else
+ return str
+ end
end
function listers.variables(pattern)
- local result=resolvers.knownvariables(pattern)
- for key,value in sortedhash(result) do
- report_lists(key)
- report_lists(" env: %s",tabstr(value.environment or "unset"))
- report_lists(" var: %s",tabstr(value.variable or "unset"))
- report_lists(" exp: %s",tabstr(value.expansion or "unset"))
- report_lists(" res: %s",tabstr(value.resolved or "unset"))
- end
+ local result=resolvers.knownvariables(pattern)
+ for key,value in sortedhash(result) do
+ report_lists(key)
+ report_lists(" env: %s",tabstr(value.environment or "unset"))
+ report_lists(" var: %s",tabstr(value.variable or "unset"))
+ report_lists(" exp: %s",tabstr(value.expansion or "unset"))
+ report_lists(" res: %s",tabstr(value.resolved or "unset"))
+ end
end
function listers.configurations()
- local configurations=resolvers.configurationfiles()
- for i=1,#configurations do
- report_resolved("file : %s",resolveprefix(configurations[i]))
- end
- report_resolved("")
- local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
- for i=1,#list do
- local li=resolveprefix(list[i])
- if lfs.isdir(li) then
- report_resolved("path - %s",li)
- else
- report_resolved("path + %s",li)
- end
+ local configurations=resolvers.configurationfiles()
+ for i=1,#configurations do
+ report_resolved("file : %s",resolveprefix(configurations[i]))
+ end
+ report_resolved("")
+ local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
+ for i=1,#list do
+ local li=resolveprefix(list[i])
+ if lfs.isdir(li) then
+ report_resolved("path - %s",li)
+ else
+ report_resolved("path + %s",li)
end
+ end
end
@@ -24120,14 +24128,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lib"] = package.loaded["util-lib"] or true
--- original size: 16094, stripped down to: 9206
+-- original size: 16094, stripped down to: 8443
if not modules then modules={} end modules ['util-lib']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local type=type
local next=next
@@ -24147,291 +24155,291 @@ local qualifiedpath=file.is_qualified_path
local isfile=lfs.isfile
local done=false
local function locate(required,version,trace,report,action)
- if type(required)~="string" then
- report("provide a proper library name")
- return
- end
- if trace then
- report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/")
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
- if isfile(addsuffix(required,os.libsuffix)) then
- if trace then
- report("qualified name %a found",required)
- end
- found_library=required
- else
- if trace then
- report("qualified name %a not found",required)
- end
- end
+ if type(required)~="string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library=nil
+ local required_full=gsub(required,"%.","/")
+ local required_path=pathpart(required_full)
+ local required_base=nameonly(required_full)
+ if qualifiedpath(required) then
+ if isfile(addsuffix(required,os.libsuffix)) then
+ if trace then
+ report("qualified name %a found",required)
+ end
+ found_library=required
else
- local required_name=required_base.."."..os.libsuffix
- local version=type(version)=="string" and version~="" and version or false
- local engine="luatex"
- if trace and not done then
- local list=expandpaths("lib")
- for i=1,#list do
- report("tds path %i: %s",i,list[i])
- end
+ if trace then
+ report("qualified name %a not found",required)
+ end
+ end
+ else
+ local required_name=required_base.."."..os.libsuffix
+ local version=type(version)=="string" and version~="" and version or false
+ local engine="luatex"
+ if trace and not done then
+ local list=expandpaths("lib")
+ for i=1,#list do
+ report("tds path %i: %s",i,list[i])
+ end
+ end
+ local function found(locate,asked_library,how,...)
+ if trace then
+ report("checking %s: %a",how,asked_library)
+ end
+ return locate(asked_library,...)
+ end
+ local function check(locate,...)
+ local found=nil
+ if version then
+ local asked_library=joinfile(required_path,version,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function found(locate,asked_library,how,...)
- if trace then
- report("checking %s: %a",how,asked_library)
- end
- return locate(asked_library,...)
- end
- local function check(locate,...)
- local found=nil
- if version then
- local asked_library=joinfile(required_path,version,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- if not found or found=="" then
- local asked_library=joinfile(required_path,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- return found and found~="" and found or false
+ found=locate(asked_library,...)
+ end
+ if not found or found=="" then
+ local asked_library=joinfile(required_path,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function attempt(checkpattern)
- if trace then
- report("checking tds lib paths strictly")
- end
- local found=findfile and check(findfile,"lib")
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- if trace then
- report("checking tds lib paths with wildcard")
- end
- local asked_library=joinfile(required_path,".*",required_name)
- if trace then
- report("checking %s: %a","latest version",asked_library)
- end
- local list=findfiles(asked_library,"lib",true)
- if list and #list>0 then
- sort(list)
- local found=list[#list]
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- if trace then
- report("checking lib paths")
- end
- package.extralibpath(environment.ownpath)
- local paths=package.libpaths()
- local pattern="/[^/]+%."..os.libsuffix.."$"
- for i=1,#paths do
- required_path=gsub(paths[i],pattern,"")
- local found=check(lfs.isfound)
- if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- return false
+ found=locate(asked_library,...)
+ end
+ return found and found~="" and found or false
+ end
+ local function attempt(checkpattern)
+ if trace then
+ report("checking tds lib paths strictly")
+ end
+ local found=findfile and check(findfile,"lib")
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
+ end
+ if trace then
+ report("checking tds lib paths with wildcard")
+ end
+ local asked_library=joinfile(required_path,".*",required_name)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
+ end
+ local list=findfiles(asked_library,"lib",true)
+ if list and #list>0 then
+ sort(list)
+ local found=list[#list]
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
end
- if engine then
- if trace then
- report("attemp 1, engine %a",engine)
- end
- found_library=attempt("/"..engine.."/")
- if not found_library then
- if trace then
- report("attemp 2, no engine",asked_library)
- end
- found_library=attempt()
- end
- else
- found_library=attempt()
+ end
+ if trace then
+ report("checking lib paths")
+ end
+ package.extralibpath(environment.ownpath)
+ local paths=package.libpaths()
+ local pattern="/[^/]+%."..os.libsuffix.."$"
+ for i=1,#paths do
+ required_path=gsub(paths[i],pattern,"")
+ local found=check(lfs.isfound)
+ if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
+ return found
end
+ end
+ return false
end
- if not found_library then
+ if engine then
+ if trace then
+ report("attemp 1, engine %a",engine)
+ end
+ found_library=attempt("/"..engine.."/")
+ if not found_library then
if trace then
- report("not found: %a",required)
+ report("attemp 2, no engine",asked_library)
end
- library=false
+ found_library=attempt()
+ end
else
- if trace then
- report("found: %a",found_library)
- end
- local result,message=action(found_library,required_base)
- if result then
- library=result
- else
- library=false
- report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
- end
+ found_library=attempt()
end
+ end
+ if not found_library then
if trace then
- if not library then
- report("unknown library: %a",required)
- else
- report("stored library: %a",required)
- end
+ report("not found: %a",required)
+ end
+ library=false
+ else
+ if trace then
+ report("found: %a",found_library)
+ end
+ local result,message=action(found_library,required_base)
+ if result then
+ library=result
+ else
+ library=false
+ report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
end
- return library or nil
+ end
+ if trace then
+ if not library then
+ report("unknown library: %a",required)
+ else
+ report("stored library: %a",required)
+ end
+ end
+ return library or nil
end
do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
- local library=loadedlibs[library]
- if library==nil then
- local trace_swiglib=trace_swiglib or package.helpers.trace
- library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
- pushdir(pathpart(name))
- local opener="luaopen_"..base
- if trace_swiglib then
- report_swiglib("opening: %a with %a",name,opener)
- end
- local library,message=loadlib(name,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
- else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
- end
- popdir()
- return library
- end)
- loadedlibs[required]=library or false
- end
- return library
- end
- function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
+ local report_swiglib=logs.reporter("swiglib")
+ local trace_swiglib=false
+ local savedrequire=require
+ local loadedlibs={}
+ local loadlib=package.loadlib
+ local pushdir=dir.push
+ local popdir=dir.pop
+ trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+ function requireswiglib(required,version)
+ local library=loadedlibs[library]
+ if library==nil then
+ local trace_swiglib=trace_swiglib or package.helpers.trace
+ library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ pushdir(pathpart(name))
+ local opener="luaopen_"..base
+ if trace_swiglib then
+ report_swiglib("opening: %a with %a",name,opener)
+ end
+ local library,message=loadlib(name,opener)
+ local libtype=type(library)
+ if libtype=="function" then
+ library=library()
else
- return savedrequire(name)
- end
- end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
- else
- fullname="swiglib."..name
- end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library=false
end
+ popdir()
return library
+ end)
+ loadedlibs[required]=library or false
+ end
+ return library
+ end
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
+ else
+ return savedrequire(name)
+ end
+ end
+ local swiglibs={}
+ local initializer="core"
+ function swiglib(name,version)
+ local library=swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
+ if trace_swiglib then
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%."..initializer.."$") then
+ fullname="swiglib."..name.."."..initializer
+ else
+ fullname="swiglib."..name
+ end
+ library=requireswiglib(fullname,version)
+ swiglibs[name]=library
+ statistics.stoptiming(swiglibs)
end
- statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
- end)
+ return library
+ end
+ statistics.register("used swiglibs",function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
+ end
+ end)
end
if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
- name=removesuffix(name)
- local l=loaded[name]
- if l==nil then
- local state,library=pcall(savedffiload,name)
- if type(library)=="userdata" then
- l=library
- elseif type(state)=="userdata" then
- l=state
- else
- l=false
- end
- loaded[name]=l
- elseif trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
+ local report_ffilib=logs.reporter("ffilib")
+ local trace_ffilib=false
+ local savedffiload=ffi.load
+ trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+ local loaded={}
+ local function locateindeed(name)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l==nil then
+ local state,library=pcall(savedffiload,name)
+ if type(library)=="userdata" then
+ l=library
+ elseif type(state)=="userdata" then
+ l=state
+ else
+ l=false
+ end
+ loaded[name]=l
+ elseif trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
end
- local function getlist(required)
- local list=directives.value("system.librarynames" )
- if type(list)=="table" then
- list=list[required]
- if type(list)=="table" then
- if trace then
- report("using lookup list for library %a: % | t",required,list)
- end
- return list
- end
+ return l
+ end
+ local function getlist(required)
+ local list=directives.value("system.librarynames" )
+ if type(list)=="table" then
+ list=list[required]
+ if type(list)=="table" then
+ if trace then
+ report("using lookup list for library %a: % | t",required,list)
end
- return { required }
+ return list
+ end
end
- function ffilib(name,version)
- name=removesuffix(name)
- local l=loaded[name]
- if l~=nil then
- if trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- end
- local list=getlist(name)
- if version=="system" then
- for i=1,#list do
- local library=locateindeed(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- else
- for i=1,#list do
- local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
- if type(library)=="userdata" then
- return library
- end
- end
- end
+ return { required }
+ end
+ function ffilib(name,version)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l~=nil then
+ if trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
+ end
+ return l
end
- function ffi.load(name)
- local list=getlist(name)
- for i=1,#list do
- local library=ffilib(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- if trace_ffilib then
- report_ffilib("trying to load %a using normal loader",name)
+ local list=getlist(name)
+ if version=="system" then
+ for i=1,#list do
+ local library=locateindeed(list[i])
+ if type(library)=="userdata" then
+ return library
end
- for i=1,#list do
- local state,library=pcall(savedffiload,list[i])
- if type(library)=="userdata" then
- return library
- elseif type(state)=="userdata" then
- return library
- end
+ end
+ else
+ for i=1,#list do
+ local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
+ if type(library)=="userdata" then
+ return library
end
+ end
+ end
+ end
+ function ffi.load(name)
+ local list=getlist(name)
+ for i=1,#list do
+ local library=ffilib(list[i])
+ if type(library)=="userdata" then
+ return library
+ end
+ end
+ if trace_ffilib then
+ report_ffilib("trying to load %a using normal loader",name)
+ end
+ for i=1,#list do
+ local state,library=pcall(savedffiload,list[i])
+ if type(library)=="userdata" then
+ return library
+ elseif type(state)=="userdata" then
+ return library
+ end
end
+ end
end
@@ -24441,13 +24449,13 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-sta"] = package.loaded["luat-sta"] or true
--- original size: 5703, stripped down to: 2507
+-- original size: 5703, stripped down to: 2321
if not modules then modules={} end modules ['luat-sta']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local gmatch,match=string.gmatch,string.match
local type=type
@@ -24460,81 +24468,81 @@ local hash=states.hash
states.tag=states.tag or ""
states.filename=states.filename or ""
function states.save(filename,tag)
- tag=tag or states.tag
- filename=file.addsuffix(filename or states.filename,'lus')
- io.savedata(filename,
- "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
- )
+ tag=tag or states.tag
+ filename=file.addsuffix(filename or states.filename,'lus')
+ io.savedata(filename,
+ "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
+ )
end
function states.load(filename,tag)
- states.filename=filename
- states.tag=tag or "whatever"
- states.filename=file.addsuffix(states.filename,'lus')
- data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
+ states.filename=filename
+ states.tag=tag or "whatever"
+ states.filename=file.addsuffix(states.filename,'lus')
+ data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
end
local function set_by_tag(tag,key,value,default,persistent)
- local d,h=data[tag],hash[tag]
- if d then
- if type(d)=="table" then
- local dkey,hkey=key,key
- local pre,post=match(key,"(.+)%.([^%.]+)$")
- if pre and post then
- for k in gmatch(pre,"[^%.]+") do
- local dk=d[k]
- if not dk then
- dk={}
- d[k]=dk
- elseif type(dk)=="string" then
- break
- end
- d=dk
- end
- dkey,hkey=post,key
- end
- if value==nil then
- value=default
- elseif value==false then
- elseif persistent then
- value=value or d[dkey] or default
- else
- value=value or default
- end
- d[dkey],h[hkey]=value,value
- elseif type(d)=="string" then
- data[tag],hash[tag]=value,value
+ local d,h=data[tag],hash[tag]
+ if d then
+ if type(d)=="table" then
+ local dkey,hkey=key,key
+ local pre,post=match(key,"(.+)%.([^%.]+)$")
+ if pre and post then
+ for k in gmatch(pre,"[^%.]+") do
+ local dk=d[k]
+ if not dk then
+ dk={}
+ d[k]=dk
+ elseif type(dk)=="string" then
+ break
+ end
+ d=dk
end
+ dkey,hkey=post,key
+ end
+ if value==nil then
+ value=default
+ elseif value==false then
+ elseif persistent then
+ value=value or d[dkey] or default
+ else
+ value=value or default
+ end
+ d[dkey],h[hkey]=value,value
+ elseif type(d)=="string" then
+ data[tag],hash[tag]=value,value
end
+ end
end
local function get_by_tag(tag,key,default)
- local h=hash[tag]
- if h and h[key] then
- return h[key]
- else
- local d=data[tag]
- if d then
- for k in gmatch(key,"[^%.]+") do
- local dk=d[k]
- if dk~=nil then
- d=dk
- else
- return default
- end
- end
- if d==false then
- return false
- else
- return d or default
- end
+ local h=hash[tag]
+ if h and h[key] then
+ return h[key]
+ else
+ local d=data[tag]
+ if d then
+ for k in gmatch(key,"[^%.]+") do
+ local dk=d[k]
+ if dk~=nil then
+ d=dk
+ else
+ return default
end
+ end
+ if d==false then
+ return false
+ else
+ return d or default
+ end
end
+ end
end
states.set_by_tag=set_by_tag
states.get_by_tag=get_by_tag
function states.set(key,value,default,persistent)
- set_by_tag(states.tag,key,value,default,persistent)
+ set_by_tag(states.tag,key,value,default,persistent)
end
function states.get(key,default)
- return get_by_tag(states.tag,key,default)
+ return get_by_tag(states.tag,key,default)
end
@@ -24544,14 +24552,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
--- original size: 9346, stripped down to: 7465
+-- original size: 9346, stripped down to: 7085
if not modules then modules={} end modules ['luat-fmt']={
- version=1.001,
- comment="companion to mtxrun",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to mtxrun",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format=string.format
local concat=table.concat
@@ -24559,223 +24567,223 @@ local quoted=string.quoted
local luasuffixes=utilities.lua.suffixes
local report_format=logs.reporter("resolvers","formats")
local function primaryflags()
- local arguments=environment.arguments
- local flags={}
- if arguments.silent then
- flags[#flags+1]="--interaction=batchmode"
- end
- if arguments.jit then
- flags[#flags+1]="--jiton"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local flags={}
+ if arguments.silent then
+ flags[#flags+1]="--interaction=batchmode"
+ end
+ if arguments.jit then
+ flags[#flags+1]="--jiton"
+ end
+ return concat(flags," ")
end
local function secondaryflags()
- local arguments=environment.arguments
- local trackers=arguments.trackers
- local directives=arguments.directives
- local flags={}
- if trackers and trackers~="" then
- flags[#flags+1]="--c:trackers="..quoted(trackers)
- end
- if directives and directives~="" then
- flags[#flags+1]="--c:directives="..quoted(directives)
- end
- if arguments.silent then
- flags[#flags+1]="--c:silent"
- end
- if arguments.errors then
- flags[#flags+1]="--c:errors"
- end
- if arguments.jit then
- flags[#flags+1]="--c:jiton"
- end
- if arguments.ansi then
- flags[#flags+1]="--c:ansi"
- end
- if arguments.strip then
- flags[#flags+1]="--c:strip"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local trackers=arguments.trackers
+ local directives=arguments.directives
+ local flags={}
+ if trackers and trackers~="" then
+ flags[#flags+1]="--c:trackers="..quoted(trackers)
+ end
+ if directives and directives~="" then
+ flags[#flags+1]="--c:directives="..quoted(directives)
+ end
+ if arguments.silent then
+ flags[#flags+1]="--c:silent"
+ end
+ if arguments.errors then
+ flags[#flags+1]="--c:errors"
+ end
+ if arguments.jit then
+ flags[#flags+1]="--c:jiton"
+ end
+ if arguments.ansi then
+ flags[#flags+1]="--c:ansi"
+ end
+ if arguments.strip then
+ flags[#flags+1]="--c:strip"
+ end
+ return concat(flags," ")
end
local template=[[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]]
local checkers={
- primaryflags="string",
- secondaryflags="string",
- luafile="readable",
- texfile="readable",
- redirect="string",
- dump="string",
+ primaryflags="string",
+ secondaryflags="string",
+ luafile="readable",
+ texfile="readable",
+ redirect="string",
+ dump="string",
}
local runners={
- luatex=sandbox.registerrunner {
- name="make luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="make luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="make luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="make luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.make_format(name,arguments)
- local engine=environment.ownmain or "luatex"
- local silent=environment.arguments.silent
- local errors=environment.arguments.errors
- local olddir=dir.current()
- local path=caches.getwritablepath("formats",engine) or ""
- if path~="" then
- lfs.chdir(path)
- end
- report_format("using format path %a",dir.current())
- local texsourcename=file.addsuffix(name,"mkiv")
- local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- if fulltexsourcename=="" then
- texsourcename=file.addsuffix(name,"tex")
- fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- end
- if fulltexsourcename=="" then
- report_format("no tex source file with name %a (mkiv or tex)",name)
- lfs.chdir(olddir)
- return
- else
- report_format("using tex source file %a",fulltexsourcename)
- end
- local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
- local specificationname=file.replacesuffix(fulltexsourcename,"lus")
- local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- if fullspecificationname=="" then
- specificationname=file.join(texsourcepath,"context.lus")
- fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- end
- if fullspecificationname=="" then
- report_format("unknown stub specification %a",specificationname)
- lfs.chdir(olddir)
- return
- end
- local specificationpath=file.dirname(fullspecificationname)
- local usedluastub=nil
- local usedlualibs=dofile(fullspecificationname)
- if type(usedlualibs)=="string" then
- usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
- elseif type(usedlualibs)=="table" then
- report_format("using stub specification %a",fullspecificationname)
- local texbasename=file.basename(name)
- local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
- local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
- report_format("creating initialization file %a",luastubname)
- utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
- if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
- report_format("using compiled initialization file %a",lucstubname)
- usedluastub=lucstubname
- else
- report_format("using uncompiled initialization file %a",luastubname)
- usedluastub=luastubname
- end
- else
- report_format("invalid stub specification %a",fullspecificationname)
- lfs.chdir(olddir)
- return
- end
- local specification={
- primaryflags=primaryflags(),
- secondaryflags=secondaryflags(),
- luafile=quoted(usedluastub),
- texfile=quoted(fulltexsourcename),
- dump=os.platform=="unix" and "\\\\dump" or "\\dump",
- }
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
- elseif silent then
- statistics.starttiming()
- specification.redirect="> temp.log"
- local result=runner(specification)
- local runtime=statistics.stoptiming()
- if result~=0 then
- print(format("%s silent make > fatal error when making format %q",engine,name))
- else
- print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
- end
- os.remove("temp.log")
- else
- runner(specification)
- end
- local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
- local mp=dir.glob(pattern)
- if mp then
- for i=1,#mp do
- local name=mp[i]
- report_format("removing related mplib format %a",file.basename(name))
- os.remove(name)
- end
- end
+ local engine=environment.ownmain or "luatex"
+ local silent=environment.arguments.silent
+ local errors=environment.arguments.errors
+ local olddir=dir.current()
+ local path=caches.getwritablepath("formats",engine) or ""
+ if path~="" then
+ lfs.chdir(path)
+ end
+ report_format("using format path %a",dir.current())
+ local texsourcename=file.addsuffix(name,"mkiv")
+ local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ if fulltexsourcename=="" then
+ texsourcename=file.addsuffix(name,"tex")
+ fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ end
+ if fulltexsourcename=="" then
+ report_format("no tex source file with name %a (mkiv or tex)",name)
lfs.chdir(olddir)
+ return
+ else
+ report_format("using tex source file %a",fulltexsourcename)
+ end
+ local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
+ local specificationname=file.replacesuffix(fulltexsourcename,"lus")
+ local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ if fullspecificationname=="" then
+ specificationname=file.join(texsourcepath,"context.lus")
+ fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ end
+ if fullspecificationname=="" then
+ report_format("unknown stub specification %a",specificationname)
+ lfs.chdir(olddir)
+ return
+ end
+ local specificationpath=file.dirname(fullspecificationname)
+ local usedluastub=nil
+ local usedlualibs=dofile(fullspecificationname)
+ if type(usedlualibs)=="string" then
+ usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
+ elseif type(usedlualibs)=="table" then
+ report_format("using stub specification %a",fullspecificationname)
+ local texbasename=file.basename(name)
+ local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
+ local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
+ report_format("creating initialization file %a",luastubname)
+ utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
+ if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
+ report_format("using compiled initialization file %a",lucstubname)
+ usedluastub=lucstubname
+ else
+ report_format("using uncompiled initialization file %a",luastubname)
+ usedluastub=luastubname
+ end
+ else
+ report_format("invalid stub specification %a",fullspecificationname)
+ lfs.chdir(olddir)
+ return
+ end
+ local specification={
+ primaryflags=primaryflags(),
+ secondaryflags=secondaryflags(),
+ luafile=quoted(usedluastub),
+ texfile=quoted(fulltexsourcename),
+ dump=os.platform=="unix" and "\\\\dump" or "\\dump",
+ }
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
+ elseif silent then
+ statistics.starttiming()
+ specification.redirect="> temp.log"
+ local result=runner(specification)
+ local runtime=statistics.stoptiming()
+ if result~=0 then
+ print(format("%s silent make > fatal error when making format %q",engine,name))
+ else
+ print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
+ end
+ os.remove("temp.log")
+ else
+ runner(specification)
+ end
+ local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
+ local mp=dir.glob(pattern)
+ if mp then
+ for i=1,#mp do
+ local name=mp[i]
+ report_format("removing related mplib format %a",file.basename(name))
+ os.remove(name)
+ end
+ end
+ lfs.chdir(olddir)
end
local template=[[%flags% --fmt=%fmtfile% --lua=%luafile% %texfile% %more%]]
local checkers={
- flags="string",
- more="string",
- fmtfile="readable",
- luafile="readable",
- texfile="readable",
+ flags="string",
+ more="string",
+ fmtfile="readable",
+ luafile="readable",
+ texfile="readable",
}
local runners={
- luatex=sandbox.registerrunner {
- name="run luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="run luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="run luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="run luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.run_format(name,data,more)
- if name and name~="" then
- local engine=environment.ownmain or "luatex"
- local barename=file.removesuffix(name)
- local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
- if fmtname=="" then
- fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
- end
- fmtname=resolvers.cleanpath(fmtname)
- if fmtname=="" then
- report_format("no format with name %a",name)
+ if name and name~="" then
+ local engine=environment.ownmain or "luatex"
+ local barename=file.removesuffix(name)
+ local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
+ if fmtname=="" then
+ fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
+ end
+ fmtname=resolvers.cleanpath(fmtname)
+ if fmtname=="" then
+ report_format("no format with name %a",name)
+ else
+ local barename=file.removesuffix(name)
+ local luaname=file.addsuffix(barename,"luc")
+ if not lfs.isfile(luaname) then
+ luaname=file.addsuffix(barename,"lua")
+ end
+ if not lfs.isfile(luaname) then
+ report_format("using format name %a",fmtname)
+ report_format("no luc/lua file with name %a",barename)
+ else
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be run, no runner available for engine %a",name,engine)
else
- local barename=file.removesuffix(name)
- local luaname=file.addsuffix(barename,"luc")
- if not lfs.isfile(luaname) then
- luaname=file.addsuffix(barename,"lua")
- end
- if not lfs.isfile(luaname) then
- report_format("using format name %a",fmtname)
- report_format("no luc/lua file with name %a",barename)
- else
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be run, no runner available for engine %a",name,engine)
- else
- runner {
- flags=primaryflags(),
- fmtfile=quoted(barename),
- luafile=quoted(luaname),
- texfile=quoted(data),
- more=more,
- }
- end
- end
+ runner {
+ flags=primaryflags(),
+ fmtfile=quoted(barename),
+ luafile=quoted(luaname),
+ texfile=quoted(data),
+ more=more,
+ }
end
+ end
end
+ end
end
@@ -24783,8 +24791,8 @@ end -- of closure
-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 988986
--- stripped bytes : 349358
+-- original bytes : 989364
+-- stripped bytes : 391967
-- end library merge
@@ -25707,7 +25715,7 @@ function runners.timedrun(filename) -- just for me
end
function runners.timed(action)
- statistics.timed(action)
+ statistics.timed(action,true)
end
function runners.associate(filename)
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 2763cbc04..168f204c7 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -63,14 +63,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lua"] = package.loaded["l-lua"] or true
--- original size: 6266, stripped down to: 3009
+-- original size: 6266, stripped down to: 2875
if not modules then modules={} end modules ['l-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,tonumber=next,type,tonumber
LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
@@ -78,111 +78,111 @@ LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
LUAVERSION=LUAMAJORVERSION+LUAMINORVERSION/10
if LUAVERSION<5.2 and jit then
- MINORVERSION=2
- LUAVERSION=5.2
+ MINORVERSION=2
+ LUAVERSION=5.2
end
_LUAVERSION=LUAVERSION
if not lpeg then
- lpeg=require("lpeg")
+ lpeg=require("lpeg")
end
if loadstring then
- local loadnormal=load
- function load(first,...)
- if type(first)=="string" then
- return loadstring(first,...)
- else
- return loadnormal(first,...)
- end
+ local loadnormal=load
+ function load(first,...)
+ if type(first)=="string" then
+ return loadstring(first,...)
+ else
+ return loadnormal(first,...)
end
+ end
else
- loadstring=load
+ loadstring=load
end
if not ipairs then
- local function iterate(a,i)
- i=i+1
- local v=a[i]
- if v~=nil then
- return i,v
- end
- end
- function ipairs(a)
- return iterate,a,0
+ local function iterate(a,i)
+ i=i+1
+ local v=a[i]
+ if v~=nil then
+ return i,v
end
+ end
+ function ipairs(a)
+ return iterate,a,0
+ end
end
if not pairs then
- function pairs(t)
- return next,t
- end
+ function pairs(t)
+ return next,t
+ end
end
if not table.unpack then
- table.unpack=_G.unpack
+ table.unpack=_G.unpack
elseif not unpack then
- _G.unpack=table.unpack
+ _G.unpack=table.unpack
end
if not package.loaders then
- package.loaders=package.searchers
+ package.loaders=package.searchers
end
local print,select,tostring=print,select,tostring
local inspectors={}
function setinspector(kind,inspector)
- inspectors[kind]=inspector
+ inspectors[kind]=inspector
end
function inspect(...)
- for s=1,select("#",...) do
- local value=select(s,...)
- if value==nil then
- print("nil")
- else
- local done=false
- local kind=type(value)
- local inspector=inspectors[kind]
- if inspector then
- done=inspector(value)
- if done then
- break
- end
- end
- for kind,inspector in next,inspectors do
- done=inspector(value)
- if done then
- break
- end
- end
- if not done then
- print(tostring(value))
- end
+ for s=1,select("#",...) do
+ local value=select(s,...)
+ if value==nil then
+ print("nil")
+ else
+ local done=false
+ local kind=type(value)
+ local inspector=inspectors[kind]
+ if inspector then
+ done=inspector(value)
+ if done then
+ break
+ end
+ end
+ for kind,inspector in next,inspectors do
+ done=inspector(value)
+ if done then
+ break
end
+ end
+ if not done then
+ print(tostring(value))
+ end
end
+ end
end
local dummy=function() end
function optionalrequire(...)
- local ok,result=xpcall(require,dummy,...)
- if ok then
- return result
- end
+ local ok,result=xpcall(require,dummy,...)
+ if ok then
+ return result
+ end
end
if lua then
- lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
+ lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
end
local flush=io.flush
if flush then
- local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
- local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
- local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
- local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
+ local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
+ local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
+ local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
+ local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
end
FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
if not FFISUPPORTED then
- local okay;okay,ffi=pcall(require,"ffi")
- FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
+ local okay;okay,ffi=pcall(require,"ffi")
+ FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
end
if not FFISUPPORTED then
- ffi=nil
+ ffi=nil
elseif not ffi.number then
- ffi.number=tonumber
+ ffi.number=tonumber
end
if not bit32 then
- bit32=require("l-bit32")
+ bit32=require("l-bit32")
end
@@ -192,14 +192,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-macro"] = package.loaded["l-macro"] or true
--- original size: 10131, stripped down to: 6337
+-- original size: 10131, stripped down to: 5991
if not modules then modules={} end modules ['l-macros']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local S,P,R,V,C,Cs,Cc,Ct,Carg=lpeg.S,lpeg.P,lpeg.R,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg
local lpegmatch=lpeg.match
@@ -229,214 +229,214 @@ local definitions={}
local resolve
local subparser
local report_lua=function(...)
- if logs and logs.reporter then
- report_lua=logs.reporter("system","lua")
- report_lua(...)
- else
- print(format(...))
- end
+ if logs and logs.reporter then
+ report_lua=logs.reporter("system","lua")
+ report_lua(...)
+ else
+ print(format(...))
+ end
end
local safeguard=P("local")*whitespace^1*name*(whitespace+P("="))
resolve=safeguard+C(C(name)*(arguments^-1))/function(raw,s,a)
- local d=definitions[s]
- if d then
- if a then
- local n=#a
- local p=patterns[s][n]
- if p then
- local d=d[n]
- for i=1,n do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return lpegmatch(p,d,1,a) or d
- else
- return raw
- end
- else
- return d[0] or raw
- end
- elseif a then
- for i=1,#a do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
+ local d=definitions[s]
+ if d then
+ if a then
+ local n=#a
+ local p=patterns[s][n]
+ if p then
+ local d=d[n]
+ for i=1,n do
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
end
- return s.."("..concat(a,",")..")"
- else
+ return lpegmatch(p,d,1,a) or d
+ else
return raw
+ end
+ else
+ return d[0] or raw
end
+ elseif a then
+ for i=1,#a do
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
+ end
+ return s.."("..concat(a,",")..")"
+ else
+ return raw
+ end
end
subparser=Cs((resolve+P(1))^1)
local enddefine=P("#enddefine")/""
local beginregister=(C(name)*(arguments+Cc(false))*C((1-enddefine)^1)*enddefine)/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
+ definitions[k]=d
+ end
+ d[n]=lpegmatch(subparser,v) or v
+ return ""
end
local register=(Cs(name)*(arguments+Cc(false))*spaces^0*Cs(body))/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
+ definitions[k]=d
+ end
+ d[n]=lpegmatch(subparser,v) or v
+ return ""
end
local unregister=(C(name)*spaces^0*(arguments+Cc(false)))/function(k,a)
- local n=0
- if a then
- n=#a
- local p=patterns[k]
- if p then
- p[n]=false
- end
- end
- local d=definitions[k]
- if d then
- d[n]=false
+ local n=0
+ if a then
+ n=#a
+ local p=patterns[k]
+ if p then
+ p[n]=false
end
- return ""
+ end
+ local d=definitions[k]
+ if d then
+ d[n]=false
+ end
+ return ""
end
local begindefine=(P("begindefine")*spaces^0/"")*beginregister
-local define=(P("define" )*spaces^0/"")*register
-local undefine=(P("undefine" )*spaces^0/"")*unregister
+local define=(P("define" )*spaces^0/"")*register
+local undefine=(P("undefine" )*spaces^0/"")*unregister
local parser=Cs((((P("#")/"")*(define+begindefine+undefine)*(newline^0/"") )+resolve+P(1) )^0 )
function macros.reset()
- definitions={}
- patterns={}
+ definitions={}
+ patterns={}
end
function macros.showdefinitions()
- for name,list in table.sortedhash(definitions) do
- local arguments=list.a
- if arguments then
- arguments="("..concat(arguments,",")..")"
- else
- arguments=""
- end
- print("macro: "..name..arguments)
- for i=0,#list do
- local l=list[i]
- if l then
- print(" "..l)
- end
- end
+ for name,list in table.sortedhash(definitions) do
+ local arguments=list.a
+ if arguments then
+ arguments="("..concat(arguments,",")..")"
+ else
+ arguments=""
+ end
+ print("macro: "..name..arguments)
+ for i=0,#list do
+ local l=list[i]
+ if l then
+ print(" "..l)
+ end
end
+ end
end
function macros.resolvestring(str)
- return lpegmatch(parser,str) or str
+ return lpegmatch(parser,str) or str
end
function macros.resolving()
- return next(patterns)
+ return next(patterns)
end
local function reload(path,name,data)
- local only=match(name,".-([^/]+)%.lua")
+ local only=match(name,".-([^/]+)%.lua")
+ if only and only~="" then
+ local name=path.."/"..only
+ local f=io.open(name,"wb")
+ f:write(data)
+ f:close()
+ local f=loadfile(name)
+ os.remove(name)
+ return f
+ end
+end
+local function reload(path,name,data)
+ if path and path~="" then
+ local only=string.match(name,".-([^/]+)%.lua")
if only and only~="" then
- local name=path.."/"..only
- local f=io.open(name,"wb")
+ local name=path.."/"..only.."-macro.lua"
+ local f=io.open(name,"wb")
+ if f then
f:write(data)
f:close()
- local f=loadfile(name)
+ local l=loadfile(name)
os.remove(name)
- return f
- end
-end
-local function reload(path,name,data)
- if path and path~="" then
- local only=string.match(name,".-([^/]+)%.lua")
- if only and only~="" then
- local name=path.."/"..only.."-macro.lua"
- local f=io.open(name,"wb")
- if f then
- f:write(data)
- f:close()
- local l=loadfile(name)
- os.remove(name)
- return l
- end
- end
+ return l
+ end
end
- return load(data,name)
+ end
+ return load(data,name)
end
local function loaded(name,trace,detail)
- local f=io.open(name,"rb")
- if not f then
- return false,format("file '%s' not found",name)
- end
- local c=f:read("*a")
- if not c then
- return false,format("file '%s' is invalid",name)
- end
- f:close()
- local n=lpegmatch(parser,c)
- if trace then
- if #n~=#c then
- report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
- if detail then
- report_lua()
- report_lua(n)
- report_lua()
- end
- elseif detail then
- report_lua("no macros expanded in '%s'",name)
- end
+ local f=io.open(name,"rb")
+ if not f then
+ return false,format("file '%s' not found",name)
+ end
+ local c=f:read("*a")
+ if not c then
+ return false,format("file '%s' is invalid",name)
+ end
+ f:close()
+ local n=lpegmatch(parser,c)
+ if trace then
+ if #n~=#c then
+ report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
+ if detail then
+ report_lua()
+ report_lua(n)
+ report_lua()
+ end
+ elseif detail then
+ report_lua("no macros expanded in '%s'",name)
end
- return reload(lfs and lfs.currentdir(),name,n)
+ end
+ return reload(lfs and lfs.currentdir(),name,n)
end
macros.loaded=loaded
function required(name,trace)
- local filename=file.addsuffix(name,"lua")
- local fullname=resolvers and resolvers.find_file(filename) or filename
- if not fullname or fullname=="" then
- return false
- end
- local codeblob=package.loaded[fullname]
- if codeblob then
- return codeblob
- end
- local code,message=loaded(fullname,macros,trace,trace)
- if type(code)=="function" then
- code=code()
- else
- report_lua("error when loading '%s'",fullname)
- return false,message
- end
- if code==nil then
- code=false
- end
- package.loaded[fullname]=code
- return code
+ local filename=file.addsuffix(name,"lua")
+ local fullname=resolvers and resolvers.find_file(filename) or filename
+ if not fullname or fullname=="" then
+ return false
+ end
+ local codeblob=package.loaded[fullname]
+ if codeblob then
+ return codeblob
+ end
+ local code,message=loaded(fullname,macros,trace,trace)
+ if type(code)=="function" then
+ code=code()
+ else
+ report_lua("error when loading '%s'",fullname)
+ return false,message
+ end
+ if code==nil then
+ code=false
+ end
+ package.loaded[fullname]=code
+ return code
end
macros.required=required
@@ -447,14 +447,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true
--- original size: 9747, stripped down to: 6739
+-- original size: 9747, stripped down to: 6313
if not modules then modules={} end modules ['l-sandbox']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local global=_G
local next=next
@@ -480,234 +480,234 @@ local trace=false
local logger=false
local blocked={}
local function report(...)
- tprint("sandbox ! "..format(...))
+ tprint("sandbox ! "..format(...))
end
sandbox.report=report
function sandbox.setreporter(r)
- report=r
- sandbox.report=r
+ report=r
+ sandbox.report=r
end
function sandbox.settrace(v)
- trace=v
+ trace=v
end
function sandbox.setlogger(l)
- logger=type(l)=="function" and l or false
+ logger=type(l)=="function" and l or false
end
local function register(func,overload,comment)
- if type(func)=="function" then
- if type(overload)=="string" then
- comment=overload
- overload=nil
- end
- local function f(...)
- if sandboxed then
- local overload=overloads[f]
- if overload then
- if logger then
- local result={ overload(func,...) }
- logger {
- comment=comments[f] or tostring(f),
- arguments={... },
- result=result[1] and true or false,
- }
- return unpack(result)
- else
- return overload(func,...)
- end
- else
- end
- else
- return func(...)
- end
- end
- if comment then
- comments[f]=comment
- if trace then
- report("registering function: %s",comment)
- end
+ if type(func)=="function" then
+ if type(overload)=="string" then
+ comment=overload
+ overload=nil
+ end
+ local function f(...)
+ if sandboxed then
+ local overload=overloads[f]
+ if overload then
+ if logger then
+ local result={ overload(func,...) }
+ logger {
+ comment=comments[f] or tostring(f),
+ arguments={... },
+ result=result[1] and true or false,
+ }
+ return unpack(result)
+ else
+ return overload(func,...)
+ end
+ else
end
- overloads[f]=overload or false
- originals[f]=func
- return f
+ else
+ return func(...)
+ end
end
+ if comment then
+ comments[f]=comment
+ if trace then
+ report("registering function: %s",comment)
+ end
+ end
+ overloads[f]=overload or false
+ originals[f]=func
+ return f
+ end
end
local function redefine(func,comment)
- if type(func)=="function" then
- skiploads[func]=comment or comments[func] or "unknown"
- if overloads[func]==false then
- overloads[func]=nil
- end
+ if type(func)=="function" then
+ skiploads[func]=comment or comments[func] or "unknown"
+ if overloads[func]==false then
+ overloads[func]=nil
end
+ end
end
sandbox.register=register
sandbox.redefine=redefine
function sandbox.original(func)
- return originals and originals[func] or func
+ return originals and originals[func] or func
end
function sandbox.overload(func,overload,comment)
- comment=comment or comments[func] or "?"
- if type(func)~="function" then
- if trace then
- report("overloading unknown function: %s",comment)
- end
- elseif type(overload)~="function" then
- if trace then
- report("overloading function with bad overload: %s",comment)
- end
- elseif overloads[func]==nil then
- if trace then
- report("function is not registered: %s",comment)
- end
- elseif skiploads[func] then
- if trace then
- report("function is not skipped: %s",comment)
- end
- else
- if trace then
- report("overloading function: %s",comment)
- end
- overloads[func]=overload
+ comment=comment or comments[func] or "?"
+ if type(func)~="function" then
+ if trace then
+ report("overloading unknown function: %s",comment)
+ end
+ elseif type(overload)~="function" then
+ if trace then
+ report("overloading function with bad overload: %s",comment)
+ end
+ elseif overloads[func]==nil then
+ if trace then
+ report("function is not registered: %s",comment)
+ end
+ elseif skiploads[func] then
+ if trace then
+ report("function is not skipped: %s",comment)
+ end
+ else
+ if trace then
+ report("overloading function: %s",comment)
end
- return func
+ overloads[func]=overload
+ end
+ return func
end
local function whatever(specification,what,target)
- if type(specification)~="table" then
- report("%s needs a specification",what)
- elseif type(specification.category)~="string" or type(specification.action)~="function" then
- report("%s needs a category and action",what)
- elseif not sandboxed then
- target[#target+1]=specification
- elseif trace then
- report("already enabled, discarding %s",what)
- end
+ if type(specification)~="table" then
+ report("%s needs a specification",what)
+ elseif type(specification.category)~="string" or type(specification.action)~="function" then
+ report("%s needs a category and action",what)
+ elseif not sandboxed then
+ target[#target+1]=specification
+ elseif trace then
+ report("already enabled, discarding %s",what)
+ end
end
function sandbox.initializer(specification)
- whatever(specification,"initializer",initializers)
+ whatever(specification,"initializer",initializers)
end
function sandbox.finalizer(specification)
- whatever(specification,"finalizer",finalizers)
+ whatever(specification,"finalizer",finalizers)
end
function require(name)
- local n=gsub(name,"^.*[\\/]","")
- local n=gsub(n,"[%.].*$","")
- local b=blocked[n]
- if b==false then
- return nil
- elseif b then
- if trace then
- report("using blocked: %s",n)
- end
- return b
- else
- if trace then
- report("requiring: %s",name)
- end
- return requiem(name)
+ local n=gsub(name,"^.*[\\/]","")
+ local n=gsub(n,"[%.].*$","")
+ local b=blocked[n]
+ if b==false then
+ return nil
+ elseif b then
+ if trace then
+ report("using blocked: %s",n)
end
-end
-function blockrequire(name,lib)
+ return b
+ else
if trace then
- report("preventing reload of: %s",name)
+ report("requiring: %s",name)
end
- blocked[name]=lib or _G[name] or false
+ return requiem(name)
+ end
+end
+function blockrequire(name,lib)
+ if trace then
+ report("preventing reload of: %s",name)
+ end
+ blocked[name]=lib or _G[name] or false
end
function sandbox.enable()
- if not sandboxed then
- debug={
- traceback=debug.traceback,
- }
- for i=1,#initializers do
- initializers[i].action()
- end
- for i=1,#finalizers do
- finalizers[i].action()
- end
- local nnot=0
- local nyes=0
- local cnot={}
- local cyes={}
- local skip={}
- for k,v in next,overloads do
- local c=comments[k]
- if v then
- if c then
- cyes[#cyes+1]=c
- else
- nyes=nyes+1
- end
- else
- if c then
- cnot[#cnot+1]=c
- else
- nnot=nnot+1
- end
- end
- end
- for k,v in next,skiploads do
- skip[#skip+1]=v
- end
- if #cyes>0 then
- sort(cyes)
- report("overloaded known: %s",concat(cyes," | "))
- end
- if nyes>0 then
- report("overloaded unknown: %s",nyes)
- end
- if #cnot>0 then
- sort(cnot)
- report("not overloaded known: %s",concat(cnot," | "))
- end
- if nnot>0 then
- report("not overloaded unknown: %s",nnot)
+ if not sandboxed then
+ debug={
+ traceback=debug.traceback,
+ }
+ for i=1,#initializers do
+ initializers[i].action()
+ end
+ for i=1,#finalizers do
+ finalizers[i].action()
+ end
+ local nnot=0
+ local nyes=0
+ local cnot={}
+ local cyes={}
+ local skip={}
+ for k,v in next,overloads do
+ local c=comments[k]
+ if v then
+ if c then
+ cyes[#cyes+1]=c
+ else
+ nyes=nyes+1
end
- if #skip>0 then
- sort(skip)
- report("not overloaded redefined: %s",concat(skip," | "))
+ else
+ if c then
+ cnot[#cnot+1]=c
+ else
+ nnot=nnot+1
end
- initializers=nil
- finalizers=nil
- originals=nil
- sandboxed=true
+ end
+ end
+ for k,v in next,skiploads do
+ skip[#skip+1]=v
+ end
+ if #cyes>0 then
+ sort(cyes)
+ report("overloaded known: %s",concat(cyes," | "))
+ end
+ if nyes>0 then
+ report("overloaded unknown: %s",nyes)
+ end
+ if #cnot>0 then
+ sort(cnot)
+ report("not overloaded known: %s",concat(cnot," | "))
+ end
+ if nnot>0 then
+ report("not overloaded unknown: %s",nnot)
end
+ if #skip>0 then
+ sort(skip)
+ report("not overloaded redefined: %s",concat(skip," | "))
+ end
+ initializers=nil
+ finalizers=nil
+ originals=nil
+ sandboxed=true
+ end
end
blockrequire("lfs",lfs)
blockrequire("io",io)
blockrequire("os",os)
blockrequire("ffi",ffi)
local function supported(library)
- local l=_G[library]
- return l
+ local l=_G[library]
+ return l
end
loadfile=register(loadfile,"loadfile")
if supported("io") then
- io.open=register(io.open,"io.open")
- io.popen=register(io.popen,"io.popen")
- io.lines=register(io.lines,"io.lines")
- io.output=register(io.output,"io.output")
- io.input=register(io.input,"io.input")
+ io.open=register(io.open,"io.open")
+ io.popen=register(io.popen,"io.popen")
+ io.lines=register(io.lines,"io.lines")
+ io.output=register(io.output,"io.output")
+ io.input=register(io.input,"io.input")
end
if supported("os") then
- os.execute=register(os.execute,"os.execute")
- os.spawn=register(os.spawn,"os.spawn")
- os.exec=register(os.exec,"os.exec")
- os.rename=register(os.rename,"os.rename")
- os.remove=register(os.remove,"os.remove")
+ os.execute=register(os.execute,"os.execute")
+ os.spawn=register(os.spawn,"os.spawn")
+ os.exec=register(os.exec,"os.exec")
+ os.rename=register(os.rename,"os.rename")
+ os.remove=register(os.remove,"os.remove")
end
if supported("lfs") then
- lfs.chdir=register(lfs.chdir,"lfs.chdir")
- lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
- lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
- lfs.isfile=register(lfs.isfile,"lfs.isfile")
- lfs.isdir=register(lfs.isdir,"lfs.isdir")
- lfs.attributes=register(lfs.attributes,"lfs.attributes")
- lfs.dir=register(lfs.dir,"lfs.dir")
- lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
- lfs.touch=register(lfs.touch,"lfs.touch")
- lfs.link=register(lfs.link,"lfs.link")
- lfs.setmode=register(lfs.setmode,"lfs.setmode")
- lfs.readlink=register(lfs.readlink,"lfs.readlink")
- lfs.shortname=register(lfs.shortname,"lfs.shortname")
- lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
+ lfs.chdir=register(lfs.chdir,"lfs.chdir")
+ lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
+ lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
+ lfs.isfile=register(lfs.isfile,"lfs.isfile")
+ lfs.isdir=register(lfs.isdir,"lfs.isdir")
+ lfs.attributes=register(lfs.attributes,"lfs.attributes")
+ lfs.dir=register(lfs.dir,"lfs.dir")
+ lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
+ lfs.touch=register(lfs.touch,"lfs.touch")
+ lfs.link=register(lfs.link,"lfs.link")
+ lfs.setmode=register(lfs.setmode,"lfs.setmode")
+ lfs.readlink=register(lfs.readlink,"lfs.readlink")
+ lfs.shortname=register(lfs.shortname,"lfs.shortname")
+ lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
end
@@ -717,14 +717,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-package"] = package.loaded["l-package"] or true
--- original size: 11605, stripped down to: 8663
+-- original size: 11605, stripped down to: 8299
if not modules then modules={} end modules ['l-package']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type=type
local gsub,format,find=string.gsub,string.format,string.find
@@ -732,40 +732,40 @@ local insert,remove=table.insert,table.remove
local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
local package=package
local searchers=package.searchers or package.loaders
-local filejoin=file and file.join or function(path,name) return path.."/"..name end
-local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
-local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
+local filejoin=file and file.join or function(path,name) return path.."/"..name end
+local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
+local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
local function cleanpath(path)
- return path
+ return path
end
local pattern=Cs((((1-S("\\/"))^0*(S("\\/")^1/"/"))^0*(P(".")^1/"/"+P(1))^1)*-1)
local function lualibfile(name)
- return lpegmatch(pattern,name) or name
+ return lpegmatch(pattern,name) or name
end
local offset=luarocks and 1 or 0
local helpers=package.helpers or {
- cleanpath=cleanpath,
- lualibfile=lualibfile,
- trace=false,
- report=function(...) print(format(...)) end,
- builtin={
- ["preload table"]=searchers[1+offset],
- ["path specification"]=searchers[2+offset],
- ["cpath specification"]=searchers[3+offset],
- ["all in one fallback"]=searchers[4+offset],
- },
- methods={},
- sequence={
- "already loaded",
- "preload table",
- "qualified path",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
- }
+ cleanpath=cleanpath,
+ lualibfile=lualibfile,
+ trace=false,
+ report=function(...) print(format(...)) end,
+ builtin={
+ ["preload table"]=searchers[1+offset],
+ ["path specification"]=searchers[2+offset],
+ ["cpath specification"]=searchers[3+offset],
+ ["all in one fallback"]=searchers[4+offset],
+ },
+ methods={},
+ sequence={
+ "already loaded",
+ "preload table",
+ "qualified path",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
+ }
}
package.helpers=helpers
local methods=helpers.methods
@@ -781,255 +781,255 @@ local nofextralib=-1
local nofpathlua=-1
local nofpathlib=-1
local function listpaths(what,paths)
- local nofpaths=#paths
- if nofpaths>0 then
- for i=1,nofpaths do
- helpers.report("using %s path %i: %s",what,i,paths[i])
- end
- else
- helpers.report("no %s paths defined",what)
+ local nofpaths=#paths
+ if nofpaths>0 then
+ for i=1,nofpaths do
+ helpers.report("using %s path %i: %s",what,i,paths[i])
end
- return nofpaths
+ else
+ helpers.report("no %s paths defined",what)
+ end
+ return nofpaths
end
local function getextraluapaths()
- if helpers.trace and #extraluapaths~=nofextralua then
- nofextralua=listpaths("extra lua",extraluapaths)
- end
- return extraluapaths
+ if helpers.trace and #extraluapaths~=nofextralua then
+ nofextralua=listpaths("extra lua",extraluapaths)
+ end
+ return extraluapaths
end
local function getextralibpaths()
- if helpers.trace and #extralibpaths~=nofextralib then
- nofextralib=listpaths("extra lib",extralibpaths)
- end
- return extralibpaths
+ if helpers.trace and #extralibpaths~=nofextralib then
+ nofextralib=listpaths("extra lib",extralibpaths)
+ end
+ return extralibpaths
end
local function getluapaths()
- local luapath=package.path or ""
- if oldluapath~=luapath then
- luapaths=file.splitpath(luapath,";")
- oldluapath=luapath
- nofpathlua=-1
- end
- if helpers.trace and #luapaths~=nofpathlua then
- nofpathlua=listpaths("builtin lua",luapaths)
- end
- return luapaths
+ local luapath=package.path or ""
+ if oldluapath~=luapath then
+ luapaths=file.splitpath(luapath,";")
+ oldluapath=luapath
+ nofpathlua=-1
+ end
+ if helpers.trace and #luapaths~=nofpathlua then
+ nofpathlua=listpaths("builtin lua",luapaths)
+ end
+ return luapaths
end
local function getlibpaths()
- local libpath=package.cpath or ""
- if oldlibpath~=libpath then
- libpaths=file.splitpath(libpath,";")
- oldlibpath=libpath
- nofpathlib=-1
- end
- if helpers.trace and #libpaths~=nofpathlib then
- nofpathlib=listpaths("builtin lib",libpaths)
- end
- return libpaths
+ local libpath=package.cpath or ""
+ if oldlibpath~=libpath then
+ libpaths=file.splitpath(libpath,";")
+ oldlibpath=libpath
+ nofpathlib=-1
+ end
+ if helpers.trace and #libpaths~=nofpathlib then
+ nofpathlib=listpaths("builtin lib",libpaths)
+ end
+ return libpaths
end
package.luapaths=getluapaths
package.libpaths=getlibpaths
package.extraluapaths=getextraluapaths
package.extralibpaths=getextralibpaths
local hashes={
- lua={},
- lib={},
+ lua={},
+ lib={},
}
local function registerpath(tag,what,target,...)
- local pathlist={... }
- local cleanpath=helpers.cleanpath
- local trace=helpers.trace
- local report=helpers.report
- local hash=hashes[what]
- local function add(path)
- local path=cleanpath(path)
- if not hash[path] then
- target[#target+1]=path
- hash[path]=true
- if trace then
- report("registered %s path %s: %s",tag,#target,path)
- end
- else
- if trace then
- report("duplicate %s path: %s",tag,path)
- end
- end
+ local pathlist={... }
+ local cleanpath=helpers.cleanpath
+ local trace=helpers.trace
+ local report=helpers.report
+ local hash=hashes[what]
+ local function add(path)
+ local path=cleanpath(path)
+ if not hash[path] then
+ target[#target+1]=path
+ hash[path]=true
+ if trace then
+ report("registered %s path %s: %s",tag,#target,path)
+ end
+ else
+ if trace then
+ report("duplicate %s path: %s",tag,path)
+ end
end
- for p=1,#pathlist do
- local path=pathlist[p]
- if type(path)=="table" then
- for i=1,#path do
- add(path[i])
- end
- else
- add(path)
- end
+ end
+ for p=1,#pathlist do
+ local path=pathlist[p]
+ if type(path)=="table" then
+ for i=1,#path do
+ add(path[i])
+ end
+ else
+ add(path)
end
+ end
end
local function pushpath(tag,what,target,path)
- local path=helpers.cleanpath(path)
- insert(target,1,path)
- if helpers.trace then
- helpers.report("pushing %s path in front: %s",tag,path)
- end
+ local path=helpers.cleanpath(path)
+ insert(target,1,path)
+ if helpers.trace then
+ helpers.report("pushing %s path in front: %s",tag,path)
+ end
end
local function poppath(tag,what,target)
- local path=remove(target,1)
- if helpers.trace then
- if path then
- helpers.report("popping %s path from front: %s",tag,path)
- else
- helpers.report("no %s path to pop",tag)
- end
+ local path=remove(target,1)
+ if helpers.trace then
+ if path then
+ helpers.report("popping %s path from front: %s",tag,path)
+ else
+ helpers.report("no %s path to pop",tag)
end
+ end
end
helpers.registerpath=registerpath
function package.extraluapath(...)
- registerpath("extra lua","lua",extraluapaths,...)
+ registerpath("extra lua","lua",extraluapaths,...)
end
function package.pushluapath(path)
- pushpath("extra lua","lua",extraluapaths,path)
+ pushpath("extra lua","lua",extraluapaths,path)
end
function package.popluapath()
- poppath("extra lua","lua",extraluapaths)
+ poppath("extra lua","lua",extraluapaths)
end
function package.extralibpath(...)
- registerpath("extra lib","lib",extralibpaths,...)
+ registerpath("extra lib","lib",extralibpaths,...)
end
function package.pushlibpath(path)
- pushpath("extra lib","lib",extralibpaths,path)
+ pushpath("extra lib","lib",extralibpaths,path)
end
function package.poplibpath()
- poppath("extra lib","lua",extralibpaths)
+ poppath("extra lib","lua",extralibpaths)
end
local function loadedaslib(resolved,rawname)
- local base=gsub(rawname,"%.","_")
- local init="luaopen_"..gsub(base,"%.","_")
- if helpers.trace then
- helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
- end
- return package.loadlib(resolved,init)
+ local base=gsub(rawname,"%.","_")
+ local init="luaopen_"..gsub(base,"%.","_")
+ if helpers.trace then
+ helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+ end
+ return package.loadlib(resolved,init)
end
helpers.loadedaslib=loadedaslib
local function loadedbypath(name,rawname,paths,islib,what)
- local trace=helpers.trace
- for p=1,#paths do
- local path=paths[p]
- local resolved=filejoin(path,name)
- if trace then
- helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
- end
- if isreadable(resolved) then
- if trace then
- helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ for p=1,#paths do
+ local path=paths[p]
+ local resolved=filejoin(path,name)
+ if trace then
+ helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
+ end
+ if isreadable(resolved) then
+ if trace then
+ helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
end
+ end
end
helpers.loadedbypath=loadedbypath
local function loadedbyname(name,rawname)
- if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
- local trace=helpers.trace
- if trace then
- helpers.report("qualified name, identifying '%s'",what,name)
- end
- if isreadable(name) then
- if trace then
- helpers.report("qualified name, '%s' found",what,name)
- end
- return loadfile(name)
- end
+ if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
+ local trace=helpers.trace
+ if trace then
+ helpers.report("qualified name, identifying '%s'",what,name)
end
+ if isreadable(name) then
+ if trace then
+ helpers.report("qualified name, '%s' found",what,name)
+ end
+ return loadfile(name)
+ end
+ end
end
helpers.loadedbyname=loadedbyname
methods["already loaded"]=function(name)
- return package.loaded[name]
+ return package.loaded[name]
end
methods["preload table"]=function(name)
- return builtin["preload table"](name)
+ return builtin["preload table"](name)
end
methods["qualified path"]=function(name)
- return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
+ return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
end
methods["lua extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
+ return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
end
methods["lib extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
+ return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
end
methods["path specification"]=function(name)
- getluapaths()
- return builtin["path specification"](name)
+ getluapaths()
+ return builtin["path specification"](name)
end
methods["cpath specification"]=function(name)
- getlibpaths()
- return builtin["cpath specification"](name)
+ getlibpaths()
+ return builtin["cpath specification"](name)
end
methods["all in one fallback"]=function(name)
- return builtin["all in one fallback"](name)
+ return builtin["all in one fallback"](name)
end
methods["not loaded"]=function(name)
- if helpers.trace then
- helpers.report("unable to locate '%s'",name or "?")
- end
- return nil
+ if helpers.trace then
+ helpers.report("unable to locate '%s'",name or "?")
+ end
+ return nil
end
local level=0
local used={}
helpers.traceused=false
function helpers.loaded(name)
- local sequence=helpers.sequence
- level=level+1
- for i=1,#sequence do
- local method=sequence[i]
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
- end
- local result,rest=methods[method](name)
- if type(result)=="function" then
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
- end
- if helpers.traceused then
- used[#used+1]={ level=level,name=name }
- end
- level=level-1
- return result,rest
- end
+ local sequence=helpers.sequence
+ level=level+1
+ for i=1,#sequence do
+ local method=sequence[i]
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
end
- level=level-1
- return nil
+ local result,rest=methods[method](name)
+ if type(result)=="function" then
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
+ end
+ if helpers.traceused then
+ used[#used+1]={ level=level,name=name }
+ end
+ level=level-1
+ return result,rest
+ end
+ end
+ level=level-1
+ return nil
end
function helpers.showused()
- local n=#used
- if n>0 then
- helpers.report("%s libraries loaded:",n)
- helpers.report()
- for i=1,n do
- local u=used[i]
- helpers.report("%i %a",u.level,u.name)
- end
- helpers.report()
- end
+ local n=#used
+ if n>0 then
+ helpers.report("%s libraries loaded:",n)
+ helpers.report()
+ for i=1,n do
+ local u=used[i]
+ helpers.report("%i %a",u.level,u.name)
+ end
+ helpers.report()
+ end
end
function helpers.unload(name)
- if helpers.trace then
- if package.loaded[name] then
- helpers.report("unloading, name '%s', %s",name,"done")
- else
- helpers.report("unloading, name '%s', %s",name,"not loaded")
- end
+ if helpers.trace then
+ if package.loaded[name] then
+ helpers.report("unloading, name '%s', %s",name,"done")
+ else
+ helpers.report("unloading, name '%s', %s",name,"not loaded")
end
- package.loaded[name]=nil
+ end
+ package.loaded[name]=nil
end
table.insert(searchers,1,helpers.loaded)
if context then
- package.path=""
+ package.path=""
end
@@ -1039,14 +1039,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
--- original size: 38434, stripped down to: 20344
+-- original size: 38434, stripped down to: 19310
if not modules then modules={} end modules ['l-lpeg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
lpeg=require("lpeg")
local lpeg=lpeg
@@ -1057,7 +1057,7 @@ local floor=math.floor
local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt
local lpegtype,lpegmatch,lpegprint=lpeg.type,lpeg.match,lpeg.print
if setinspector then
- setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
+ setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
end
lpeg.patterns=lpeg.patterns or {}
local patterns=lpeg.patterns
@@ -1080,7 +1080,7 @@ local underscore=P("_")
local hexdigit=digit+lowercase+uppercase
local hexdigits=hexdigit^1
local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
-local newline=P("\r")*(P("\n")+P(true))+P("\n")
+local newline=P("\r")*(P("\n")+P(true))+P("\n")
local escaped=P("\\")*anything
local squote=P("'")
local dquote=P('"')
@@ -1089,9 +1089,9 @@ local period=P(".")
local comma=P(",")
local utfbom_32_be=P('\000\000\254\255')
local utfbom_32_le=P('\255\254\000\000')
-local utfbom_16_be=P('\254\255')
-local utfbom_16_le=P('\255\254')
-local utfbom_8=P('\239\187\191')
+local utfbom_16_be=P('\254\255')
+local utfbom_16_le=P('\255\254')
+local utfbom_8=P('\239\187\191')
local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8
local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8")
local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")
@@ -1123,7 +1123,7 @@ patterns.utf8character=utf8character
patterns.validutf8=validutf8char
patterns.validutf8char=validutf8char
local eol=S("\n\r")
-local spacer=S(" \t\f\v")
+local spacer=S(" \t\f\v")
local whitespace=eol+spacer
local nonspacer=1-spacer
local nonwhitespace=1-whitespace
@@ -1132,7 +1132,7 @@ patterns.spacer=spacer
patterns.whitespace=whitespace
patterns.nonspacer=nonspacer
patterns.nonwhitespace=nonwhitespace
-local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
+local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0)
local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0)
@@ -1209,82 +1209,82 @@ patterns.somecontent=(anything-newline-space)^1
patterns.beginline=#(1-newline)
patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0))
function anywhere(pattern)
- return (1-P(pattern))^0*P(pattern)
+ return (1-P(pattern))^0*P(pattern)
end
lpeg.anywhere=anywhere
function lpeg.instringchecker(p)
- p=anywhere(p)
- return function(str)
- return lpegmatch(p,str) and true or false
- end
+ p=anywhere(p)
+ return function(str)
+ return lpegmatch(p,str) and true or false
+ end
end
function lpeg.splitter(pattern,action)
- if action then
- return (((1-P(pattern))^1)/action+1)^0
- else
- return (Cs((1-P(pattern))^1)+1)^0
- end
+ if action then
+ return (((1-P(pattern))^1)/action+1)^0
+ else
+ return (Cs((1-P(pattern))^1)+1)^0
+ end
end
function lpeg.tsplitter(pattern,action)
- if action then
- return Ct((((1-P(pattern))^1)/action+1)^0)
- else
- return Ct((Cs((1-P(pattern))^1)+1)^0)
- end
+ if action then
+ return Ct((((1-P(pattern))^1)/action+1)^0)
+ else
+ return Ct((Cs((1-P(pattern))^1)+1)^0)
+ end
end
local splitters_s,splitters_m,splitters_t={},{},{}
local function splitat(separator,single)
- local splitter=(single and splitters_s[separator]) or splitters_m[separator]
- if not splitter then
- separator=P(separator)
- local other=C((1-separator)^0)
- if single then
- local any=anything
- splitter=other*(separator*C(any^0)+"")
- splitters_s[separator]=splitter
- else
- splitter=other*(separator*other)^0
- splitters_m[separator]=splitter
- end
+ local splitter=(single and splitters_s[separator]) or splitters_m[separator]
+ if not splitter then
+ separator=P(separator)
+ local other=C((1-separator)^0)
+ if single then
+ local any=anything
+ splitter=other*(separator*C(any^0)+"")
+ splitters_s[separator]=splitter
+ else
+ splitter=other*(separator*other)^0
+ splitters_m[separator]=splitter
end
- return splitter
+ end
+ return splitter
end
local function tsplitat(separator)
- local splitter=splitters_t[separator]
- if not splitter then
- splitter=Ct(splitat(separator))
- splitters_t[separator]=splitter
- end
- return splitter
+ local splitter=splitters_t[separator]
+ if not splitter then
+ splitter=Ct(splitat(separator))
+ splitters_t[separator]=splitter
+ end
+ return splitter
end
lpeg.splitat=splitat
lpeg.tsplitat=tsplitat
function string.splitup(str,separator)
- if not separator then
- separator=","
- end
- return lpegmatch(splitters_m[separator] or splitat(separator),str)
+ if not separator then
+ separator=","
+ end
+ return lpegmatch(splitters_m[separator] or splitat(separator),str)
end
local cache={}
function lpeg.split(separator,str)
+ local c=cache[separator]
+ if not c then
+ c=tsplitat(separator)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+function string.split(str,separator)
+ if separator then
local c=cache[separator]
if not c then
- c=tsplitat(separator)
- cache[separator]=c
+ c=tsplitat(separator)
+ cache[separator]=c
end
return lpegmatch(c,str)
-end
-function string.split(str,separator)
- if separator then
- local c=cache[separator]
- if not c then
- c=tsplitat(separator)
- cache[separator]=c
- end
- return lpegmatch(c,str)
- else
- return { str }
- end
+ else
+ return { str }
+ end
end
local spacing=patterns.spacer^0*newline
local empty=spacing*Cc("")
@@ -1294,463 +1294,463 @@ patterns.textline=content
local linesplitter=tsplitat(newline)
patterns.linesplitter=linesplitter
function string.splitlines(str)
- return lpegmatch(linesplitter,str)
+ return lpegmatch(linesplitter,str)
end
local cache={}
function lpeg.checkedsplit(separator,str)
- local c=cache[separator]
- if not c then
- separator=P(separator)
- local other=C((1-separator)^1)
- c=Ct(separator^0*other*(separator^1*other)^0)
- cache[separator]=c
- end
- return lpegmatch(c,str)
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
end
function string.checkedsplit(str,separator)
- local c=cache[separator]
- if not c then
- separator=P(separator)
- local other=C((1-separator)^1)
- c=Ct(separator^0*other*(separator^1*other)^0)
- cache[separator]=c
- end
- return lpegmatch(c,str)
-end
-local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
-local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
+local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
local function f4(s) local c1,c2,c3,c4=byte(s,1,4) return ((c1*64+c2)*64+c3)*64+c4-63447168 end
local utf8byte=patterns.utf8one/byte+patterns.utf8two/f2+patterns.utf8three/f3+patterns.utf8four/f4
patterns.utf8byte=utf8byte
local cache={}
function lpeg.stripper(str)
- if type(str)=="string" then
- local s=cache[str]
- if not s then
- s=Cs(((S(str)^1)/""+1)^0)
- cache[str]=s
- end
- return s
- else
- return Cs(((str^1)/""+1)^0)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs(((S(str)^1)/""+1)^0)
+ cache[str]=s
end
+ return s
+ else
+ return Cs(((str^1)/""+1)^0)
+ end
end
local cache={}
function lpeg.keeper(str)
- if type(str)=="string" then
- local s=cache[str]
- if not s then
- s=Cs((((1-S(str))^1)/""+1)^0)
- cache[str]=s
- end
- return s
- else
- return Cs((((1-str)^1)/""+1)^0)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs((((1-S(str))^1)/""+1)^0)
+ cache[str]=s
end
+ return s
+ else
+ return Cs((((1-str)^1)/""+1)^0)
+ end
end
function lpeg.frontstripper(str)
- return (P(str)+P(true))*Cs(anything^0)
+ return (P(str)+P(true))*Cs(anything^0)
end
function lpeg.endstripper(str)
- return Cs((1-P(str)*endofstring)^0)
+ return Cs((1-P(str)*endofstring)^0)
end
function lpeg.replacer(one,two,makefunction,isutf)
- local pattern
- local u=isutf and utf8char or 1
- if type(one)=="table" then
- local no=#one
- local p=P(false)
- if no==0 then
- for k,v in next,one do
- p=p+P(k)/v
- end
- pattern=Cs((p+u)^0)
- elseif no==1 then
- local o=one[1]
- one,two=P(o[1]),o[2]
- pattern=Cs((one/two+u)^0)
- else
- for i=1,no do
- local o=one[i]
- p=p+P(o[1])/o[2]
- end
- pattern=Cs((p+u)^0)
- end
- else
- pattern=Cs((P(one)/(two or "")+u)^0)
+ local pattern
+ local u=isutf and utf8char or 1
+ if type(one)=="table" then
+ local no=#one
+ local p=P(false)
+ if no==0 then
+ for k,v in next,one do
+ p=p+P(k)/v
+ end
+ pattern=Cs((p+u)^0)
+ elseif no==1 then
+ local o=one[1]
+ one,two=P(o[1]),o[2]
+ pattern=Cs((one/two+u)^0)
+ else
+ for i=1,no do
+ local o=one[i]
+ p=p+P(o[1])/o[2]
+ end
+ pattern=Cs((p+u)^0)
end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ else
+ pattern=Cs((P(one)/(two or "")+u)^0)
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
end
+ else
+ return pattern
+ end
end
function lpeg.finder(lst,makefunction,isutf)
- local pattern
- if type(lst)=="table" then
- pattern=P(false)
- if #lst==0 then
- for k,v in next,lst do
- pattern=pattern+P(k)
- end
- else
- for i=1,#lst do
- pattern=pattern+P(lst[i])
- end
- end
- else
- pattern=P(lst)
- end
- if isutf then
- pattern=((utf8char or 1)-pattern)^0*pattern
+ local pattern
+ if type(lst)=="table" then
+ pattern=P(false)
+ if #lst==0 then
+ for k,v in next,lst do
+ pattern=pattern+P(k)
+ end
else
- pattern=(1-pattern)^0*pattern
+ for i=1,#lst do
+ pattern=pattern+P(lst[i])
+ end
end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ else
+ pattern=P(lst)
+ end
+ if isutf then
+ pattern=((utf8char or 1)-pattern)^0*pattern
+ else
+ pattern=(1-pattern)^0*pattern
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
end
+ else
+ return pattern
+ end
end
local splitters_f,splitters_s={},{}
function lpeg.firstofsplit(separator)
- local splitter=splitters_f[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)
- splitters_f[separator]=splitter
- end
- return splitter
+ local splitter=splitters_f[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)
+ splitters_f[separator]=splitter
+ end
+ return splitter
end
function lpeg.secondofsplit(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=(1-pattern)^0*pattern*C(anything^0)
- splitters_s[separator]=splitter
- end
- return splitter
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=(1-pattern)^0*pattern*C(anything^0)
+ splitters_s[separator]=splitter
+ end
+ return splitter
end
local splitters_s,splitters_p={},{}
function lpeg.beforesuffix(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)*pattern*endofstring
- splitters_s[separator]=splitter
- end
- return splitter
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)*pattern*endofstring
+ splitters_s[separator]=splitter
+ end
+ return splitter
end
function lpeg.afterprefix(separator)
- local splitter=splitters_p[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=pattern*C(anything^0)
- splitters_p[separator]=splitter
- end
- return splitter
+ local splitter=splitters_p[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=pattern*C(anything^0)
+ splitters_p[separator]=splitter
+ end
+ return splitter
end
function lpeg.balancer(left,right)
- left,right=P(left),P(right)
- return P { left*((1-left-right)+V(1))^0*right }
+ left,right=P(left),P(right)
+ return P { left*((1-left-right)+V(1))^0*right }
end
function lpeg.counter(pattern,action)
- local n=0
- local pattern=(P(pattern)/function() n=n+1 end+anything)^0
- if action then
- return function(str) n=0;lpegmatch(pattern,str);action(n) end
- else
- return function(str) n=0;lpegmatch(pattern,str);return n end
- end
+ local n=0
+ local pattern=(P(pattern)/function() n=n+1 end+anything)^0
+ if action then
+ return function(str) n=0;lpegmatch(pattern,str);action(n) end
+ else
+ return function(str) n=0;lpegmatch(pattern,str);return n end
+ end
end
function lpeg.is_lpeg(p)
- return p and lpegtype(p)=="pattern"
+ return p and lpegtype(p)=="pattern"
end
function lpeg.oneof(list,...)
- if type(list)~="table" then
- list={ list,... }
- end
- local p=P(list[1])
- for l=2,#list do
- p=p+P(list[l])
- end
- return p
+ if type(list)~="table" then
+ list={ list,... }
+ end
+ local p=P(list[1])
+ for l=2,#list do
+ p=p+P(list[l])
+ end
+ return p
end
local sort=table.sort
local function copyindexed(old)
- local new={}
- for i=1,#old do
- new[i]=old
- end
- return new
+ local new={}
+ for i=1,#old do
+ new[i]=old
+ end
+ return new
end
local function sortedkeys(tab)
- local keys,s={},0
- for key,_ in next,tab do
- s=s+1
- keys[s]=key
- end
- sort(keys)
- return keys
+ local keys,s={},0
+ for key,_ in next,tab do
+ s=s+1
+ keys[s]=key
+ end
+ sort(keys)
+ return keys
end
function lpeg.append(list,pp,delayed,checked)
- local p=pp
- if #list>0 then
- local keys=copyindexed(list)
- sort(keys)
- for i=#keys,1,-1 do
- local k=keys[i]
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- elseif delayed then
- local keys=sortedkeys(list)
+ local p=pp
+ if #list>0 then
+ local keys=copyindexed(list)
+ sort(keys)
+ for i=#keys,1,-1 do
+ local k=keys[i]
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
+ end
+ elseif delayed then
+ local keys=sortedkeys(list)
+ if p then
+ for i=1,#keys,1 do
+ local k=keys[i]
+ local v=list[k]
+ p=P(k)/list+p
+ end
+ else
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
if p then
- for i=1,#keys,1 do
- local k=keys[i]
- local v=list[k]
- p=P(k)/list+p
- end
+ p=P(k)+p
else
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- if p then
- p=p/list
- end
+ p=P(k)
end
- elseif checked then
- local keys=sortedkeys(list)
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- if k==v then
- p=P(k)+p
- else
- p=P(k)/v+p
- end
- else
- if k==v then
- p=P(k)
- else
- p=P(k)/v
- end
- end
+ end
+ if p then
+ p=p/list
+ end
+ end
+ elseif checked then
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ if k==v then
+ p=P(k)+p
+ else
+ p=P(k)/v+p
end
- else
- local keys=sortedkeys(list)
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- p=P(k)/v+p
- else
- p=P(k)/v
- end
+ else
+ if k==v then
+ p=P(k)
+ else
+ p=P(k)/v
end
+ end
end
- return p
+ else
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ p=P(k)/v+p
+ else
+ p=P(k)/v
+ end
+ end
+ end
+ return p
end
local p_false=P(false)
local p_true=P(true)
local lower=utf and utf.lower or string.lower
local upper=utf and utf.upper or string.upper
function lpeg.setutfcasers(l,u)
- lower=l or lower
- upper=u or upper
+ lower=l or lower
+ upper=u or upper
end
local function make1(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
- local k=keys[i]
- if k~="" then
- local v=t[k]
- if v==true then
- p=p+P(k)*p_true
- elseif v==false then
- else
- p=p+P(k)*make1(v,v[""])
- end
- end
- end
- if rest then
- p=p+p_true
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+P(k)*p_true
+ elseif v==false then
+ else
+ p=p+P(k)*make1(v,v[""])
+ end
end
- return p
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
end
local function make2(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
- local k=keys[i]
- if k~="" then
- local v=t[k]
- if v==true then
- p=p+(P(lower(k))+P(upper(k)))*p_true
- elseif v==false then
- else
- p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
- end
- end
- end
- if rest then
- p=p+p_true
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+(P(lower(k))+P(upper(k)))*p_true
+ elseif v==false then
+ else
+ p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
+ end
end
- return p
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
end
local function utfchartabletopattern(list,insensitive)
- local tree={}
- local n=#list
- if n==0 then
- for s in next,list do
- local t=tree
- local p,pk
- for c in gmatch(s,".") do
- if t==true then
- t={ [c]=true,[""]=true }
- p[pk]=t
- p=t
- t=false
- elseif t==false then
- t={ [c]=false }
- p[pk]=t
- p=t
- t=false
- else
- local tc=t[c]
- if not tc then
- tc=false
- t[c]=false
- end
- p=t
- t=tc
- end
- pk=c
- end
- if t==false then
- p[pk]=true
- elseif t==true then
- else
- t[""]=true
- end
+ local tree={}
+ local n=#list
+ if n==0 then
+ for s in next,list do
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
end
- else
- for i=1,n do
- local s=list[i]
- local t=tree
- local p,pk
- for c in gmatch(s,".") do
- if t==true then
- t={ [c]=true,[""]=true }
- p[pk]=t
- p=t
- t=false
- elseif t==false then
- t={ [c]=false }
- p[pk]=t
- p=t
- t=false
- else
- local tc=t[c]
- if not tc then
- tc=false
- t[c]=false
- end
- p=t
- t=tc
- end
- pk=c
- end
- if t==false then
- p[pk]=true
- elseif t==true then
- else
- t[""]=true
- end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
+ end
+ else
+ for i=1,n do
+ local s=list[i]
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
end
- return (insensitive and make2 or make1)(tree)
+ end
+ return (insensitive and make2 or make1)(tree)
end
lpeg.utfchartabletopattern=utfchartabletopattern
function lpeg.utfreplacer(list,insensitive)
- local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
- return function(str)
- return lpegmatch(pattern,str) or str
- end
+ local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
+ return function(str)
+ return lpegmatch(pattern,str) or str
+ end
end
patterns.containseol=lpeg.finder(eol)
local function nextstep(n,step,result)
- local m=n%step
- local d=floor(n/step)
- if d>0 then
- local v=V(tostring(step))
- local s=result.start
- for i=1,d do
- if s then
- s=v*s
- else
- s=v
- end
- end
- result.start=s
- end
- if step>1 and result.start then
- local v=V(tostring(step/2))
- result[tostring(step)]=v*v
- end
- if step>0 then
- return nextstep(m,step/2,result)
- else
- return result
+ local m=n%step
+ local d=floor(n/step)
+ if d>0 then
+ local v=V(tostring(step))
+ local s=result.start
+ for i=1,d do
+ if s then
+ s=v*s
+ else
+ s=v
+ end
end
+ result.start=s
+ end
+ if step>1 and result.start then
+ local v=V(tostring(step/2))
+ result[tostring(step)]=v*v
+ end
+ if step>0 then
+ return nextstep(m,step/2,result)
+ else
+ return result
+ end
end
function lpeg.times(pattern,n)
- return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
+ return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
end
do
- local trailingzeros=zero^0*-digit
- local stripper=Cs((
- digits*(
- period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
- )+1
- )^0)
- lpeg.patterns.stripzeros=stripper
- local nonzero=digit-zero
- local trailingzeros=zero^1*endofstring
- local stripper=Cs((1-period)^0*(
- period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
- ))
- lpeg.patterns.stripzero=stripper
+ local trailingzeros=zero^0*-digit
+ local stripper=Cs((
+ digits*(
+ period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
+ )+1
+ )^0)
+ lpeg.patterns.stripzeros=stripper
+ local nonzero=digit-zero
+ local trailingzeros=zero^1*endofstring
+ local stripper=Cs((1-period)^0*(
+ period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
+ ))
+ lpeg.patterns.stripzero=stripper
end
local byte_to_HEX={}
local byte_to_hex={}
local byte_to_dec={}
local hex_to_byte={}
for i=0,255 do
- local H=format("%02X",i)
- local h=format("%02x",i)
- local d=format("%03i",i)
- local c=char(i)
- byte_to_HEX[c]=H
- byte_to_hex[c]=h
- byte_to_dec[c]=d
- hex_to_byte[h]=c
- hex_to_byte[H]=c
+ local H=format("%02X",i)
+ local h=format("%02x",i)
+ local d=format("%03i",i)
+ local c=char(i)
+ byte_to_HEX[c]=H
+ byte_to_hex[c]=h
+ byte_to_dec[c]=d
+ hex_to_byte[h]=c
+ hex_to_byte[H]=c
end
local hextobyte=P(2)/hex_to_byte
local bytetoHEX=P(1)/byte_to_HEX
@@ -1769,47 +1769,47 @@ patterns.bytestoHEX=bytestoHEX
patterns.bytestohex=bytestohex
patterns.bytestodec=bytestodec
function string.toHEX(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestoHEX,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestoHEX,s)
+ end
end
function string.tohex(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestohex,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestohex,s)
+ end
end
function string.todec(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestodec,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestodec,s)
+ end
end
function string.tobytes(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(hextobytes,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(hextobytes,s)
+ end
end
local patterns={}
local function containsws(what)
- local p=patterns[what]
- if not p then
- local p1=P(what)*(whitespace+endofstring)*Cc(true)
- local p2=whitespace*P(p1)
- p=P(p1)+P(1-p2)^0*p2+Cc(false)
- patterns[what]=p
- end
- return p
+ local p=patterns[what]
+ if not p then
+ local p1=P(what)*(whitespace+endofstring)*Cc(true)
+ local p2=whitespace*P(p1)
+ p=P(p1)+P(1-p2)^0*p2+Cc(false)
+ patterns[what]=p
+ end
+ return p
end
lpeg.containsws=containsws
function string.containsws(str,what)
- return lpegmatch(patterns[what] or containsws(what),str)
+ return lpegmatch(patterns[what] or containsws(what),str)
end
@@ -1819,14 +1819,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-function"] = package.loaded["l-function"] or true
--- original size: 361, stripped down to: 322
+-- original size: 361, stripped down to: 317
if not modules then modules={} end modules ['l-functions']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
functions=functions or {}
function functions.dummy() end
@@ -1838,14 +1838,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-string"] = package.loaded["l-string"] or true
--- original size: 6461, stripped down to: 3341
+-- original size: 6461, stripped down to: 3255
if not modules then modules={} end modules ['l-string']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local string=string
local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower
@@ -1853,25 +1853,25 @@ local lpegmatch,patterns=lpeg.match,lpeg.patterns
local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs
local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote
function string.unquoted(str)
- return lpegmatch(unquoted,str) or str
+ return lpegmatch(unquoted,str) or str
end
function string.quoted(str)
- return format("%q",str)
+ return format("%q",str)
end
function string.count(str,pattern)
- local n=0
- for _ in gmatch(str,pattern) do
- n=n+1
- end
- return n
+ local n=0
+ for _ in gmatch(str,pattern) do
+ n=n+1
+ end
+ return n
end
function string.limit(str,n,sentinel)
- if #str>n then
- sentinel=sentinel or "..."
- return sub(str,1,(n-#sentinel))..sentinel
- else
- return str
- end
+ if #str>n then
+ sentinel=sentinel or "..."
+ return sub(str,1,(n-#sentinel))..sentinel
+ else
+ return str
+ end
end
local stripper=patterns.stripper
local fullstripper=patterns.fullstripper
@@ -1879,81 +1879,81 @@ local collapser=patterns.collapser
local nospacer=patterns.nospacer
local longtostring=patterns.longtostring
function string.strip(str)
- return str and lpegmatch(stripper,str) or ""
+ return str and lpegmatch(stripper,str) or ""
end
function string.fullstrip(str)
- return str and lpegmatch(fullstripper,str) or ""
+ return str and lpegmatch(fullstripper,str) or ""
end
function string.collapsespaces(str)
- return str and lpegmatch(collapser,str) or ""
+ return str and lpegmatch(collapser,str) or ""
end
function string.nospaces(str)
- return str and lpegmatch(nospacer,str) or ""
+ return str and lpegmatch(nospacer,str) or ""
end
function string.longtostring(str)
- return str and lpegmatch(longtostring,str) or ""
+ return str and lpegmatch(longtostring,str) or ""
end
local pattern=P(" ")^0*P(-1)
function string.is_empty(str)
- if not str or str=="" then
- return true
- else
- return lpegmatch(pattern,str) and true or false
- end
+ if not str or str=="" then
+ return true
+ else
+ return lpegmatch(pattern,str) and true or false
+ end
end
local anything=patterns.anything
local allescapes=Cc("%")*S(".-+%?()[]*")
-local someescapes=Cc("%")*S(".-+%()[]")
-local matchescapes=Cc(".")*S("*?")
+local someescapes=Cc("%")*S(".-+%()[]")
+local matchescapes=Cc(".")*S("*?")
local pattern_a=Cs ((allescapes+anything )^0 )
local pattern_b=Cs ((someescapes+matchescapes+anything )^0 )
local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") )
function string.escapedpattern(str,simple)
- return lpegmatch(simple and pattern_b or pattern_a,str)
+ return lpegmatch(simple and pattern_b or pattern_a,str)
end
function string.topattern(str,lowercase,strict)
- if str=="" or type(str)~="string" then
- return ".*"
- elseif strict then
- str=lpegmatch(pattern_c,str)
- else
- str=lpegmatch(pattern_b,str)
- end
- if lowercase then
- return lower(str)
- else
- return str
- end
+ if str=="" or type(str)~="string" then
+ return ".*"
+ elseif strict then
+ str=lpegmatch(pattern_c,str)
+ else
+ str=lpegmatch(pattern_b,str)
+ end
+ if lowercase then
+ return lower(str)
+ else
+ return str
+ end
end
function string.valid(str,default)
- return (type(str)=="string" and str~="" and str) or default or nil
+ return (type(str)=="string" and str~="" and str) or default or nil
end
string.itself=function(s) return s end
local pattern_c=Ct(C(1)^0)
local pattern_b=Ct((C(1)/byte)^0)
function string.totable(str,bytes)
- return lpegmatch(bytes and pattern_b or pattern_c,str)
+ return lpegmatch(bytes and pattern_b or pattern_c,str)
end
local replacer=lpeg.replacer("@","%%")
function string.tformat(fmt,...)
- return format(lpegmatch(replacer,fmt),...)
+ return format(lpegmatch(replacer,fmt),...)
end
string.quote=string.quoted
string.unquote=string.unquoted
if not string.bytetable then
- local limit=5000
- function string.bytetable(str)
- local n=#str
- if n>limit then
- local t={ byte(str,1,limit) }
- for i=limit+1,n do
- t[i]=byte(str,i)
- end
- return t
- else
- return { byte(str,1,n) }
- end
+ local limit=5000
+ function string.bytetable(str)
+ local n=#str
+ if n>limit then
+ local t={ byte(str,1,limit) }
+ for i=limit+1,n do
+ t[i]=byte(str,i)
+ end
+ return t
+ else
+ return { byte(str,1,n) }
end
+ end
end
@@ -1963,14 +1963,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 40960, stripped down to: 24090
+-- original size: 40960, stripped down to: 21348
if not modules then modules={} end modules ['l-table']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber,select=type,next,tostring,tonumber,select
local table,string=table,string
@@ -1981,147 +1981,147 @@ local lpegmatch,patterns=lpeg.match,lpeg.patterns
local floor=math.floor
local stripper=patterns.stripper
function table.getn(t)
- return t and #t
+ return t and #t
end
function table.strip(tab)
- local lst,l={},0
- for i=1,#tab do
- local s=lpegmatch(stripper,tab[i]) or ""
- if s=="" then
- else
- l=l+1
- lst[l]=s
- end
+ local lst,l={},0
+ for i=1,#tab do
+ local s=lpegmatch(stripper,tab[i]) or ""
+ if s=="" then
+ else
+ l=l+1
+ lst[l]=s
end
- return lst
+ end
+ return lst
end
function table.keys(t)
- if t then
- local keys,k={},0
- for key in next,t do
- k=k+1
- keys[k]=key
- end
- return keys
- else
- return {}
+ if t then
+ local keys,k={},0
+ for key in next,t do
+ k=k+1
+ keys[k]=key
end
+ return keys
+ else
+ return {}
+ end
end
local function compare(a,b)
- local ta=type(a)
- if ta=="number" then
- local tb=type(b)
- if ta==tb then
- return a<b
- elseif tb=="string" then
- return tostring(a)<b
- end
- elseif ta=="string" then
- local tb=type(b)
- if ta==tb then
- return a<b
- else
- return a<tostring(b)
- end
+ local ta=type(a)
+ if ta=="number" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ elseif tb=="string" then
+ return tostring(a)<b
+ end
+ elseif ta=="string" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ else
+ return a<tostring(b)
end
- return tostring(a)<tostring(b)
+ end
+ return tostring(a)<tostring(b)
end
local function sortedkeys(tab)
- if tab then
- local srt,category,s={},0,0
- for key in next,tab do
- s=s+1
- srt[s]=key
- if category==3 then
- elseif category==1 then
- if type(key)~="string" then
- category=3
- end
- elseif category==2 then
- if type(key)~="number" then
- category=3
- end
- else
- local tkey=type(key)
- if tkey=="string" then
- category=1
- elseif tkey=="number" then
- category=2
- else
- category=3
- end
- end
- end
- if s<2 then
- elseif category==3 then
- sort(srt,compare)
+ if tab then
+ local srt,category,s={},0,0
+ for key in next,tab do
+ s=s+1
+ srt[s]=key
+ if category==3 then
+ elseif category==1 then
+ if type(key)~="string" then
+ category=3
+ end
+ elseif category==2 then
+ if type(key)~="number" then
+ category=3
+ end
+ else
+ local tkey=type(key)
+ if tkey=="string" then
+ category=1
+ elseif tkey=="number" then
+ category=2
else
- sort(srt)
+ category=3
end
- return srt
+ end
+ end
+ if s<2 then
+ elseif category==3 then
+ sort(srt,compare)
else
- return {}
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="string" then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if type(key)=="string" then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedindexonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="number" then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if type(key)=="number" then
+ s=s+1
+ srt[s]=key
+ end
end
+ if s>1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashkeys(tab,cmp)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if key then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt,cmp)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if key then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt,cmp)
end
+ return srt
+ else
+ return {}
+ end
end
function table.allkeys(t)
- local keys={}
- for k,v in next,t do
- for k in next,v do
- keys[k]=true
- end
+ local keys={}
+ for k,v in next,t do
+ for k in next,v do
+ keys[k]=true
end
- return sortedkeys(keys)
+ end
+ return sortedkeys(keys)
end
table.sortedkeys=sortedkeys
table.sortedhashonly=sortedhashonly
@@ -2129,927 +2129,927 @@ table.sortedindexonly=sortedindexonly
table.sortedhashkeys=sortedhashkeys
local function nothing() end
local function sortedhash(t,cmp)
- if t then
- local s
- if cmp then
- s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
- else
- s=sortedkeys(t)
- end
- local m=#s
- if m==1 then
- return next,t
- elseif m>0 then
- local n=0
- return function()
- if n<m then
- n=n+1
- local k=s[n]
- return k,t[k]
- end
- end
+ if t then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local m=#s
+ if m==1 then
+ return next,t
+ elseif m>0 then
+ local n=0
+ return function()
+ if n<m then
+ n=n+1
+ local k=s[n]
+ return k,t[k]
end
+ end
end
- return nothing
+ end
+ return nothing
end
table.sortedhash=sortedhash
table.sortedpairs=sortedhash
function table.append(t,list)
- local n=#t
- for i=1,#list do
- n=n+1
- t[n]=list[i]
- end
- return t
+ local n=#t
+ for i=1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ return t
end
function table.prepend(t,list)
- local nl=#list
- local nt=nl+#t
- for i=#t,1,-1 do
- t[nt]=t[i]
- nt=nt-1
- end
- for i=1,#list do
- t[i]=list[i]
- end
- return t
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+ t[nt]=t[i]
+ nt=nt-1
+ end
+ for i=1,#list do
+ t[i]=list[i]
+ end
+ return t
end
function table.merge(t,...)
- t=t or {}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ t=t or {}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.merged(...)
- local t={}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ local t={}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.imerge(t,...)
- local nt=#t
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- nt=nt+1
- t[nt]=nst[j]
- end
+ local nt=#t
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ nt=nt+1
+ t[nt]=nst[j]
end
- return t
+ end
+ return t
end
function table.imerged(...)
- local tmp,ntmp={},0
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- ntmp=ntmp+1
- tmp[ntmp]=nst[j]
- end
+ local tmp,ntmp={},0
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ ntmp=ntmp+1
+ tmp[ntmp]=nst[j]
end
- return tmp
+ end
+ return tmp
end
local function fastcopy(old,metatabletoo)
- if old then
- local new={}
- for k,v in next,old do
- if type(v)=="table" then
- new[k]=fastcopy(v,metatabletoo)
- else
- new[k]=v
- end
- end
- if metatabletoo then
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ if type(v)=="table" then
+ new[k]=fastcopy(v,metatabletoo)
+ else
+ new[k]=v
+ end
end
+ if metatabletoo then
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ end
+ return new
+ else
+ return {}
+ end
end
local function copy(t,tables)
- tables=tables or {}
- local tcopy={}
- if not tables[t] then
- tables[t]=tcopy
- end
- for i,v in next,t do
- if type(i)=="table" then
- if tables[i] then
- i=tables[i]
- else
- i=copy(i,tables)
- end
- end
- if type(v)~="table" then
- tcopy[i]=v
- elseif tables[v] then
- tcopy[i]=tables[v]
- else
- tcopy[i]=copy(v,tables)
- end
+ tables=tables or {}
+ local tcopy={}
+ if not tables[t] then
+ tables[t]=tcopy
+ end
+ for i,v in next,t do
+ if type(i)=="table" then
+ if tables[i] then
+ i=tables[i]
+ else
+ i=copy(i,tables)
+ end
end
- local mt=getmetatable(t)
- if mt then
- setmetatable(tcopy,mt)
+ if type(v)~="table" then
+ tcopy[i]=v
+ elseif tables[v] then
+ tcopy[i]=tables[v]
+ else
+ tcopy[i]=copy(v,tables)
end
- return tcopy
+ end
+ local mt=getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
end
table.fastcopy=fastcopy
table.copy=copy
function table.derive(parent)
- local child={}
- if parent then
- setmetatable(child,{ __index=parent })
- end
- return child
+ local child={}
+ if parent then
+ setmetatable(child,{ __index=parent })
+ end
+ return child
end
function table.tohash(t,value)
- local h={}
- if t then
- if value==nil then value=true end
- for _,v in next,t do
- h[v]=value
- end
+ local h={}
+ if t then
+ if value==nil then value=true end
+ for _,v in next,t do
+ h[v]=value
end
- return h
+ end
+ return h
end
function table.fromhash(t)
- local hsh,h={},0
- for k,v in next,t do
- if v then
- h=h+1
- hsh[h]=k
- end
+ local hsh,h={},0
+ for k,v in next,t do
+ if v then
+ h=h+1
+ hsh[h]=k
end
- return hsh
+ end
+ return hsh
end
local noquotes,hexify,handle,compact,inline,functions,metacheck
local reserved=table.tohash {
- 'and','break','do','else','elseif','end','false','for','function','if',
- 'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
}
local function is_simple_table(t,hexify)
- local nt=#t
- if nt>0 then
- local n=0
- for _,v in next,t do
- n=n+1
- if type(v)=="table" then
- return nil
- end
+ local nt=#t
+ if nt>0 then
+ local n=0
+ for _,v in next,t do
+ n=n+1
+ if type(v)=="table" then
+ return nil
+ end
+ end
+ local haszero=rawget(t,0)
+ if n==nt then
+ local tt={}
+ for i=1,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i]=format("0x%X",v)
+ else
+ tt[i]=v
+ end
+ elseif tv=="string" then
+ tt[i]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i]=v and "true" or "false"
+ else
+ return nil
end
- local haszero=rawget(t,0)
- if n==nt then
- local tt={}
- for i=1,nt do
- local v=t[i]
- local tv=type(v)
- if tv=="number" then
- if hexify then
- tt[i]=format("0x%X",v)
- else
- tt[i]=v
- end
- elseif tv=="string" then
- tt[i]=format("%q",v)
- elseif tv=="boolean" then
- tt[i]=v and "true" or "false"
- else
- return nil
- end
- end
- return tt
- elseif haszero and (n==nt+1) then
- local tt={}
- for i=0,nt do
- local v=t[i]
- local tv=type(v)
- if tv=="number" then
- if hexify then
- tt[i+1]=format("0x%X",v)
- else
- tt[i+1]=v
- end
- elseif tv=="string" then
- tt[i+1]=format("%q",v)
- elseif tv=="boolean" then
- tt[i+1]=v and "true" or "false"
- else
- return nil
- end
- end
- tt[1]="[0] = "..tt[1]
- return tt
+ end
+ return tt
+ elseif haszero and (n==nt+1) then
+ local tt={}
+ for i=0,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i+1]=format("0x%X",v)
+ else
+ tt[i+1]=v
+ end
+ elseif tv=="string" then
+ tt[i+1]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i+1]=v and "true" or "false"
+ else
+ return nil
end
+ end
+ tt[1]="[0] = "..tt[1]
+ return tt
end
- return nil
+ end
+ return nil
end
table.is_simple_table=is_simple_table
local propername=patterns.propername
local function dummy() end
local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- depth=depth.." "
- if indexed then
- handle(format("%s{",depth))
+ if level>0 then
+ depth=depth.." "
+ if indexed then
+ handle(format("%s{",depth))
+ else
+ local tn=type(name)
+ if tn=="number" then
+ if hexify then
+ handle(format("%s[0x%X]={",depth,name))
else
- local tn=type(name)
- if tn=="number" then
- if hexify then
- handle(format("%s[0x%X]={",depth,name))
- else
- handle(format("%s[%s]={",depth,name))
- end
- elseif tn=="string" then
- if noquotes and not reserved[name] and lpegmatch(propername,name) then
- handle(format("%s%s={",depth,name))
- else
- handle(format("%s[%q]={",depth,name))
- end
- elseif tn=="boolean" then
- handle(format("%s[%s]={",depth,name and "true" or "false"))
- else
- handle(format("%s{",depth))
- end
+ handle(format("%s[%s]={",depth,name))
end
+ elseif tn=="string" then
+ if noquotes and not reserved[name] and lpegmatch(propername,name) then
+ handle(format("%s%s={",depth,name))
+ else
+ handle(format("%s[%q]={",depth,name))
+ end
+ elseif tn=="boolean" then
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
+ else
+ handle(format("%s{",depth))
+ end
end
- if root and next(root)~=nil then
- local first,last=nil,0
- if compact then
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
- end
- if last>0 then
- first=1
- end
+ end
+ if root and next(root)~=nil then
+ local first,last=nil,0
+ if compact then
+ last=#root
+ for k=1,last do
+ if rawget(root,k)==nil then
+ last=k-1
+ break
end
- local sk=sortedkeys(root)
- for i=1,#sk do
- local k=sk[i]
- local v=root[k]
- local tv=type(v)
- local tk=type(k)
- if compact and first and tk=="number" and k>=first and k<=last then
- if tv=="number" then
- if hexify then
- handle(format("%s 0x%X,",depth,v))
- else
- handle(format("%s %s,",depth,v))
- end
- elseif tv=="string" then
- handle(format("%s %q,",depth,v))
- elseif tv=="table" then
- if next(v)==nil then
- handle(format("%s {},",depth))
- elseif inline then
- local st=is_simple_table(v,hexify)
- if st then
- handle(format("%s { %s },",depth,concat(st,", ")))
- else
- do_serialize(v,k,depth,level+1,true)
- end
- else
- do_serialize(v,k,depth,level+1,true)
- end
- elseif tv=="boolean" then
- handle(format("%s %s,",depth,v and "true" or "false"))
- elseif tv=="function" then
- if functions then
- handle(format('%s load(%q),',depth,dump(v)))
- else
- handle(format('%s "function",',depth))
- end
- else
- handle(format("%s %q,",depth,tostring(v)))
- end
- elseif k=="__p__" then
- if false then
- handle(format("%s __p__=nil,",depth))
- end
- elseif tv=="number" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=0x%X,",depth,k,v))
- else
- handle(format("%s [%s]=%s,",depth,k,v))
- end
- elseif tk=="boolean" then
- if hexify then
- handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
- else
- handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
- end
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- if hexify then
- handle(format("%s %s=0x%X,",depth,k,v))
- else
- handle(format("%s %s=%s,",depth,k,v))
- end
- else
- if hexify then
- handle(format("%s [%q]=0x%X,",depth,k,v))
- else
- handle(format("%s [%q]=%s,",depth,k,v))
- end
- end
- elseif tv=="string" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%q,",depth,k,v))
- else
- handle(format("%s [%s]=%q,",depth,k,v))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%q,",depth,k,v))
- else
- handle(format("%s [%q]=%q,",depth,k,v))
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]={},",depth,k))
- else
- handle(format("%s [%s]={},",depth,k))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]={},",depth,k and "true" or "false"))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s={},",depth,k))
- else
- handle(format("%s [%q]={},",depth,k))
- end
- elseif inline then
- local st=is_simple_table(v,hexify)
- if st then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
- else
- handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
- else
- handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
- end
- else
- do_serialize(v,k,depth,level+1)
- end
- else
- do_serialize(v,k,depth,level+1)
- end
- elseif tv=="boolean" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
- else
- handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
- else
- handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
- end
- elseif tv=="function" then
- if functions then
- local getinfo=debug and debug.getinfo
- if getinfo then
- local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=load(%q),",depth,k,f))
- else
- handle(format("%s [%s]=load(%q),",depth,k,f))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=load(%q),",depth,k,f))
- else
- handle(format("%s [%q]=load(%q),",depth,k,f))
- end
- end
- end
+ end
+ if last>0 then
+ first=1
+ end
+ end
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if compact and first and tk=="number" and k>=first and k<=last then
+ if tv=="number" then
+ if hexify then
+ handle(format("%s 0x%X,",depth,v))
+ else
+ handle(format("%s %s,",depth,v))
+ end
+ elseif tv=="string" then
+ handle(format("%s %q,",depth,v))
+ elseif tv=="table" then
+ if next(v)==nil then
+ handle(format("%s {},",depth))
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ handle(format("%s { %s },",depth,concat(st,", ")))
else
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
- else
- handle(format("%s [%s]=%q,",depth,k,tostring(v)))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%q,",depth,k,tostring(v)))
- else
- handle(format("%s [%q]=%q,",depth,k,tostring(v)))
- end
+ do_serialize(v,k,depth,level+1,true)
end
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ elseif tv=="boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv=="function" then
+ if functions then
+ handle(format('%s load(%q),',depth,dump(v)))
+ else
+ handle(format('%s "function",',depth))
+ end
+ else
+ handle(format("%s %q,",depth,tostring(v)))
end
- end
- if level>0 then
- handle(format("%s},",depth))
- end
-end
-local function serialize(_handle,root,name,specification)
- local tname=type(name)
- if type(specification)=="table" then
- noquotes=specification.noquotes
- hexify=specification.hexify
- handle=_handle or specification.handle or print
- functions=specification.functions
- compact=specification.compact
- inline=specification.inline and compact
- metacheck=specification.metacheck
- if functions==nil then
- functions=true
- end
- if compact==nil then
- compact=true
- end
- if inline==nil then
- inline=compact
- end
- if metacheck==nil then
- metacheck=true
+ elseif k=="__p__" then
+ if false then
+ handle(format("%s __p__=nil,",depth))
end
- else
- noquotes=false
- hexify=false
- handle=_handle or print
- compact=true
- inline=true
- functions=true
- metacheck=true
- end
- if tname=="string" then
- if name=="return" then
- handle("return {")
+ elseif tv=="number" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ if hexify then
+ handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ else
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
+ end
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ if hexify then
+ handle(format("%s %s=0x%X,",depth,k,v))
+ else
+ handle(format("%s %s=%s,",depth,k,v))
+ end
else
- handle(name.."={")
+ if hexify then
+ handle(format("%s [%q]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v))
+ end
end
- elseif tname=="number" then
- if hexify then
- handle(format("[0x%X]={",name))
+ elseif tv=="string" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,v))
+ else
+ handle(format("%s [%s]=%q,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,v))
else
- handle("["..name.."]={")
+ handle(format("%s [%q]=%q,",depth,k,v))
end
- elseif tname=="boolean" then
- if name then
- handle("return {")
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={},",depth,k))
+ else
+ handle(format("%s [%s]={},",depth,k))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={},",depth,k))
+ else
+ handle(format("%s [%q]={},",depth,k))
+ end
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
else
- handle("{")
+ do_serialize(v,k,depth,level+1)
end
- else
- handle("t={")
- end
- if root then
- if metacheck and getmetatable(root) then
- local dummy=root._w_h_a_t_e_v_e_r_
- root._w_h_a_t_e_v_e_r_=nil
+ elseif tv=="boolean" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
end
- if next(root)~=nil then
- do_serialize(root,name,"",0)
+ elseif tv=="function" then
+ if functions then
+ local getinfo=debug and debug.getinfo
+ if getinfo then
+ local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%s]=load(%q),",depth,k,f))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%q]=load(%q),",depth,k,f))
+ end
+ end
+ end
+ else
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
end
+ end
end
- handle("}")
+ end
+ if level>0 then
+ handle(format("%s},",depth))
+ end
end
-function table.serialize(root,name,specification)
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
+local function serialize(_handle,root,name,specification)
+ local tname=type(name)
+ if type(specification)=="table" then
+ noquotes=specification.noquotes
+ hexify=specification.hexify
+ handle=_handle or specification.handle or print
+ functions=specification.functions
+ compact=specification.compact
+ inline=specification.inline and compact
+ metacheck=specification.metacheck
+ if functions==nil then
+ functions=true
+ end
+ if compact==nil then
+ compact=true
+ end
+ if inline==nil then
+ inline=compact
+ end
+ if metacheck==nil then
+ metacheck=true
+ end
+ else
+ noquotes=false
+ hexify=false
+ handle=_handle or print
+ compact=true
+ inline=true
+ functions=true
+ metacheck=true
+ end
+ if tname=="string" then
+ if name=="return" then
+ handle("return {")
+ else
+ handle(name.."={")
+ end
+ elseif tname=="number" then
+ if hexify then
+ handle(format("[0x%X]={",name))
+ else
+ handle("["..name.."]={")
+ end
+ elseif tname=="boolean" then
+ if name then
+ handle("return {")
+ else
+ handle("{")
+ end
+ else
+ handle("t={")
+ end
+ if root then
+ if metacheck and getmetatable(root) then
+ local dummy=root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_=nil
+ end
+ if next(root)~=nil then
+ do_serialize(root,name,"",0)
end
- serialize(flush,root,name,specification)
- return concat(t,"\n")
+ end
+ handle("}")
+end
+function table.serialize(root,name,specification)
+ local t,n={},0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ end
+ serialize(flush,root,name,specification)
+ return concat(t,"\n")
end
table.tohandle=serialize
local maxtab=2*1024
function table.tofile(filename,root,name,specification)
- local f=io.open(filename,'w')
- if f then
- if maxtab>1 then
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
- if n>maxtab then
- f:write(concat(t,"\n"),"\n")
- t,n={},0
- end
- end
- serialize(flush,root,name,specification)
- f:write(concat(t,"\n"),"\n")
- else
- local function flush(s)
- f:write(s,"\n")
- end
- serialize(flush,root,name,specification)
+ local f=io.open(filename,'w')
+ if f then
+ if maxtab>1 then
+ local t,n={},0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ if n>maxtab then
+ f:write(concat(t,"\n"),"\n")
+ t,n={},0
end
- f:close()
- io.flush()
+ end
+ serialize(flush,root,name,specification)
+ f:write(concat(t,"\n"),"\n")
+ else
+ local function flush(s)
+ f:write(s,"\n")
+ end
+ serialize(flush,root,name,specification)
end
+ f:close()
+ io.flush()
+ end
end
local function flattened(t,f,depth)
- if f==nil then
- f={}
- depth=0xFFFF
- elseif tonumber(f) then
- depth=f
- f={}
- elseif not depth then
- depth=0xFFFF
- end
- for k,v in next,t do
- if type(k)~="number" then
- if depth>0 and type(v)=="table" then
- flattened(v,f,depth-1)
- else
- f[#f+1]=v
- end
- end
+ if f==nil then
+ f={}
+ depth=0xFFFF
+ elseif tonumber(f) then
+ depth=f
+ f={}
+ elseif not depth then
+ depth=0xFFFF
+ end
+ for k,v in next,t do
+ if type(k)~="number" then
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
+ end
end
- for k=1,#t do
- local v=t[k]
- if depth>0 and type(v)=="table" then
- flattened(v,f,depth-1)
- else
- f[#f+1]=v
- end
+ end
+ for k=1,#t do
+ local v=t[k]
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
end
- return f
+ end
+ return f
end
table.flattened=flattened
local function collapsed(t,f,h)
- if f==nil then
- f={}
- h={}
- end
- for k=1,#t do
- local v=t[k]
- if type(v)=="table" then
- collapsed(v,f,h)
- elseif not h[v] then
- f[#f+1]=v
- h[v]=true
- end
+ if f==nil then
+ f={}
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsed(v,f,h)
+ elseif not h[v] then
+ f[#f+1]=v
+ h[v]=true
end
- return f
+ end
+ return f
end
local function collapsedhash(t,h)
- if h==nil then
- h={}
- end
- for k=1,#t do
- local v=t[k]
- if type(v)=="table" then
- collapsedhash(v,h)
- else
- h[v]=true
- end
+ if h==nil then
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsedhash(v,h)
+ else
+ h[v]=true
end
- return h
+ end
+ return h
end
-table.collapsed=collapsed
+table.collapsed=collapsed
table.collapsedhash=collapsedhash
local function unnest(t,f)
- if not f then
- f={}
- end
- for i=1,#t do
- local v=t[i]
- if type(v)=="table" then
- if type(v[1])=="table" then
- unnest(v,f)
- else
- f[#f+1]=v
- end
- else
- f[#f+1]=v
- end
+ if not f then
+ f={}
+ end
+ for i=1,#t do
+ local v=t[i]
+ if type(v)=="table" then
+ if type(v[1])=="table" then
+ unnest(v,f)
+ else
+ f[#f+1]=v
+ end
+ else
+ f[#f+1]=v
end
- return f
+ end
+ return f
end
function table.unnest(t)
- return unnest(t)
+ return unnest(t)
end
local function are_equal(a,b,n,m)
- if a==b then
- return true
- elseif a and b and #a==#b then
- n=n or 1
- m=m or #a
- for i=n,m do
- local ai,bi=a[i],b[i]
- if ai==bi then
- elseif type(ai)=="table" and type(bi)=="table" then
- if not are_equal(ai,bi) then
- return false
- end
- else
- return false
- end
- end
- return true
- else
+ if a==b then
+ return true
+ elseif a and b and #a==#b then
+ n=n or 1
+ m=m or #a
+ for i=n,m do
+ local ai,bi=a[i],b[i]
+ if ai==bi then
+ elseif type(ai)=="table" and type(bi)=="table" then
+ if not are_equal(ai,bi) then
+ return false
+ end
+ else
return false
+ end
end
+ return true
+ else
+ return false
+ end
end
local function identical(a,b)
- if a~=b then
- for ka,va in next,a do
- local vb=b[ka]
- if va==vb then
- elseif type(va)=="table" and type(vb)=="table" then
- if not identical(va,vb) then
- return false
- end
- else
- return false
- end
- end
+ if a~=b then
+ for ka,va in next,a do
+ local vb=b[ka]
+ if va==vb then
+ elseif type(va)=="table" and type(vb)=="table" then
+ if not identical(va,vb) then
+ return false
+ end
+ else
+ return false
+ end
end
- return true
+ end
+ return true
end
table.identical=identical
table.are_equal=are_equal
local function sparse(old,nest,keeptables)
- local new={}
- for k,v in next,old do
- if not (v=="" or v==false) then
- if nest and type(v)=="table" then
- v=sparse(v,nest)
- if keeptables or next(v)~=nil then
- new[k]=v
- end
- else
- new[k]=v
- end
- end
+ local new={}
+ for k,v in next,old do
+ if not (v=="" or v==false) then
+ if nest and type(v)=="table" then
+ v=sparse(v,nest)
+ if keeptables or next(v)~=nil then
+ new[k]=v
+ end
+ else
+ new[k]=v
+ end
end
- return new
+ end
+ return new
end
table.sparse=sparse
function table.compact(t)
- return sparse(t,true,true)
+ return sparse(t,true,true)
end
function table.contains(t,v)
- if t then
- for i=1,#t do
- if t[i]==v then
- return i
- end
- end
+ if t then
+ for i=1,#t do
+ if t[i]==v then
+ return i
+ end
end
- return false
+ end
+ return false
end
function table.count(t)
- local n=0
- for k,v in next,t do
- n=n+1
- end
- return n
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ end
+ return n
end
function table.swapped(t,s)
- local n={}
- if s then
- for k,v in next,s do
- n[k]=v
- end
+ local n={}
+ if s then
+ for k,v in next,s do
+ n[k]=v
end
- for k,v in next,t do
- n[v]=k
- end
- return n
+ end
+ for k,v in next,t do
+ n[v]=k
+ end
+ return n
end
function table.hashed(t)
- for i=1,#t do
- t[t[i]]=i
- end
- return t
+ for i=1,#t do
+ t[t[i]]=i
+ end
+ return t
end
function table.mirrored(t)
- local n={}
- for k,v in next,t do
- n[v]=k
- n[k]=v
- end
- return n
+ local n={}
+ for k,v in next,t do
+ n[v]=k
+ n[k]=v
+ end
+ return n
end
function table.reversed(t)
- if t then
- local tt,tn={},#t
- if tn>0 then
- local ttn=0
- for i=tn,1,-1 do
- ttn=ttn+1
- tt[ttn]=t[i]
- end
- end
- return tt
+ if t then
+ local tt,tn={},#t
+ if tn>0 then
+ local ttn=0
+ for i=tn,1,-1 do
+ ttn=ttn+1
+ tt[ttn]=t[i]
+ end
end
+ return tt
+ end
end
function table.reverse(t)
- if t then
- local n=#t
- local m=n+1
- for i=1,floor(n/2) do
- local j=m-i
- t[i],t[j]=t[j],t[i]
- end
- return t
+ if t then
+ local n=#t
+ local m=n+1
+ for i=1,floor(n/2) do
+ local j=m-i
+ t[i],t[j]=t[j],t[i]
end
+ return t
+ end
end
local function sequenced(t,sep,simple)
- if not t then
- return ""
- elseif type(t)=="string" then
- return t
+ if not t then
+ return ""
+ elseif type(t)=="string" then
+ return t
+ end
+ local n=#t
+ local s={}
+ if n>0 then
+ for i=1,n do
+ local v=t[i]
+ if type(v)=="table" then
+ s[i]="{"..sequenced(v,sep,simple).."}"
+ else
+ s[i]=tostring(t[i])
+ end
end
- local n=#t
- local s={}
- if n>0 then
- for i=1,n do
- local v=t[i]
- if type(v)=="table" then
- s[i]="{"..sequenced(v,sep,simple).."}"
- else
- s[i]=tostring(t[i])
- end
+ else
+ n=0
+ for k,v in sortedhash(t) do
+ if simple then
+ if v==true then
+ n=n+1
+ s[n]=k
+ elseif v and v~="" then
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
+ end
end
- else
- n=0
- for k,v in sortedhash(t) do
- if simple then
- if v==true then
- n=n+1
- s[n]=k
- elseif v and v~="" then
- n=n+1
- if type(v)=="table" then
- s[n]=k.."={"..sequenced(v,sep,simple).."}"
- else
- s[n]=k.."="..tostring(v)
- end
- end
- else
- n=n+1
- if type(v)=="table" then
- s[n]=k.."={"..sequenced(v,sep,simple).."}"
- else
- s[n]=k.."="..tostring(v)
- end
- end
+ else
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
end
+ end
end
- return concat(s,sep or " | ")
+ end
+ return concat(s,sep or " | ")
end
table.sequenced=sequenced
function table.print(t,...)
- if type(t)~="table" then
- print(tostring(t))
- else
- serialize(print,t,...)
- end
+ if type(t)~="table" then
+ print(tostring(t))
+ else
+ serialize(print,t,...)
+ end
end
if setinspector then
- setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
+ setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
end
function table.sub(t,i,j)
- return { unpack(t,i,j) }
+ return { unpack(t,i,j) }
end
function table.is_empty(t)
- return not t or next(t)==nil
+ return not t or next(t)==nil
end
function table.has_one_entry(t)
- return t and next(t,next(t))==nil
+ return t and next(t,next(t))==nil
end
function table.loweredkeys(t)
- local l={}
- for k,v in next,t do
- l[lower(k)]=v
- end
- return l
+ local l={}
+ for k,v in next,t do
+ l[lower(k)]=v
+ end
+ return l
end
function table.unique(old)
- local hash={}
- local new={}
- local n=0
- for i=1,#old do
- local oi=old[i]
- if not hash[oi] then
- n=n+1
- new[n]=oi
- hash[oi]=true
- end
- end
- return new
+ local hash={}
+ local new={}
+ local n=0
+ for i=1,#old do
+ local oi=old[i]
+ if not hash[oi] then
+ n=n+1
+ new[n]=oi
+ hash[oi]=true
+ end
+ end
+ return new
end
function table.sorted(t,...)
- sort(t,...)
- return t
+ sort(t,...)
+ return t
end
function table.values(t,s)
- if t then
- local values,keys,v={},{},0
- for key,value in next,t do
- if not keys[value] then
- v=v+1
- values[v]=value
- keys[k]=key
- end
- end
- if s then
- sort(values)
- end
- return values
- else
- return {}
+ if t then
+ local values,keys,v={},{},0
+ for key,value in next,t do
+ if not keys[value] then
+ v=v+1
+ values[v]=value
+ keys[k]=key
+ end
end
+ if s then
+ sort(values)
+ end
+ return values
+ else
+ return {}
+ end
end
function table.filtered(t,pattern,sort,cmp)
- if t and type(pattern)=="string" then
- if sort then
- local s
- if cmp then
- s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
- else
- s=sortedkeys(t)
- end
- local n=0
- local m=#s
- local function kv(s)
- while n<m do
- n=n+1
- local k=s[n]
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return kv,s
- else
- local n=next(t)
- local function iterator()
- while n~=nil do
- local k=n
- n=next(t,k)
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return iterator,t
+ if t and type(pattern)=="string" then
+ if sort then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local n=0
+ local m=#s
+ local function kv(s)
+ while n<m do
+ n=n+1
+ local k=s[n]
+ if find(k,pattern) then
+ return k,t[k]
+ end
end
- else
- return nothing
+ end
+ return kv,s
+ else
+ local n=next(t)
+ local function iterator()
+ while n~=nil do
+ local k=n
+ n=next(t,k)
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return iterator,t
end
+ else
+ return nothing
+ end
end
if not table.move then
- function table.move(a1,f,e,t,a2)
- if a2 and a1~=a2 then
- for i=f,e do
- a2[t]=a1[i]
- t=t+1
- end
- return a2
- else
- t=t+e-f
- for i=e,f,-1 do
- a1[t]=a1[i]
- t=t-1
- end
- return a1
- end
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1~=a2 then
+ for i=f,e do
+ a2[t]=a1[i]
+ t=t+1
+ end
+ return a2
+ else
+ t=t+e-f
+ for i=e,f,-1 do
+ a1[t]=a1[i]
+ t=t-1
+ end
+ return a1
end
+ end
end
@@ -3059,14 +3059,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-io"] = package.loaded["l-io"] or true
--- original size: 11823, stripped down to: 6945
+-- original size: 11823, stripped down to: 6325
if not modules then modules={} end modules ['l-io']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local io=io
local open,flush,write,read=io.open,io.flush,io.write,io.read
@@ -3074,334 +3074,334 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
local concat=table.concat
local type=type
if string.find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator="\\",";"
+ io.fileseparator,io.pathseparator="\\",";"
else
- io.fileseparator,io.pathseparator="/",":"
+ io.fileseparator,io.pathseparator="/",":"
end
local large=0x01000000
local medium=0x00100000
local small=0x00020000
local function readall(f)
- local size=f:seek("end")
- if size>0 then
- f:seek("set",0)
- return f:read(size)
- else
- return ""
- end
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ return f:read(size)
+ else
+ return ""
+ end
end
io.readall=readall
function io.loaddata(filename,textmode)
- local f=open(filename,(textmode and 'r') or 'rb')
- if f then
- local size=f:seek("end")
- local data=nil
- if size>0 then
- f:seek("set",0)
- data=f:read(size)
- end
- f:close()
- return data
+ local f=open(filename,(textmode and 'r') or 'rb')
+ if f then
+ local size=f:seek("end")
+ local data=nil
+ if size>0 then
+ f:seek("set",0)
+ data=f:read(size)
end
+ f:close()
+ return data
+ end
end
function io.copydata(source,target,action)
- local f=open(source,"rb")
- if f then
- local g=open(target,"wb")
- if g then
- local size=f:seek("end")
- if size>0 then
- f:seek("set",0)
- local data=f:read(size)
- if action then
- data=action(data)
- end
- if data then
- g:write(data)
- end
- end
- g:close()
+ local f=open(source,"rb")
+ if f then
+ local g=open(target,"wb")
+ if g then
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ local data=f:read(size)
+ if action then
+ data=action(data)
end
- f:close()
- flush()
+ if data then
+ g:write(data)
+ end
+ end
+ g:close()
end
+ f:close()
+ flush()
+ end
end
function io.savedata(filename,data,joiner)
- local f=open(filename,"wb")
- if f then
- if type(data)=="table" then
- f:write(concat(data,joiner or ""))
- elseif type(data)=="function" then
- data(f)
- else
- f:write(data or "")
- end
- f:close()
- flush()
- return true
+ local f=open(filename,"wb")
+ if f then
+ if type(data)=="table" then
+ f:write(concat(data,joiner or ""))
+ elseif type(data)=="function" then
+ data(f)
else
- return false
+ f:write(data or "")
end
+ f:close()
+ flush()
+ return true
+ else
+ return false
+ end
end
if fio and fio.readline then
- local readline=fio.readline
- function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=readline(f)
- if line then
- lines[i]=line
- else
- break
- end
- end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
+ local readline=fio.readline
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=readline(f)
+ if line then
+ lines[i]=line
else
- local line=readline(f)
- f:close()
- if line and #line>0 then
- return line
- end
+ break
end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=readline(f)
+ f:close()
+ if line and #line>0 then
+ return line
+ end
end
+ end
else
- function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=f:read("*lines")
- if line then
- lines[i]=line
- else
- break
- end
- end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=f:read("*lines")
+ if line then
+ lines[i]=line
else
- local line=f:read("*line") or ""
- f:close()
- if #line>0 then
- return line
- end
+ break
end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=f:read("*line") or ""
+ f:close()
+ if #line>0 then
+ return line
+ end
end
+ end
end
function io.loadchunk(filename,n)
- local f=open(filename,'rb')
- if f then
- local data=f:read(n or 1024)
- f:close()
- if #data>0 then
- return data
- end
+ local f=open(filename,'rb')
+ if f then
+ local data=f:read(n or 1024)
+ f:close()
+ if #data>0 then
+ return data
end
+ end
end
function io.exists(filename)
- local f=open(filename)
- if f==nil then
- return false
- else
- f:close()
- return true
- end
+ local f=open(filename)
+ if f==nil then
+ return false
+ else
+ f:close()
+ return true
+ end
end
function io.size(filename)
- local f=open(filename)
- if f==nil then
- return 0
- else
- local s=f:seek("end")
- f:close()
- return s
- end
+ local f=open(filename)
+ if f==nil then
+ return 0
+ else
+ local s=f:seek("end")
+ f:close()
+ return s
+ end
end
local function noflines(f)
- if type(f)=="string" then
- local f=open(filename)
- if f then
- local n=f and noflines(f) or 0
- f:close()
- return n
- else
- return 0
- end
+ if type(f)=="string" then
+ local f=open(filename)
+ if f then
+ local n=f and noflines(f) or 0
+ f:close()
+ return n
else
- local n=0
- for _ in f:lines() do
- n=n+1
- end
- f:seek('set',0)
- return n
+ return 0
+ end
+ else
+ local n=0
+ for _ in f:lines() do
+ n=n+1
end
+ f:seek('set',0)
+ return n
+ end
end
io.noflines=noflines
local nextchar={
- [ 4]=function(f)
- return f:read(1,1,1,1)
- end,
- [ 2]=function(f)
- return f:read(1,1)
- end,
- [ 1]=function(f)
- return f:read(1)
- end,
- [-2]=function(f)
- local a,b=f:read(1,1)
- return b,a
- end,
- [-4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- return d,c,b,a
- end
+ [ 4]=function(f)
+ return f:read(1,1,1,1)
+ end,
+ [ 2]=function(f)
+ return f:read(1,1)
+ end,
+ [ 1]=function(f)
+ return f:read(1)
+ end,
+ [-2]=function(f)
+ local a,b=f:read(1,1)
+ return b,a
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ return d,c,b,a
+ end
}
function io.characters(f,n)
- if f then
- return nextchar[n or 1],f
- end
+ if f then
+ return nextchar[n or 1],f
+ end
end
local nextbyte={
- [4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- if d then
- return byte(a),byte(b),byte(c),byte(d)
- end
- end,
- [3]=function(f)
- local a,b,c=f:read(1,1,1)
- if b then
- return byte(a),byte(b),byte(c)
- end
- end,
- [2]=function(f)
- local a,b=f:read(1,1)
- if b then
- return byte(a),byte(b)
- end
- end,
- [1]=function (f)
- local a=f:read(1)
- if a then
- return byte(a)
- end
- end,
- [-2]=function (f)
- local a,b=f:read(1,1)
- if b then
- return byte(b),byte(a)
- end
- end,
- [-3]=function(f)
- local a,b,c=f:read(1,1,1)
- if b then
- return byte(c),byte(b),byte(a)
- end
- end,
- [-4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- if d then
- return byte(d),byte(c),byte(b),byte(a)
- end
+ [4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(a),byte(b),byte(c),byte(d)
+ end
+ end,
+ [3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(a),byte(b),byte(c)
+ end
+ end,
+ [2]=function(f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(a),byte(b)
+ end
+ end,
+ [1]=function (f)
+ local a=f:read(1)
+ if a then
+ return byte(a)
+ end
+ end,
+ [-2]=function (f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(b),byte(a)
+ end
+ end,
+ [-3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(c),byte(b),byte(a)
+ end
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(d),byte(c),byte(b),byte(a)
end
+ end
}
function io.bytes(f,n)
- if f then
- return nextbyte[n or 1],f
- else
- return nil,nil
- end
+ if f then
+ return nextbyte[n or 1],f
+ else
+ return nil,nil
+ end
end
function io.ask(question,default,options)
- while true do
- write(question)
- if options then
- write(format(" [%s]",concat(options,"|")))
- end
- if default then
- write(format(" [%s]",default))
- end
- write(format(" "))
- flush()
- local answer=read()
- answer=gsub(answer,"^%s*(.*)%s*$","%1")
- if answer=="" and default then
- return default
- elseif not options then
- return answer
- else
- for k=1,#options do
- if options[k]==answer then
- return answer
- end
- end
- local pattern="^"..answer
- for k=1,#options do
- local v=options[k]
- if find(v,pattern) then
- return v
- end
- end
+ while true do
+ write(question)
+ if options then
+ write(format(" [%s]",concat(options,"|")))
+ end
+ if default then
+ write(format(" [%s]",default))
+ end
+ write(format(" "))
+ flush()
+ local answer=read()
+ answer=gsub(answer,"^%s*(.*)%s*$","%1")
+ if answer=="" and default then
+ return default
+ elseif not options then
+ return answer
+ else
+ for k=1,#options do
+ if options[k]==answer then
+ return answer
end
+ end
+ local pattern="^"..answer
+ for k=1,#options do
+ local v=options[k]
+ if find(v,pattern) then
+ return v
+ end
+ end
end
+ end
end
local function readnumber(f,n,m)
- if m then
- f:seek("set",n)
- n=m
- end
- if n==1 then
- return byte(f:read(1))
- elseif n==2 then
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
- elseif n==3 then
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
- elseif n==4 then
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==8 then
- local a,b=readnumber(f,4),readnumber(f,4)
- return 0x100*a+b
- elseif n==12 then
- local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
- return 0x10000*a+0x100*b+c
- elseif n==-2 then
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
- elseif n==-3 then
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
- elseif n==-4 then
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==-8 then
- local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
- return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
- else
- return 0
- end
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ if n==1 then
+ return byte(f:read(1))
+ elseif n==2 then
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==3 then
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==4 then
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==8 then
+ local a,b=readnumber(f,4),readnumber(f,4)
+ return 0x100*a+b
+ elseif n==12 then
+ local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
+ return 0x10000*a+0x100*b+c
+ elseif n==-2 then
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==-3 then
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==-4 then
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==-8 then
+ local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
+ return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+ else
+ return 0
+ end
end
io.readnumber=readnumber
function io.readstring(f,n,m)
- if m then
- f:seek("set",n)
- n=m
- end
- local str=gsub(f:read(n),"\000","")
- return str
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ local str=gsub(f:read(n),"\000","")
+ return str
end
@@ -3411,14 +3411,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-number"] = package.loaded["l-number"] or true
--- original size: 5720, stripped down to: 2392
+-- original size: 5720, stripped down to: 2176
if not modules then modules={} end modules ['l-number']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tostring,tonumber=tostring,tonumber
local format,floor,match,rep=string.format,math.floor,string.match,string.rep
@@ -3428,107 +3428,107 @@ local floor=math.floor
number=number or {}
local number=number
if bit32 then
- local bextract=bit32.extract
- local t={
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- }
- function number.tobitstring(b,m,w)
- if not w then
- w=32
- end
- local n=w
- for i=0,w-1 do
- local v=bextract(b,i)
- local k=w-i
- if v==1 then
- n=k
- t[k]="1"
- else
- t[k]="0"
- end
- end
- if w then
- return concat(t,"",1,w)
- elseif m then
- m=33-m*8
- if m<1 then
- m=1
- end
- return concat(t,"",1,m)
- elseif n<8 then
- return concat(t)
- elseif n<16 then
- return concat(t,"",9)
- elseif n<24 then
- return concat(t,"",17)
- else
- return concat(t,"",25)
- end
+ local bextract=bit32.extract
+ local t={
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ }
+ function number.tobitstring(b,m,w)
+ if not w then
+ w=32
+ end
+ local n=w
+ for i=0,w-1 do
+ local v=bextract(b,i)
+ local k=w-i
+ if v==1 then
+ n=k
+ t[k]="1"
+ else
+ t[k]="0"
+ end
+ end
+ if w then
+ return concat(t,"",1,w)
+ elseif m then
+ m=33-m*8
+ if m<1 then
+ m=1
+ end
+ return concat(t,"",1,m)
+ elseif n<8 then
+ return concat(t)
+ elseif n<16 then
+ return concat(t,"",9)
+ elseif n<24 then
+ return concat(t,"",17)
+ else
+ return concat(t,"",25)
end
+ end
else
- function number.tobitstring(n,m)
- if n>0 then
- local t={}
- while n>0 do
- insert(t,1,n%2>0 and 1 or 0)
- n=floor(n/2)
- end
- local nn=8-#t%8
- if nn>0 and nn<8 then
- for i=1,nn do
- insert(t,1,0)
- end
- end
- if m then
- m=m*8-#t
- if m>0 then
- insert(t,1,rep("0",m))
- end
- end
- return concat(t)
- elseif m then
- rep("00000000",m)
- else
- return "00000000"
+ function number.tobitstring(n,m)
+ if n>0 then
+ local t={}
+ while n>0 do
+ insert(t,1,n%2>0 and 1 or 0)
+ n=floor(n/2)
+ end
+ local nn=8-#t%8
+ if nn>0 and nn<8 then
+ for i=1,nn do
+ insert(t,1,0)
+ end
+ end
+ if m then
+ m=m*8-#t
+ if m>0 then
+ insert(t,1,rep("0",m))
end
+ end
+ return concat(t)
+ elseif m then
+ rep("00000000",m)
+ else
+ return "00000000"
end
+ end
end
function number.valid(str,default)
- return tonumber(str) or default or nil
+ return tonumber(str) or default or nil
end
function number.toevenhex(n)
- local s=format("%X",n)
- if #s%2==0 then
- return s
- else
- return "0"..s
- end
+ local s=format("%X",n)
+ if #s%2==0 then
+ return s
+ else
+ return "0"..s
+ end
end
function number.bytetodecimal(b)
- local d=floor(b*100/255+0.5)
- if d>100 then
- return 100
- elseif d<-100 then
- return -100
- else
- return d
- end
+ local d=floor(b*100/255+0.5)
+ if d>100 then
+ return 100
+ elseif d<-100 then
+ return -100
+ else
+ return d
+ end
end
function number.decimaltobyte(d)
- local b=floor(d*255/100+0.5)
- if b>255 then
- return 255
- elseif b<-255 then
- return -255
- else
- return b
- end
+ local b=floor(d*255/100+0.5)
+ if b>255 then
+ return 255
+ elseif b<-255 then
+ return -255
+ else
+ return b
+ end
end
function number.idiv(i,d)
- return floor(i/d)
+ return floor(i/d)
end
@@ -3538,14 +3538,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-set"] = package.loaded["l-set"] or true
--- original size: 1923, stripped down to: 1133
+-- original size: 1923, stripped down to: 1044
if not modules then modules={} end modules ['l-set']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
set=set or {}
local nums={}
@@ -3554,54 +3554,54 @@ local concat=table.concat
local next,type=next,type
set.create=table.tohash
function set.tonumber(t)
- if next(t) then
- local s=""
- for k,v in next,t do
- if v then
- s=s.." "..k
- end
- end
- local n=nums[s]
- if not n then
- n=#tabs+1
- tabs[n]=t
- nums[s]=n
- end
- return n
- else
- return 0
+ if next(t) then
+ local s=""
+ for k,v in next,t do
+ if v then
+ s=s.." "..k
+ end
+ end
+ local n=nums[s]
+ if not n then
+ n=#tabs+1
+ tabs[n]=t
+ nums[s]=n
end
+ return n
+ else
+ return 0
+ end
end
function set.totable(n)
- if n==0 then
- return {}
- else
- return tabs[n] or {}
- end
+ if n==0 then
+ return {}
+ else
+ return tabs[n] or {}
+ end
end
function set.tolist(n)
- if n==0 or not tabs[n] then
- return ""
- else
- local t,n={},0
- for k,v in next,tabs[n] do
- if v then
- n=n+1
- t[n]=k
- end
- end
- return concat(t," ")
+ if n==0 or not tabs[n] then
+ return ""
+ else
+ local t,n={},0
+ for k,v in next,tabs[n] do
+ if v then
+ n=n+1
+ t[n]=k
+ end
end
+ return concat(t," ")
+ end
end
function set.contains(n,s)
- if type(n)=="table" then
- return n[s]
- elseif n==0 then
- return false
- else
- local t=tabs[n]
- return t and t[s]
- end
+ if type(n)=="table" then
+ return n[s]
+ elseif n==0 then
+ return false
+ else
+ local t=tabs[n]
+ return t and t[s]
+ end
end
@@ -3611,14 +3611,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-os"] = package.loaded["l-os"] or true
--- original size: 19347, stripped down to: 11016
+-- original size: 19347, stripped down to: 10258
if not modules then modules={} end modules ['l-os']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local os=os
local date,time=os.date,os.time
@@ -3627,433 +3627,433 @@ local concat=table.concat
local random,ceil,randomseed=math.random,math.ceil,math.randomseed
local rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring=rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring
do
- local selfdir=os.selfdir
- if selfdir=="" then
- selfdir=nil
+ local selfdir=os.selfdir
+ if selfdir=="" then
+ selfdir=nil
+ end
+ if not selfdir then
+ if arg then
+ for i=1,#arg do
+ local a=arg[i]
+ if find(a,"^%-%-[c:]*texmfbinpath=") then
+ selfdir=gsub(a,"^.-=","")
+ break
+ end
+ end
end
if not selfdir then
- if arg then
- for i=1,#arg do
- local a=arg[i]
- if find(a,"^%-%-[c:]*texmfbinpath=") then
- selfdir=gsub(a,"^.-=","")
- break
- end
+ selfdir=os.selfbin or "luatex"
+ if find(selfdir,"[/\\]") then
+ selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
+ elseif os.getenv then
+ local path=os.getenv("PATH")
+ local name=gsub(selfdir,"^.*[/\\][^/\\]","")
+ local patt="[^:]+"
+ if os.type=="windows" then
+ patt="[^;]+"
+ name=name..".exe"
+ end
+ local isfile
+ if lfs then
+ local attributes=lfs.attributes
+ isfile=function(name)
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
+ end
+ else
+ local open=io.open
+ isfile=function(name)
+ local f=open(name)
+ if f then
+ f:close()
+ return true
end
+ end
end
- if not selfdir then
- selfdir=os.selfbin or "luatex"
- if find(selfdir,"[/\\]") then
- selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
- elseif os.getenv then
- local path=os.getenv("PATH")
- local name=gsub(selfdir,"^.*[/\\][^/\\]","")
- local patt="[^:]+"
- if os.type=="windows" then
- patt="[^;]+"
- name=name..".exe"
- end
- local isfile
- if lfs then
- local attributes=lfs.attributes
- isfile=function(name)
- local a=attributes(name,"mode")
- return a=="file" or a=="link" or nil
- end
- else
- local open=io.open
- isfile=function(name)
- local f=open(name)
- if f then
- f:close()
- return true
- end
- end
- end
- for p in gmatch(path,patt) do
- if isfile(p.."/"..name) then
- selfdir=p
- break
- end
- end
- end
+ for p in gmatch(path,patt) do
+ if isfile(p.."/"..name) then
+ selfdir=p
+ break
+ end
end
- os.selfdir=selfdir or "."
+ end
end
+ os.selfdir=selfdir or "."
+ end
end
math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
randomseed(math.initialseed)
if not os.__getenv__ then
- os.__getenv__=os.getenv
- os.__setenv__=os.setenv
- if os.env then
- local osgetenv=os.getenv
- local ossetenv=os.setenv
- local osenv=os.env local _=osenv.PATH
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- if type(v)=="table" then
- v=concat(v,";")
- end
- ossetenv(K,v)
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
- end
- else
- local ossetenv=os.setenv
- local osgetenv=os.getenv
- local osenv={}
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
- end
- local function __index(t,k)
- return os.getenv(k)
- end
- local function __newindex(t,k,v)
- os.setenv(k,v)
- end
- os.env={}
- setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ os.__getenv__=os.getenv
+ os.__setenv__=os.setenv
+ if os.env then
+ local osgetenv=os.getenv
+ local ossetenv=os.setenv
+ local osenv=os.env local _=osenv.PATH
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ if type(v)=="table" then
+ v=concat(v,";")
+ end
+ ossetenv(K,v)
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ else
+ local ossetenv=os.setenv
+ local osgetenv=os.getenv
+ local osenv={}
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ local function __index(t,k)
+ return os.getenv(k)
+ end
+ local function __newindex(t,k,v)
+ os.setenv(k,v)
+ end
+ os.env={}
+ setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
end
local execute=os.execute
local iopopen=io.popen
local function resultof(command)
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- else
- return ""
- end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ else
+ return ""
+ end
end
os.resultof=resultof
function os.pipeto(command)
- return iopopen(command,"w")
+ return iopopen(command,"w")
end
if not io.fileseparator then
- if find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
- else
- io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
- end
+ if find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
+ else
+ io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
+ end
end
os.type=os.type or (io.pathseparator==";" and "windows") or "unix"
-os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
+os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
if os.type=="windows" then
- os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
else
- os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
end
local launchers={
- windows="start %s",
- macosx="open %s",
- unix="xdg-open %s &> /dev/null &",
+ windows="start %s",
+ macosx="open %s",
+ unix="xdg-open %s &> /dev/null &",
}
function os.launch(str)
- execute(format(launchers[os.name] or launchers.unix,str))
+ execute(format(launchers[os.name] or launchers.unix,str))
end
if not os.times then
- function os.times()
- return {
- utime=os.gettimeofday(),
- stime=0,
- cutime=0,
- cstime=0,
- }
- end
+ function os.times()
+ return {
+ utime=os.gettimeofday(),
+ stime=0,
+ cutime=0,
+ cstime=0,
+ }
+ end
end
local gettimeofday=os.gettimeofday or os.clock
os.gettimeofday=gettimeofday
local startuptime=gettimeofday()
function os.runtime()
- return gettimeofday()-startuptime
+ return gettimeofday()-startuptime
end
local resolvers=os.resolvers or {}
os.resolvers=resolvers
setmetatable(os,{ __index=function(t,k)
- local r=resolvers[k]
- return r and r(t,k) or nil
+ local r=resolvers[k]
+ return r and r(t,k) or nil
end })
local name,platform=os.name or "linux",os.getenv("MTX_PLATFORM") or ""
if platform~="" then
- os.platform=platform
+ os.platform=platform
elseif os.type=="windows" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
- local platform=""
- if find(architecture,"AMD64",1,true) then
- platform="win64"
- else
- platform="mswin"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
+ local platform=""
+ if find(architecture,"AMD64",1,true) then
+ platform="win64"
+ else
+ platform="mswin"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="linux" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- local platform=os.getenv("MTX_PLATFORM") or ""
- local musl=find(os.selfdir or "","linuxmusl")
- if platform~="" then
- elseif find(architecture,"x86_64",1,true) then
- platform=musl and "linuxmusl" or "linux-64"
- elseif find(architecture,"ppc",1,true) then
- platform="linux-ppc"
- else
- platform=musl and "linuxmusl" or "linux"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=os.getenv("MTX_PLATFORM") or ""
+ local musl=find(os.selfdir or "","linuxmusl")
+ if platform~="" then
+ elseif find(architecture,"x86_64",1,true) then
+ platform=musl and "linuxmusl" or "linux-64"
+ elseif find(architecture,"ppc",1,true) then
+ platform="linux-ppc"
+ else
+ platform=musl and "linuxmusl" or "linux"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="macosx" then
- function resolvers.platform(t,k)
- local architecture=resultof("echo $HOSTTYPE") or ""
- local platform=""
- if architecture=="" then
- platform="osx-intel"
- elseif find(architecture,"i386",1,true) then
- platform="osx-intel"
- elseif find(architecture,"x86_64",1,true) then
- platform="osx-64"
- else
- platform="osx-ppc"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local architecture=resultof("echo $HOSTTYPE") or ""
+ local platform=""
+ if architecture=="" then
+ platform="osx-intel"
+ elseif find(architecture,"i386",1,true) then
+ platform="osx-intel"
+ elseif find(architecture,"x86_64",1,true) then
+ platform="osx-64"
+ else
+ platform="osx-ppc"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="sunos" then
- function resolvers.platform(t,k)
- local architecture=resultof("uname -m") or ""
- local platform=""
- if find(architecture,"sparc",1,true) then
- platform="solaris-sparc"
- else
- platform="solaris-intel"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"sparc",1,true) then
+ platform="solaris-sparc"
+ else
+ platform="solaris-intel"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="freebsd" then
- function resolvers.platform(t,k)
- local architecture=resultof("uname -m") or ""
- local platform=""
- if find(architecture,"amd64",1,true) then
- platform="freebsd-amd64"
- else
- platform="freebsd"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"amd64",1,true) then
+ platform="freebsd-amd64"
+ else
+ platform="freebsd"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="kfreebsd" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- local platform=""
- if find(architecture,"x86_64",1,true) then
- platform="kfreebsd-amd64"
- else
- platform="kfreebsd-i386"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"x86_64",1,true) then
+ platform="kfreebsd-amd64"
+ else
+ platform="kfreebsd-i386"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
else
- function resolvers.platform(t,k)
- local platform="linux"
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local platform="linux"
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
end
os.newline=name=="windows" and "\013\010" or "\010"
function resolvers.bits(t,k)
- local bits=find(os.platform,"64",1,true) and 64 or 32
- os.bits=bits
- return bits
+ local bits=find(os.platform,"64",1,true) and 64 or 32
+ os.bits=bits
+ return bits
end
local t={ 8,9,"a","b" }
function os.uuid()
- return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
- random(0xFFFF),random(0xFFFF),
- random(0x0FFF),
- t[ceil(random(4))] or 8,random(0x0FFF),
- random(0xFFFF),
- random(0xFFFF),random(0xFFFF),random(0xFFFF)
- )
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
end
local d
function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
- if delta then
- if d>0 then
- return format("+%02i:00",d)
- else
- return format("-%02i:00",-d)
- end
+ d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ if delta then
+ if d>0 then
+ return format("+%02i:00",d)
else
- return 1
+ return format("-%02i:00",-d)
end
+ else
+ return 1
+ end
end
local timeformat=format("%%s%s",os.timezone(true))
local dateformat="!%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.fulltime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=format(timeformat,date(dateformat))
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=format(timeformat,date(dateformat))
+ end
+ return lastdate
end
local dateformat="%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.localtime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=date(dateformat,t)
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=date(dateformat,t)
+ end
+ return lastdate
end
function os.converttime(t,default)
- local t=tonumber(t)
- if t and t>0 then
- return date(dateformat,t)
- else
- return default or "-"
- end
+ local t=tonumber(t)
+ if t and t>0 then
+ return date(dateformat,t)
+ else
+ return default or "-"
+ end
end
local memory={}
local function which(filename)
- local fullname=memory[filename]
- if fullname==nil then
- local suffix=file.suffix(filename)
- local suffixes=suffix=="" and os.binsuffixes or { suffix }
- for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
- local df=file.join(directory,filename)
- for i=1,#suffixes do
- local dfs=file.addsuffix(df,suffixes[i])
- if io.exists(dfs) then
- fullname=dfs
- break
- end
- end
- end
- if not fullname then
- fullname=false
+ local fullname=memory[filename]
+ if fullname==nil then
+ local suffix=file.suffix(filename)
+ local suffixes=suffix=="" and os.binsuffixes or { suffix }
+ for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local df=file.join(directory,filename)
+ for i=1,#suffixes do
+ local dfs=file.addsuffix(df,suffixes[i])
+ if io.exists(dfs) then
+ fullname=dfs
+ break
end
- memory[filename]=fullname
+ end
end
- return fullname
+ if not fullname then
+ fullname=false
+ end
+ memory[filename]=fullname
+ end
+ return fullname
end
os.which=which
os.where=which
function os.today()
- return date("!*t")
+ return date("!*t")
end
function os.now()
- return date("!%Y-%m-%d %H:%M:%S")
+ return date("!%Y-%m-%d %H:%M:%S")
end
if not os.sleep then
- local socket=socket
- function os.sleep(n)
- if not socket then
- socket=require("socket")
- end
- socket.sleep(n)
+ local socket=socket
+ function os.sleep(n)
+ if not socket then
+ socket=require("socket")
end
+ socket.sleep(n)
+ end
end
local function isleapyear(year)
- return (year%4==0) and (year%100~=0 or year%400==0)
+ return (year%4==0) and (year%100~=0 or year%400==0)
end
os.isleapyear=isleapyear
local days={ 31,28,31,30,31,30,31,31,30,31,30,31 }
local function nofdays(year,month)
- if not month then
- return isleapyear(year) and 365 or 364
- else
- return month==2 and isleapyear(year) and 29 or days[month]
- end
+ if not month then
+ return isleapyear(year) and 365 or 364
+ else
+ return month==2 and isleapyear(year) and 29 or days[month]
+ end
end
os.nofdays=nofdays
function os.weekday(day,month,year)
- return date("%w",time { year=year,month=month,day=day })+1
+ return date("%w",time { year=year,month=month,day=day })+1
end
function os.validdate(year,month,day)
- if month<1 then
- month=1
- elseif month>12 then
- month=12
- end
- if day<1 then
- day=1
- else
- local max=nofdays(year,month)
- if day>max then
- day=max
- end
- end
- return year,month,day
+ if month<1 then
+ month=1
+ elseif month>12 then
+ month=12
+ end
+ if day<1 then
+ day=1
+ else
+ local max=nofdays(year,month)
+ if day>max then
+ day=max
+ end
+ end
+ return year,month,day
end
local osexit=os.exit
local exitcode=nil
function os.setexitcode(code)
- exitcode=code
+ exitcode=code
end
function os.exit(c)
- if exitcode~=nil then
- return osexit(exitcode)
- end
- if c~=nil then
- return osexit(c)
- end
- return osexit()
+ if exitcode~=nil then
+ return osexit(exitcode)
+ end
+ if c~=nil then
+ return osexit(c)
+ end
+ return osexit()
end
@@ -4063,19 +4063,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-file"] = package.loaded["l-file"] or true
--- original size: 21804, stripped down to: 10461
+-- original size: 21804, stripped down to: 9980
if not modules then modules={} end modules ['l-file']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
file=file or {}
local file=file
if not lfs then
- lfs=optionalrequire("lfs")
+ lfs=optionalrequire("lfs")
end
local insert,concat=table.insert,table.concat
local match,find,gmatch=string.match,string.find,string.gmatch
@@ -4085,20 +4085,20 @@ local checkedsplit=string.checkedsplit
local P,R,S,C,Cs,Cp,Cc,Ct=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cp,lpeg.Cc,lpeg.Ct
local attributes=lfs.attributes
function lfs.isdir(name)
- return attributes(name,"mode")=="directory"
+ return attributes(name,"mode")=="directory"
end
function lfs.isfile(name)
- local a=attributes(name,"mode")
- return a=="file" or a=="link" or nil
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
end
function lfs.isfound(name)
- local a=attributes(name,"mode")
- return (a=="file" or a=="link") and name or nil
+ local a=attributes(name,"mode")
+ return (a=="file" or a=="link") and name or nil
end
if sandbox then
- sandbox.redefine(lfs.isfile,"lfs.isfile")
- sandbox.redefine(lfs.isdir,"lfs.isdir")
- sandbox.redefine(lfs.isfound,"lfs.isfound")
+ sandbox.redefine(lfs.isfile,"lfs.isfile")
+ sandbox.redefine(lfs.isdir,"lfs.isdir")
+ sandbox.redefine(lfs.isfound,"lfs.isfound")
end
local colon=P(":")
local period=P(".")
@@ -4112,27 +4112,27 @@ local name=noperiod^1
local suffix=period/""*(1-period-slashes)^1*-1
local pattern=C((1-(slashes^1*noslashes^1*-1))^1)*P(1)
local function pathpart(name,default)
- return name and lpegmatch(pattern,name) or default or ""
+ return name and lpegmatch(pattern,name) or default or ""
end
local pattern=(noslashes^0*slashes)^1*C(noslashes^1)*-1
local function basename(name)
- return name and lpegmatch(pattern,name) or name
+ return name and lpegmatch(pattern,name) or name
end
local pattern=(noslashes^0*slashes^1)^0*Cs((1-suffix)^1)*suffix^0
local function nameonly(name)
- return name and lpegmatch(pattern,name) or name
+ return name and lpegmatch(pattern,name) or name
end
local pattern=(noslashes^0*slashes)^0*(noperiod^1*period)^1*C(noperiod^1)*-1
local function suffixonly(name)
- return name and lpegmatch(pattern,name) or ""
+ return name and lpegmatch(pattern,name) or ""
end
local pattern=(noslashes^0*slashes)^0*noperiod^1*((period*C(noperiod^1))^1)*-1+Cc("")
local function suffixesonly(name)
- if name then
- return lpegmatch(pattern,name)
- else
- return ""
- end
+ if name then
+ return lpegmatch(pattern,name)
+ else
+ return ""
+ end
end
file.pathpart=pathpart
file.basename=basename
@@ -4141,7 +4141,7 @@ file.suffixonly=suffixonly
file.suffix=suffixonly
file.suffixesonly=suffixesonly
file.suffixes=suffixesonly
-file.dirname=pathpart
+file.dirname=pathpart
file.extname=suffixonly
local drive=C(R("az","AZ"))*colon
local path=C((noslashes^0*slashes)^0)
@@ -4157,142 +4157,142 @@ local pattern_b=path*base*suffix
local pattern_c=C(drive*path)*C(base*suffix)
local pattern_d=path*rest
function file.splitname(str,splitdrive)
- if not str then
- elseif splitdrive then
- return lpegmatch(pattern_a,str)
- else
- return lpegmatch(pattern_b,str)
- end
+ if not str then
+ elseif splitdrive then
+ return lpegmatch(pattern_a,str)
+ else
+ return lpegmatch(pattern_b,str)
+ end
end
function file.splitbase(str)
- if str then
- return lpegmatch(pattern_d,str)
- else
- return "",str
- end
+ if str then
+ return lpegmatch(pattern_d,str)
+ else
+ return "",str
+ end
end
function file.nametotable(str,splitdrive)
- if str then
- local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
- if splitdrive then
- return {
- path=path,
- drive=drive,
- subpath=subpath,
- name=name,
- base=base,
- suffix=suffix,
- }
- else
- return {
- path=path,
- name=name,
- base=base,
- suffix=suffix,
- }
- end
+ if str then
+ local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
+ if splitdrive then
+ return {
+ path=path,
+ drive=drive,
+ subpath=subpath,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
+ else
+ return {
+ path=path,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
end
+ end
end
local pattern=Cs(((period*(1-period-slashes)^1*-1)/""+1)^1)
function file.removesuffix(name)
- return name and lpegmatch(pattern,name)
+ return name and lpegmatch(pattern,name)
end
local suffix=period/""*(1-period-slashes)^1*-1
local pattern=Cs((noslashes^0*slashes^1)^0*((1-suffix)^1))*Cs(suffix)
function file.addsuffix(filename,suffix,criterium)
- if not filename or not suffix or suffix=="" then
- return filename
- elseif criterium==true then
- return filename.."."..suffix
- elseif not criterium then
- local n,s=lpegmatch(pattern,filename)
- if not s or s=="" then
- return filename.."."..suffix
- else
+ if not filename or not suffix or suffix=="" then
+ return filename
+ elseif criterium==true then
+ return filename.."."..suffix
+ elseif not criterium then
+ local n,s=lpegmatch(pattern,filename)
+ if not s or s=="" then
+ return filename.."."..suffix
+ else
+ return filename
+ end
+ else
+ local n,s=lpegmatch(pattern,filename)
+ if s and s~="" then
+ local t=type(criterium)
+ if t=="table" then
+ for i=1,#criterium do
+ if s==criterium[i] then
return filename
+ end
end
- else
- local n,s=lpegmatch(pattern,filename)
- if s and s~="" then
- local t=type(criterium)
- if t=="table" then
- for i=1,#criterium do
- if s==criterium[i] then
- return filename
- end
- end
- elseif t=="string" then
- if s==criterium then
- return filename
- end
- end
+ elseif t=="string" then
+ if s==criterium then
+ return filename
end
- return (n or filename).."."..suffix
+ end
end
+ return (n or filename).."."..suffix
+ end
end
local suffix=period*(1-period-slashes)^1*-1
local pattern=Cs((1-suffix)^0)
function file.replacesuffix(name,suffix)
- if name and suffix and suffix~="" then
- return lpegmatch(pattern,name).."."..suffix
- else
- return name
- end
+ if name and suffix and suffix~="" then
+ return lpegmatch(pattern,name).."."..suffix
+ else
+ return name
+ end
end
local reslasher=lpeg.replacer(P("\\"),"/")
function file.reslash(str)
- return str and lpegmatch(reslasher,str)
+ return str and lpegmatch(reslasher,str)
end
function file.is_writable(name)
- if not name then
- elseif lfs.isdir(name) then
- name=name.."/m_t_x_t_e_s_t.tmp"
- local f=io.open(name,"wb")
- if f then
- f:close()
- os.remove(name)
- return true
- end
- elseif lfs.isfile(name) then
- local f=io.open(name,"ab")
- if f then
- f:close()
- return true
- end
- else
- local f=io.open(name,"ab")
- if f then
- f:close()
- os.remove(name)
- return true
- end
+ if not name then
+ elseif lfs.isdir(name) then
+ name=name.."/m_t_x_t_e_s_t.tmp"
+ local f=io.open(name,"wb")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
end
- return false
+ elseif lfs.isfile(name) then
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ return true
+ end
+ else
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ end
+ return false
end
local readable=P("r")*Cc(true)
function file.is_readable(name)
- if name then
- local a=attributes(name)
- return a and lpegmatch(readable,a.permissions) or false
- else
- return false
- end
+ if name then
+ local a=attributes(name)
+ return a and lpegmatch(readable,a.permissions) or false
+ else
+ return false
+ end
end
file.isreadable=file.is_readable
file.iswritable=file.is_writable
function file.size(name)
- if name then
- local a=attributes(name)
- return a and a.size or 0
- else
- return 0
- end
+ if name then
+ local a=attributes(name)
+ return a and a.size or 0
+ else
+ return 0
+ end
end
function file.splitpath(str,separator)
- return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
+ return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
end
function file.joinpath(tab,separator)
- return tab and concat(tab,separator or io.pathseparator)
+ return tab and concat(tab,separator or io.pathseparator)
end
local someslash=S("\\/")
local stripper=Cs(P(fwslash)^0/""*reslasher)
@@ -4302,30 +4302,30 @@ local hasroot=fwslash^1
local reslasher=lpeg.replacer(S("\\/"),"/")
local deslasher=lpeg.replacer(S("\\/")^1,"/")
function file.join(one,two,three,...)
- if not two then
- return one=="" and one or lpegmatch(reslasher,one)
- end
- if one=="" then
- return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
- end
- if lpegmatch(isnetwork,one) then
- local one=lpegmatch(reslasher,one)
- local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
- if lpegmatch(hasroot,two) then
- return one..two
- else
- return one.."/"..two
- end
- elseif lpegmatch(isroot,one) then
- local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
- if lpegmatch(hasroot,two) then
- return two
- else
- return "/"..two
- end
- else
- return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
- end
+ if not two then
+ return one=="" and one or lpegmatch(reslasher,one)
+ end
+ if one=="" then
+ return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
+ end
+ if lpegmatch(isnetwork,one) then
+ local one=lpegmatch(reslasher,one)
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return one..two
+ else
+ return one.."/"..two
+ end
+ elseif lpegmatch(isroot,one) then
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return two
+ else
+ return "/"..two
+ end
+ else
+ return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+ end
end
local drivespec=R("az","AZ")^1*colon
local anchors=fwslash+drivespec
@@ -4335,56 +4335,56 @@ local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//")
local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
local absolute=fwslash
function file.collapsepath(str,anchor)
- if not str then
- return
- end
- if anchor==true and not lpegmatch(anchors,str) then
- str=getcurrentdir().."/"..str
- end
- if str=="" or str=="." then
- return "."
- elseif lpegmatch(untouched,str) then
- return lpegmatch(reslasher,str)
- end
- local starter,oldelements=lpegmatch(splitstarter,str)
- local newelements={}
- local i=#oldelements
- while i>0 do
- local element=oldelements[i]
- if element=='.' then
- elseif element=='..' then
- local n=i-1
- while n>0 do
- local element=oldelements[n]
- if element~='..' and element~='.' then
- oldelements[n]='.'
- break
- else
- n=n-1
- end
- end
- if n<1 then
- insert(newelements,1,'..')
- end
- elseif element~="" then
- insert(newelements,1,element)
- end
- i=i-1
- end
- if #newelements==0 then
- return starter or "."
- elseif starter then
- return starter..concat(newelements,'/')
- elseif lpegmatch(absolute,str) then
- return "/"..concat(newelements,'/')
- else
- newelements=concat(newelements,'/')
- if anchor=="." and find(str,"^%./") then
- return "./"..newelements
+ if not str then
+ return
+ end
+ if anchor==true and not lpegmatch(anchors,str) then
+ str=getcurrentdir().."/"..str
+ end
+ if str=="" or str=="." then
+ return "."
+ elseif lpegmatch(untouched,str) then
+ return lpegmatch(reslasher,str)
+ end
+ local starter,oldelements=lpegmatch(splitstarter,str)
+ local newelements={}
+ local i=#oldelements
+ while i>0 do
+ local element=oldelements[i]
+ if element=='.' then
+ elseif element=='..' then
+ local n=i-1
+ while n>0 do
+ local element=oldelements[n]
+ if element~='..' and element~='.' then
+ oldelements[n]='.'
+ break
else
- return newelements
+ n=n-1
end
- end
+ end
+ if n<1 then
+ insert(newelements,1,'..')
+ end
+ elseif element~="" then
+ insert(newelements,1,element)
+ end
+ i=i-1
+ end
+ if #newelements==0 then
+ return starter or "."
+ elseif starter then
+ return starter..concat(newelements,'/')
+ elseif lpegmatch(absolute,str) then
+ return "/"..concat(newelements,'/')
+ else
+ newelements=concat(newelements,'/')
+ if anchor=="." and find(str,"^%./") then
+ return "./"..newelements
+ else
+ return newelements
+ end
+ end
end
local validchars=R("az","09","AZ","--","..")
local pattern_a=lpeg.replacer(1-validchars)
@@ -4392,26 +4392,26 @@ local pattern_a=Cs((validchars+P(1)/"-")^1)
local whatever=P("-")^0/""
local pattern_b=Cs(whatever*(1-whatever*-1)^1)
function file.robustname(str,strict)
- if str then
- str=lpegmatch(pattern_a,str) or str
- if strict then
- return lpegmatch(pattern_b,str) or str
- else
- return str
- end
+ if str then
+ str=lpegmatch(pattern_a,str) or str
+ if strict then
+ return lpegmatch(pattern_b,str) or str
+ else
+ return str
end
+ end
end
local loaddata=io.loaddata
local savedata=io.savedata
file.readdata=loaddata
file.savedata=savedata
function file.copy(oldname,newname)
- if oldname and newname then
- local data=loaddata(oldname)
- if data and data~="" then
- savedata(newname,data)
- end
+ if oldname and newname then
+ local data=loaddata(oldname)
+ if data and data~="" then
+ savedata(newname,data)
end
+ end
end
local letter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -4420,44 +4420,44 @@ local rootbased=fwslash+letter*colon
lpeg.patterns.qualified=qualified
lpeg.patterns.rootbased=rootbased
function file.is_qualified_path(filename)
- return filename and lpegmatch(qualified,filename)~=nil
+ return filename and lpegmatch(qualified,filename)~=nil
end
function file.is_rootbased_path(filename)
- return filename and lpegmatch(rootbased,filename)~=nil
+ return filename and lpegmatch(rootbased,filename)~=nil
end
function file.strip(name,dir)
- if name then
- local b,a=match(name,"^(.-)"..dir.."(.*)$")
- return a~="" and a or name
- end
+ if name then
+ local b,a=match(name,"^(.-)"..dir.."(.*)$")
+ return a~="" and a or name
+ end
end
function lfs.mkdirs(path)
- local full=""
- for sub in gmatch(path,"(/*[^\\/]+)") do
- full=full..sub
- lfs.mkdir(full)
- end
+ local full=""
+ for sub in gmatch(path,"(/*[^\\/]+)") do
+ full=full..sub
+ lfs.mkdir(full)
+ end
end
function file.withinbase(path)
- local l=0
- if not find(path,"^/") then
- path="/"..path
- end
- for dir in gmatch(path,"/([^/]+)") do
- if dir==".." then
- l=l-1
- elseif dir~="." then
- l=l+1
- end
- if l<0 then
- return false
- end
- end
- return true
+ local l=0
+ if not find(path,"^/") then
+ path="/"..path
+ end
+ for dir in gmatch(path,"/([^/]+)") do
+ if dir==".." then
+ l=l-1
+ elseif dir~="." then
+ l=l+1
+ end
+ if l<0 then
+ return false
+ end
+ end
+ return true
end
local symlinkattributes=lfs.symlinkattributes
function lfs.readlink(name)
- return symlinkattributes(name,"target") or nil
+ return symlinkattributes(name,"target") or nil
end
@@ -4467,51 +4467,51 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-gzip"] = package.loaded["l-gzip"] or true
--- original size: 1211, stripped down to: 1002
+-- original size: 1211, stripped down to: 951
if not modules then modules={} end modules ['l-gzip']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not gzip then
- return
+ return
end
local suffix,suffixes=file.suffix,file.suffixes
function gzip.load(filename)
- local f=io.open(filename,"rb")
- if not f then
- elseif suffix(filename)=="gz" then
- f:close()
- local g=gzip.open(filename,"rb")
- if g then
- local str=g:read("*all")
- g:close()
- return str
- end
- else
- local str=f:read("*all")
- f:close()
- return str
- end
+ local f=io.open(filename,"rb")
+ if not f then
+ elseif suffix(filename)=="gz" then
+ f:close()
+ local g=gzip.open(filename,"rb")
+ if g then
+ local str=g:read("*all")
+ g:close()
+ return str
+ end
+ else
+ local str=f:read("*all")
+ f:close()
+ return str
+ end
end
function gzip.save(filename,data)
- if suffix(filename)~="gz" then
- filename=filename..".gz"
- end
- local f=io.open(filename,"wb")
- if f then
- local s=zlib.compress(data or "",9,nil,15+16)
- f:write(s)
- f:close()
- return #s
- end
+ if suffix(filename)~="gz" then
+ filename=filename..".gz"
+ end
+ local f=io.open(filename,"wb")
+ if f then
+ local s=zlib.compress(data or "",9,nil,15+16)
+ f:write(s)
+ f:close()
+ return #s
+ end
end
function gzip.suffix(filename)
- local suffix,extra=suffixes(filename)
- local gzipped=extra=="gz"
- return suffix,gzipped
+ local suffix,extra=suffixes(filename)
+ local gzipped=extra=="gz"
+ return suffix,gzipped
end
@@ -4521,87 +4521,87 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-md5"] = package.loaded["l-md5"] or true
--- original size: 3309, stripped down to: 2314
+-- original size: 3309, stripped down to: 2218
if not modules then modules={} end modules ['l-md5']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not md5 then
- md5=optionalrequire("md5")
+ md5=optionalrequire("md5")
end
if not md5 then
- md5={
- sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
- sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
- }
+ md5={
+ sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
+ sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
+ }
end
local md5,file=md5,file
local gsub=string.gsub
do
- local patterns=lpeg and lpeg.patterns
- if patterns then
- local bytestoHEX=patterns.bytestoHEX
- local bytestohex=patterns.bytestohex
- local bytestodec=patterns.bytestodec
- local lpegmatch=lpeg.match
- local md5sum=md5.sum
- if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
- if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
- if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
- md5.sumhexa=md5.hex
- md5.sumHEXA=md5.HEX
- end
+ local patterns=lpeg and lpeg.patterns
+ if patterns then
+ local bytestoHEX=patterns.bytestoHEX
+ local bytestohex=patterns.bytestohex
+ local bytestodec=patterns.bytestodec
+ local lpegmatch=lpeg.match
+ local md5sum=md5.sum
+ if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
+ if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
+ if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
+ md5.sumhexa=md5.hex
+ md5.sumHEXA=md5.HEX
+ end
end
function file.needsupdating(oldname,newname,threshold)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime then
- local newtime=lfs.attributes(newname,"modification")
- if not newtime then
- return true
- elseif newtime>=oldtime then
- return false
- elseif oldtime-newtime<(threshold or 1) then
- return false
- else
- return true
- end
- else
- return false
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime then
+ local newtime=lfs.attributes(newname,"modification")
+ if not newtime then
+ return true
+ elseif newtime>=oldtime then
+ return false
+ elseif oldtime-newtime<(threshold or 1) then
+ return false
+ else
+ return true
+ end
+ else
+ return false
+ end
end
file.needs_updating=file.needsupdating
function file.syncmtimes(oldname,newname)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime and lfs.isfile(newname) then
- lfs.touch(newname,oldtime,oldtime)
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime and lfs.isfile(newname) then
+ lfs.touch(newname,oldtime,oldtime)
+ end
end
function file.checksum(name)
- if md5 then
- local data=io.loaddata(name)
- if data then
- return md5.HEX(data)
- end
+ if md5 then
+ local data=io.loaddata(name)
+ if data then
+ return md5.HEX(data)
end
- return nil
+ end
+ return nil
end
function file.loadchecksum(name)
- if md5 then
- local data=io.loaddata(name..".md5")
- return data and (gsub(data,"%s",""))
- end
- return nil
+ if md5 then
+ local data=io.loaddata(name..".md5")
+ return data and (gsub(data,"%s",""))
+ end
+ return nil
end
function file.savechecksum(name,checksum)
- if not checksum then checksum=file.checksum(name) end
- if checksum then
- io.savedata(name..".md5",checksum)
- return checksum
- end
- return nil
+ if not checksum then checksum=file.checksum(name) end
+ if checksum then
+ io.savedata(name..".md5",checksum)
+ return checksum
+ end
+ return nil
end
@@ -4611,29 +4611,29 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-sha"] = package.loaded["l-sha"] or true
--- original size: 1085, stripped down to: 987
+-- original size: 1085, stripped down to: 969
if not modules then modules={} end modules ['l-sha']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if sha2 then
- local lpegmatch=lpeg.match
- local lpegpatterns=lpeg.patterns
- local bytestohex=lpegpatterns.bytestohex
- local bytestoHEX=lpegpatterns.bytestoHEX
- local digest256=sha2.digest256
- local digest384=sha2.digest384
- local digest512=sha2.digest512
- sha2.hash256=function(str) return lpegmatch(bytestohex,digest256(str)) end
- sha2.hash384=function(str) return lpegmatch(bytestohex,digest384(str)) end
- sha2.hash512=function(str) return lpegmatch(bytestohex,digest512(str)) end
- sha2.HASH256=function(str) return lpegmatch(bytestoHEX,digest256(str)) end
- sha2.HASH384=function(str) return lpegmatch(bytestoHEX,digest384(str)) end
- sha2.HASH512=function(str) return lpegmatch(bytestoHEX,digest512(str)) end
+ local lpegmatch=lpeg.match
+ local lpegpatterns=lpeg.patterns
+ local bytestohex=lpegpatterns.bytestohex
+ local bytestoHEX=lpegpatterns.bytestoHEX
+ local digest256=sha2.digest256
+ local digest384=sha2.digest384
+ local digest512=sha2.digest512
+ sha2.hash256=function(str) return lpegmatch(bytestohex,digest256(str)) end
+ sha2.hash384=function(str) return lpegmatch(bytestohex,digest384(str)) end
+ sha2.hash512=function(str) return lpegmatch(bytestohex,digest512(str)) end
+ sha2.HASH256=function(str) return lpegmatch(bytestoHEX,digest256(str)) end
+ sha2.HASH384=function(str) return lpegmatch(bytestoHEX,digest384(str)) end
+ sha2.HASH512=function(str) return lpegmatch(bytestoHEX,digest512(str)) end
end
@@ -4643,14 +4643,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-url"] = package.loaded["l-url"] or true
--- original size: 14755, stripped down to: 7236
+-- original size: 14755, stripped down to: 6981
if not modules then modules={} end modules ['l-url']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local char,format,byte=string.char,string.format,string.byte
local concat=table.concat
@@ -4663,14 +4663,14 @@ local url=url
local unescapes={}
local escapes={}
setmetatable(unescapes,{ __index=function(t,k)
- local v=char(tonumber(k,16))
- t[k]=v
- return v
+ local v=char(tonumber(k,16))
+ t[k]=v
+ return v
end })
setmetatable(escapes,{ __index=function(t,k)
- local v=format("%%%02X",byte(k))
- t[k]=v
- return v
+ local v=format("%%%02X",byte(k))
+ t[k]=v
+ return v
end })
local colon=P(":")
local qmark=P("?")
@@ -4689,21 +4689,21 @@ local escaped=(plus/" ")+escapedchar
local noslash=P("/")/""
local plustospace=P("+")/" "
local decoder=Cs((
- plustospace+escapedchar+P("\r\n")/"\n"+P(1)
- )^0 )
+ plustospace+escapedchar+P("\r\n")/"\n"+P(1)
+ )^0 )
local encoder=Cs((
- R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
- )^0 )
+ R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
+ )^0 )
lpegpatterns.urldecoder=decoder
lpegpatterns.urlencoder=encoder
-function url.decode (str) return str and lpegmatch(decoder,str) or str end
-function url.encode (str) return str and lpegmatch(encoder,str) or str end
+function url.decode (str) return str and lpegmatch(decoder,str) or str end
+function url.encode (str) return str and lpegmatch(encoder,str) or str end
function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2)
local authoritystr=Cs((escaped+(1- slash-qmark-hash))^0)
-local pathstr=Cs((escaped+(1- qmark-hash))^0)
-local querystr=Cs(((1- hash))^0)
-local fragmentstr=Cs((escaped+(1- endofstring))^0)
+local pathstr=Cs((escaped+(1- qmark-hash))^0)
+local querystr=Cs(((1- hash))^0)
+local fragmentstr=Cs((escaped+(1- endofstring))^0)
local scheme=schemestr*colon+nothing
local authority=slash*slash*authoritystr+nothing
local path=slash*pathstr+nothing
@@ -4721,19 +4721,19 @@ lpegpatterns.urlescaper=escaper
lpegpatterns.urlunescaper=unescaper
lpegpatterns.urlgetcleaner=getcleaner
function url.unescapeget(str)
- return lpegmatch(getcleaner,str)
+ return lpegmatch(getcleaner,str)
end
local function split(str)
- return (type(str)=="string" and lpegmatch(parser,str)) or str
+ return (type(str)=="string" and lpegmatch(parser,str)) or str
end
local isscheme=schemestr*colon*slash*slash
local function hasscheme(str)
- if str then
- local scheme=lpegmatch(isscheme,str)
- return scheme~="" and scheme or false
- else
- return false
- end
+ if str then
+ local scheme=lpegmatch(isscheme,str)
+ return scheme~="" and scheme or false
+ else
+ return false
+ end
end
local rootletter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -4743,161 +4743,161 @@ local barswapper=replacer("|",":")
local backslashswapper=replacer("\\","/")
local equal=P("=")
local amp=P("&")
-local key=Cs(((plustospace+escapedchar+1)-equal )^0)
+local key=Cs(((plustospace+escapedchar+1)-equal )^0)
local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0)
local splitquery=Cf (Ct("")*P { "sequence",
- sequence=V("pair")*(amp*V("pair"))^0,
- pair=Cg(key*equal*value),
+ sequence=V("pair")*(amp*V("pair"))^0,
+ pair=Cg(key*equal*value),
},rawset)
local userpart=(1-atsign-colon)^1
local serverpart=(1-colon)^1
local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil))
local function hashed(str)
- if not str or str=="" then
- return {
- scheme="invalid",
- original=str,
- }
- end
- local detailed=split(str)
- local rawscheme=""
- local rawquery=""
- local somescheme=false
- local somequery=false
- if detailed then
- rawscheme=detailed[1]
- rawquery=detailed[4]
- somescheme=rawscheme~=""
- somequery=rawquery~=""
- end
- if not somescheme and not somequery then
- return {
- scheme="file",
- authority="",
- path=str,
- query="",
- fragment="",
- original=str,
- noscheme=true,
- filename=str,
- }
- end
- local authority=detailed[2]
- local path=detailed[3]
- local filename
- local username
- local password
- local host
- local port
- if authority~="" then
- username,password,host,port=lpegmatch(splitauthority,authority)
- end
- if authority=="" then
- filename=path
- elseif path=="" then
- filename=""
- else
- filename=authority.."/"..path
- end
+ if not str or str=="" then
return {
- scheme=rawscheme,
- authority=authority,
- path=path,
- query=lpegmatch(unescaper,rawquery),
- queries=lpegmatch(splitquery,rawquery),
- fragment=detailed[5],
- original=str,
- noscheme=false,
- filename=filename,
- host=host,
- port=port,
+ scheme="invalid",
+ original=str,
+ }
+ end
+ local detailed=split(str)
+ local rawscheme=""
+ local rawquery=""
+ local somescheme=false
+ local somequery=false
+ if detailed then
+ rawscheme=detailed[1]
+ rawquery=detailed[4]
+ somescheme=rawscheme~=""
+ somequery=rawquery~=""
+ end
+ if not somescheme and not somequery then
+ return {
+ scheme="file",
+ authority="",
+ path=str,
+ query="",
+ fragment="",
+ original=str,
+ noscheme=true,
+ filename=str,
}
+ end
+ local authority=detailed[2]
+ local path=detailed[3]
+ local filename
+ local username
+ local password
+ local host
+ local port
+ if authority~="" then
+ username,password,host,port=lpegmatch(splitauthority,authority)
+ end
+ if authority=="" then
+ filename=path
+ elseif path=="" then
+ filename=""
+ else
+ filename=authority.."/"..path
+ end
+ return {
+ scheme=rawscheme,
+ authority=authority,
+ path=path,
+ query=lpegmatch(unescaper,rawquery),
+ queries=lpegmatch(splitquery,rawquery),
+ fragment=detailed[5],
+ original=str,
+ noscheme=false,
+ filename=filename,
+ host=host,
+ port=port,
+ }
end
url.split=split
url.hasscheme=hasscheme
url.hashed=hashed
function url.addscheme(str,scheme)
- if hasscheme(str) then
- return str
- elseif not scheme then
- return "file:///"..str
- else
- return scheme..":///"..str
- end
+ if hasscheme(str) then
+ return str
+ elseif not scheme then
+ return "file:///"..str
+ else
+ return scheme..":///"..str
+ end
end
function url.construct(hash)
- local result,r={},0
- local scheme=hash.scheme
- local authority=hash.authority
- local path=hash.path
- local queries=hash.queries
- local fragment=hash.fragment
- if scheme and scheme~="" then
- r=r+1;result[r]=lpegmatch(escaper,scheme)
- r=r+1;result[r]="://"
- end
- if authority and authority~="" then
- r=r+1;result[r]=lpegmatch(escaper,authority)
- end
- if path and path~="" then
- r=r+1;result[r]="/"
- r=r+1;result[r]=lpegmatch(escaper,path)
- end
- if queries then
- local done=false
- for k,v in sortedhash(queries) do
- r=r+1;result[r]=done and "&" or "?"
- r=r+1;result[r]=lpegmatch(escaper,k)
- r=r+1;result[r]="="
- r=r+1;result[r]=lpegmatch(escaper,v)
- done=true
- end
- end
- if fragment and fragment~="" then
- r=r+1;result[r]="#"
- r=r+1;result[r]=lpegmatch(escaper,fragment)
- end
- return concat(result)
+ local result,r={},0
+ local scheme=hash.scheme
+ local authority=hash.authority
+ local path=hash.path
+ local queries=hash.queries
+ local fragment=hash.fragment
+ if scheme and scheme~="" then
+ r=r+1;result[r]=lpegmatch(escaper,scheme)
+ r=r+1;result[r]="://"
+ end
+ if authority and authority~="" then
+ r=r+1;result[r]=lpegmatch(escaper,authority)
+ end
+ if path and path~="" then
+ r=r+1;result[r]="/"
+ r=r+1;result[r]=lpegmatch(escaper,path)
+ end
+ if queries then
+ local done=false
+ for k,v in sortedhash(queries) do
+ r=r+1;result[r]=done and "&" or "?"
+ r=r+1;result[r]=lpegmatch(escaper,k)
+ r=r+1;result[r]="="
+ r=r+1;result[r]=lpegmatch(escaper,v)
+ done=true
+ end
+ end
+ if fragment and fragment~="" then
+ r=r+1;result[r]="#"
+ r=r+1;result[r]=lpegmatch(escaper,fragment)
+ end
+ return concat(result)
end
local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0)
function url.filename(filename)
- local spec=hashed(filename)
- local path=spec.path
- return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
+ local spec=hashed(filename)
+ local path=spec.path
+ return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
end
local function escapestring(str)
- return lpegmatch(escaper,str)
+ return lpegmatch(escaper,str)
end
url.escape=escapestring
function url.query(str)
- if type(str)=="string" then
- return lpegmatch(splitquery,str) or ""
- else
- return str
- end
+ if type(str)=="string" then
+ return lpegmatch(splitquery,str) or ""
+ else
+ return str
+ end
end
function url.toquery(data)
- local td=type(data)
- if td=="string" then
- return #str and escape(data) or nil
- elseif td=="table" then
- if next(data) then
- local t={}
- for k,v in next,data do
- t[#t+1]=format("%s=%s",k,escapestring(v))
- end
- return concat(t,"&")
- end
- else
+ local td=type(data)
+ if td=="string" then
+ return #str and escape(data) or nil
+ elseif td=="table" then
+ if next(data) then
+ local t={}
+ for k,v in next,data do
+ t[#t+1]=format("%s=%s",k,escapestring(v))
+ end
+ return concat(t,"&")
end
+ else
+ end
end
local pattern=Cs(noslash^0*(1-noslash*P(-1))^0)
function url.barepath(path)
- if not path or path=="" then
- return ""
- else
- return lpegmatch(pattern,path)
- end
+ if not path or path=="" then
+ return ""
+ else
+ return lpegmatch(pattern,path)
+ end
end
@@ -4907,14 +4907,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-dir"] = package.loaded["l-dir"] or true
--- original size: 18002, stripped down to: 11863
+-- original size: 18002, stripped down to: 10681
if not modules then modules={} end modules ['l-dir']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,select=type,select
local find,gmatch,match,gsub,sub=string.find,string.gmatch,string.match,string.gsub,string.sub
@@ -4926,478 +4926,478 @@ local dir=dir
local lfs=lfs
local attributes=lfs.attributes
local walkdir=lfs.dir
-local isdir=lfs.isdir
+local isdir=lfs.isdir
local isfile=lfs.isfile
local currentdir=lfs.currentdir
local chdir=lfs.chdir
local mkdir=lfs.mkdir
local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true)
if onwindows then
- local tricky=S("/\\")*P(-1)
- isdir=function(name)
- if lpegmatch(tricky,name) then
- return attributes(name,"mode")=="directory"
- else
- return attributes(name.."/.","mode")=="directory"
- end
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ local tricky=S("/\\")*P(-1)
+ isdir=function(name)
+ if lpegmatch(tricky,name) then
+ return attributes(name,"mode")=="directory"
+ else
+ return attributes(name.."/.","mode")=="directory"
+ end
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
else
- isdir=function(name)
- return attributes(name,"mode")=="directory"
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ isdir=function(name)
+ return attributes(name,"mode")=="directory"
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
end
function dir.current()
- return (gsub(currentdir(),"\\","/"))
+ return (gsub(currentdir(),"\\","/"))
end
local function glob_pattern_function(path,patt,recurse,action)
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- local nofdirs=0
- for name in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- action(full)
- end
- elseif recurse and mode=="directory" then
- if dirs then
- nofdirs=nofdirs+1
- dirs[nofdirs]=full
- else
- nofdirs=1
- dirs={ full }
- end
- end
- end
- end
- if dirs then
- for i=1,nofdirs do
- glob_pattern_function(dirs[i],patt,recurse,action)
- end
- end
- end
-end
-local function glob_pattern_table(path,patt,recurse,result)
- if not result then
- result={}
- end
+ if isdir(path) then
local usedpath
if path=="/" then
- usedpath="/."
+ usedpath="/."
elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
+ usedpath=path.."/."
+ path=path.."/"
else
- usedpath=path
+ usedpath=path
end
local dirs
local nofdirs=0
- local noffiles=#result
- for name,a in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- noffiles=noffiles+1
- result[noffiles]=full
- end
- elseif recurse and mode=="directory" then
- if dirs then
- nofdirs=nofdirs+1
- dirs[nofdirs]=full
- else
- nofdirs=1
- dirs={ full }
- end
- end
+ for name in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ action(full)
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
end
+ end
end
if dirs then
- for i=1,nofdirs do
- glob_pattern_table(dirs[i],patt,recurse,result)
- end
+ for i=1,nofdirs do
+ glob_pattern_function(dirs[i],patt,recurse,action)
+ end
end
- return result
+ end
end
-local function globpattern(path,patt,recurse,method)
- local kind=type(method)
- if patt and sub(patt,1,-3)==path then
- patt=false
+local function glob_pattern_table(path,patt,recurse,result)
+ if not result then
+ result={}
+ end
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ local noffiles=#result
+ for name,a in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ noffiles=noffiles+1
+ result[noffiles]=full
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
+ end
end
- local okay=isdir(path)
- if kind=="function" then
- return okay and glob_pattern_function(path,patt,recurse,method) or {}
- elseif kind=="table" then
- return okay and glob_pattern_table(path,patt,recurse,method) or method
- else
- return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_table(dirs[i],patt,recurse,result)
end
+ end
+ return result
+end
+local function globpattern(path,patt,recurse,method)
+ local kind=type(method)
+ if patt and sub(patt,1,-3)==path then
+ patt=false
+ end
+ local okay=isdir(path)
+ if kind=="function" then
+ return okay and glob_pattern_function(path,patt,recurse,method) or {}
+ elseif kind=="table" then
+ return okay and glob_pattern_table(path,patt,recurse,method) or method
+ else
+ return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
end
dir.globpattern=globpattern
local function collectpattern(path,patt,recurse,result)
- local ok,scanner
- result=result or {}
- if path=="/" then
- ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
- else
- ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
- end
- if ok and type(scanner)=="function" then
- if not find(path,"/$") then
- path=path..'/'
- end
- for name in scanner,first do
- if name=="." then
- elseif name==".." then
- else
- local full=path..name
- local attr=attributes(full)
- local mode=attr.mode
- if mode=='file' then
- if find(full,patt) then
- result[name]=attr
- end
- elseif recurse and mode=="directory" then
- attr.list=collectpattern(full,patt,recurse)
- result[name]=attr
- end
- end
+ local ok,scanner
+ result=result or {}
+ if path=="/" then
+ ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
+ else
+ ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
+ end
+ if ok and type(scanner)=="function" then
+ if not find(path,"/$") then
+ path=path..'/'
+ end
+ for name in scanner,first do
+ if name=="." then
+ elseif name==".." then
+ else
+ local full=path..name
+ local attr=attributes(full)
+ local mode=attr.mode
+ if mode=='file' then
+ if find(full,patt) then
+ result[name]=attr
+ end
+ elseif recurse and mode=="directory" then
+ attr.list=collectpattern(full,patt,recurse)
+ result[name]=attr
end
+ end
end
- return result
+ end
+ return result
end
dir.collectpattern=collectpattern
local separator,pattern
if onwindows then
- local slash=S("/\\")/"/"
- pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
- }
+ local slash=S("/\\")/"/"
+ pattern={
+ [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
+ [3]=Cs(P(1)^0)
+ }
else
- pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
- }
+ pattern={
+ [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ [2]=C(((1-S("*?/"))^0*P("/"))^0),
+ [3]=C(P(1)^0)
+ }
end
local filter=Cs ((
- P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
+ P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
)^0 )
local function glob(str,t)
- if type(t)=="function" then
- if type(str)=="table" then
- for s=1,#str do
- glob(str[s],t)
- end
- elseif isfile(str) then
- t(str)
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- globpattern(start,result,recurse,t)
- end
- end
+ if type(t)=="function" then
+ if type(str)=="table" then
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ elseif isfile(str) then
+ t(str)
+ else
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ globpattern(start,result,recurse,t)
+ end
+ end
+ else
+ if type(str)=="table" then
+ local t=t or {}
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ return t
+ elseif isfile(str) then
+ if t then
+ t[#t+1]=str
+ return t
+ else
+ return { str }
+ end
else
- if type(str)=="table" then
- local t=t or {}
- for s=1,#str do
- glob(str[s],t)
- end
- return t
- elseif isfile(str) then
- if t then
- t[#t+1]=str
- return t
- else
- return { str }
- end
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- return globpattern(start,result,recurse,t)
- else
- return {}
- end
- end
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ return globpattern(start,result,recurse,t)
+ else
+ return {}
+ end
end
+ end
end
dir.glob=glob
local function globfiles(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if recurse then
- globfiles(path.."/"..name,recurse,func,files)
- end
- elseif mode=="file" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if recurse then
+ globfiles(path.."/"..name,recurse,func,files)
+ end
+ elseif mode=="file" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
end
+ end
end
- return files
+ end
+ return files
end
dir.globfiles=globfiles
local function globdirs(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- if recurse then
- globdirs(path.."/"..name,recurse,func,files)
- end
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
+ if recurse then
+ globdirs(path.."/"..name,recurse,func,files)
+ end
end
+ end
end
- return files
+ end
+ return files
end
dir.globdirs=globdirs
function dir.ls(pattern)
- return concat(glob(pattern),"\n")
+ return concat(glob(pattern),"\n")
end
local make_indeed=true
if onwindows then
- function dir.mkdirs(...)
- local n=select("#",...)
- local str
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s=="" then
+ elseif str=="" then
+ str=s
else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s=="" then
- elseif str=="" then
- str=s
- else
- str=str.."/"..s
- end
- end
+ str=str.."/"..s
end
- local pth=""
- local drive=false
- local first,middle,last=match(str,"^(//)(//*)(.*)$")
- if first then
+ end
+ end
+ local pth=""
+ local drive=false
+ local first,middle,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ else
+ first,last=match(str,"^(//)/*(.-)$")
+ if first then
+ middle,last=match(str,"([^/]+)/+(.-)$")
+ if middle then
+ pth="//"..middle
else
- first,last=match(str,"^(//)/*(.-)$")
- if first then
- middle,last=match(str,"([^/]+)/+(.-)$")
- if middle then
- pth="//"..middle
- else
- pth="//"..last
- last=""
- end
- else
- first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
- if first then
- pth,drive=first..middle,true
- else
- middle,last=match(str,"^(/*)(.-)$")
- if not middle then
- last=str
- end
- end
- end
+ pth="//"..last
+ last=""
end
- for s in gmatch(last,"[^/]+") do
- if pth=="" then
- pth=s
- elseif drive then
- pth,drive=pth..s,false
- else
- pth=pth.."/"..s
- end
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
+ else
+ first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
+ if first then
+ pth,drive=first..middle,true
+ else
+ middle,last=match(str,"^(/*)(.-)$")
+ if not middle then
+ last=str
+ end
end
- return pth,(isdir(pth)==true)
+ end
end
+ for s in gmatch(last,"[^/]+") do
+ if pth=="" then
+ pth=s
+ elseif drive then
+ pth,drive=pth..s,false
+ else
+ pth=pth.."/"..s
+ end
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ return pth,(isdir(pth)==true)
+ end
else
- function dir.mkdirs(...)
- local n=select("#",...)
- local str,pth
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
- else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s and s~="" then
- if str~="" then
- str=str.."/"..s
- else
- str=s
- end
- end
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str,pth
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s and s~="" then
+ if str~="" then
+ str=str.."/"..s
+ else
+ str=s
+ end
end
- str=gsub(str,"/+","/")
- if find(str,"^/") then
- pth="/"
- for s in gmatch(str,"[^/]+") do
- local first=(pth=="/")
- if first then
- pth=pth..s
- else
- pth=pth.."/"..s
- end
- if make_indeed and not first and not isdir(pth) then
- mkdir(pth)
- end
- end
+ end
+ end
+ str=gsub(str,"/+","/")
+ if find(str,"^/") then
+ pth="/"
+ for s in gmatch(str,"[^/]+") do
+ local first=(pth=="/")
+ if first then
+ pth=pth..s
else
- pth="."
- for s in gmatch(str,"[^/]+") do
- pth=pth.."/"..s
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
- end
+ pth=pth.."/"..s
+ end
+ if make_indeed and not first and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ else
+ pth="."
+ for s in gmatch(str,"[^/]+") do
+ pth=pth.."/"..s
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
end
- return pth,(isdir(pth)==true)
+ end
end
+ return pth,(isdir(pth)==true)
+ end
end
dir.makedirs=dir.mkdirs
do
- local chdir=sandbox and sandbox.original(chdir) or chdir
- if onwindows then
- local xcurrentdir=dir.current
- function dir.expandname(str)
- local first,nothing,last=match(str,"^(//)(//*)(.*)$")
- if first then
- first=xcurrentdir().."/"
- end
- if not first then
- first,last=match(str,"^(//)/*(.*)$")
- end
- if not first then
- first,last=match(str,"^([a-zA-Z]:)(.*)$")
- if first and not find(last,"^/") then
- local d=currentdir()
- if chdir(first) then
- first=xcurrentdir()
- end
- chdir(d)
- end
- end
- if not first then
- first,last=xcurrentdir(),str
- end
- last=gsub(last,"//","/")
- last=gsub(last,"/%./","/")
- last=gsub(last,"^/*","")
- first=gsub(first,"/*$","")
- if last=="" or last=="." then
- return first
- else
- return first.."/"..last
- end
- end
- else
- function dir.expandname(str)
- if not find(str,"^/") then
- str=currentdir().."/"..str
- end
- str=gsub(str,"//","/")
- str=gsub(str,"/%./","/")
- str=gsub(str,"(.)/%.$","%1")
- return str
+ local chdir=sandbox and sandbox.original(chdir) or chdir
+ if onwindows then
+ local xcurrentdir=dir.current
+ function dir.expandname(str)
+ local first,nothing,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ first=xcurrentdir().."/"
+ end
+ if not first then
+ first,last=match(str,"^(//)/*(.*)$")
+ end
+ if not first then
+ first,last=match(str,"^([a-zA-Z]:)(.*)$")
+ if first and not find(last,"^/") then
+ local d=currentdir()
+ if chdir(first) then
+ first=xcurrentdir()
+ end
+ chdir(d)
end
+ end
+ if not first then
+ first,last=xcurrentdir(),str
+ end
+ last=gsub(last,"//","/")
+ last=gsub(last,"/%./","/")
+ last=gsub(last,"^/*","")
+ first=gsub(first,"/*$","")
+ if last=="" or last=="." then
+ return first
+ else
+ return first.."/"..last
+ end
+ end
+ else
+ function dir.expandname(str)
+ if not find(str,"^/") then
+ str=currentdir().."/"..str
+ end
+ str=gsub(str,"//","/")
+ str=gsub(str,"/%./","/")
+ str=gsub(str,"(.)/%.$","%1")
+ return str
end
+ end
end
file.expandname=dir.expandname
local stack={}
function dir.push(newdir)
- local curdir=currentdir()
- insert(stack,curdir)
- if newdir and newdir~="" then
- chdir(newdir)
- return newdir
- else
- return curdir
- end
+ local curdir=currentdir()
+ insert(stack,curdir)
+ if newdir and newdir~="" then
+ chdir(newdir)
+ return newdir
+ else
+ return curdir
+ end
end
function dir.pop()
- local d=remove(stack)
- if d then
- chdir(d)
- end
- return d
+ local d=remove(stack)
+ if d then
+ chdir(d)
+ end
+ return d
end
local function found(...)
- for i=1,select("#",...) do
- local path=select(i,...)
- local kind=type(path)
- if kind=="string" then
- if isdir(path) then
- return path
- end
- elseif kind=="table" then
- local path=found(unpack(path))
- if path then
- return path
- end
- end
+ for i=1,select("#",...) do
+ local path=select(i,...)
+ local kind=type(path)
+ if kind=="string" then
+ if isdir(path) then
+ return path
+ end
+ elseif kind=="table" then
+ local path=found(unpack(path))
+ if path then
+ return path
+ end
end
+ end
end
dir.found=found
@@ -5408,69 +5408,69 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-boolean"] = package.loaded["l-boolean"] or true
--- original size: 1850, stripped down to: 1568
+-- original size: 1850, stripped down to: 1498
if not modules then modules={} end modules ['l-boolean']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber=type,tonumber
boolean=boolean or {}
local boolean=boolean
function boolean.tonumber(b)
- if b then return 1 else return 0 end
+ if b then return 1 else return 0 end
end
function toboolean(str,tolerant)
- if str==nil then
- return false
- elseif str==false then
- return false
- elseif str==true then
- return true
- elseif str=="true" then
- return true
- elseif str=="false" then
- return false
- elseif not tolerant then
- return false
- elseif str==0 then
- return false
- elseif (tonumber(str) or 0)>0 then
- return true
- else
- return str=="yes" or str=="on" or str=="t"
- end
+ if str==nil then
+ return false
+ elseif str==false then
+ return false
+ elseif str==true then
+ return true
+ elseif str=="true" then
+ return true
+ elseif str=="false" then
+ return false
+ elseif not tolerant then
+ return false
+ elseif str==0 then
+ return false
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
end
string.toboolean=toboolean
function string.booleanstring(str)
- if str=="0" then
- return false
- elseif str=="1" then
- return true
- elseif str=="" then
- return false
- elseif str=="false" then
- return false
- elseif str=="true" then
- return true
- elseif (tonumber(str) or 0)>0 then
- return true
- else
- return str=="yes" or str=="on" or str=="t"
- end
+ if str=="0" then
+ return false
+ elseif str=="1" then
+ return true
+ elseif str=="" then
+ return false
+ elseif str=="false" then
+ return false
+ elseif str=="true" then
+ return true
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
end
function string.is_boolean(str,default,strict)
- if type(str)=="string" then
- if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
- return true
- elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
- return false
- end
+ if type(str)=="string" then
+ if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
+ return true
+ elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
+ return false
end
- return default
+ end
+ return default
end
@@ -5480,22 +5480,22 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 41047, stripped down to: 18594
+-- original size: 41047, stripped down to: 17171
if not modules then modules={} end modules ['l-unicode']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utf=utf or {}
unicode=nil
if not string.utfcharacters then
- local gmatch=string.gmatch
- function string.characters(str)
- return gmatch(str,".[\128-\191]*")
- end
+ local gmatch=string.gmatch
+ function string.characters(str)
+ return gmatch(str,".[\128-\191]*")
+ end
end
utf.characters=string.utfcharacters
local type=type
@@ -5518,304 +5518,304 @@ local p_utfbom=patterns.utfbom
local p_newline=patterns.newline
local p_whitespace=patterns.whitespace
if not utf.char then
- utf.char=string.utfcharacter or (utf8 and utf8.char)
- if not utf.char then
- local char=string.char
- if bit32 then
- local rshift=bit32.rshift
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+rshift(n,6),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+rshift(n,12),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+rshift(n,18),
- 0x80+(rshift(n,12)%0x40),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
+ utf.char=string.utfcharacter or (utf8 and utf8.char)
+ if not utf.char then
+ local char=string.char
+ if bit32 then
+ local rshift=bit32.rshift
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+rshift(n,6),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+rshift(n,12),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+rshift(n,18),
+ 0x80+(rshift(n,12)%0x40),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
else
- local floor=math.floor
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+floor(n/0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+floor(n/0x1000),
- 0x80+(floor(n/0x40)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+floor(n/0x40000),
- 0x80+(floor(n/0x1000)%0x40),
- 0x80+(floor(n/0x40)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
+ return ""
+ end
+ end
+ else
+ local floor=math.floor
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+floor(n/0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+floor(n/0x1000),
+ 0x80+(floor(n/0x40)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+floor(n/0x40000),
+ 0x80+(floor(n/0x1000)%0x40),
+ 0x80+(floor(n/0x40)%0x40),
+ 0x80+(n%0x40)
+ )
+ else
+ return ""
end
+ end
end
+ end
end
if not utf.byte then
- utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
- if not utf.byte then
- function utf.byte(c)
- return lpegmatch(p_utf8byte,c)
- end
+ utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
+ if not utf.byte then
+ function utf.byte(c)
+ return lpegmatch(p_utf8byte,c)
end
+ end
end
local utfchar,utfbyte=utf.char,utf.byte
function utf.filetype(data)
- return data and lpegmatch(p_utftype,data) or "unknown"
+ return data and lpegmatch(p_utftype,data) or "unknown"
end
local toentities=Cs (
- (
- patterns.utf8one+(
- patterns.utf8two+patterns.utf8three+patterns.utf8four
- )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
- )^0
+ (
+ patterns.utf8one+(
+ patterns.utf8two+patterns.utf8three+patterns.utf8four
+ )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
+ )^0
)
patterns.toentities=toentities
function utf.toentities(str)
- return lpegmatch(toentities,str)
+ return lpegmatch(toentities,str)
end
local one=P(1)
local two=C(1)*C(1)
local four=C(R(utfchar(0xD8),utfchar(0xFF)))*C(1)*C(1)*C(1)
local pattern=P("\254\255")*Cs((
- four/function(a,b,c,d)
- local ab=0xFF*byte(a)+byte(b)
- local cd=0xFF*byte(c)+byte(d)
- return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
- end+two/function(a,b)
- return utfchar(byte(a)*256+byte(b))
- end+one
- )^1 )+P("\255\254")*Cs((
- four/function(b,a,d,c)
- local ab=0xFF*byte(a)+byte(b)
- local cd=0xFF*byte(c)+byte(d)
- return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
- end+two/function(b,a)
- return utfchar(byte(a)*256+byte(b))
- end+one
- )^1 )
+ four/function(a,b,c,d)
+ local ab=0xFF*byte(a)+byte(b)
+ local cd=0xFF*byte(c)+byte(d)
+ return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+ end+two/function(a,b)
+ return utfchar(byte(a)*256+byte(b))
+ end+one
+ )^1 )+P("\255\254")*Cs((
+ four/function(b,a,d,c)
+ local ab=0xFF*byte(a)+byte(b)
+ local cd=0xFF*byte(c)+byte(d)
+ return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+ end+two/function(b,a)
+ return utfchar(byte(a)*256+byte(b))
+ end+one
+ )^1 )
function string.toutf(s)
- return lpegmatch(pattern,s) or s
+ return lpegmatch(pattern,s) or s
end
local validatedutf=Cs (
- (
- patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
- )^0
+ (
+ patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
+ )^0
)
patterns.validatedutf=validatedutf
function utf.is_valid(str)
- return type(str)=="string" and lpegmatch(validatedutf,str) or false
+ return type(str)=="string" and lpegmatch(validatedutf,str) or false
end
if not utf.len then
- utf.len=string.utflength or (utf8 and utf8.len)
- if not utf.len then
- local n,f=0,1
- local utfcharcounter=patterns.utfbom^-1*Cmt (
- Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
- function(_,t,d)
- n=n+(t-f)/d
- f=t
- return true
- end
- )^0
- function utf.len(str)
- n,f=0,1
- lpegmatch(utfcharcounter,str or "")
- return n
- end
+ utf.len=string.utflength or (utf8 and utf8.len)
+ if not utf.len then
+ local n,f=0,1
+ local utfcharcounter=patterns.utfbom^-1*Cmt (
+ Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
+ function(_,t,d)
+ n=n+(t-f)/d
+ f=t
+ return true
+ end
+ )^0
+ function utf.len(str)
+ n,f=0,1
+ lpegmatch(utfcharcounter,str or "")
+ return n
end
+ end
end
utf.length=utf.len
if not utf.sub then
- local utflength=utf.length
- local b,e,n,first,last=0,0,0,0,0
- local function slide_zero(s,p)
- n=n+1
- if n>=last then
- e=p-1
- else
- return p
- end
+ local utflength=utf.length
+ local b,e,n,first,last=0,0,0,0,0
+ local function slide_zero(s,p)
+ n=n+1
+ if n>=last then
+ e=p-1
+ else
+ return p
end
- local function slide_one(s,p)
- n=n+1
- if n==first then
- b=p
- end
- if n>=last then
- e=p-1
- else
- return p
- end
+ end
+ local function slide_one(s,p)
+ n=n+1
+ if n==first then
+ b=p
end
- local function slide_two(s,p)
- n=n+1
- if n==first then
- b=p
- else
- return true
- end
+ if n>=last then
+ e=p-1
+ else
+ return p
end
- local pattern_zero=Cmt(p_utf8character,slide_zero)^0
- local pattern_one=Cmt(p_utf8character,slide_one )^0
- local pattern_two=Cmt(p_utf8character,slide_two )^0
- local pattern_first=C(p_utf8character)
- function utf.sub(str,start,stop)
- if not start then
- return str
- end
- if start==0 then
- start=1
- end
- if not stop then
- if start<0 then
- local l=utflength(str)
- start=l+start
- else
- start=start-1
- end
- b,n,first=0,0,start
- lpegmatch(pattern_two,str)
- if n>=first then
- return sub(str,b)
- else
- return ""
- end
- end
- if start<0 or stop<0 then
- local l=utf.length(str)
- if start<0 then
- start=l+start
- if start<=0 then
- start=1
- else
- start=start+1
- end
- end
- if stop<0 then
- stop=l+stop
- if stop==0 then
- stop=1
- else
- stop=stop+1
- end
- end
+ end
+ local function slide_two(s,p)
+ n=n+1
+ if n==first then
+ b=p
+ else
+ return true
+ end
+ end
+ local pattern_zero=Cmt(p_utf8character,slide_zero)^0
+ local pattern_one=Cmt(p_utf8character,slide_one )^0
+ local pattern_two=Cmt(p_utf8character,slide_two )^0
+ local pattern_first=C(p_utf8character)
+ function utf.sub(str,start,stop)
+ if not start then
+ return str
+ end
+ if start==0 then
+ start=1
+ end
+ if not stop then
+ if start<0 then
+ local l=utflength(str)
+ start=l+start
+ else
+ start=start-1
+ end
+ b,n,first=0,0,start
+ lpegmatch(pattern_two,str)
+ if n>=first then
+ return sub(str,b)
+ else
+ return ""
+ end
+ end
+ if start<0 or stop<0 then
+ local l=utf.length(str)
+ if start<0 then
+ start=l+start
+ if start<=0 then
+ start=1
+ else
+ start=start+1
end
- if start==1 and stop==1 then
- return lpegmatch(pattern_first,str) or ""
- elseif start>stop then
- return ""
- elseif start>1 then
- b,e,n,first,last=0,0,0,start-1,stop
- lpegmatch(pattern_one,str)
- if n>=first and e==0 then
- e=#str
- end
- return sub(str,b,e)
+ end
+ if stop<0 then
+ stop=l+stop
+ if stop==0 then
+ stop=1
else
- b,e,n,last=1,0,0,stop
- lpegmatch(pattern_zero,str)
- if e==0 then
- e=#str
- end
- return sub(str,b,e)
+ stop=stop+1
end
+ end
end
+ if start==1 and stop==1 then
+ return lpegmatch(pattern_first,str) or ""
+ elseif start>stop then
+ return ""
+ elseif start>1 then
+ b,e,n,first,last=0,0,0,start-1,stop
+ lpegmatch(pattern_one,str)
+ if n>=first and e==0 then
+ e=#str
+ end
+ return sub(str,b,e)
+ else
+ b,e,n,last=1,0,0,stop
+ lpegmatch(pattern_zero,str)
+ if e==0 then
+ e=#str
+ end
+ return sub(str,b,e)
+ end
+ end
end
function utf.remapper(mapping,option,action)
- local variant=type(mapping)
- if variant=="table" then
- action=action or mapping
- if option=="dynamic" then
- local pattern=false
- table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
- return function(str)
- if not str or str=="" then
- return ""
- else
- if not pattern then
- pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
- end
- return lpegmatch(pattern,str)
- end
- end
- elseif option=="pattern" then
- return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ local variant=type(mapping)
+ if variant=="table" then
+ action=action or mapping
+ if option=="dynamic" then
+ local pattern=false
+ table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
+ return function(str)
+ if not str or str=="" then
+ return ""
else
- local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
- return function(str)
- if not str or str=="" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end,pattern
+ if not pattern then
+ pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ end
+ return lpegmatch(pattern,str)
end
- elseif variant=="function" then
- if option=="pattern" then
- return Cs((p_utf8character/mapping+p_utf8character)^0)
+ end
+ elseif option=="pattern" then
+ return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ else
+ local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
else
- local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
- return function(str)
- if not str or str=="" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end,pattern
+ return lpegmatch(pattern,str)
end
+ end,pattern
+ end
+ elseif variant=="function" then
+ if option=="pattern" then
+ return Cs((p_utf8character/mapping+p_utf8character)^0)
else
- return function(str)
- return str or ""
+ local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
end
+ end,pattern
end
-end
-function utf.replacer(t)
- local r=replacer(t,false,false,true)
+ else
return function(str)
- return lpegmatch(r,str)
+ return str or ""
end
+ end
+end
+function utf.replacer(t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ return lpegmatch(r,str)
+ end
end
function utf.subtituter(t)
- local f=finder (t)
- local r=replacer(t,false,false,true)
- return function(str)
- local i=lpegmatch(f,str)
- if not i then
- return str
- elseif i>#str then
- return str
- else
- return lpegmatch(r,str)
- end
+ local f=finder (t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ local i=lpegmatch(f,str)
+ if not i then
+ return str
+ elseif i>#str then
+ return str
+ else
+ return lpegmatch(r,str)
end
+ end
end
local utflinesplitter=p_utfbom^-1*lpeg.tsplitat(p_newline)
local utfcharsplitter_ows=p_utfbom^-1*Ct(C(p_utf8character)^0)
@@ -5823,25 +5823,25 @@ local utfcharsplitter_iws=p_utfbom^-1*Ct((p_whitespace^1+C(p_utf8character))^0)
local utfcharsplitter_raw=Ct(C(p_utf8character)^0)
patterns.utflinesplitter=utflinesplitter
function utf.splitlines(str)
- return lpegmatch(utflinesplitter,str or "")
+ return lpegmatch(utflinesplitter,str or "")
end
function utf.split(str,ignorewhitespace)
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
+ if ignorewhitespace then
+ return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+ return lpegmatch(utfcharsplitter_ows,str or "")
+ end
end
function utf.totable(str)
- return lpegmatch(utfcharsplitter_raw,str)
+ return lpegmatch(utfcharsplitter_raw,str)
end
function utf.magic(f)
- local str=f:read(4) or ""
- local off=lpegmatch(p_utfoffset,str)
- if off<4 then
- f:seek('set',off)
- end
- return lpegmatch(p_utftype,str)
+ local str=f:read(4) or ""
+ local off=lpegmatch(p_utfoffset,str)
+ if off<4 then
+ f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
end
local utf16_to_utf8_be,utf16_to_utf8_le
local utf32_to_utf8_be,utf32_to_utf8_le
@@ -5855,36 +5855,36 @@ local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_n
local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
local more=0
local p_utf16_to_utf8_be=C(1)*C(1)/function(left,right)
- local now=256*byte(left)+byte(right)
- if more>0 then
- now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ return ""
+ else
+ return utfchar(now)
+ end
end
local p_utf16_to_utf8_le=C(1)*C(1)/function(right,left)
- local now=256*byte(left)+byte(right)
- if more>0 then
- now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ return ""
+ else
+ return utfchar(now)
+ end
end
local p_utf32_to_utf8_be=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
- return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
+ return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
end
local p_utf32_to_utf8_le=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
- return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
+ return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
end
p_utf16_to_utf8_be=P(true)/function() more=0 end*utf_16_be_getbom*Cs(p_utf16_to_utf8_be^0)
p_utf16_to_utf8_le=P(true)/function() more=0 end*utf_16_le_getbom*Cs(p_utf16_to_utf8_le^0)
@@ -5895,88 +5895,88 @@ patterns.utf16_to_utf8_le=p_utf16_to_utf8_le
patterns.utf32_to_utf8_be=p_utf32_to_utf8_be
patterns.utf32_to_utf8_le=p_utf32_to_utf8_le
utf16_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_be,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+ return s
+ end
end
local utf16_to_utf8_be_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_16_be_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf16_to_utf8_be,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_16_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf16_to_utf8_be,s)
end
- return t
+ end
+ return t
end
utf16_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+ return s
+ end
end
local utf16_to_utf8_le_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_16_le_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf16_to_utf8_le,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_16_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf16_to_utf8_le,s)
end
- return t
+ end
+ return t
end
utf32_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_be,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+ return s
+ end
end
local utf32_to_utf8_be_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_32_be_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf32_to_utf8_be,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_32_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf32_to_utf8_be,s)
end
- return t
+ end
+ return t
end
utf32_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+ return s
+ end
end
local utf32_to_utf8_le_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_32_le_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf32_to_utf8_le,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_32_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf32_to_utf8_le,s)
end
- return t
+ end
+ return t
end
utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
@@ -5987,225 +5987,225 @@ utf.utf16_to_utf8_be=utf16_to_utf8_be
utf.utf32_to_utf8_le=utf32_to_utf8_le
utf.utf32_to_utf8_be=utf32_to_utf8_be
function utf.utf8_to_utf8_t(t)
- return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
+ return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
end
function utf.utf16_to_utf8_t(t,endian)
- return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
+ return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
end
function utf.utf32_to_utf8_t(t,endian)
- return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
+ return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
end
local function little(b)
- if b<0x10000 then
- return char(b%256,rshift(b,8))
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
- end
+ if b<0x10000 then
+ return char(b%256,rshift(b,8))
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
end
local function big(b)
- if b<0x10000 then
- return char(rshift(b,8),b%256)
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
- end
+ if b<0x10000 then
+ return char(rshift(b,8),b%256)
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
end
local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
local function utf8_to_utf16_be(str,nobom)
- if nobom then
- return lpegmatch(b_remap,str)
- else
- return char(254,255)..lpegmatch(b_remap,str)
- end
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
end
local function utf8_to_utf16_le(str,nobom)
- if nobom then
- return lpegmatch(l_remap,str)
- else
- return char(255,254)..lpegmatch(l_remap,str)
- end
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
end
utf.utf8_to_utf16_be=utf8_to_utf16_be
utf.utf8_to_utf16_le=utf8_to_utf16_le
function utf.utf8_to_utf16(str,littleendian,nobom)
- if littleendian then
- return utf8_to_utf16_le(str,nobom)
- else
- return utf8_to_utf16_be(str,nobom)
- end
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
end
local pattern=Cs (
- (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
+ (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
)
function utf.tocodes(str,separator)
- return lpegmatch(pattern,str,1,separator or " ")
+ return lpegmatch(pattern,str,1,separator or " ")
end
function utf.ustring(s)
- return format("U+%05X",type(s)=="number" and s or utfbyte(s))
+ return format("U+%05X",type(s)=="number" and s or utfbyte(s))
end
function utf.xstring(s)
- return format("0x%05X",type(s)=="number" and s or utfbyte(s))
+ return format("0x%05X",type(s)=="number" and s or utfbyte(s))
end
function utf.toeight(str)
- if not str or str=="" then
- return nil
- end
- local utftype=lpegmatch(p_utfstricttype,str)
- if utftype=="utf-8" then
- return sub(str,4)
- elseif utftype=="utf-16-be" then
- return utf16_to_utf8_be(str)
- elseif utftype=="utf-16-le" then
- return utf16_to_utf8_le(str)
- else
- return str
- end
+ if not str or str=="" then
+ return nil
+ end
+ local utftype=lpegmatch(p_utfstricttype,str)
+ if utftype=="utf-8" then
+ return sub(str,4)
+ elseif utftype=="utf-16-be" then
+ return utf16_to_utf8_be(str)
+ elseif utftype=="utf-16-le" then
+ return utf16_to_utf8_le(str)
+ else
+ return str
+ end
end
do
- local p_nany=p_utf8character/""
- local cache={}
- function utf.count(str,what)
- if type(what)=="string" then
- local p=cache[what]
- if not p then
- p=Cs((P(what)/" "+p_nany)^0)
- cache[p]=p
- end
- return #lpegmatch(p,str)
- else
- return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
- end
+ local p_nany=p_utf8character/""
+ local cache={}
+ function utf.count(str,what)
+ if type(what)=="string" then
+ local p=cache[what]
+ if not p then
+ p=Cs((P(what)/" "+p_nany)^0)
+ cache[p]=p
+ end
+ return #lpegmatch(p,str)
+ else
+ return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
end
+ end
end
if not string.utfvalues then
- local find=string.find
- local dummy=function()
- end
- function string.utfvalues(str)
- local n=#str
- if n==0 then
- return dummy
- elseif n==1 then
- return function() return utfbyte(str) end
- else
- local p=1
- return function()
- local b,e=find(str,".[\128-\191]*",p)
- if b then
- p=e+1
- return utfbyte(sub(str,b,e))
- end
- end
- end
+ local find=string.find
+ local dummy=function()
+ end
+ function string.utfvalues(str)
+ local n=#str
+ if n==0 then
+ return dummy
+ elseif n==1 then
+ return function() return utfbyte(str) end
+ else
+ local p=1
+ return function()
+ local b,e=find(str,".[\128-\191]*",p)
+ if b then
+ p=e+1
+ return utfbyte(sub(str,b,e))
+ end
+ end
end
+ end
end
utf.values=string.utfvalues
function utf.chrlen(u)
- return
- (u<0x80 and 1) or
- (u<0xE0 and 2) or
- (u<0xF0 and 3) or
- (u<0xF8 and 4) or
- (u<0xFC and 5) or
- (u<0xFE and 6) or 0
+ return
+ (u<0x80 and 1) or
+ (u<0xE0 and 2) or
+ (u<0xF0 and 3) or
+ (u<0xF8 and 4) or
+ (u<0xFC and 5) or
+ (u<0xFE and 6) or 0
end
if bit32 then
- local extract=bit32.extract
- local char=string.char
- function utf.toutf32string(n)
- if n<=0xFF then
- return
- char(n).."\000\000\000"
- elseif n<=0xFFFF then
- return
- char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
- elseif n<=0xFFFFFF then
- return
- char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
- else
- return
- char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
- end
- end
+ local extract=bit32.extract
+ local char=string.char
+ function utf.toutf32string(n)
+ if n<=0xFF then
+ return
+ char(n).."\000\000\000"
+ elseif n<=0xFFFF then
+ return
+ char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
+ elseif n<=0xFFFFFF then
+ return
+ char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
+ else
+ return
+ char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
+ end
+ end
end
local len=utf.len
local rep=rep
function string.utfpadd(s,n)
- if n and n~=0 then
- local l=len(s)
- if n>0 then
- local d=n-l
- if d>0 then
- return rep(c or " ",d)..s
- end
- else
- local d=- n-l
- if d>0 then
- return s..rep(c or " ",d)
- end
- end
+ if n and n~=0 then
+ local l=len(s)
+ if n>0 then
+ local d=n-l
+ if d>0 then
+ return rep(c or " ",d)..s
+ end
+ else
+ local d=- n-l
+ if d>0 then
+ return s..rep(c or " ",d)
+ end
end
- return s
+ end
+ return s
end
do
- local utfcharacters=utf.characters or string.utfcharacters
- local utfchar=utf.char or string.utfcharacter
- lpeg.UP=P
- if utfcharacters then
- function lpeg.US(str)
- local p=P(false)
- for uc in utfcharacters(str) do
- p=p+P(uc)
- end
- return p
- end
- else
- function lpeg.US(str)
- local p=P(false)
- local f=function(uc)
- p=p+P(uc)
- end
- lpegmatch((p_utf8char/f)^0,str)
- return p
- end
+ local utfcharacters=utf.characters or string.utfcharacters
+ local utfchar=utf.char or string.utfcharacter
+ lpeg.UP=P
+ if utfcharacters then
+ function lpeg.US(str)
+ local p=P(false)
+ for uc in utfcharacters(str) do
+ p=p+P(uc)
+ end
+ return p
end
- local range=p_utf8byte*p_utf8byte+Cc(false)
- function lpeg.UR(str,more)
- local first,last
- if type(str)=="number" then
- first=str
- last=more or first
- else
- first,last=lpegmatch(range,str)
- if not last then
- return P(str)
- end
- end
- if first==last then
- return P(str)
- end
- if not utfchar then
- utfchar=utf.char
- end
- if utfchar and (last-first<8) then
- local p=P(false)
- for i=first,last do
- p=p+P(utfchar(i))
- end
- return p
- else
- local f=function(b)
- return b>=first and b<=last
- end
- return p_utf8byte/f
- end
+ else
+ function lpeg.US(str)
+ local p=P(false)
+ local f=function(uc)
+ p=p+P(uc)
+ end
+ lpegmatch((p_utf8char/f)^0,str)
+ return p
+ end
+ end
+ local range=p_utf8byte*p_utf8byte+Cc(false)
+ function lpeg.UR(str,more)
+ local first,last
+ if type(str)=="number" then
+ first=str
+ last=more or first
+ else
+ first,last=lpegmatch(range,str)
+ if not last then
+ return P(str)
+ end
+ end
+ if first==last then
+ return P(str)
+ end
+ if not utfchar then
+ utfchar=utf.char
+ end
+ if utfchar and (last-first<8) then
+ local p=P(false)
+ for i=first,last do
+ p=p+P(utfchar(i))
+ end
+ return p
+ else
+ local f=function(b)
+ return b>=first and b<=last
+ end
+ return p_utf8byte/f
end
+ end
end
@@ -6215,93 +6215,93 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-math"] = package.loaded["l-math"] or true
--- original size: 2555, stripped down to: 1900
+-- original size: 2555, stripped down to: 1831
if not modules then modules={} end modules ['l-math']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not math.ceiling then
- math.ceiling=math.ceil
+ math.ceiling=math.ceil
end
if not math.round then
- local floor=math.floor
- function math.round(x) return floor(x+0.5) end
+ local floor=math.floor
+ function math.round(x) return floor(x+0.5) end
end
if not math.div then
- local floor=math.floor
- function math.div(n,m) return floor(n/m) end
+ local floor=math.floor
+ function math.div(n,m) return floor(n/m) end
end
if not math.mod then
- function math.mod(n,m) return n%m end
+ function math.mod(n,m) return n%m end
end
if not math.sind then
- local sin,cos,tan=math.sin,math.cos,math.tan
- local pipi=2*math.pi/360
- function math.sind(d) return sin(d*pipi) end
- function math.cosd(d) return cos(d*pipi) end
- function math.tand(d) return tan(d*pipi) end
+ local sin,cos,tan=math.sin,math.cos,math.tan
+ local pipi=2*math.pi/360
+ function math.sind(d) return sin(d*pipi) end
+ function math.cosd(d) return cos(d*pipi) end
+ function math.tand(d) return tan(d*pipi) end
end
if not math.odd then
- function math.odd (n) return n%2~=0 end
- function math.even(n) return n%2==0 end
+ function math.odd (n) return n%2~=0 end
+ function math.even(n) return n%2==0 end
end
if not math.cosh then
- local exp=math.exp
- function math.cosh(x)
- local xx=exp(x)
- return (xx+1/xx)/2
- end
- function math.sinh(x)
- local xx=exp(x)
- return (xx-1/xx)/2
- end
- function math.tanh(x)
- local xx=exp(x)
- return (xx-1/xx)/(xx+1/xx)
- end
+ local exp=math.exp
+ function math.cosh(x)
+ local xx=exp(x)
+ return (xx+1/xx)/2
+ end
+ function math.sinh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/2
+ end
+ function math.tanh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/(xx+1/xx)
+ end
end
if not math.pow then
- function math.pow(x,y)
- return x^y
- end
+ function math.pow(x,y)
+ return x^y
+ end
end
if not math.atan2 then
- math.atan2=math.atan
+ math.atan2=math.atan
end
if not math.ldexp then
- function math.ldexp(x,e)
- return x*2.0^e
- end
+ function math.ldexp(x,e)
+ return x*2.0^e
+ end
end
if not math.log10 then
- local log=math.log
- function math.log10(x)
- return log(x,10)
- end
+ local log=math.log
+ function math.log10(x)
+ return log(x,10)
+ end
end
if not math.type then
- function math.type()
- return "float"
- end
+ function math.type()
+ return "float"
+ end
end
if not math.tointeger then
- math.mininteger=-0x4FFFFFFFFFFF
- math.maxinteger=0x4FFFFFFFFFFF
- local floor=math.floor
- function math.tointeger(n)
- local f=floor(n)
- return f==n and f or nil
- end
+ math.mininteger=-0x4FFFFFFFFFFF
+ math.maxinteger=0x4FFFFFFFFFFF
+ local floor=math.floor
+ function math.tointeger(n)
+ local f=floor(n)
+ return f==n and f or nil
+ end
end
if not math.ult then
- local floor=math.floor
- function math.tointeger(m,n)
- return floor(m)<floor(n)
- end
+ local floor=math.floor
+ function math.tointeger(m,n)
+ return floor(m)<floor(n)
+ end
end
@@ -6311,14 +6311,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 43481, stripped down to: 23845
+-- original size: 43481, stripped down to: 23049
if not modules then modules={} end modules ['util-str']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.strings=utilities.strings or {}
@@ -6334,17 +6334,17 @@ local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
local loadstripped=nil
local oldfashioned=LUAVERSION<5.2
if oldfashioned then
- loadstripped=function(str,shortcuts)
- return load(str)
- end
+ loadstripped=function(str,shortcuts)
+ return load(str)
+ end
else
- loadstripped=function(str,shortcuts)
- if shortcuts then
- return load(dump(load(str),true),nil,nil,shortcuts)
- else
- return load(dump(load(str),true))
- end
+ loadstripped=function(str,shortcuts)
+ if shortcuts then
+ return load(dump(load(str),true),nil,nil,shortcuts)
+ else
+ return load(dump(load(str),true))
end
+ end
end
if not number then number={} end
local stripzero=patterns.stripzero
@@ -6362,32 +6362,32 @@ local period=patterns.period
local ptf=1/65536
local bpf=(7200/7227)/65536
local function points(n)
- if n==0 then
- return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
- return "0pt"
- end
- n=n*ptf
- if n%1==0 then
- return format("%ipt",n)
- end
- return lpegmatch(stripzeros,format("%.5fpt",n))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*ptf
+ if n%1==0 then
+ return format("%ipt",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fpt",n))
end
local function basepoints(n)
- if n==0 then
- return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
- return "0pt"
- end
- n=n*bpf
- if n%1==0 then
- return format("%ibp",n)
- end
- return lpegmatch(stripzeros,format("%.5fbp",n))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*bpf
+ if n%1==0 then
+ return format("%ibp",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fbp",n))
end
number.points=points
number.basepoints=basepoints
@@ -6399,65 +6399,65 @@ local trailing=(anyrubish^1*endofstring)/""
local redundant=rubish^3/"\n"
local pattern=Cs(leading*(trailing+redundant+stripped+anything)^0)
function strings.collapsecrlf(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local repeaters={}
function strings.newrepeater(str,offset)
- offset=offset or 0
- local s=repeaters[str]
- if not s then
- s={}
- repeaters[str]=s
- end
- local t=s[offset]
- if t then
- return t
- end
- t={}
- setmetatable(t,{ __index=function(t,k)
- if not k then
- return ""
- end
- local n=k+offset
- local s=n>0 and rep(str,n) or ""
- t[k]=s
- return s
- end })
- s[offset]=t
+ offset=offset or 0
+ local s=repeaters[str]
+ if not s then
+ s={}
+ repeaters[str]=s
+ end
+ local t=s[offset]
+ if t then
return t
+ end
+ t={}
+ setmetatable(t,{ __index=function(t,k)
+ if not k then
+ return ""
+ end
+ local n=k+offset
+ local s=n>0 and rep(str,n) or ""
+ t[k]=s
+ return s
+ end })
+ s[offset]=t
+ return t
end
local extra,tab,start=0,0,4,0
local nspaces=strings.newrepeater(" ")
string.nspaces=nspaces
local pattern=Carg(1)/function(t)
- extra,tab,start=0,t or 7,1
- end*Cs((
+ extra,tab,start=0,t or 7,1
+ end*Cs((
Cp()*patterns.tab/function(position)
- local current=(position-start+1)+extra
- local spaces=tab-(current-1)%tab
- if spaces>0 then
- extra=extra+spaces-1
- return nspaces[spaces]
- else
- return ""
- end
+ local current=(position-start+1)+extra
+ local spaces=tab-(current-1)%tab
+ if spaces>0 then
+ extra=extra+spaces-1
+ return nspaces[spaces]
+ else
+ return ""
+ end
end+newline*Cp()/function(position)
- extra,start=0,position
+ extra,start=0,position
end+anything
- )^1)
+ )^1)
function strings.tabtospace(str,tab)
- return lpegmatch(pattern,str,1,tab or 7)
+ return lpegmatch(pattern,str,1,tab or 7)
end
function string.utfpadding(s,n)
- if not n or n==0 then
- return ""
- end
- local l=utflen(s)
- if n>0 then
- return nspaces[n-l]
- else
- return nspaces[-n-l]
- end
+ if not n or n==0 then
+ return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
end
local optionalspace=spacer^0
local nospace=optionalspace/""
@@ -6475,130 +6475,130 @@ local notrailing=noleading*endofstring
local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 )
local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 )
local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 )
-local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
+local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
local p_retain_normal=Cs ((normalline+normalempty )^0 )
local p_retain_collapse=Cs ((normalline+doubleempty )^0 )
local p_retain_noempty=Cs ((normalline+singleempty )^0 )
local striplinepatterns={
- ["prune"]=p_prune_normal,
- ["prune and collapse"]=p_prune_collapse,
- ["prune and no empty"]=p_prune_noempty,
- ["prune and to space"]=p_prune_intospace,
- ["retain"]=p_retain_normal,
- ["retain and collapse"]=p_retain_collapse,
- ["retain and no empty"]=p_retain_noempty,
- ["collapse"]=patterns.collapser,
+ ["prune"]=p_prune_normal,
+ ["prune and collapse"]=p_prune_collapse,
+ ["prune and no empty"]=p_prune_noempty,
+ ["prune and to space"]=p_prune_intospace,
+ ["retain"]=p_retain_normal,
+ ["retain and collapse"]=p_retain_collapse,
+ ["retain and no empty"]=p_retain_noempty,
+ ["collapse"]=patterns.collapser,
}
setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end })
strings.striplinepatterns=striplinepatterns
function strings.striplines(str,how)
- return str and lpegmatch(striplinepatterns[how],str) or str
+ return str and lpegmatch(striplinepatterns[how],str) or str
end
function strings.collapse(str)
- return str and lpegmatch(p_prune_intospace,str) or str
+ return str and lpegmatch(p_prune_intospace,str) or str
end
strings.striplong=strings.striplines
function strings.nice(str)
- str=gsub(str,"[:%-+_]+"," ")
- return str
+ str=gsub(str,"[:%-+_]+"," ")
+ return str
end
local n=0
local sequenced=table.sequenced
function string.autodouble(s,sep)
- if s==nil then
- return '""'
- end
- local t=type(s)
- if t=="number" then
- return tostring(s)
- end
- if t=="table" then
- return ('"'..sequenced(s,sep or ",")..'"')
- end
- return ('"'..tostring(s)..'"')
+ if s==nil then
+ return '""'
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ('"'..sequenced(s,sep or ",")..'"')
+ end
+ return ('"'..tostring(s)..'"')
end
function string.autosingle(s,sep)
- if s==nil then
- return "''"
- end
- local t=type(s)
- if t=="number" then
- return tostring(s)
- end
- if t=="table" then
- return ("'"..sequenced(s,sep or ",").."'")
- end
- return ("'"..tostring(s).."'")
+ if s==nil then
+ return "''"
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ("'"..sequenced(s,sep or ",").."'")
+ end
+ return ("'"..tostring(s).."'")
end
local tracedchars={ [0]=
- "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
- "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
- "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
- "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
- "[space]",
+ "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
+ "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
+ "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
+ "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
+ "[space]",
}
string.tracedchars=tracedchars
strings.tracers=tracedchars
function string.tracedchar(b)
- if type(b)=="number" then
- return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
- else
- local c=utfbyte(b)
- return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
- end
+ if type(b)=="number" then
+ return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
+ else
+ local c=utfbyte(b)
+ return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
+ end
end
function number.signed(i)
- if i>0 then
- return "+",i
- else
- return "-",-i
- end
+ if i>0 then
+ return "+",i
+ else
+ return "-",-i
+ end
end
local two=digit*digit
local three=two*digit
local prefix=(Carg(1)*three)^1
local splitter=Cs (
- (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
+ (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
)
local splitter3=Cs (
- three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
+ three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
)
patterns.formattednumber=splitter
function number.formatted(n,sep1,sep2)
- if sep1==false then
- if type(n)=="number" then
- n=tostring(n)
- end
- return lpegmatch(splitter3,n,1,sep2 or ".")
+ if sep1==false then
+ if type(n)=="number" then
+ n=tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n)=="number" then
+ n=format("%0.2f",n)
+ end
+ if sep1==true then
+ return lpegmatch(splitter,n,1,".",",")
+ elseif sep1=="." then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
+ elseif sep1=="," then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
else
- if type(n)=="number" then
- n=format("%0.2f",n)
- end
- if sep1==true then
- return lpegmatch(splitter,n,1,".",",")
- elseif sep1=="." then
- return lpegmatch(splitter,n,1,sep1,sep2 or ",")
- elseif sep1=="," then
- return lpegmatch(splitter,n,1,sep1,sep2 or ".")
- else
- return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
- end
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
end
+ end
end
local p=Cs(
- P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
- )
+ P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
+ )
function number.compactfloat(n,fmt)
- if n==0 then
- return "0"
- elseif n==1 then
- return "1"
- end
- n=lpegmatch(p,format(fmt or "%0.3f",n))
- if n=="." or n=="" or n=="-" then
- return "0"
- end
- return n
+ if n==0 then
+ return "0"
+ elseif n==1 then
+ return "1"
+ end
+ n=lpegmatch(p,format(fmt or "%0.3f",n))
+ if n=="." or n=="" or n=="-" then
+ return "0"
+ end
+ return n
end
local zero=P("0")^1/""
local plus=P("+")/""
@@ -6609,41 +6609,41 @@ local exponent=(S("eE")*(plus+Cs((minus*zero^0*endofstring)/"")+minus)*zero^0*(e
local pattern_a=Cs(minus^0*digit^1*(separator/""*trailing+separator*(trailing+digit)^0)*exponent)
local pattern_b=Cs((exponent+anything)^0)
function number.sparseexponent(f,n)
- if not n then
- n=f
- f="%e"
- end
- local tn=type(n)
- if tn=="string" then
- local m=tonumber(n)
- if m then
- return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
- end
- elseif tn=="number" then
- return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ if not n then
+ n=f
+ f="%e"
+ end
+ local tn=type(n)
+ if tn=="string" then
+ local m=tonumber(n)
+ if m then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
end
- return tostring(n)
+ elseif tn=="number" then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ end
+ return tostring(n)
end
local hf={}
local hs={}
setmetatable(hf,{ __index=function(t,k)
- local v="%."..k.."f"
- t[k]=v
- return v
+ local v="%."..k.."f"
+ t[k]=v
+ return v
end } )
setmetatable(hs,{ __index=function(t,k)
- local v="%"..k.."s"
- t[k]=v
- return v
+ local v="%"..k.."s"
+ t[k]=v
+ return v
end } )
function number.formattedfloat(n,b,a)
- local s=format(hf[a],n)
- local l=(b or 0)+(a or 0)+1
- if #s<l then
- return format(hs[l],s)
- else
- return s
- end
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
end
local template=[[
%s
@@ -6652,7 +6652,7 @@ return function(%s) return %s end
]]
local preamble,environment="",{}
if oldfashioned then
- preamble=[[
+ preamble=[[
local lpeg=lpeg
local type=type
local tostring=tostring
@@ -6678,339 +6678,339 @@ local stripzero=lpeg.patterns.stripzero
local stripzeros=lpeg.patterns.stripzeros
]]
else
- environment={
- global=global or _G,
- lpeg=lpeg,
- type=type,
- tostring=tostring,
- tonumber=tonumber,
- format=string.format,
- concat=table.concat,
- signed=number.signed,
- points=number.points,
- basepoints=number.basepoints,
- utfchar=utf.char,
- utfbyte=utf.byte,
- lpegmatch=lpeg.match,
- nspaces=string.nspaces,
- utfpadding=string.utfpadding,
- tracedchar=string.tracedchar,
- autosingle=string.autosingle,
- autodouble=string.autodouble,
- sequenced=table.sequenced,
- formattednumber=number.formatted,
- sparseexponent=number.sparseexponent,
- formattedfloat=number.formattedfloat,
- stripzero=lpeg.patterns.stripzero,
- stripzeros=lpeg.patterns.stripzeros,
- }
+ environment={
+ global=global or _G,
+ lpeg=lpeg,
+ type=type,
+ tostring=tostring,
+ tonumber=tonumber,
+ format=string.format,
+ concat=table.concat,
+ signed=number.signed,
+ points=number.points,
+ basepoints=number.basepoints,
+ utfchar=utf.char,
+ utfbyte=utf.byte,
+ lpegmatch=lpeg.match,
+ nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
+ tracedchar=string.tracedchar,
+ autosingle=string.autosingle,
+ autodouble=string.autodouble,
+ sequenced=table.sequenced,
+ formattednumber=number.formatted,
+ sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat,
+ stripzero=lpeg.patterns.stripzero,
+ stripzeros=lpeg.patterns.stripzeros,
+ }
end
local arguments={ "a1" }
setmetatable(arguments,{ __index=function(t,k)
- local v=t[k-1]..",a"..k
- t[k]=v
- return v
- end
+ local v=t[k-1]..",a"..k
+ t[k]=v
+ return v
+ end
})
local prefix_any=C((sign+space+period+digit)^0)
local prefix_sub=(C((sign+digit)^0)+Cc(0))*period*(C((sign+digit)^0)+Cc(0))
local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
local format_s=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',a%s)",f,n)
- else
- return format("(a%s or '')",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("(a%s or '')",n)
+ end
end
local format_S=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',tostring(a%s))",f,n)
- else
- return format("tostring(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',tostring(a%s))",f,n)
+ else
+ return format("tostring(a%s)",n)
+ end
end
local format_right=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
- return format("(a%s or '')",n)
- elseif f>0 then
- return format("utfpadding(a%s,%i)..a%s",n,f,n)
- else
- return format("a%s..utfpadding(a%s,%i)",n,n,f)
- end
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ elseif f>0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
end
local format_left=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
- return format("(a%s or '')",n)
- end
- if f<0 then
- return format("utfpadding(a%s,%i)..a%s",n,-f,n)
- else
- return format("a%s..utfpadding(a%s,%i)",n,n,-f)
- end
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ end
+ if f<0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
end
local format_q=function()
- n=n+1
- return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
end
local format_Q=function()
- n=n+1
- return format("format('%%q',tostring(a%s))",n)
+ n=n+1
+ return format("format('%%q',tostring(a%s))",n)
end
local format_i=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%si',a%s)",f,n)
- else
- return format("format('%%i',a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%si',a%s)",f,n)
+ else
+ return format("format('%%i',a%s)",n)
+ end
end
local format_d=format_i
local format_I=function(f)
- n=n+1
- return format("format('%%s%%%si',signed(a%s))",f,n)
+ n=n+1
+ return format("format('%%s%%%si',signed(a%s))",f,n)
end
local format_f=function(f)
- n=n+1
- return format("format('%%%sf',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sf',a%s)",f,n)
end
local format_F=function(f)
- n=n+1
- if not f or f=="" then
- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
- else
- return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
- end
+ n=n+1
+ if not f or f=="" then
+ return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
+ else
+ return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
+ end
end
local format_k=function(b,a)
- n=n+1
- return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
+ n=n+1
+ return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
end
local format_g=function(f)
- n=n+1
- return format("format('%%%sg',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sg',a%s)",f,n)
end
local format_G=function(f)
- n=n+1
- return format("format('%%%sG',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sG',a%s)",f,n)
end
local format_e=function(f)
- n=n+1
- return format("format('%%%se',a%s)",f,n)
+ n=n+1
+ return format("format('%%%se',a%s)",f,n)
end
local format_E=function(f)
- n=n+1
- return format("format('%%%sE',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sE',a%s)",f,n)
end
local format_j=function(f)
- n=n+1
- return format("sparseexponent('%%%se',a%s)",f,n)
+ n=n+1
+ return format("sparseexponent('%%%se',a%s)",f,n)
end
local format_J=function(f)
- n=n+1
- return format("sparseexponent('%%%sE',a%s)",f,n)
+ n=n+1
+ return format("sparseexponent('%%%sE',a%s)",f,n)
end
local format_x=function(f)
- n=n+1
- return format("format('%%%sx',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sx',a%s)",f,n)
end
local format_X=function(f)
- n=n+1
- return format("format('%%%sX',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sX',a%s)",f,n)
end
local format_o=function(f)
- n=n+1
- return format("format('%%%so',a%s)",f,n)
+ n=n+1
+ return format("format('%%%so',a%s)",f,n)
end
local format_c=function()
- n=n+1
- return format("utfchar(a%s)",n)
+ n=n+1
+ return format("utfchar(a%s)",n)
end
local format_C=function()
- n=n+1
- return format("tracedchar(a%s)",n)
+ n=n+1
+ return format("tracedchar(a%s)",n)
end
local format_r=function(f)
- n=n+1
- return format("format('%%%s.0f',a%s)",f,n)
+ n=n+1
+ return format("format('%%%s.0f',a%s)",f,n)
end
local format_h=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_H=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_u=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_U=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_p=function()
- n=n+1
- return format("points(a%s)",n)
+ n=n+1
+ return format("points(a%s)",n)
end
local format_b=function()
- n=n+1
- return format("basepoints(a%s)",n)
+ n=n+1
+ return format("basepoints(a%s)",n)
end
local format_t=function(f)
- n=n+1
- if f and f~="" then
- return format("concat(a%s,%q)",n,f)
- else
- return format("concat(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("concat(a%s,%q)",n,f)
+ else
+ return format("concat(a%s)",n)
+ end
end
local format_T=function(f)
- n=n+1
- if f and f~="" then
- return format("sequenced(a%s,%q)",n,f)
- else
- return format("sequenced(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("sequenced(a%s,%q)",n,f)
+ else
+ return format("sequenced(a%s)",n)
+ end
end
local format_l=function()
- n=n+1
- return format("(a%s and 'true' or 'false')",n)
+ n=n+1
+ return format("(a%s and 'true' or 'false')",n)
end
local format_L=function()
- n=n+1
- return format("(a%s and 'TRUE' or 'FALSE')",n)
+ n=n+1
+ return format("(a%s and 'TRUE' or 'FALSE')",n)
end
local format_n=function()
- n=n+1
- return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+ n=n+1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
end
local format_N=function(f)
- n=n+1
- if not f or f=="" then
- f=".9"
- end
- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+ n=n+1
+ if not f or f=="" then
+ f=".9"
+ end
+ return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
end
local format_a=function(f)
- n=n+1
- if f and f~="" then
- return format("autosingle(a%s,%q)",n,f)
- else
- return format("autosingle(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("autosingle(a%s,%q)",n,f)
+ else
+ return format("autosingle(a%s)",n)
+ end
end
local format_A=function(f)
- n=n+1
- if f and f~="" then
- return format("autodouble(a%s,%q)",n,f)
- else
- return format("autodouble(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("autodouble(a%s,%q)",n,f)
+ else
+ return format("autodouble(a%s)",n)
+ end
end
local format_w=function(f)
- n=n+1
- f=tonumber(f)
- if f then
- return format("nspaces[%s+a%s]",f,n)
- else
- return format("nspaces[a%s]",n)
- end
+ n=n+1
+ f=tonumber(f)
+ if f then
+ return format("nspaces[%s+a%s]",f,n)
+ else
+ return format("nspaces[a%s]",n)
+ end
end
local format_W=function(f)
- return format("nspaces[%s]",tonumber(f) or 0)
+ return format("nspaces[%s]",tonumber(f) or 0)
end
local format_m=function(f)
- n=n+1
- if not f or f=="" then
- f=","
- end
- if f=="0" then
- return format([[formattednumber(a%s,false)]],n)
- else
- return format([[formattednumber(a%s,%q,".")]],n,f)
- end
+ n=n+1
+ if not f or f=="" then
+ f=","
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,".")]],n,f)
+ end
end
local format_M=function(f)
- n=n+1
- if not f or f=="" then
- f="."
- end
- if f=="0" then
- return format([[formattednumber(a%s,false)]],n)
- else
- return format([[formattednumber(a%s,%q,",")]],n,f)
- end
+ n=n+1
+ if not f or f=="" then
+ f="."
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,",")]],n,f)
+ end
end
local format_z=function(f)
- n=n+(tonumber(f) or 1)
- return "''"
+ n=n+(tonumber(f) or 1)
+ return "''"
end
local format_rest=function(s)
- return format("%q",s)
+ return format("%q",s)
end
local format_extension=function(extensions,f,name)
- local extension=extensions[name] or "tostring(%s)"
- local f=tonumber(f) or 1
- local w=find(extension,"%.%.%.")
- if f==0 then
- if w then
- extension=gsub(extension,"%.%.%.","")
- end
- return extension
- elseif f==1 then
- if w then
- extension=gsub(extension,"%.%.%.","%%s")
- end
- n=n+1
- local a="a"..n
- return format(extension,a,a)
- elseif f<0 then
- local a="a"..(n+f+1)
- return format(extension,a,a)
- else
- if w then
- extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
- end
- local t={}
- for i=1,f do
- n=n+1
- t[i]="a"..n
- end
- return format(extension,unpack(t))
+ local extension=extensions[name] or "tostring(%s)"
+ local f=tonumber(f) or 1
+ local w=find(extension,"%.%.%.")
+ if f==0 then
+ if w then
+ extension=gsub(extension,"%.%.%.","")
+ end
+ return extension
+ elseif f==1 then
+ if w then
+ extension=gsub(extension,"%.%.%.","%%s")
+ end
+ n=n+1
+ local a="a"..n
+ return format(extension,a,a)
+ elseif f<0 then
+ local a="a"..(n+f+1)
+ return format(extension,a,a)
+ else
+ if w then
+ extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
end
+ local t={}
+ for i=1,f do
+ n=n+1
+ t[i]="a"..n
+ end
+ return format(extension,unpack(t))
+ end
end
local builder=Cs { "start",
- start=(
- (
- P("%")/""*(
- V("!")
+ start=(
+ (
+ P("%")/""*(
+ V("!")
+V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
+V("c")+V("C")+V("S")
+V("Q")
@@ -7026,119 +7026,119 @@ local builder=Cs { "start",
+V("z")
+V(">")
+V("<")
- )+V("*")
- )*(endofstring+Carg(1))
- )^0,
- ["s"]=(prefix_any*P("s"))/format_s,
- ["q"]=(prefix_any*P("q"))/format_q,
- ["i"]=(prefix_any*P("i"))/format_i,
- ["d"]=(prefix_any*P("d"))/format_d,
- ["f"]=(prefix_any*P("f"))/format_f,
- ["F"]=(prefix_any*P("F"))/format_F,
- ["g"]=(prefix_any*P("g"))/format_g,
- ["G"]=(prefix_any*P("G"))/format_G,
- ["e"]=(prefix_any*P("e"))/format_e,
- ["E"]=(prefix_any*P("E"))/format_E,
- ["x"]=(prefix_any*P("x"))/format_x,
- ["X"]=(prefix_any*P("X"))/format_X,
- ["o"]=(prefix_any*P("o"))/format_o,
- ["S"]=(prefix_any*P("S"))/format_S,
- ["Q"]=(prefix_any*P("Q"))/format_Q,
- ["n"]=(prefix_any*P("n"))/format_n,
- ["N"]=(prefix_any*P("N"))/format_N,
- ["k"]=(prefix_sub*P("k"))/format_k,
- ["c"]=(prefix_any*P("c"))/format_c,
- ["C"]=(prefix_any*P("C"))/format_C,
- ["r"]=(prefix_any*P("r"))/format_r,
- ["h"]=(prefix_any*P("h"))/format_h,
- ["H"]=(prefix_any*P("H"))/format_H,
- ["u"]=(prefix_any*P("u"))/format_u,
- ["U"]=(prefix_any*P("U"))/format_U,
- ["p"]=(prefix_any*P("p"))/format_p,
- ["b"]=(prefix_any*P("b"))/format_b,
- ["t"]=(prefix_tab*P("t"))/format_t,
- ["T"]=(prefix_tab*P("T"))/format_T,
- ["l"]=(prefix_any*P("l"))/format_l,
- ["L"]=(prefix_any*P("L"))/format_L,
- ["I"]=(prefix_any*P("I"))/format_I,
- ["w"]=(prefix_any*P("w"))/format_w,
- ["W"]=(prefix_any*P("W"))/format_W,
- ["j"]=(prefix_any*P("j"))/format_j,
- ["J"]=(prefix_any*P("J"))/format_J,
- ["m"]=(prefix_any*P("m"))/format_m,
- ["M"]=(prefix_any*P("M"))/format_M,
- ["z"]=(prefix_any*P("z"))/format_z,
- ["a"]=(prefix_any*P("a"))/format_a,
- ["A"]=(prefix_any*P("A"))/format_A,
- ["<"]=(prefix_any*P("<"))/format_left,
- [">"]=(prefix_any*P(">"))/format_right,
- ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
- ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
- ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
+ )+V("*")
+ )*(endofstring+Carg(1))
+ )^0,
+ ["s"]=(prefix_any*P("s"))/format_s,
+ ["q"]=(prefix_any*P("q"))/format_q,
+ ["i"]=(prefix_any*P("i"))/format_i,
+ ["d"]=(prefix_any*P("d"))/format_d,
+ ["f"]=(prefix_any*P("f"))/format_f,
+ ["F"]=(prefix_any*P("F"))/format_F,
+ ["g"]=(prefix_any*P("g"))/format_g,
+ ["G"]=(prefix_any*P("G"))/format_G,
+ ["e"]=(prefix_any*P("e"))/format_e,
+ ["E"]=(prefix_any*P("E"))/format_E,
+ ["x"]=(prefix_any*P("x"))/format_x,
+ ["X"]=(prefix_any*P("X"))/format_X,
+ ["o"]=(prefix_any*P("o"))/format_o,
+ ["S"]=(prefix_any*P("S"))/format_S,
+ ["Q"]=(prefix_any*P("Q"))/format_Q,
+ ["n"]=(prefix_any*P("n"))/format_n,
+ ["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
+ ["c"]=(prefix_any*P("c"))/format_c,
+ ["C"]=(prefix_any*P("C"))/format_C,
+ ["r"]=(prefix_any*P("r"))/format_r,
+ ["h"]=(prefix_any*P("h"))/format_h,
+ ["H"]=(prefix_any*P("H"))/format_H,
+ ["u"]=(prefix_any*P("u"))/format_u,
+ ["U"]=(prefix_any*P("U"))/format_U,
+ ["p"]=(prefix_any*P("p"))/format_p,
+ ["b"]=(prefix_any*P("b"))/format_b,
+ ["t"]=(prefix_tab*P("t"))/format_t,
+ ["T"]=(prefix_tab*P("T"))/format_T,
+ ["l"]=(prefix_any*P("l"))/format_l,
+ ["L"]=(prefix_any*P("L"))/format_L,
+ ["I"]=(prefix_any*P("I"))/format_I,
+ ["w"]=(prefix_any*P("w"))/format_w,
+ ["W"]=(prefix_any*P("W"))/format_W,
+ ["j"]=(prefix_any*P("j"))/format_j,
+ ["J"]=(prefix_any*P("J"))/format_J,
+ ["m"]=(prefix_any*P("m"))/format_m,
+ ["M"]=(prefix_any*P("M"))/format_M,
+ ["z"]=(prefix_any*P("z"))/format_z,
+ ["a"]=(prefix_any*P("a"))/format_a,
+ ["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
+ ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
+ ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
+ ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
}
local xx=setmetatable({},{ __index=function(t,k) local v=format("%02x",k) t[k]=v return v end })
local XX=setmetatable({},{ __index=function(t,k) local v=format("%02X",k) t[k]=v return v end })
local preset={
- ["%02x"]=function(n) return xx[n] end,
- ["%02X"]=function(n) return XX[n] end,
+ ["%02x"]=function(n) return xx[n] end,
+ ["%02X"]=function(n) return XX[n] end,
}
local direct=P("%")*(sign+space+period+digit)^0*S("sqidfgGeExXo")*endofstring/[[local format = string.format return function(str) return format("%0",str) end]]
local function make(t,str)
- local f=preset[str]
- if f then
- return f
- end
- local p=lpegmatch(direct,str)
- if p then
- f=loadstripped(p)()
+ local f=preset[str]
+ if f then
+ return f
+ end
+ local p=lpegmatch(direct,str)
+ if p then
+ f=loadstripped(p)()
+ else
+ n=0
+ p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
+ if n>0 then
+ p=format(template,preamble,t._preamble_,arguments[n],p)
+ f=loadstripped(p,t._environment_)()
else
- n=0
- p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
- if n>0 then
- p=format(template,preamble,t._preamble_,arguments[n],p)
- f=loadstripped(p,t._environment_)()
- else
- f=function() return str end
- end
+ f=function() return str end
end
- t[str]=f
- return f
+ end
+ t[str]=f
+ return f
end
local function use(t,fmt,...)
- return t[fmt](...)
+ return t[fmt](...)
end
strings.formatters={}
if oldfashioned then
- function strings.formatters.new(noconcat)
- local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} }
- setmetatable(t,{ __index=make,__call=use })
- return t
- end
+ function strings.formatters.new(noconcat)
+ local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
+ end
else
- function strings.formatters.new(noconcat)
- local e={}
- for k,v in next,environment do
- e[k]=v
- end
- local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e }
- setmetatable(t,{ __index=make,__call=use })
- return t
+ function strings.formatters.new(noconcat)
+ local e={}
+ for k,v in next,environment do
+ e[k]=v
end
+ local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
+ end
end
local formatters=strings.formatters.new()
string.formatters=formatters
string.formatter=function(str,...) return formatters[str](...) end
local function add(t,name,template,preamble)
- if type(t)=="table" and t._type_=="formatter" then
- t._extensions_[name]=template or "%s"
- if type(preamble)=="string" then
- t._preamble_=preamble.."\n"..t._preamble_
- elseif type(preamble)=="table" then
- for k,v in next,preamble do
- t._environment_[k]=v
- end
- end
+ if type(t)=="table" and t._type_=="formatter" then
+ t._extensions_[name]=template or "%s"
+ if type(preamble)=="string" then
+ t._preamble_=preamble.."\n"..t._preamble_
+ elseif type(preamble)=="table" then
+ for k,v in next,preamble do
+ t._environment_[k]=v
+ end
end
+ end
end
strings.formatters.add=add
patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+anything)^0)
@@ -7146,44 +7146,44 @@ patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+anything)^0)
patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0)
patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"'))
if oldfashioned then
- add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
- add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
- add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
+ add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
+ add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
+ add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
else
- add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape })
- add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
- add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
+ add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape })
+ add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
+ add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
end
local dquote=patterns.dquote
local equote=patterns.escaped+dquote/'\\"'+1
local cquote=Cc('"')
-local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
+local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
+Cs(cquote*(equote-space)^0*space*equote^0*cquote)
function string.optionalquoted(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local pattern=Cs((newline/(os.newline or "\r")+1)^0)
function string.replacenewlines(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function strings.newcollector()
- local result,r={},0
- return
- function(fmt,str,...)
- r=r+1
- result[r]=str==nil and fmt or formatters[fmt](str,...)
- end,
- function(connector)
- if result then
- local str=concat(result,connector)
- result,r={},0
- return str
- end
- end
+ local result,r={},0
+ return
+ function(fmt,str,...)
+ r=r+1
+ result[r]=str==nil and fmt or formatters[fmt](str,...)
+ end,
+ function(connector)
+ if result then
+ local str=concat(result,connector)
+ result,r={},0
+ return str
+ end
+ end
end
local f_16_16=formatters["%0.5N"]
function number.to16dot16(n)
- return f_16_16(n/65536.0)
+ return f_16_16(n/65536.0)
end
@@ -7193,14 +7193,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 28756, stripped down to: 17693
+-- original size: 28756, stripped down to: 16104
if not modules then modules={} end modules ['util-tab']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.tables=utilities.tables or {}
@@ -7215,219 +7215,219 @@ local formatters=string.formatters
local utftoeight=utf.toeight
local splitter=lpeg.tsplitat(".")
function utilities.tables.definetable(target,nofirst,nolast)
- local composed,t=nil,{}
- local snippets=lpegmatch(splitter,target)
- for i=1,#snippets-(nolast and 1 or 0) do
- local name=snippets[i]
- if composed then
- composed=composed.."."..name
- t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
- else
- composed=name
- if not nofirst then
- t[#t+1]=formatters["%s = %s or { }"](composed,composed)
- end
- end
- end
+ local composed,t=nil,{}
+ local snippets=lpegmatch(splitter,target)
+ for i=1,#snippets-(nolast and 1 or 0) do
+ local name=snippets[i]
if composed then
- if nolast then
- composed=composed.."."..snippets[#snippets]
- end
- return concat(t,"\n"),composed
+ composed=composed.."."..name
+ t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
else
- return "",target
+ composed=name
+ if not nofirst then
+ t[#t+1]=formatters["%s = %s or { }"](composed,composed)
+ end
end
+ end
+ if composed then
+ if nolast then
+ composed=composed.."."..snippets[#snippets]
+ end
+ return concat(t,"\n"),composed
+ else
+ return "",target
+ end
end
function tables.definedtable(...)
- local t=_G
- for i=1,select("#",...) do
- local li=select(i,...)
- local tl=t[li]
- if not tl then
- tl={}
- t[li]=tl
- end
- t=tl
- end
- return t
+ local t=_G
+ for i=1,select("#",...) do
+ local li=select(i,...)
+ local tl=t[li]
+ if not tl then
+ tl={}
+ t[li]=tl
+ end
+ t=tl
+ end
+ return t
end
function tables.accesstable(target,root)
- local t=root or _G
- for name in gmatch(target,"([^%.]+)") do
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ for name in gmatch(target,"([^%.]+)") do
+ t=t[name]
+ if not t then
+ return
end
- return t
+ end
+ return t
end
function tables.migratetable(target,v,root)
- local t=root or _G
- local names=lpegmatch(splitter,target)
- for i=1,#names-1 do
- local name=names[i]
- t[name]=t[name] or {}
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ local names=lpegmatch(splitter,target)
+ for i=1,#names-1 do
+ local name=names[i]
+ t[name]=t[name] or {}
+ t=t[name]
+ if not t then
+ return
end
- t[names[#names]]=v
+ end
+ t[names[#names]]=v
end
function tables.removevalue(t,value)
- if value then
- for i=1,#t do
- if t[i]==value then
- remove(t,i)
- end
- end
+ if value then
+ for i=1,#t do
+ if t[i]==value then
+ remove(t,i)
+ end
end
+ end
end
function tables.replacevalue(t,oldvalue,newvalue)
- if oldvalue and newvalue then
- for i=1,#t do
- if t[i]==oldvalue then
- t[i]=newvalue
- end
- end
+ if oldvalue and newvalue then
+ for i=1,#t do
+ if t[i]==oldvalue then
+ t[i]=newvalue
+ end
end
+ end
end
function tables.insertbeforevalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i,extra)
+ return
end
- insert(t,1,extra)
+ end
+ insert(t,1,extra)
end
function tables.insertaftervalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i+1,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i+1,extra)
+ return
end
- insert(t,#t+1,extra)
+ end
+ insert(t,#t+1,extra)
end
local escape=Cs(Cc('"')*((P('"')/'""'+P(1))^0)*Cc('"'))
function table.tocsv(t,specification)
- if t and #t>0 then
- local result={}
- local r={}
- specification=specification or {}
- local fields=specification.fields
- if type(fields)~="string" then
- fields=sortedkeys(t[1])
- end
- local separator=specification.separator or ","
- local noffields=#fields
- if specification.preamble==true then
- for f=1,noffields do
- r[f]=lpegmatch(escape,tostring(fields[f]))
- end
- result[1]=concat(r,separator)
- end
- for i=1,#t do
- local ti=t[i]
- for f=1,noffields do
- local field=ti[fields[f]]
- if type(field)=="string" then
- r[f]=lpegmatch(escape,field)
- else
- r[f]=tostring(field)
- end
- end
- result[i+1]=concat(r,separator)
+ if t and #t>0 then
+ local result={}
+ local r={}
+ specification=specification or {}
+ local fields=specification.fields
+ if type(fields)~="string" then
+ fields=sortedkeys(t[1])
+ end
+ local separator=specification.separator or ","
+ local noffields=#fields
+ if specification.preamble==true then
+ for f=1,noffields do
+ r[f]=lpegmatch(escape,tostring(fields[f]))
+ end
+ result[1]=concat(r,separator)
+ end
+ for i=1,#t do
+ local ti=t[i]
+ for f=1,noffields do
+ local field=ti[fields[f]]
+ if type(field)=="string" then
+ r[f]=lpegmatch(escape,field)
+ else
+ r[f]=tostring(field)
end
- return concat(result,"\n")
- else
- return ""
+ end
+ result[i+1]=concat(r,separator)
end
+ return concat(result,"\n")
+ else
+ return ""
+ end
end
local nspaces=utilities.strings.newrepeater(" ")
local function toxml(t,d,result,step)
- local r=#result
- for k,v in sortedpairs(t) do
- local s=nspaces[d]
- local tk=type(k)
- local tv=type(v)
- if tv=="table" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</entry>"](s,k)
- else
- r=r+1 result[r]=formatters["%s<%s>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</%s>"](s,k)
- end
- elseif tv=="string" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
- end
- elseif tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
- end
+ local r=#result
+ for k,v in sortedpairs(t) do
+ local s=nspaces[d]
+ local tk=type(k)
+ local tv=type(v)
+ if tv=="table" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</entry>"](s,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</%s>"](s,k)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
+ end
+ elseif tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
end
+ end
end
function table.toxml(t,specification)
- specification=specification or {}
- local name=specification.name
- local noroot=name==false
- local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
- local indent=specification.indent or 0
- local spaces=specification.spaces or 1
- if noroot then
- toxml(t,indent,result,spaces)
- else
- toxml({ [name or "data"]=t },indent,result,spaces)
- end
- return concat(result,"\n")
+ specification=specification or {}
+ local name=specification.name
+ local noroot=name==false
+ local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
+ local indent=specification.indent or 0
+ local spaces=specification.spaces or 1
+ if noroot then
+ toxml(t,indent,result,spaces)
+ else
+ toxml({ [name or "data"]=t },indent,result,spaces)
+ end
+ return concat(result,"\n")
end
function tables.encapsulate(core,capsule,protect)
- if type(capsule)~="table" then
- protect=true
- capsule={}
- end
+ if type(capsule)~="table" then
+ protect=true
+ capsule={}
+ end
+ for key,value in next,core do
+ if capsule[key] then
+ print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
+ os.exit()
+ else
+ capsule[key]=value
+ end
+ end
+ if protect then
for key,value in next,core do
+ core[key]=nil
+ end
+ setmetatable(core,{
+ __index=capsule,
+ __newindex=function(t,key,value)
if capsule[key] then
- print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
- os.exit()
+ print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
+ os.exit()
else
- capsule[key]=value
+ rawset(t,key,value)
end
- end
- if protect then
- for key,value in next,core do
- core[key]=nil
- end
- setmetatable(core,{
- __index=capsule,
- __newindex=function(t,key,value)
- if capsule[key] then
- print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
- os.exit()
- else
- rawset(t,key,value)
- end
- end
- } )
- end
+ end
+ } )
+ end
end
local f_hashed_string=formatters["[%q]=%q,"]
local f_hashed_number=formatters["[%q]=%s,"]
@@ -7441,157 +7441,157 @@ local f_ordered_string=formatters["%q,"]
local f_ordered_number=formatters["%s,"]
local f_ordered_boolean=formatters["%l,"]
function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- for i=0,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
- end
- end
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ for i=0,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
- end
- end
- else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
- end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ else
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_hashed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_hashed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_hashed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
- return r
+ end
end
- return concat(fastserialize(t,true))
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
+ end
+ return concat(fastserialize(t,true))
end
function table.deserialize(str)
- if not str or str=="" then
- return
- end
- local code=load(str)
- if not code then
- return
- end
- code=code()
- if not code then
- return
- end
- return code
+ if not str or str=="" then
+ return
+ end
+ local code=load(str)
+ if not code then
+ return
+ end
+ code=code()
+ if not code then
+ return
+ end
+ return code
end
function table.load(filename,loader)
- if filename then
- local t=(loader or io.loaddata)(filename)
- if t and t~="" then
- local t=utftoeight(t)
- t=load(t)
- if type(t)=="function" then
- t=t()
- if type(t)=="table" then
- return t
- end
- end
+ if filename then
+ local t=(loader or io.loaddata)(filename)
+ if t and t~="" then
+ local t=utftoeight(t)
+ t=load(t)
+ if type(t)=="function" then
+ t=t()
+ if type(t)=="table" then
+ return t
end
+ end
end
+ end
end
function table.save(filename,t,n,...)
- io.savedata(filename,table.serialize(t,n==nil and true or n,...))
+ io.savedata(filename,table.serialize(t,n==nil and true or n,...))
end
local f_key_value=formatters["%s=%q"]
local f_add_table=formatters[" {%t},\n"]
local f_return_table=formatters["return {\n%t}"]
local function slowdrop(t)
- local r={}
- local l={}
- for i=1,#t do
- local ti=t[i]
- local j=0
- for k,v in next,ti do
- j=j+1
- l[j]=f_key_value(k,v)
- end
- r[i]=f_add_table(l)
- end
- return f_return_table(r)
+ local r={}
+ local l={}
+ for i=1,#t do
+ local ti=t[i]
+ local j=0
+ for k,v in next,ti do
+ j=j+1
+ l[j]=f_key_value(k,v)
+ end
+ r[i]=f_add_table(l)
+ end
+ return f_return_table(r)
end
local function fastdrop(t)
- local r={ "return {\n" }
- local m=1
- for i=1,#t do
- local ti=t[i]
- m=m+1 r[m]=" {"
- for k,v in next,ti do
- m=m+1 r[m]=f_key_value(k,v)
- end
- m=m+1 r[m]="},\n"
- end
- m=m+1
- r[m]="}"
- return concat(r)
+ local r={ "return {\n" }
+ local m=1
+ for i=1,#t do
+ local ti=t[i]
+ m=m+1 r[m]=" {"
+ for k,v in next,ti do
+ m=m+1 r[m]=f_key_value(k,v)
+ end
+ m=m+1 r[m]="},\n"
+ end
+ m=m+1
+ r[m]="}"
+ return concat(r)
end
function table.drop(t,slow)
- if #t==0 then
- return "return { }"
- elseif slow==true then
- return slowdrop(t)
- else
- return fastdrop(t)
- end
+ if #t==0 then
+ return "return { }"
+ elseif slow==true then
+ return slowdrop(t)
+ else
+ return fastdrop(t)
+ end
end
local selfmapper={ __index=function(t,k) t[k]=k return k end }
-function table.twowaymapper(t)
- if not t then
- t={}
- else
- local zero=rawget(t,0)
- for i=zero and 0 or 1,#t do
- local ti=t[i]
- if ti then
- local i=tostring(i)
- t[i]=ti
- t[ti]=i
- end
- end
+function table.twowaymapper(t)
+ if not t then
+ t={}
+ else
+ local zero=rawget(t,0)
+ for i=zero and 0 or 1,#t do
+ local ti=t[i]
+ if ti then
+ local i=tostring(i)
+ t[i]=ti
+ t[ti]=i
+ end
end
- setmetatable(t,selfmapper)
- return t
+ end
+ setmetatable(t,selfmapper)
+ return t
end
local f_start_key_idx=formatters["%w{"]
local f_start_key_num=formatters["%w[%s]={"]
@@ -7629,223 +7629,223 @@ local spaces=utilities.strings.newrepeater(" ")
local original_serialize=table.serialize
local is_simple_table=table.is_simple_table
local function serialize(root,name,specification)
- if type(specification)=="table" then
- return original_serialize(root,name,specification)
- end
- local t
- local n=1
- local unknown=false
- local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- n=n+1
- if indexed then
- t[n]=f_start_key_idx(depth)
+ if type(specification)=="table" then
+ return original_serialize(root,name,specification)
+ end
+ local t
+ local n=1
+ local unknown=false
+ local function do_serialize(root,name,depth,level,indexed)
+ if level>0 then
+ n=n+1
+ if indexed then
+ t[n]=f_start_key_idx(depth)
+ else
+ local tn=type(name)
+ if tn=="number" then
+ t[n]=f_start_key_num(depth,name)
+ elseif tn=="string" then
+ t[n]=f_start_key_str(depth,name)
+ elseif tn=="boolean" then
+ t[n]=f_start_key_boo(depth,name)
+ else
+ t[n]=f_start_key_nop(depth)
+ end
+ end
+ depth=depth+1
+ end
+ if root and next(root)~=nil then
+ local first=nil
+ local last=0
+ last=#root
+ for k=1,last do
+ if rawget(root,k)==nil then
+ last=k-1
+ break
+ end
+ end
+ if last>0 then
+ first=1
+ end
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if first and tk=="number" and k<=last and k>=first then
+ if tv=="number" then
+ n=n+1 t[n]=f_val_num(depth,v)
+ elseif tv=="string" then
+ n=n+1 t[n]=f_val_str(depth,v)
+ elseif tv=="table" then
+ if next(v)==nil then
+ n=n+1 t[n]=f_val_not(depth)
else
- local tn=type(name)
- if tn=="number" then
- t[n]=f_start_key_num(depth,name)
- elseif tn=="string" then
- t[n]=f_start_key_str(depth,name)
- elseif tn=="boolean" then
- t[n]=f_start_key_boo(depth,name)
- else
- t[n]=f_start_key_nop(depth)
- end
- end
- depth=depth+1
- end
- if root and next(root)~=nil then
- local first=nil
- local last=0
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
+ local st=is_simple_table(v)
+ if st then
+ n=n+1 t[n]=f_val_seq(depth,st)
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
end
- if last>0 then
- first=1
+ elseif tv=="boolean" then
+ n=n+1 t[n]=f_val_boo(depth,v)
+ elseif unknown then
+ n=n+1 t[n]=f_val_str(depth,tostring(v))
+ end
+ elseif tv=="number" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_num(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_num(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
+ end
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_not(depth,k)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_not(depth,k)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_not(depth,k)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
end
- local sk=sortedkeys(root)
- for i=1,#sk do
- local k=sk[i]
- local v=root[k]
- local tv=type(v)
- local tk=type(k)
- if first and tk=="number" and k<=last and k>=first then
- if tv=="number" then
- n=n+1 t[n]=f_val_num(depth,v)
- elseif tv=="string" then
- n=n+1 t[n]=f_val_str(depth,v)
- elseif tv=="table" then
- if next(v)==nil then
- n=n+1 t[n]=f_val_not(depth)
- else
- local st=is_simple_table(v)
- if st then
- n=n+1 t[n]=f_val_seq(depth,st)
- else
- do_serialize(v,k,depth,level+1,true)
- end
- end
- elseif tv=="boolean" then
- n=n+1 t[n]=f_val_boo(depth,v)
- elseif unknown then
- n=n+1 t[n]=f_val_str(depth,tostring(v))
- end
- elseif tv=="number" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_num(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_num(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
- end
- elseif tv=="string" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_not(depth,k)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_not(depth,k)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_not(depth,k)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
- end
- else
- local st=is_simple_table(v)
- if not st then
- do_serialize(v,k,depth,level+1)
- elseif tk=="number" then
- n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
- end
- end
- elseif tv=="boolean" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
- end
- else
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
- end
- end
+ else
+ local st=is_simple_table(v)
+ if not st then
+ do_serialize(v,k,depth,level+1)
+ elseif tk=="number" then
+ n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
end
- end
- if level>0 then
- n=n+1 t[n]=f_stop(depth-1)
- end
- end
- local tname=type(name)
- if tname=="string" then
- if name=="return" then
- t={ f_table_return() }
- else
- t={ f_table_name(name) }
- end
- elseif tname=="number" then
- t={ f_table_entry(name) }
- elseif tname=="boolean" then
- if name then
- t={ f_table_return() }
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
+ end
else
- t={ f_table_direct() }
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
+ end
end
+ end
+ end
+ if level>0 then
+ n=n+1 t[n]=f_stop(depth-1)
+ end
+ end
+ local tname=type(name)
+ if tname=="string" then
+ if name=="return" then
+ t={ f_table_return() }
else
- t={ f_table_name("t") }
+ t={ f_table_name(name) }
end
- if root then
- if getmetatable(root) then
- local dummy=root._w_h_a_t_e_v_e_r_
- root._w_h_a_t_e_v_e_r_=nil
- end
- if next(root)~=nil then
- local st=is_simple_table(root)
- if st then
- return t[1]..f_fin_seq(st)
- else
- do_serialize(root,name,1,0)
- end
- end
+ elseif tname=="number" then
+ t={ f_table_entry(name) }
+ elseif tname=="boolean" then
+ if name then
+ t={ f_table_return() }
+ else
+ t={ f_table_direct() }
+ end
+ else
+ t={ f_table_name("t") }
+ end
+ if root then
+ if getmetatable(root) then
+ local dummy=root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_=nil
+ end
+ if next(root)~=nil then
+ local st=is_simple_table(root)
+ if st then
+ return t[1]..f_fin_seq(st)
+ else
+ do_serialize(root,name,1,0)
+ end
end
- n=n+1
- t[n]=f_table_finish()
- return concat(t,"\n")
+ end
+ n=n+1
+ t[n]=f_table_finish()
+ return concat(t,"\n")
end
table.serialize=serialize
if setinspector then
- setinspector("table",function(v)
- if type(v)=="table" then
- print(serialize(v,"table",{ metacheck=false }))
- return true
- end
- end)
+ setinspector("table",function(v)
+ if type(v)=="table" then
+ print(serialize(v,"table",{ metacheck=false }))
+ return true
+ end
+ end)
end
local mt={
- __newindex=function(t,k,v)
- local n=t.last+1
- t.last=n
- t.list[n]=k
- t.hash[k]=v
- end,
- __index=function(t,k)
- return t.hash[k]
- end,
- __len=function(t)
- return t.last
- end,
+ __newindex=function(t,k,v)
+ local n=t.last+1
+ t.last=n
+ t.list[n]=k
+ t.hash[k]=v
+ end,
+ __index=function(t,k)
+ return t.hash[k]
+ end,
+ __len=function(t)
+ return t.last
+ end,
}
function table.orderedhash()
- return setmetatable({ list={},hash={},last=0 },mt)
+ return setmetatable({ list={},hash={},last=0 },mt)
end
function table.ordered(t)
- local n=t.last
- if n>0 then
- local l=t.list
- local i=1
- local h=t.hash
- local f=function()
- if i<=n then
- local k=i
- local v=h[l[k]]
- i=i+1
- return k,v
- end
- end
- return f,1,h[l[1]]
- else
- return function() end
+ local n=t.last
+ if n>0 then
+ local l=t.list
+ local i=1
+ local h=t.hash
+ local f=function()
+ if i<=n then
+ local k=i
+ local v=h[l[k]]
+ i=i+1
+ return k,v
+ end
end
+ return f,1,h[l[1]]
+ else
+ return function() end
+ end
end
@@ -7855,14 +7855,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fil"] = package.loaded["util-fil"] or true
--- original size: 8607, stripped down to: 6990
+-- original size: 8607, stripped down to: 6727
if not modules then modules={} end modules ['util-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber=tonumber
local byte=string.byte
@@ -7872,280 +7872,280 @@ local files={}
utilities.files=files
local zerobased={}
function files.open(filename,zb)
- local f=io.open(filename,"rb")
- if f then
- zerobased[f]=zb or false
- end
- return f
+ local f=io.open(filename,"rb")
+ if f then
+ zerobased[f]=zb or false
+ end
+ return f
end
function files.close(f)
- zerobased[f]=nil
- f:close()
+ zerobased[f]=nil
+ f:close()
end
function files.size(f)
- local current=f:seek()
- local size=f:seek("end")
- f:seek("set",current)
- return size
+ local current=f:seek()
+ local size=f:seek("end")
+ f:seek("set",current)
+ return size
end
files.getsize=files.size
function files.setposition(f,n)
- if zerobased[f] then
- f:seek("set",n)
- else
- f:seek("set",n-1)
- end
+ if zerobased[f] then
+ f:seek("set",n)
+ else
+ f:seek("set",n-1)
+ end
end
function files.getposition(f)
- if zerobased[f] then
- return f:seek()
- else
- return f:seek()+1
- end
+ if zerobased[f] then
+ return f:seek()
+ else
+ return f:seek()+1
+ end
end
function files.look(f,n,chars)
- local p=f:seek()
- local s=f:read(n)
- f:seek("set",p)
- if chars then
- return s
- else
- return byte(s,1,#s)
- end
+ local p=f:seek()
+ local s=f:read(n)
+ f:seek("set",p)
+ if chars then
+ return s
+ else
+ return byte(s,1,#s)
+ end
end
function files.skip(f,n)
- if n==1 then
- f:read(n)
- else
- f:seek("set",f:seek()+n)
- end
+ if n==1 then
+ f:read(n)
+ else
+ f:seek("set",f:seek()+n)
+ end
end
function files.readbyte(f)
- return byte(f:read(1))
+ return byte(f:read(1))
end
function files.readbytes(f,n)
- return byte(f:read(n),1,n)
+ return byte(f:read(n),1,n)
end
function files.readbytetable(f,n)
- local s=f:read(n or 1)
- return { byte(s,1,#s) }
+ local s=f:read(n or 1)
+ return { byte(s,1,#s) }
end
function files.readchar(f)
- return f:read(1)
+ return f:read(1)
end
function files.readstring(f,n)
- return f:read(n or 1)
+ return f:read(n or 1)
end
-function files.readinteger1(f)
- local n=byte(f:read(1))
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+function files.readinteger1(f)
+ local n=byte(f:read(1))
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-files.readcardinal1=files.readbyte
+files.readcardinal1=files.readbyte
files.readcardinal=files.readcardinal1
files.readinteger=files.readinteger1
files.readsignedbyte=files.readinteger1
function files.readcardinal2(f)
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
end
function files.readcardinal2le(f)
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
end
function files.readinteger2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function files.readinteger2le(f)
- local b,a=byte(f:read(2),1,2)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local b,a=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function files.readcardinal3(f)
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
end
function files.readcardinal3le(f)
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
end
function files.readinteger3(f)
- local a,b,c=byte(f:read(3),1,3)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local a,b,c=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function files.readinteger3le(f)
- local c,b,a=byte(f:read(3),1,3)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local c,b,a=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function files.readcardinal4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function files.readcardinal4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function files.readinteger4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function files.readinteger4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local d,c,b,a=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function files.readfixed2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- tonumber((a-0x100).."."..b)
- else
- tonumber((a ).."."..b)
- end
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function files.readfixed4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
- else
- tonumber((0x100*a+b ).."."..(0x100*c+d))
- end
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
end
if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function files.read2dot14(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- local n=-(0x100*a+b)
- return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- else
- local n=0x100*a+b
- return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- end
+ local extract=bit32.extract
+ local band=bit32.band
+ function files.read2dot14(f)
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+ else
+ local n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function files.skipshort(f,n)
- f:read(2*(n or 1))
+ f:read(2*(n or 1))
end
function files.skiplong(f,n)
- f:read(4*(n or 1))
+ f:read(4*(n or 1))
end
if bit32 then
- local rshift=bit32.rshift
- function files.writecardinal2(f,n)
- local a=char(n%256)
- n=rshift(n,8)
- local b=char(n%256)
- f:write(b,a)
- end
-else
- local floor=math.floor
- function files.writecardinal2(f,n)
- local a=char(n%256)
- n=floor(n/256)
- local b=char(n%256)
- f:write(b,a)
- end
-end
-function files.writecardinal4(f,n)
+ local rshift=bit32.rshift
+ function files.writecardinal2(f,n)
local a=char(n%256)
n=rshift(n,8)
local b=char(n%256)
- n=rshift(n,8)
- local c=char(n%256)
- n=rshift(n,8)
- local d=char(n%256)
- f:write(d,c,b,a)
+ f:write(b,a)
+ end
+else
+ local floor=math.floor
+ function files.writecardinal2(f,n)
+ local a=char(n%256)
+ n=floor(n/256)
+ local b=char(n%256)
+ f:write(b,a)
+ end
+end
+function files.writecardinal4(f,n)
+ local a=char(n%256)
+ n=rshift(n,8)
+ local b=char(n%256)
+ n=rshift(n,8)
+ local c=char(n%256)
+ n=rshift(n,8)
+ local d=char(n%256)
+ f:write(d,c,b,a)
end
function files.writestring(f,s)
- f:write(char(byte(s,1,#s)))
+ f:write(char(byte(s,1,#s)))
end
function files.writebyte(f,b)
- f:write(char(b))
+ f:write(char(b))
end
if fio and fio.readcardinal1 then
- files.readcardinal1=fio.readcardinal1
- files.readcardinal2=fio.readcardinal2
- files.readcardinal3=fio.readcardinal3
- files.readcardinal4=fio.readcardinal4
- files.readinteger1=fio.readinteger1
- files.readinteger2=fio.readinteger2
- files.readinteger3=fio.readinteger3
- files.readinteger4=fio.readinteger4
- files.readfixed2=fio.readfixed2
- files.readfixed4=fio.readfixed4
- files.read2dot14=fio.read2dot14
- files.setposition=fio.setposition
- files.getposition=fio.getposition
- files.readbyte=files.readcardinal1
- files.readsignedbyte=files.readinteger1
- files.readcardinal=files.readcardinal1
- files.readinteger=files.readinteger1
- local skipposition=fio.skipposition
- files.skipposition=skipposition
- files.readbytes=fio.readbytes
- files.readbytetable=fio.readbytetable
- function files.skipshort(f,n)
- skipposition(f,2*(n or 1))
- end
- function files.skiplong(f,n)
- skipposition(f,4*(n or 1))
- end
+ files.readcardinal1=fio.readcardinal1
+ files.readcardinal2=fio.readcardinal2
+ files.readcardinal3=fio.readcardinal3
+ files.readcardinal4=fio.readcardinal4
+ files.readinteger1=fio.readinteger1
+ files.readinteger2=fio.readinteger2
+ files.readinteger3=fio.readinteger3
+ files.readinteger4=fio.readinteger4
+ files.readfixed2=fio.readfixed2
+ files.readfixed4=fio.readfixed4
+ files.read2dot14=fio.read2dot14
+ files.setposition=fio.setposition
+ files.getposition=fio.getposition
+ files.readbyte=files.readcardinal1
+ files.readsignedbyte=files.readinteger1
+ files.readcardinal=files.readcardinal1
+ files.readinteger=files.readinteger1
+ local skipposition=fio.skipposition
+ files.skipposition=skipposition
+ files.readbytes=fio.readbytes
+ files.readbytetable=fio.readbytetable
+ function files.skipshort(f,n)
+ skipposition(f,2*(n or 1))
+ end
+ function files.skiplong(f,n)
+ skipposition(f,4*(n or 1))
+ end
end
if fio and fio.readcardinaltable then
- files.readcardinaltable=fio.readcardinaltable
- files.readintegertable=fio.readintegertable
+ files.readcardinaltable=fio.readcardinaltable
+ files.readintegertable=fio.readintegertable
else
- local readcardinal1=files.readcardinal1
- local readcardinal2=files.readcardinal2
- local readcardinal3=files.readcardinal3
- local readcardinal4=files.readcardinal4
- function files.readcardinaltable(f,n,b)
- local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
- return t
- end
- local readinteger1=files.readinteger1
- local readinteger2=files.readinteger2
- local readinteger3=files.readinteger3
- local readinteger4=files.readinteger4
- function files.readintegertable(f,n,b)
- local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
- return t
- end
+ local readcardinal1=files.readcardinal1
+ local readcardinal2=files.readcardinal2
+ local readcardinal3=files.readcardinal3
+ local readcardinal4=files.readcardinal4
+ function files.readcardinaltable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readcardinal1(f) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
+ return t
+ end
+ local readinteger1=files.readinteger1
+ local readinteger2=files.readinteger2
+ local readinteger3=files.readinteger3
+ local readinteger4=files.readinteger4
+ function files.readintegertable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readinteger1(f) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
+ return t
+ end
end
@@ -8155,14 +8155,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sac"] = package.loaded["util-sac"] or true
--- original size: 11065, stripped down to: 8695
+-- original size: 11065, stripped down to: 8209
if not modules then modules={} end modules ['util-sac']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local byte,sub=string.byte,string.sub
local tonumber=tonumber
@@ -8170,397 +8170,397 @@ utilities=utilities or {}
local streams={}
utilities.streams=streams
function streams.open(filename,zerobased)
- local f=filename and io.loaddata(filename)
- if f then
- return { f,1,#f,zerobased or false }
- end
+ local f=filename and io.loaddata(filename)
+ if f then
+ return { f,1,#f,zerobased or false }
+ end
end
function streams.openstring(f,zerobased)
- if f then
- return { f,1,#f,zerobased or false }
- end
+ if f then
+ return { f,1,#f,zerobased or false }
+ end
end
function streams.close()
end
function streams.size(f)
- return f and f[3] or 0
+ return f and f[3] or 0
end
function streams.setposition(f,i)
- if f[4] then
- if i<=0 then
- f[2]=1
- else
- f[2]=i+1
- end
+ if f[4] then
+ if i<=0 then
+ f[2]=1
else
- if i<=1 then
- f[2]=1
- else
- f[2]=i
- end
+ f[2]=i+1
end
-end
-function streams.getposition(f)
- if f[4] then
- return f[2]-1
+ else
+ if i<=1 then
+ f[2]=1
else
- return f[2]
+ f[2]=i
end
+ end
+end
+function streams.getposition(f)
+ if f[4] then
+ return f[2]-1
+ else
+ return f[2]
+ end
end
function streams.look(f,n,chars)
- local b=f[2]
- local e=b+n-1
- if chars then
- return sub(f[1],b,e)
- else
- return byte(f[1],b,e)
- end
+ local b=f[2]
+ local e=b+n-1
+ if chars then
+ return sub(f[1],b,e)
+ else
+ return byte(f[1],b,e)
+ end
end
function streams.skip(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readbyte(f)
- local i=f[2]
- f[2]=i+1
- return byte(f[1],i)
+ local i=f[2]
+ f[2]=i+1
+ return byte(f[1],i)
end
function streams.readbytes(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return byte(f[1],i,j-1)
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return byte(f[1],i,j-1)
end
function streams.readbytetable(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return { byte(f[1],i,j-1) }
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return { byte(f[1],i,j-1) }
end
function streams.skipbytes(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readchar(f)
- local i=f[2]
- f[2]=i+1
- return sub(f[1],i,i)
+ local i=f[2]
+ f[2]=i+1
+ return sub(f[1],i,i)
end
function streams.readstring(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return sub(f[1],i,j-1)
-end
-function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- local n=byte(f[1],i)
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return sub(f[1],i,j-1)
+end
+function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ local n=byte(f[1],i)
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-streams.readcardinal1=streams.readbyte
+streams.readcardinal1=streams.readbyte
streams.readcardinal=streams.readcardinal1
streams.readinteger=streams.readinteger1
function streams.readcardinal2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readcardinal2LE(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readinteger2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readinteger2le(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readcardinal3(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readcardinal3le(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readinteger3(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readinteger3le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readcardinal4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function streams.readinteger4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function streams.readinteger4le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local d,c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local d,c,b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function streams.readfixed2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- tonumber((a-0x100).."."..b)
- else
- tonumber((a ).."."..b)
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function streams.readfixed4(f)
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
+end
+if bit32 then
+ local extract=bit32.extract
+ local band=bit32.band
+ function streams.read2dot14(f)
local i=f[2]
- local j=i+3
+ local j=i+1
f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
+ local a,b=byte(f[1],i,j)
if a>=0x80 then
- tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
else
- tonumber((0x100*a+b ).."."..(0x100*c+d))
- end
-end
-if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function streams.read2dot14(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- local n=-(0x100*a+b)
- return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- else
- local n=0x100*a+b
- return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- end
+ local n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function streams.skipshort(f,n)
- f[2]=f[2]+2*(n or 1)
+ f[2]=f[2]+2*(n or 1)
end
function streams.skiplong(f,n)
- f[2]=f[2]+4*(n or 1)
+ f[2]=f[2]+4*(n or 1)
end
if sio and sio.readcardinal2 then
- local readcardinal1=sio.readcardinal1
- local readcardinal2=sio.readcardinal2
- local readcardinal3=sio.readcardinal3
- local readcardinal4=sio.readcardinal4
- local readinteger1=sio.readinteger1
- local readinteger2=sio.readinteger2
- local readinteger3=sio.readinteger3
- local readinteger4=sio.readinteger4
- local readfixed2=sio.readfixed2
- local readfixed4=sio.readfixed4
- local read2dot14=sio.read2dot14
- local readbytes=sio.readbytes
- local readbytetable=sio.readbytetable
- function streams.readcardinal1(f)
- local i=f[2]
- f[2]=i+1
- return readcardinal1(f[1],i)
- end
- function streams.readcardinal2(f)
- local i=f[2]
- f[2]=i+2
- return readcardinal2(f[1],i)
- end
- function streams.readcardinal3(f)
- local i=f[2]
- f[2]=i+3
- return readcardinal3(f[1],i)
- end
- function streams.readcardinal4(f)
- local i=f[2]
- f[2]=i+4
- return readcardinal4(f[1],i)
- end
- function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- return readinteger1(f[1],i)
- end
- function streams.readinteger2(f)
- local i=f[2]
- f[2]=i+2
- return readinteger2(f[1],i)
- end
- function streams.readinteger3(f)
- local i=f[2]
- f[2]=i+3
- return readinteger3(f[1],i)
- end
- function streams.readinteger4(f)
- local i=f[2]
- f[2]=i+4
- return readinteger4(f[1],i)
- end
- function streams.read2dot4(f)
- local i=f[2]
- f[2]=i+2
- return read2dot4(f[1],i)
- end
- function streams.readbytes(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytes(f[1],i,n)
+ local readcardinal1=sio.readcardinal1
+ local readcardinal2=sio.readcardinal2
+ local readcardinal3=sio.readcardinal3
+ local readcardinal4=sio.readcardinal4
+ local readinteger1=sio.readinteger1
+ local readinteger2=sio.readinteger2
+ local readinteger3=sio.readinteger3
+ local readinteger4=sio.readinteger4
+ local readfixed2=sio.readfixed2
+ local readfixed4=sio.readfixed4
+ local read2dot14=sio.read2dot14
+ local readbytes=sio.readbytes
+ local readbytetable=sio.readbytetable
+ function streams.readcardinal1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readcardinal1(f[1],i)
+ end
+ function streams.readcardinal2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readcardinal2(f[1],i)
+ end
+ function streams.readcardinal3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readcardinal3(f[1],i)
+ end
+ function streams.readcardinal4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readcardinal4(f[1],i)
+ end
+ function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readinteger1(f[1],i)
+ end
+ function streams.readinteger2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readinteger2(f[1],i)
+ end
+ function streams.readinteger3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readinteger3(f[1],i)
+ end
+ function streams.readinteger4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readinteger4(f[1],i)
+ end
+ function streams.read2dot4(f)
+ local i=f[2]
+ f[2]=i+2
+ return read2dot4(f[1],i)
+ end
+ function streams.readbytes(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- function streams.readbytetable(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytetable(f[1],i,n)
+ return readbytes(f[1],i,n)
+ end
+ function streams.readbytetable(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- streams.readbyte=streams.readcardinal1
- streams.readsignedbyte=streams.readinteger1
- streams.readcardinal=streams.readcardinal1
- streams.readinteger=streams.readinteger1
+ return readbytetable(f[1],i,n)
+ end
+ streams.readbyte=streams.readcardinal1
+ streams.readsignedbyte=streams.readinteger1
+ streams.readcardinal=streams.readcardinal1
+ streams.readinteger=streams.readinteger1
end
if sio and sio.readcardinaltable then
- local readcardinaltable=sio.readcardinaltable
- local readintegertable=sio.readintegertable
- function utilities.streams.readcardinaltable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readcardinaltable(f[1],i,n,b)
+ local readcardinaltable=sio.readcardinaltable
+ local readintegertable=sio.readintegertable
+ function utilities.streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- function utilities.streams.readintegertable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readintegertable(f[1],i,n,b)
+ return readcardinaltable(f[1],i,n,b)
+ end
+ function utilities.streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
+ return readintegertable(f[1],i,n,b)
+ end
else
- local readcardinal1=streams.readcardinal1
- local readcardinal2=streams.readcardinal2
- local readcardinal3=streams.readcardinal3
- local readcardinal4=streams.readcardinal4
- function streams.readcardinaltable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
- return t
+ local readcardinal1=streams.readcardinal1
+ local readcardinal2=streams.readcardinal2
+ local readcardinal3=streams.readcardinal3
+ local readcardinal4=streams.readcardinal4
+ function streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- local readinteger1=streams.readinteger1
- local readinteger2=streams.readinteger2
- local readinteger3=streams.readinteger3
- local readinteger4=streams.readinteger4
- function streams.readintegertable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
- return t
+ local t={}
+ if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
+ return t
+ end
+ local readinteger1=streams.readinteger1
+ local readinteger2=streams.readinteger2
+ local readinteger3=streams.readinteger3
+ local readinteger4=streams.readinteger4
+ function streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
+ local t={}
+ if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
+ return t
+ end
end
@@ -8570,168 +8570,168 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sto"] = package.loaded["util-sto"] or true
--- original size: 6661, stripped down to: 3245
+-- original size: 6661, stripped down to: 3074
if not modules then modules={} end modules ['util-sto']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type
utilities=utilities or {}
utilities.storage=utilities.storage or {}
local storage=utilities.storage
function storage.mark(t)
- if not t then
- print("\nfatal error: storage cannot be marked\n")
- os.exit()
- return
- end
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ if not t then
+ print("\nfatal error: storage cannot be marked\n")
+ os.exit()
+ return
+ end
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.allocate(t)
- t=t or {}
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ t=t or {}
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.marked(t)
- local m=getmetatable(t)
- return m and m.__storage__
+ local m=getmetatable(t)
+ return m and m.__storage__
end
function storage.checked(t)
- if not t then
- report("\nfatal error: storage has not been allocated\n")
- os.exit()
- return
- end
- return t
+ if not t then
+ report("\nfatal error: storage has not been allocated\n")
+ os.exit()
+ return
+ end
+ return t
end
function storage.setinitializer(data,initialize)
- local m=getmetatable(data) or {}
- m.__index=function(data,k)
- m.__index=nil
- initialize()
- return data[k]
- end
- setmetatable(data,m)
+ local m=getmetatable(data) or {}
+ m.__index=function(data,k)
+ m.__index=nil
+ initialize()
+ return data[k]
+ end
+ setmetatable(data,m)
end
local keyisvalue={ __index=function(t,k)
- t[k]=k
- return k
+ t[k]=k
+ return k
end }
function storage.sparse(t)
- t=t or {}
- setmetatable(t,keyisvalue)
- return t
-end
-local function f_empty () return "" end
-local function f_self (t,k) t[k]=k return k end
-local function f_table (t,k) local v={} t[k]=v return v end
-local function f_number(t,k) t[k]=0 return 0 end
-local function f_ignore() end
+ t=t or {}
+ setmetatable(t,keyisvalue)
+ return t
+end
+local function f_empty () return "" end
+local function f_self (t,k) t[k]=k return k end
+local function f_table (t,k) local v={} t[k]=v return v end
+local function f_number(t,k) t[k]=0 return 0 end
+local function f_ignore() end
local f_index={
- ["empty"]=f_empty,
- ["self"]=f_self,
- ["table"]=f_table,
- ["number"]=f_number,
+ ["empty"]=f_empty,
+ ["self"]=f_self,
+ ["table"]=f_table,
+ ["number"]=f_number,
}
function table.setmetatableindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- else
- setmetatable(t,{ __index=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ else
+ setmetatable(t,{ __index=i })
+ end
+ return t
end
local f_index={
- ["ignore"]=f_ignore,
+ ["ignore"]=f_ignore,
}
function table.setmetatablenewindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__newindex=i
- else
- setmetatable(t,{ __newindex=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__newindex=i
+ else
+ setmetatable(t,{ __newindex=i })
+ end
+ return t
end
function table.setmetatablecall(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- if m then
- m.__call=f
- else
- setmetatable(t,{ __call=f })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__call=f
+ else
+ setmetatable(t,{ __call=f })
+ end
+ return t
end
function table.setmetatableindices(t,f,n,c)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- m.__newindex=n
- m.__call=c
- else
- setmetatable(t,{
- __index=i,
- __newindex=n,
- __call=c,
- })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ m.__newindex=n
+ m.__call=c
+ else
+ setmetatable(t,{
+ __index=i,
+ __newindex=n,
+ __call=c,
+ })
+ end
+ return t
end
function table.setmetatablekey(t,key,value)
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m[key]=value
- return t
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m[key]=value
+ return t
end
function table.getmetatablekey(t,key,value)
- local m=getmetatable(t)
- return m and m[key]
+ local m=getmetatable(t)
+ return m and m[key]
end
function table.makeweak(t)
- if not t then
- t={}
- end
- local m=getmetatable(t)
- if m then
- m.__mode="v"
- else
- setmetatable(t,{ __mode="v" })
- end
- return t
+ if not t then
+ t={}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__mode="v"
+ else
+ setmetatable(t,{ __mode="v" })
+ end
+ return t
end
@@ -8741,14 +8741,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 23400, stripped down to: 16473
+-- original size: 23400, stripped down to: 15802
if not modules then modules={} end modules ['util-prs']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local lpeg,table,string=lpeg,table,string
local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp
@@ -8790,8 +8790,8 @@ local noparent=1-(lparent+rparent)
local nobracket=1-(lbracket+rbracket)
local escape,left,right=P("\\"),P('{'),P('}')
lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+ [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
+ [2]=left*V(1)*right
}
local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -8799,9 +8799,9 @@ local nestedbrackets=P { lbracket*(nobracket+V(1))^0*rbracket }
local spaces=space^0
local argument=Cs((lbrace/"")*((nobrace+nestedbraces)^0)*(rbrace/""))
local content=(1-endofstring)^0
-lpegpatterns.nestedbraces=nestedbraces
+lpegpatterns.nestedbraces=nestedbraces
lpegpatterns.nestedparents=nestedparents
-lpegpatterns.nested=nestedbraces
+lpegpatterns.nested=nestedbraces
lpegpatterns.argument=argument
lpegpatterns.content=content
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
@@ -8813,7 +8813,7 @@ local key=C((1-space-equal-comma)^1)
local pattern_b=spaces*comma^0*spaces*(key*((spaces*equal*spaces*value)+C("")))
local hash={}
local function set(key,value)
- hash[key]=value
+ hash[key]=value
end
local pattern_a_s=(pattern_a/set)^1
local pattern_b_s=(pattern_b/set)^1
@@ -8824,300 +8824,300 @@ patterns.settings_to_hash_b=pattern_b_s
patterns.settings_to_hash_c=pattern_c_s
patterns.settings_to_hash_d=pattern_d_s
function parsers.make_settings_to_hash_pattern(set,how)
- if how=="strict" then
- return (pattern_c/set)^1
- elseif how=="tolerant" then
- return (pattern_b/set)^1
- else
- return (pattern_a/set)^1
- end
+ if how=="strict" then
+ return (pattern_c/set)^1
+ elseif how=="tolerant" then
+ return (pattern_b/set)^1
+ else
+ return (pattern_a/set)^1
+ end
end
function parsers.settings_to_hash(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_a_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_a_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_colon_too(str)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- else
- hash={}
- lpegmatch(pattern_d_s,str)
- return hash
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ else
+ hash={}
+ lpegmatch(pattern_d_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_tolerant(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_b_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_b_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_strict(str,existing)
- if not str or str=="" then
- return nil
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
- elseif str and str~="" then
- hash=existing or {}
- lpegmatch(pattern_c_s,str)
- return next(hash) and hash
+ if not str or str=="" then
+ return nil
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
+ else
+ return str
end
+ elseif str and str~="" then
+ hash=existing or {}
+ lpegmatch(pattern_c_s,str)
+ return next(hash) and hash
+ end
end
local separator=comma*space^0
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
local pattern=spaces*Ct(value*(separator*value)^0)
patterns.settings_to_array=pattern
function parsers.settings_to_array(str,strict)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- elseif strict then
- if find(str,"{",1,true) then
- return lpegmatch(pattern,str)
- else
- return { str }
- end
- elseif find(str,",",1,true) then
- return lpegmatch(pattern,str)
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ elseif strict then
+ if find(str,"{",1,true) then
+ return lpegmatch(pattern,str)
else
- return { str }
+ return { str }
end
+ elseif find(str,",",1,true) then
+ return lpegmatch(pattern,str)
+ else
+ return { str }
+ end
end
function parsers.settings_to_numbers(str)
- if not str or str=="" then
- return {}
- end
- if type(str)=="table" then
- elseif find(str,",",1,true) then
- str=lpegmatch(pattern,str)
- else
- return { tonumber(str) }
- end
- for i=1,#str do
- str[i]=tonumber(str[i])
- end
- return str
+ if not str or str=="" then
+ return {}
+ end
+ if type(str)=="table" then
+ elseif find(str,",",1,true) then
+ str=lpegmatch(pattern,str)
+ else
+ return { tonumber(str) }
+ end
+ for i=1,#str do
+ str[i]=tonumber(str[i])
+ end
+ return str
end
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
local pattern=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_obey_fences(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache_a={}
local cache_b={}
function parsers.groupedsplitat(symbol,withaction)
- if not symbol then
- symbol=","
- end
- local pattern=(withaction and cache_b or cache_a)[symbol]
- if not pattern then
- local symbols=S(symbol)
- local separator=space^0*symbols*space^0
- local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
- if withaction then
- local withvalue=Carg(1)*value/function(f,s) return f(s) end
- pattern=spaces*withvalue*(separator*withvalue)^0
- cache_b[symbol]=pattern
- else
- pattern=spaces*Ct(value*(separator*value)^0)
- cache_a[symbol]=pattern
- end
- end
- return pattern
+ if not symbol then
+ symbol=","
+ end
+ local pattern=(withaction and cache_b or cache_a)[symbol]
+ if not pattern then
+ local symbols=S(symbol)
+ local separator=space^0*symbols*space^0
+ local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
+ if withaction then
+ local withvalue=Carg(1)*value/function(f,s) return f(s) end
+ pattern=spaces*withvalue*(separator*withvalue)^0
+ cache_b[symbol]=pattern
+ else
+ pattern=spaces*Ct(value*(separator*value)^0)
+ cache_a[symbol]=pattern
+ end
+ end
+ return pattern
end
local pattern_a=parsers.groupedsplitat(",",false)
local pattern_b=parsers.groupedsplitat(",",true)
function parsers.stripped_settings_to_array(str)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_a,str)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_a,str)
+ end
end
function parsers.process_stripped_settings(str,action)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_b,str,1,action)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_b,str,1,action)
+ end
end
local function set(t,v)
- t[#t+1]=v
+ t[#t+1]=v
end
local value=P(Carg(1)*value)/set
local pattern=value*(separator*value)^0*Carg(1)
function parsers.add_settings_to_array(t,str)
- return lpegmatch(pattern,str,nil,t)
+ return lpegmatch(pattern,str,nil,t)
end
function parsers.hash_to_string(h,separator,yes,no,strict,omit)
- if h then
- local t,tn,s={},0,sortedkeys(h)
- omit=omit and tohash(omit)
- for i=1,#s do
- local key=s[i]
- if not omit or not omit[key] then
- local value=h[key]
- if type(value)=="boolean" then
- if yes and no then
- if value then
- tn=tn+1
- t[tn]=key..'='..yes
- elseif not strict then
- tn=tn+1
- t[tn]=key..'='..no
- end
- elseif value or not strict then
- tn=tn+1
- t[tn]=key..'='..tostring(value)
- end
- else
- tn=tn+1
- t[tn]=key..'='..value
- end
- end
+ if h then
+ local t,tn,s={},0,sortedkeys(h)
+ omit=omit and tohash(omit)
+ for i=1,#s do
+ local key=s[i]
+ if not omit or not omit[key] then
+ local value=h[key]
+ if type(value)=="boolean" then
+ if yes and no then
+ if value then
+ tn=tn+1
+ t[tn]=key..'='..yes
+ elseif not strict then
+ tn=tn+1
+ t[tn]=key..'='..no
+ end
+ elseif value or not strict then
+ tn=tn+1
+ t[tn]=key..'='..tostring(value)
+ end
+ else
+ tn=tn+1
+ t[tn]=key..'='..value
end
- return concat(t,separator or ",")
- else
- return ""
+ end
end
+ return concat(t,separator or ",")
+ else
+ return ""
+ end
end
function parsers.array_to_string(a,separator)
- if a then
- return concat(a,separator or ",")
- else
- return ""
- end
+ if a then
+ return concat(a,separator or ",")
+ else
+ return ""
+ end
end
local pattern=Cf(Ct("")*Cg(C((1-S(", "))^1)*S(", ")^0*Cc(true))^1,rawset)
function utilities.parsers.settings_to_set(str)
- return str and lpegmatch(pattern,str) or {}
+ return str and lpegmatch(pattern,str) or {}
end
hashes.settings_to_set=table.setmetatableindex(function(t,k)
- local v=k and lpegmatch(pattern,k) or {}
- t[k]=v
- return v
+ local v=k and lpegmatch(pattern,k) or {}
+ t[k]=v
+ return v
end)
getmetatable(hashes.settings_to_set).__mode="kv"
function parsers.simple_hash_to_string(h,separator)
- local t,tn={},0
- for k,v in sortedhash(h) do
- if v then
- tn=tn+1
- t[tn]=k
- end
+ local t,tn={},0
+ for k,v in sortedhash(h) do
+ if v then
+ tn=tn+1
+ t[tn]=k
end
- return concat(t,separator or ",")
+ end
+ return concat(t,separator or ",")
end
local str=Cs(lpegpatterns.unquoted)+C((1-whitespace-equal)^1)
local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset)
local splitter=setting^1
function utilities.parsers.options_to_hash(str,target)
- return str and lpegmatch(splitter,str,1,target or {}) or {}
+ return str and lpegmatch(splitter,str,1,target or {}) or {}
end
local splitter=lpeg.tsplitat(" ")
function utilities.parsers.options_to_array(str)
- return str and lpegmatch(splitter,str) or {}
+ return str and lpegmatch(splitter,str) or {}
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1)
local pattern_a=spaces*Ct(value*(separator*value)^0)
local function repeater(n,str)
- if not n then
- return str
+ if not n then
+ return str
+ else
+ local s=lpegmatch(pattern_a,str)
+ if n==1 then
+ return unpack(s)
else
- local s=lpegmatch(pattern_a,str)
- if n==1 then
- return unpack(s)
- else
- local t,tn={},0
- for i=1,n do
- for j=1,#s do
- tn=tn+1
- t[tn]=s[j]
- end
- end
- return unpack(t)
+ local t,tn={},0
+ for i=1,n do
+ for j=1,#s do
+ tn=tn+1
+ t[tn]=s[j]
end
+ end
+ return unpack(t)
end
+ end
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+(C(digit^1)/tonumber*lparent*Cs((noparent+nestedparents)^1)*rparent)/repeater+C((nestedbraces+(1-comma))^1)
local pattern_b=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_with_repeat(str,expand)
- if expand then
- return lpegmatch(pattern_b,str) or {}
- else
- return lpegmatch(pattern_a,str) or {}
- end
+ if expand then
+ return lpegmatch(pattern_b,str) or {}
+ else
+ return lpegmatch(pattern_a,str) or {}
+ end
end
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace
local pattern=Ct((space+value)^0)
function parsers.arguments_to_table(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function parsers.getparameters(self,class,parentclass,settings)
- local sc=self[class]
- if not sc then
- sc={}
- self[class]=sc
- if parentclass then
- local sp=self[parentclass]
- if not sp then
- sp={}
- self[parentclass]=sp
- end
- setmetatableindex(sc,sp)
- end
+ local sc=self[class]
+ if not sc then
+ sc={}
+ self[class]=sc
+ if parentclass then
+ local sp=self[parentclass]
+ if not sp then
+ sp={}
+ self[parentclass]=sp
+ end
+ setmetatableindex(sc,sp)
end
- parsers.settings_to_hash(settings,sc)
+ end
+ parsers.settings_to_hash(settings,sc)
end
function parsers.listitem(str)
- return gmatch(str,"[^, ]+")
+ return gmatch(str,"[^, ]+")
end
local pattern=Cs { "start",
- start=V("one")+V("two")+V("three"),
- rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
- thousand=digit*digit*digit,
- one=digit*V("rest"),
- two=digit*digit*V("rest"),
- three=V("thousand")*V("rest"),
+ start=V("one")+V("two")+V("three"),
+ rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
+ thousand=digit*digit*digit,
+ one=digit*V("rest"),
+ two=digit*digit*V("rest"),
+ three=V("thousand")*V("rest"),
}
lpegpatterns.splitthousands=pattern
function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local optionalwhitespace=whitespace^0
lpegpatterns.words=Ct((Cs((1-punctuation-whitespace)^1)+anything)^1)
@@ -9131,75 +9131,75 @@ local key=C((1-equal)^1)
local value=dquote*C((1-dquote-escape*dquote)^0)*dquote
local pattern=Cf(Ct("")*(Cg(key*equal*value)*separator^0)^1,rawset)^0*P(-1)
function parsers.keq_to_hash(str)
- if str and str~="" then
- return lpegmatch(pattern,str)
- else
- return {}
- end
+ if str and str~="" then
+ return lpegmatch(pattern,str)
+ else
+ return {}
+ end
end
local defaultspecification={ separator=",",quote='"' }
function parsers.csvsplitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=specification.quote
- local separator=S(separator~="" and separator or ",")
- local whatever=C((1-separator-newline)^0)
- if quotechar and quotechar~="" then
- local quotedata=nil
- for chr in gmatch(quotechar,".") do
- local quotechar=P(chr)
- local quoteword=quotechar*C((1-quotechar)^0)*quotechar
- if quotedata then
- quotedata=quotedata+quoteword
- else
- quotedata=quoteword
- end
- end
- whatever=quotedata+whatever
- end
- local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
- return function(data)
- return lpegmatch(parser,data)
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=specification.quote
+ local separator=S(separator~="" and separator or ",")
+ local whatever=C((1-separator-newline)^0)
+ if quotechar and quotechar~="" then
+ local quotedata=nil
+ for chr in gmatch(quotechar,".") do
+ local quotechar=P(chr)
+ local quoteword=quotechar*C((1-quotechar)^0)*quotechar
+ if quotedata then
+ quotedata=quotedata+quoteword
+ else
+ quotedata=quoteword
+ end
end
+ whatever=quotedata+whatever
+ end
+ local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
+ return function(data)
+ return lpegmatch(parser,data)
+ end
end
function parsers.rfc4180splitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=P(specification.quote)
- local dquotechar=quotechar*quotechar
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=P(specification.quote)
+ local dquotechar=quotechar*quotechar
/specification.quote
- local separator=S(separator~="" and separator or ",")
- local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
- local non_escaped=C((1-quotechar-newline-separator)^1)
- local field=escaped+non_escaped+Cc("")
- local record=Ct(field*(separator*field)^1)
- local headerline=record*Cp()
- local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
- local headeryes=Ct(morerecords)
- local headernop=Ct(record*morerecords)
- return function(data,getheader)
- if getheader then
- local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(headeryes,data,position)
- return data,header
- else
- return lpegmatch(headernop,data)
- end
- end
+ local separator=S(separator~="" and separator or ",")
+ local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
+ local non_escaped=C((1-quotechar-newline-separator)^1)
+ local field=escaped+non_escaped+Cc("")
+ local record=Ct(field*(separator*field)^1)
+ local headerline=record*Cp()
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
+ return function(data,getheader)
+ if getheader then
+ local header,position=lpegmatch(headerline,data)
+ local data=lpegmatch(headeryes,data,position)
+ return data,header
+ else
+ return lpegmatch(headernop,data)
+ end
+ end
end
local function ranger(first,last,n,action)
- if not first then
- elseif last==true then
- for i=first,n or first do
- action(i)
- end
- elseif last then
- for i=first,last do
- action(i)
- end
- else
- action(first)
+ if not first then
+ elseif last==true then
+ for i=first,n or first do
+ action(i)
+ end
+ elseif last then
+ for i=first,last do
+ action(i)
end
+ else
+ action(first)
+ end
end
local cardinal=lpegpatterns.cardinal/tonumber
local spacers=lpegpatterns.spacer^0
@@ -9207,89 +9207,89 @@ local endofstring=lpegpatterns.endofstring
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
function parsers.stepper(str,n,action)
- if type(n)=="function" then
- lpegmatch(stepper,str,1,false,n or print)
- else
- lpegmatch(stepper,str,1,n,action or print)
- end
+ if type(n)=="function" then
+ lpegmatch(stepper,str,1,false,n or print)
+ else
+ lpegmatch(stepper,str,1,n,action or print)
+ end
end
local pattern_math=Cs((P("%")/"\\percent "+P("^")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
local pattern_text=Cs((P("%")/"\\percent "+(P("^")/"\\high")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
patterns.unittotex=pattern
function parsers.unittotex(str,textmode)
- return lpegmatch(textmode and pattern_text or pattern_math,str)
+ return lpegmatch(textmode and pattern_text or pattern_math,str)
end
local pattern=Cs((P("^")/"<sup>"*lpegpatterns.integer*Cc("</sup>")+anything)^0)
function parsers.unittoxml(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache={}
local spaces=lpegpatterns.space^0
local dummy=function() end
setmetatableindex(cache,function(t,k)
- local separator=P(k)
- local value=(1-separator)^0
- local pattern=spaces*C(value)*separator^0*Cp()
- t[k]=pattern
- return pattern
+ local separator=P(k)
+ local value=(1-separator)^0
+ local pattern=spaces*C(value)*separator^0*Cp()
+ t[k]=pattern
+ return pattern
end)
local commalistiterator=cache[","]
function utilities.parsers.iterator(str,separator)
- local n=#str
- if n==0 then
- return dummy
- else
- local pattern=separator and cache[separator] or commalistiterator
- local p=1
- return function()
- if p<=n then
- local s,e=lpegmatch(pattern,str,p)
- if e then
- p=e
- return s
- end
- end
+ local n=#str
+ if n==0 then
+ return dummy
+ else
+ local pattern=separator and cache[separator] or commalistiterator
+ local p=1
+ return function()
+ if p<=n then
+ local s,e=lpegmatch(pattern,str,p)
+ if e then
+ p=e
+ return s
end
+ end
end
+ end
end
local function initialize(t,name)
- local source=t[name]
- if source then
- local result={}
- for k,v in next,t[name] do
- result[k]=v
- end
- return result
- else
- return {}
+ local source=t[name]
+ if source then
+ local result={}
+ for k,v in next,t[name] do
+ result[k]=v
end
+ return result
+ else
+ return {}
+ end
end
local function fetch(t,name)
- return t[name] or {}
+ return t[name] or {}
end
local function process(result,more)
- for k,v in next,more do
- result[k]=v
- end
- return result
+ for k,v in next,more do
+ result[k]=v
+ end
+ return result
end
local name=C((1-S(", "))^1)
local parser=(Carg(1)*name/initialize)*(S(", ")^1*(Carg(1)*name/fetch))^0
local merge=Cf(parser,process)
function utilities.parsers.mergehashes(hash,list)
- return lpegmatch(merge,list,1,hash)
+ return lpegmatch(merge,list,1,hash)
end
function utilities.parsers.runtime(time)
- if not time then
- time=os.runtime()
- end
- local days=div(time,24*60*60)
- time=mod(time,24*60*60)
- local hours=div(time,60*60)
- time=mod(time,60*60)
- local minutes=div(time,60)
- local seconds=mod(time,60)
- return days,hours,minutes,seconds
+ if not time then
+ time=os.runtime()
+ end
+ local days=div(time,24*60*60)
+ time=mod(time,24*60*60)
+ local hours=div(time,60*60)
+ time=mod(time,60*60)
+ local minutes=div(time,60)
+ local seconds=mod(time,60)
+ return days,hours,minutes,seconds
end
local spacing=whitespace^0
local apply=P("->")
@@ -9297,11 +9297,11 @@ local method=C((1-apply)^1)
local token=lbrace*C((1-rbrace)^1)*rbrace+C(anything^1)
local pattern=spacing*(method*spacing*apply+Carg(1))*spacing*token
function utilities.parsers.splitmethod(str,default)
- if str then
- return lpegmatch(pattern,str,1,default or false)
- else
- return default or false,""
- end
+ if str then
+ return lpegmatch(pattern,str,1,default or false)
+ else
+ return default or false,""
+ end
end
@@ -9311,14 +9311,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fmt"] = package.loaded["util-fmt"] or true
--- original size: 2274, stripped down to: 1781
+-- original size: 2274, stripped down to: 1607
if not modules then modules={} end modules ['util-fmt']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.formatters=utilities.formatters or {}
@@ -9329,60 +9329,60 @@ local strip=string.strip
local lpegmatch=lpeg.match
local stripper=lpeg.patterns.stripzeros
function formatters.stripzeros(str)
- return lpegmatch(stripper,str)
+ return lpegmatch(stripper,str)
end
function formatters.formatcolumns(result,between)
- if result and #result>0 then
- between=between or " "
- local widths,numbers={},{}
- local first=result[1]
- local n=#first
- for i=1,n do
- widths[i]=0
- end
- for i=1,#result do
- local r=result[i]
- for j=1,n do
- local rj=r[j]
- local tj=type(rj)
- if tj=="number" then
- numbers[j]=true
- end
- if tj~="string" then
- rj=tostring(rj)
- r[j]=rj
- end
- local w=#rj
- if w>widths[j] then
- widths[j]=w
- end
- end
+ if result and #result>0 then
+ between=between or " "
+ local widths,numbers={},{}
+ local first=result[1]
+ local n=#first
+ for i=1,n do
+ widths[i]=0
+ end
+ for i=1,#result do
+ local r=result[i]
+ for j=1,n do
+ local rj=r[j]
+ local tj=type(rj)
+ if tj=="number" then
+ numbers[j]=true
+ end
+ if tj~="string" then
+ rj=tostring(rj)
+ r[j]=rj
+ end
+ local w=#rj
+ if w>widths[j] then
+ widths[j]=w
end
- for i=1,n do
- local w=widths[i]
- if numbers[i] then
- if w>80 then
- widths[i]="%s"..between
- else
- widths[i]="%0"..w.."i"..between
- end
- else
- if w>80 then
- widths[i]="%s"..between
- elseif w>0 then
- widths[i]="%-"..w.."s"..between
- else
- widths[i]="%s"
- end
- end
+ end
+ end
+ for i=1,n do
+ local w=widths[i]
+ if numbers[i] then
+ if w>80 then
+ widths[i]="%s"..between
+ else
+ widths[i]="%0"..w.."i"..between
end
- local template=strip(concat(widths))
- for i=1,#result do
- local str=format(template,unpack(result[i]))
- result[i]=strip(str)
+ else
+ if w>80 then
+ widths[i]="%s"..between
+ elseif w>0 then
+ widths[i]="%-"..w.."s"..between
+ else
+ widths[i]="%s"
end
+ end
end
- return result
+ local template=strip(concat(widths))
+ for i=1,#result do
+ local str=format(template,unpack(result[i]))
+ result[i]=strip(str)
+ end
+ end
+ return result
end
@@ -9414,7 +9414,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true
--- original size: 4870, stripped down to: 3861
+-- original size: 4870, stripped down to: 3527
local type,tostring,setmetatable=type,tostring,setmetatable
@@ -9427,67 +9427,67 @@ local tcp6=socket.tcp6
local getaddrinfo=socket.dns.getaddrinfo
local defaulthost="0.0.0.0"
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("socket")
- report(fmt,first,...)
- elseif fmt then
- fmt="socket: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("socket")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="socket: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
socket.report=report
function socket.connect4(address,port,laddress,lport)
- return connect(address,port,laddress,lport,"inet")
+ return connect(address,port,laddress,lport,"inet")
end
function socket.connect6(address,port,laddress,lport)
- return connect(address,port,laddress,lport,"inet6")
+ return connect(address,port,laddress,lport,"inet6")
end
function socket.bind(host,port,backlog)
- if host=="*" or host=="" then
- host=defaulthost
- end
- local addrinfo,err=getaddrinfo(host)
- if not addrinfo then
- return nil,err
- end
- for i=1,#addrinfo do
- local alt=addrinfo[i]
- local sock,err=(alt.family=="inet" and tcp4 or tcp6)()
- if not sock then
- return nil,err or "unknown error"
- end
- sock:setoption("reuseaddr",true)
- local res,err=sock:bind(alt.addr,port)
- if res then
- res,err=sock:listen(backlog)
- if res then
- return sock
- else
- sock:close()
- end
- else
- sock:close()
- end
+ if host=="*" or host=="" then
+ host=defaulthost
+ end
+ local addrinfo,err=getaddrinfo(host)
+ if not addrinfo then
+ return nil,err
+ end
+ for i=1,#addrinfo do
+ local alt=addrinfo[i]
+ local sock,err=(alt.family=="inet" and tcp4 or tcp6)()
+ if not sock then
+ return nil,err or "unknown error"
+ end
+ sock:setoption("reuseaddr",true)
+ local res,err=sock:bind(alt.addr,port)
+ if res then
+ res,err=sock:listen(backlog)
+ if res then
+ return sock
+ else
+ sock:close()
+ end
+ else
+ sock:close()
end
- return nil,"invalid address"
+ end
+ return nil,"invalid address"
end
socket.try=socket.newtry()
function socket.choose(list)
- return function(name,opt1,opt2)
- if type(name)~="string" then
- name,opt1,opt2="default",name,opt1
- end
- local f=list[name or "nil"]
- if f then
- return f(opt1,opt2)
- else
- report("error: unknown key '%s'",tostring(name))
- end
+ return function(name,opt1,opt2)
+ if type(name)~="string" then
+ name,opt1,opt2="default",name,opt1
+ end
+ local f=list[name or "nil"]
+ if f then
+ return f(opt1,opt2)
+ else
+ report("error: unknown key '%s'",tostring(name))
end
+ end
end
local sourcet={}
local sinkt={}
@@ -9495,88 +9495,88 @@ socket.sourcet=sourcet
socket.sinkt=sinkt
socket.BLOCKSIZE=2048
sinkt["close-when-done"]=function(sock)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function(self,chunk,err)
- if chunk then
- return sock:send(chunk)
- else
- sock:close()
- return 1
- end
- end
- }
- )
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },
+ {
+ __call=function(self,chunk,err)
+ if chunk then
+ return sock:send(chunk)
+ else
+ sock:close()
+ return 1
+ end
+ end
+ }
+ )
end
sinkt["keep-open"]=function(sock)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function(self,chunk,err)
- if chunk then
- return sock:send(chunk)
- else
- return 1
- end
- end
- }
- )
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },{
+ __call=function(self,chunk,err)
+ if chunk then
+ return sock:send(chunk)
+ else
+ return 1
+ end
+ end
+ }
+ )
end
sinkt["default"]=sinkt["keep-open"]
socket.sink=socket.choose(sinkt)
sourcet["by-length"]=function(sock,length)
- local blocksize=socket.BLOCKSIZE
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function()
- if length<=0 then
- return nil
- end
- local chunk,err=sock:receive(min(blocksize,length))
- if err then
- return nil,err
- end
- length=length-#chunk
- return chunk
- end
- }
- )
+ local blocksize=socket.BLOCKSIZE
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },
+ {
+ __call=function()
+ if length<=0 then
+ return nil
+ end
+ local chunk,err=sock:receive(min(blocksize,length))
+ if err then
+ return nil,err
+ end
+ length=length-#chunk
+ return chunk
+ end
+ }
+ )
end
sourcet["until-closed"]=function(sock)
- local blocksize=socket.BLOCKSIZE
- local done=false
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function()
- if done then
- return nil
- end
- local chunk,status,partial=sock:receive(blocksize)
- if not status then
- return chunk
- elseif status=="closed" then
- sock:close()
- done=true
- return partial
- else
- return nil,status
- end
- end
- }
- )
+ local blocksize=socket.BLOCKSIZE
+ local done=false
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },{
+ __call=function()
+ if done then
+ return nil
+ end
+ local chunk,status,partial=sock:receive(blocksize)
+ if not status then
+ return chunk
+ elseif status=="closed" then
+ sock:close()
+ done=true
+ return partial
+ else
+ return nil,status
+ end
+ end
+ }
+ )
end
sourcet["default"]=sourcet["until-closed"]
socket.source=socket.choose(sourcet)
@@ -9590,7 +9590,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
--- original size: 25844, stripped down to: 16066
+-- original size: 25844, stripped down to: 14821
local socket=socket or require("socket")
@@ -9608,333 +9608,333 @@ local resumecoroutine=coroutine.resume
local yieldcoroutine=coroutine.yield
local runningcoroutine=coroutine.running
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("copas")
- report(fmt,first,...)
- elseif fmt then
- fmt="copas: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("copas")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="copas: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
local copas={
- _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project",
- _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services",
- _VERSION="Copas 2.0.1",
- autoclose=true,
- running=false,
- report=report,
+ _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project",
+ _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services",
+ _VERSION="Copas 2.0.1",
+ autoclose=true,
+ running=false,
+ report=report,
}
local function statushandler(status,...)
- if status then
- return...
- end
- local err=(...)
- if type(err)=="table" then
- err=err[1]
- end
- report("error: %s",tostring(err))
- return nil,err
+ if status then
+ return...
+ end
+ local err=(...)
+ if type(err)=="table" then
+ err=err[1]
+ end
+ report("error: %s",tostring(err))
+ return nil,err
end
function socket.protect(func)
- return function(...)
- return statushandler(pcall(func,...))
- end
+ return function(...)
+ return statushandler(pcall(func,...))
+ end
end
function socket.newtry(finalizer)
- return function (...)
- local status=(...)
- if not status then
- local detail=select(2,...)
- pcall(finalizer,detail)
- report("error: %s",tostring(detail))
- return
- end
- return...
+ return function (...)
+ local status=(...)
+ if not status then
+ local detail=select(2,...)
+ pcall(finalizer,detail)
+ report("error: %s",tostring(detail))
+ return
end
+ return...
+ end
end
local function newset()
- local reverse={}
- local set={}
- local queue={}
- setmetatable(set,{
- __index={
- insert=function(set,value)
- if not reverse[value] then
- local n=#set+1
- set[n]=value
- reverse[value]=n
- end
- end,
- remove=function(set,value)
- local index=reverse[value]
- if index then
- reverse[value]=nil
- local n=#set
- local top=set[n]
- set[n]=nil
- if top~=value then
- reverse[top]=index
- set[index]=top
- end
- end
- end,
- push=function (set,key,itm)
- local entry=queue[key]
- if entry==nil then
- queue[key]={ itm }
- else
- entry[#entry+1]=itm
- end
- end,
- pop=function (set,key)
- local top=queue[key]
- if top~=nil then
- local ret=remove(top,1)
- if top[1]==nil then
- queue[key]=nil
- end
- return ret
- end
- end
- }
- } )
- return set
-end
-local _sleeping={
- times={},
- cos={},
- lethargy={},
- insert=function()
- end,
- remove=function()
+ local reverse={}
+ local set={}
+ local queue={}
+ setmetatable(set,{
+ __index={
+ insert=function(set,value)
+ if not reverse[value] then
+ local n=#set+1
+ set[n]=value
+ reverse[value]=n
+ end
end,
- push=function(self,sleeptime,co)
- if not co then
- return
- end
- if sleeptime<0 then
- self.lethargy[co]=true
- return
- else
- sleeptime=gettime()+sleeptime
+ remove=function(set,value)
+ local index=reverse[value]
+ if index then
+ reverse[value]=nil
+ local n=#set
+ local top=set[n]
+ set[n]=nil
+ if top~=value then
+ reverse[top]=index
+ set[index]=top
end
- local t=self.times
- local c=self.cos
- local i=1
- local n=#t
- while i<=n and t[i]<=sleeptime do
- i=i+1
- end
- insert(t,i,sleeptime)
- insert(c,i,co)
- end,
- getnext=
- function(self)
- local t=self.times
- local delay=t[1] and t[1]-gettime() or nil
- return delay and max(delay,0) or nil
+ end
end,
- pop=
- function(self,time)
- local t=self.times
- local c=self.cos
- if #t==0 or time<t[1] then
- return
- end
- local co=c[1]
- remove(t,1)
- remove(c,1)
- return co
+ push=function (set,key,itm)
+ local entry=queue[key]
+ if entry==nil then
+ queue[key]={ itm }
+ else
+ entry[#entry+1]=itm
+ end
end,
- wakeup=function(self,co)
- local let=self.lethargy
- if let[co] then
- self:push(0,co)
- let[co]=nil
- else
- local c=self.cos
- local t=self.times
- for i=1,#c do
- if c[i]==co then
- remove(c,i)
- remove(t,i)
- self:push(0,co)
- return
- end
- end
- end
+ pop=function (set,key)
+ local top=queue[key]
+ if top~=nil then
+ local ret=remove(top,1)
+ if top[1]==nil then
+ queue[key]=nil
+ end
+ return ret
+ end
+ end
+ }
+ } )
+ return set
+end
+local _sleeping={
+ times={},
+ cos={},
+ lethargy={},
+ insert=function()
+ end,
+ remove=function()
+ end,
+ push=function(self,sleeptime,co)
+ if not co then
+ return
+ end
+ if sleeptime<0 then
+ self.lethargy[co]=true
+ return
+ else
+ sleeptime=gettime()+sleeptime
+ end
+ local t=self.times
+ local c=self.cos
+ local i=1
+ local n=#t
+ while i<=n and t[i]<=sleeptime do
+ i=i+1
+ end
+ insert(t,i,sleeptime)
+ insert(c,i,co)
+ end,
+ getnext=
+ function(self)
+ local t=self.times
+ local delay=t[1] and t[1]-gettime() or nil
+ return delay and max(delay,0) or nil
+ end,
+ pop=
+ function(self,time)
+ local t=self.times
+ local c=self.cos
+ if #t==0 or time<t[1] then
+ return
+ end
+ local co=c[1]
+ remove(t,1)
+ remove(c,1)
+ return co
+ end,
+ wakeup=function(self,co)
+ local let=self.lethargy
+ if let[co] then
+ self:push(0,co)
+ let[co]=nil
+ else
+ local c=self.cos
+ local t=self.times
+ for i=1,#c do
+ if c[i]==co then
+ remove(c,i)
+ remove(t,i)
+ self:push(0,co)
+ return
end
+ end
+ end
+ end
}
local _servers=newset()
local _reading=newset()
local _writing=newset()
local _reading_log={}
local _writing_log={}
-local _is_timeout={
- timeout=true,
- wantread=true,
- wantwrite=true,
+local _is_timeout={
+ timeout=true,
+ wantread=true,
+ wantwrite=true,
}
local function isTCP(socket)
- return not find(tostring(socket),"^udp")
+ return not find(tostring(socket),"^udp")
end
local function copasreceive(client,pattern,part)
- if not pattern or pattern=="" then
- pattern="*l"
- end
- local current_log=_reading_log
- local s,err
- repeat
- s,err,part=client:receive(pattern,part)
- if s or (not _is_timeout[err]) then
- current_log[client]=nil
- return s,err,part
- end
- if err=="wantwrite" then
- current_log=_writing_log
- current_log[client]=gettime()
- yieldcoroutine(client,_writing)
- else
- current_log=_reading_log
- current_log[client]=gettime()
- yieldcoroutine(client,_reading)
- end
- until false
+ if not pattern or pattern=="" then
+ pattern="*l"
+ end
+ local current_log=_reading_log
+ local s,err
+ repeat
+ s,err,part=client:receive(pattern,part)
+ if s or (not _is_timeout[err]) then
+ current_log[client]=nil
+ return s,err,part
+ end
+ if err=="wantwrite" then
+ current_log=_writing_log
+ current_log[client]=gettime()
+ yieldcoroutine(client,_writing)
+ else
+ current_log=_reading_log
+ current_log[client]=gettime()
+ yieldcoroutine(client,_reading)
+ end
+ until false
end
local function copasreceivefrom(client,size)
- local s,err,port
- if not size or size==0 then
- size=UDP_DATAGRAM_MAX
- end
- repeat
- s,err,port=client:receivefrom(size)
- if s or err~="timeout" then
- _reading_log[client]=nil
- return s,err,port
- end
- _reading_log[client]=gettime()
- yieldcoroutine(client,_reading)
- until false
+ local s,err,port
+ if not size or size==0 then
+ size=UDP_DATAGRAM_MAX
+ end
+ repeat
+ s,err,port=client:receivefrom(size)
+ if s or err~="timeout" then
+ _reading_log[client]=nil
+ return s,err,port
+ end
+ _reading_log[client]=gettime()
+ yieldcoroutine(client,_reading)
+ until false
end
local function copasreceivepartial(client,pattern,part)
- if not pattern or pattern=="" then
- pattern="*l"
- end
- local logger=_reading_log
- local queue=_reading
- local s,err
- repeat
- s,err,part=client:receive(pattern,part)
- if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then
- logger[client]=nil
- return s,err,part
- end
- if err=="wantwrite" then
- logger=_writing_log
- queue=_writing
- else
- logger=_reading_log
- queue=_reading
- end
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- until false
+ if not pattern or pattern=="" then
+ pattern="*l"
+ end
+ local logger=_reading_log
+ local queue=_reading
+ local s,err
+ repeat
+ s,err,part=client:receive(pattern,part)
+ if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then
+ logger[client]=nil
+ return s,err,part
+ end
+ if err=="wantwrite" then
+ logger=_writing_log
+ queue=_writing
+ else
+ logger=_reading_log
+ queue=_reading
+ end
+ logger[client]=gettime()
+ yieldcoroutine(client,queue)
+ until false
end
local function copassend(client,data,from,to)
- if not from then
- from=1
- end
- local lastIndex=from-1
- local logger=_writing_log
- local queue=_writing
- local s,err
- repeat
- s,err,lastIndex=client:send(data,lastIndex+1,to)
- if random(100)>90 then
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- end
- if s or not _is_timeout[err] then
- logger[client]=nil
- return s,err,lastIndex
- end
- if err=="wantread" then
- logger=_reading_log
- queue=_reading
- else
- logger=_writing_log
- queue=_writing
- end
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- until false
+ if not from then
+ from=1
+ end
+ local lastIndex=from-1
+ local logger=_writing_log
+ local queue=_writing
+ local s,err
+ repeat
+ s,err,lastIndex=client:send(data,lastIndex+1,to)
+ if random(100)>90 then
+ logger[client]=gettime()
+ yieldcoroutine(client,queue)
+ end
+ if s or not _is_timeout[err] then
+ logger[client]=nil
+ return s,err,lastIndex
+ end
+ if err=="wantread" then
+ logger=_reading_log
+ queue=_reading
+ else
+ logger=_writing_log
+ queue=_writing
+ end
+ logger[client]=gettime()
+ yieldcoroutine(client,queue)
+ until false
end
local function copassendto(client,data,ip,port)
- repeat
- local s,err=client:sendto(data,ip,port)
- if random(100)>90 then
- _writing_log[client]=gettime()
- yieldcoroutine(client,_writing)
- end
- if s or err~="timeout" then
- _writing_log[client]=nil
- return s,err
- end
- _writing_log[client]=gettime()
- yieldcoroutine(client,_writing)
- until false
+ repeat
+ local s,err=client:sendto(data,ip,port)
+ if random(100)>90 then
+ _writing_log[client]=gettime()
+ yieldcoroutine(client,_writing)
+ end
+ if s or err~="timeout" then
+ _writing_log[client]=nil
+ return s,err
+ end
+ _writing_log[client]=gettime()
+ yieldcoroutine(client,_writing)
+ until false
end
local function copasconnect(skt,host,port)
- skt:settimeout(0)
- local ret,err,tried_more_than_once
- repeat
- ret,err=skt:connect (host,port)
- if ret or (err~="timeout" and err~="Operation already in progress") then
- if not ret and err=="already connected" and tried_more_than_once then
- ret=1
- err=nil
- end
- _writing_log[skt]=nil
- return ret,err
- end
- tried_more_than_once=tried_more_than_once or true
- _writing_log[skt]=gettime()
- yieldcoroutine(skt,_writing)
- until false
+ skt:settimeout(0)
+ local ret,err,tried_more_than_once
+ repeat
+ ret,err=skt:connect (host,port)
+ if ret or (err~="timeout" and err~="Operation already in progress") then
+ if not ret and err=="already connected" and tried_more_than_once then
+ ret=1
+ err=nil
+ end
+ _writing_log[skt]=nil
+ return ret,err
+ end
+ tried_more_than_once=tried_more_than_once or true
+ _writing_log[skt]=gettime()
+ yieldcoroutine(skt,_writing)
+ until false
end
local function copasdohandshake(skt,sslt)
- if not ssl then
- ssl=require("ssl")
- end
- if not ssl then
- report("error: no ssl library")
- return
- end
- local nskt,err=ssl.wrap(skt,sslt)
- if not nskt then
- report("error: %s",tostring(err))
- return
- end
- nskt:settimeout(0)
- local queue
- repeat
- local success,err=nskt:dohandshake()
- if success then
- return nskt
- elseif err=="wantwrite" then
- queue=_writing
- elseif err=="wantread" then
- queue=_reading
- else
- report("error: %s",tostring(err))
- return
- end
- yieldcoroutine(nskt,queue)
- until false
+ if not ssl then
+ ssl=require("ssl")
+ end
+ if not ssl then
+ report("error: no ssl library")
+ return
+ end
+ local nskt,err=ssl.wrap(skt,sslt)
+ if not nskt then
+ report("error: %s",tostring(err))
+ return
+ end
+ nskt:settimeout(0)
+ local queue
+ repeat
+ local success,err=nskt:dohandshake()
+ if success then
+ return nskt
+ elseif err=="wantwrite" then
+ queue=_writing
+ elseif err=="wantread" then
+ queue=_reading
+ else
+ report("error: %s",tostring(err))
+ return
+ end
+ yieldcoroutine(nskt,queue)
+ until false
end
local function copasflush(client)
end
@@ -9948,326 +9948,326 @@ copas.copasreceivePartial=copasreceivepartial
copas.dohandshake=copasdohandshake
copas.flush=copasflush
local function _skt_mt_tostring(self)
- return tostring(self.socket).." (copas wrapped)"
+ return tostring(self.socket).." (copas wrapped)"
end
local _skt_mt_tcp_index={
- send=function(self,data,from,to)
- return copassend (self.socket,data,from,to)
- end,
- receive=function (self,pattern,prefix)
- if self.timeout==0 then
- return copasreceivePartial(self.socket,pattern,prefix)
- else
- return copasreceive(self.socket,pattern,prefix)
- end
- end,
- flush=function (self)
- return copasflush(self.socket)
- end,
- settimeout=function (self,time)
- self.timeout=time
- return true
- end,
- connect=function(self,...)
- local res,err=copasconnect(self.socket,...)
- if res and self.ssl_params then
- res,err=self:dohandshake()
- end
- return res,err
- end,
- close=function(self,...)
- return self.socket:close(...)
- end,
- bind=function(self,...)
- return self.socket:bind(...)
- end,
- getsockname=function(self,...)
- return self.socket:getsockname(...)
- end,
- getstats=function(self,...)
- return self.socket:getstats(...)
- end,
- setstats=function(self,...)
- return self.socket:setstats(...)
- end,
- listen=function(self,...)
- return self.socket:listen(...)
- end,
- accept=function(self,...)
- return self.socket:accept(...)
- end,
- setoption=function(self,...)
- return self.socket:setoption(...)
- end,
- getpeername=function(self,...)
- return self.socket:getpeername(...)
- end,
- shutdown=function(self,...)
- return self.socket:shutdown(...)
- end,
- dohandshake=function(self,sslt)
- self.ssl_params=sslt or self.ssl_params
- local nskt,err=copasdohandshake(self.socket,self.ssl_params)
- if not nskt then
- return nskt,err
- end
- self.socket=nskt
- return self
- end,
+ send=function(self,data,from,to)
+ return copassend (self.socket,data,from,to)
+ end,
+ receive=function (self,pattern,prefix)
+ if self.timeout==0 then
+ return copasreceivePartial(self.socket,pattern,prefix)
+ else
+ return copasreceive(self.socket,pattern,prefix)
+ end
+ end,
+ flush=function (self)
+ return copasflush(self.socket)
+ end,
+ settimeout=function (self,time)
+ self.timeout=time
+ return true
+ end,
+ connect=function(self,...)
+ local res,err=copasconnect(self.socket,...)
+ if res and self.ssl_params then
+ res,err=self:dohandshake()
+ end
+ return res,err
+ end,
+ close=function(self,...)
+ return self.socket:close(...)
+ end,
+ bind=function(self,...)
+ return self.socket:bind(...)
+ end,
+ getsockname=function(self,...)
+ return self.socket:getsockname(...)
+ end,
+ getstats=function(self,...)
+ return self.socket:getstats(...)
+ end,
+ setstats=function(self,...)
+ return self.socket:setstats(...)
+ end,
+ listen=function(self,...)
+ return self.socket:listen(...)
+ end,
+ accept=function(self,...)
+ return self.socket:accept(...)
+ end,
+ setoption=function(self,...)
+ return self.socket:setoption(...)
+ end,
+ getpeername=function(self,...)
+ return self.socket:getpeername(...)
+ end,
+ shutdown=function(self,...)
+ return self.socket:shutdown(...)
+ end,
+ dohandshake=function(self,sslt)
+ self.ssl_params=sslt or self.ssl_params
+ local nskt,err=copasdohandshake(self.socket,self.ssl_params)
+ if not nskt then
+ return nskt,err
+ end
+ self.socket=nskt
+ return self
+ end,
}
local _skt_mt_tcp={
- __tostring=_skt_mt_tostring,
- __index=_skt_mt_tcp_index,
+ __tostring=_skt_mt_tostring,
+ __index=_skt_mt_tcp_index,
}
local _skt_mt_udp_index={
- sendto=function (self,...)
- return copassendto(self.socket,...)
- end,
- receive=function (self,size)
- return copasreceive(self.socket,size or UDP_DATAGRAM_MAX)
- end,
- receivefrom=function (self,size)
- return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX)
- end,
- setpeername=function(self,...)
- return self.socket:getpeername(...)
- end,
- setsockname=function(self,...)
- return self.socket:setsockname(...)
- end,
- close=function(self,...)
- return true
- end
+ sendto=function (self,...)
+ return copassendto(self.socket,...)
+ end,
+ receive=function (self,size)
+ return copasreceive(self.socket,size or UDP_DATAGRAM_MAX)
+ end,
+ receivefrom=function (self,size)
+ return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX)
+ end,
+ setpeername=function(self,...)
+ return self.socket:getpeername(...)
+ end,
+ setsockname=function(self,...)
+ return self.socket:setsockname(...)
+ end,
+ close=function(self,...)
+ return true
+ end
}
local _skt_mt_udp={
- __tostring=_skt_mt_tostring,
- __index=_skt_mt_udp_index,
+ __tostring=_skt_mt_tostring,
+ __index=_skt_mt_udp_index,
}
for k,v in next,_skt_mt_tcp_index do
- if not _skt_mt_udp_index[k] then
- _skt_mt_udp_index[k]=v
- end
+ if not _skt_mt_udp_index[k] then
+ _skt_mt_udp_index[k]=v
+ end
end
local function wrap(skt,sslt)
- if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
- return skt
- end
- skt:settimeout(0)
- if isTCP(skt) then
- return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp)
- else
- return setmetatable ({ socket=skt },_skt_mt_udp)
- end
+ if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
+ return skt
+ end
+ skt:settimeout(0)
+ if isTCP(skt) then
+ return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp)
+ else
+ return setmetatable ({ socket=skt },_skt_mt_udp)
+ end
end
copas.wrap=wrap
function copas.handler(handler,sslparams)
- return function (skt,...)
- skt=wrap(skt)
- if sslparams then
- skt:dohandshake(sslparams)
- end
- return handler(skt,...)
+ return function (skt,...)
+ skt=wrap(skt)
+ if sslparams then
+ skt:dohandshake(sslparams)
end
+ return handler(skt,...)
+ end
end
local _errhandlers={}
function copas.setErrorHandler(err)
- local co=runningcoroutine()
- if co then
- _errhandlers[co]=err
- end
+ local co=runningcoroutine()
+ if co then
+ _errhandlers[co]=err
+ end
end
local function _deferror (msg,co,skt)
- report("%s (%s) (%s)",msg,tostring(co),tostring(skt))
+ report("%s (%s) (%s)",msg,tostring(co),tostring(skt))
end
local function _doTick (co,skt,...)
- if not co then
- return
+ if not co then
+ return
+ end
+ local ok,res,new_q=resumecoroutine(co,skt,...)
+ if ok and res and new_q then
+ new_q:insert(res)
+ new_q:push(res,co)
+ else
+ if not ok then
+ pcall(_errhandlers[co] or _deferror,res,co,skt)
end
- local ok,res,new_q=resumecoroutine(co,skt,...)
- if ok and res and new_q then
- new_q:insert(res)
- new_q:push(res,co)
- else
- if not ok then
- pcall(_errhandlers[co] or _deferror,res,co,skt)
- end
- if skt and copas.autoclose and isTCP(skt) then
- skt:close()
- end
- _errhandlers[co]=nil
+ if skt and copas.autoclose and isTCP(skt) then
+ skt:close()
end
+ _errhandlers[co]=nil
+ end
end
local function _accept(input,handler)
- local client=input:accept()
- if client then
- client:settimeout(0)
- local co=createcoroutine(handler)
- _doTick (co,client)
- end
- return client
+ local client=input:accept()
+ if client then
+ client:settimeout(0)
+ local co=createcoroutine(handler)
+ _doTick (co,client)
+ end
+ return client
end
local function _tickRead(skt)
- _doTick(_reading:pop(skt),skt)
+ _doTick(_reading:pop(skt),skt)
end
local function _tickWrite(skt)
- _doTick(_writing:pop(skt),skt)
+ _doTick(_writing:pop(skt),skt)
end
local function addTCPserver(server,handler,timeout)
- server:settimeout(timeout or 0)
- _servers[server]=handler
- _reading:insert(server)
+ server:settimeout(timeout or 0)
+ _servers[server]=handler
+ _reading:insert(server)
end
local function addUDPserver(server,handler,timeout)
- server:settimeout(timeout or 0)
- local co=createcoroutine(handler)
- _reading:insert(server)
- _doTick(co,server)
+ server:settimeout(timeout or 0)
+ local co=createcoroutine(handler)
+ _reading:insert(server)
+ _doTick(co,server)
end
function copas.addserver(server,handler,timeout)
- if isTCP(server) then
- addTCPserver(server,handler,timeout)
- else
- addUDPserver(server,handler,timeout)
- end
+ if isTCP(server) then
+ addTCPserver(server,handler,timeout)
+ else
+ addUDPserver(server,handler,timeout)
+ end
end
function copas.removeserver(server,keep_open)
- local s=server
- local mt=getmetatable(server)
- if mt==_skt_mt_tcp or mt==_skt_mt_udp then
- s=server.socket
- end
- _servers[s]=nil
- _reading:remove(s)
- if keep_open then
- return true
- end
- return server:close()
+ local s=server
+ local mt=getmetatable(server)
+ if mt==_skt_mt_tcp or mt==_skt_mt_udp then
+ s=server.socket
+ end
+ _servers[s]=nil
+ _reading:remove(s)
+ if keep_open then
+ return true
+ end
+ return server:close()
end
function copas.addthread(handler,...)
- local thread=createcoroutine(function(_,...) return handler(...) end)
- _doTick(thread,nil,...)
- return thread
+ local thread=createcoroutine(function(_,...) return handler(...) end)
+ _doTick(thread,nil,...)
+ return thread
end
local _tasks={}
local function addtaskRead(task)
- task.def_tick=_tickRead
- _tasks[task]=true
+ task.def_tick=_tickRead
+ _tasks[task]=true
end
local function addtaskWrite(task)
- task.def_tick=_tickWrite
- _tasks[task]=true
+ task.def_tick=_tickWrite
+ _tasks[task]=true
end
local function tasks()
- return next,_tasks
+ return next,_tasks
end
local _readable_t={
- events=function(self)
- local i=0
- return function ()
- i=i+1
- return self._evs[i]
- end
- end,
- tick=function(self,input)
- local handler=_servers[input]
- if handler then
- input=_accept(input,handler)
- else
- _reading:remove(input)
- self.def_tick(input)
- end
- end
+ events=function(self)
+ local i=0
+ return function ()
+ i=i+1
+ return self._evs[i]
+ end
+ end,
+ tick=function(self,input)
+ local handler=_servers[input]
+ if handler then
+ input=_accept(input,handler)
+ else
+ _reading:remove(input)
+ self.def_tick(input)
+ end
+ end
}
addtaskRead(_readable_t)
local _writable_t={
- events=function(self)
- local i=0
- return function()
- i=i+1
- return self._evs[i]
- end
- end,
- tick=function(self,output)
- _writing:remove(output)
- self.def_tick(output)
- end
+ events=function(self)
+ local i=0
+ return function()
+ i=i+1
+ return self._evs[i]
+ end
+ end,
+ tick=function(self,output)
+ _writing:remove(output)
+ self.def_tick(output)
+ end
}
addtaskWrite(_writable_t)
local _sleeping_t={
- tick=function(self,time,...)
- _doTick(_sleeping:pop(time),...)
- end
+ tick=function(self,time,...)
+ _doTick(_sleeping:pop(time),...)
+ end
}
function copas.sleep(sleeptime)
- yieldcoroutine((sleeptime or 0),_sleeping)
+ yieldcoroutine((sleeptime or 0),_sleeping)
end
function copas.wakeup(co)
- _sleeping:wakeup(co)
+ _sleeping:wakeup(co)
end
local last_cleansing=0
local function _select(timeout)
- local now=gettime()
- local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout)
- _readable_t._evs=r_evs
- _writable_t._evs=w_evs
- if (last_cleansing-now)>WATCH_DOG_TIMEOUT then
- last_cleansing=now
- for skt,time in next,_reading_log do
- if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
- local n=#r_evs+1
- _reading_log[skt]=nil
- r_evs[n]=skt
- r_evs[skt]=n
- end
- end
- for skt,time in next,_writing_log do
- if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
- local n=#w_evs+1
- _writing_log[skt]=nil
- w_evs[n]=skt
- w_evs[skt]=n
- end
- end
+ local now=gettime()
+ local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout)
+ _readable_t._evs=r_evs
+ _writable_t._evs=w_evs
+ if (last_cleansing-now)>WATCH_DOG_TIMEOUT then
+ last_cleansing=now
+ for skt,time in next,_reading_log do
+ if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
+ local n=#r_evs+1
+ _reading_log[skt]=nil
+ r_evs[n]=skt
+ r_evs[skt]=n
+ end
end
- if err=="timeout" and #r_evs+#w_evs>0 then
- return nil
- else
- return err
+ for skt,time in next,_writing_log do
+ if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
+ local n=#w_evs+1
+ _writing_log[skt]=nil
+ w_evs[n]=skt
+ w_evs[skt]=n
+ end
end
+ end
+ if err=="timeout" and #r_evs+#w_evs>0 then
+ return nil
+ else
+ return err
+ end
end
local function copasfinished()
- return not (next(_reading) or next(_writing) or _sleeping:getnext())
+ return not (next(_reading) or next(_writing) or _sleeping:getnext())
end
local function copasstep(timeout)
- _sleeping_t:tick(gettime())
- local nextwait=_sleeping:getnext()
- if nextwait then
- timeout=timeout and min(nextwait,timeout) or nextwait
- elseif copasfinished() then
- return false
- end
- local err=_select(timeout)
- if err then
- if err=="timeout" then
- return false
- end
- return nil,err
+ _sleeping_t:tick(gettime())
+ local nextwait=_sleeping:getnext()
+ if nextwait then
+ timeout=timeout and min(nextwait,timeout) or nextwait
+ elseif copasfinished() then
+ return false
+ end
+ local err=_select(timeout)
+ if err then
+ if err=="timeout" then
+ return false
end
- for task in tasks() do
- for event in task:events() do
- task:tick(event)
- end
+ return nil,err
+ end
+ for task in tasks() do
+ for event in task:events() do
+ task:tick(event)
end
- return true
+ end
+ return true
end
copas.finished=copasfinished
copas.step=copasstep
function copas.loop(timeout)
- copas.running=true
- while not copasfinished() do
- copasstep(timeout)
- end
- copas.running=false
+ copas.running=true
+ while not copasfinished() do
+ copasstep(timeout)
+ end
+ copas.running=false
end
package.loaded["copas"]=copas
@@ -10278,321 +10278,321 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true
--- original size: 8709, stripped down to: 6105
+-- original size: 8709, stripped down to: 5411
local select,unpack=select,unpack
local insert,remove=table.insert,table.remove
local sub=string.sub
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("ltn12")
- report(fmt,first,...)
- elseif fmt then
- fmt="ltn12: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("ltn12")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="ltn12: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
local filter={}
local source={}
local sink={}
local pump={}
local ltn12={
- _VERSION="LTN12 1.0.3",
- BLOCKSIZE=2048,
- filter=filter,
- source=source,
- sink=sink,
- pump=pump,
- report=report,
+ _VERSION="LTN12 1.0.3",
+ BLOCKSIZE=2048,
+ filter=filter,
+ source=source,
+ sink=sink,
+ pump=pump,
+ report=report,
}
function filter.cycle(low,ctx,extra)
- if low then
- return function(chunk)
- return (low(ctx,chunk,extra))
- end
+ if low then
+ return function(chunk)
+ return (low(ctx,chunk,extra))
end
+ end
end
function filter.chain(...)
- local arg={... }
- local n=select('#',...)
- local top=1
- local index=1
- local retry=""
- return function(chunk)
- retry=chunk and retry
- while true do
- local action=arg[index]
- if index==top then
- chunk=action(chunk)
- if chunk=="" or top==n then
- return chunk
- elseif chunk then
- index=index+1
- else
- top=top+1
- index=top
- end
- else
- chunk=action(chunk or "")
- if chunk=="" then
- index=index-1
- chunk=retry
- elseif chunk then
- if index==n then
- return chunk
- else
- index=index+1
- end
- else
- report("error: filter returned inappropriate 'nil'")
- return
- end
- end
+ local arg={... }
+ local n=select('#',...)
+ local top=1
+ local index=1
+ local retry=""
+ return function(chunk)
+ retry=chunk and retry
+ while true do
+ local action=arg[index]
+ if index==top then
+ chunk=action(chunk)
+ if chunk=="" or top==n then
+ return chunk
+ elseif chunk then
+ index=index+1
+ else
+ top=top+1
+ index=top
+ end
+ else
+ chunk=action(chunk or "")
+ if chunk=="" then
+ index=index-1
+ chunk=retry
+ elseif chunk then
+ if index==n then
+ return chunk
+ else
+ index=index+1
+ end
+ else
+ report("error: filter returned inappropriate 'nil'")
+ return
end
+ end
end
+ end
end
local function empty()
- return nil
+ return nil
end
function source.empty()
- return empty
+ return empty
end
local function sourceerror(err)
- return function()
- return nil,err
- end
+ return function()
+ return nil,err
+ end
end
source.error=sourceerror
function source.file(handle,io_err)
- if handle then
- local blocksize=ltn12.BLOCKSIZE
- return function()
- local chunk=handle:read(blocksize)
- if not chunk then
- handle:close()
- end
- return chunk
- end
- else
- return sourceerror(io_err or "unable to open file")
+ if handle then
+ local blocksize=ltn12.BLOCKSIZE
+ return function()
+ local chunk=handle:read(blocksize)
+ if not chunk then
+ handle:close()
+ end
+ return chunk
end
+ else
+ return sourceerror(io_err or "unable to open file")
+ end
end
function source.simplify(src)
- return function()
- local chunk,err_or_new=src()
- if err_or_new then
- src=err_or_new
- end
- if chunk then
- return chunk
- else
- return nil,err_or_new
- end
+ return function()
+ local chunk,err_or_new=src()
+ if err_or_new then
+ src=err_or_new
+ end
+ if chunk then
+ return chunk
+ else
+ return nil,err_or_new
end
+ end
end
function source.string(s)
- if s then
- local blocksize=ltn12.BLOCKSIZE
- local i=1
- return function()
- local nexti=i+blocksize
- local chunk=sub(s,i,nexti-1)
- i=nexti
- if chunk~="" then
- return chunk
- else
- return nil
- end
- end
- else return source.empty() end
+ if s then
+ local blocksize=ltn12.BLOCKSIZE
+ local i=1
+ return function()
+ local nexti=i+blocksize
+ local chunk=sub(s,i,nexti-1)
+ i=nexti
+ if chunk~="" then
+ return chunk
+ else
+ return nil
+ end
+ end
+ else return source.empty() end
end
function source.rewind(src)
- local t={}
- return function(chunk)
- if chunk then
- insert(t,chunk)
- else
- chunk=remove(t)
- if chunk then
- return chunk
- else
- return src()
- end
- end
+ local t={}
+ return function(chunk)
+ if chunk then
+ insert(t,chunk)
+ else
+ chunk=remove(t)
+ if chunk then
+ return chunk
+ else
+ return src()
+ end
end
+ end
end
function source.chain(src,f,...)
- if... then
- f=filter.chain(f,...)
+ if... then
+ f=filter.chain(f,...)
+ end
+ local last_in=""
+ local last_out=""
+ local state="feeding"
+ local err
+ return function()
+ if not last_out then
+ report("error: source is empty")
+ return
end
- local last_in=""
- local last_out=""
- local state="feeding"
- local err
- return function()
+ while true do
+ if state=="feeding" then
+ last_in,err=src()
+ if err then
+ return nil,err
+ end
+ last_out=f(last_in)
if not last_out then
- report("error: source is empty")
- return
+ if last_in then
+ report("error: filter returned inappropriate 'nil'")
+ end
+ return nil
+ elseif last_out~="" then
+ state="eating"
+ if last_in then
+ last_in=""
+ end
+ return last_out
end
- while true do
- if state=="feeding" then
- last_in,err=src()
- if err then
- return nil,err
- end
- last_out=f(last_in)
- if not last_out then
- if last_in then
- report("error: filter returned inappropriate 'nil'")
- end
- return nil
- elseif last_out~="" then
- state="eating"
- if last_in then
- last_in=""
- end
- return last_out
- end
- else
- last_out=f(last_in)
- if last_out=="" then
- if last_in=="" then
- state="feeding"
- else
- report("error: filter returned nothing")
- return
- end
- elseif not last_out then
- if last_in then
- report("filter returned inappropriate 'nil'")
- end
- return nil
- else
- return last_out
- end
- end
+ else
+ last_out=f(last_in)
+ if last_out=="" then
+ if last_in=="" then
+ state="feeding"
+ else
+ report("error: filter returned nothing")
+ return
+ end
+ elseif not last_out then
+ if last_in then
+ report("filter returned inappropriate 'nil'")
+ end
+ return nil
+ else
+ return last_out
end
+ end
end
+ end
end
function source.cat(...)
- local arg={... }
- local src=remove(arg,1)
- return function()
- while src do
- local chunk,err=src()
- if chunk then
- return chunk
- end
- if err then
- return nil,err
- end
- src=remove(arg,1)
- end
+ local arg={... }
+ local src=remove(arg,1)
+ return function()
+ while src do
+ local chunk,err=src()
+ if chunk then
+ return chunk
+ end
+ if err then
+ return nil,err
+ end
+ src=remove(arg,1)
end
+ end
end
function sink.table(t)
- if not t then
- t={}
- end
- local f=function(chunk,err)
- if chunk then
- insert(t,chunk)
- end
- return 1
+ if not t then
+ t={}
+ end
+ local f=function(chunk,err)
+ if chunk then
+ insert(t,chunk)
end
- return f,t
+ return 1
+ end
+ return f,t
end
function sink.simplify(snk)
- return function(chunk,err)
- local ret,err_or_new=snk(chunk,err)
- if not ret then
- return nil,err_or_new
- end
- if err_or_new then
- snk=err_or_new
- end
- return 1
+ return function(chunk,err)
+ local ret,err_or_new=snk(chunk,err)
+ if not ret then
+ return nil,err_or_new
end
+ if err_or_new then
+ snk=err_or_new
+ end
+ return 1
+ end
end
local function null()
- return 1
+ return 1
end
function sink.null()
- return null
+ return null
end
local function sinkerror(err)
- return function()
- return nil,err
- end
+ return function()
+ return nil,err
+ end
end
sink.error=sinkerror
function sink.file(handle,io_err)
- if handle then
- return function(chunk,err)
- if not chunk then
- handle:close()
- return 1
- else
- return handle:write(chunk)
- end
- end
- else
- return sinkerror(io_err or "unable to open file")
+ if handle then
+ return function(chunk,err)
+ if not chunk then
+ handle:close()
+ return 1
+ else
+ return handle:write(chunk)
+ end
end
+ else
+ return sinkerror(io_err or "unable to open file")
+ end
end
function sink.chain(f,snk,...)
- if... then
- local args={ f,snk,... }
- snk=remove(args,#args)
- f=filter.chain(unpack(args))
- end
- return function(chunk,err)
- if chunk~="" then
- local filtered=f(chunk)
- local done=chunk and ""
- while true do
- local ret,snkerr=snk(filtered,err)
- if not ret then
- return nil,snkerr
- end
- if filtered==done then
- return 1
- end
- filtered=f(done)
- end
- else
- return 1
+ if... then
+ local args={ f,snk,... }
+ snk=remove(args,#args)
+ f=filter.chain(unpack(args))
+ end
+ return function(chunk,err)
+ if chunk~="" then
+ local filtered=f(chunk)
+ local done=chunk and ""
+ while true do
+ local ret,snkerr=snk(filtered,err)
+ if not ret then
+ return nil,snkerr
+ end
+ if filtered==done then
+ return 1
end
+ filtered=f(done)
+ end
+ else
+ return 1
end
+ end
end
function pump.step(src,snk)
- local chunk,src_err=src()
- local ret,snk_err=snk(chunk,src_err)
- if chunk and ret then
- return 1
- else
- return nil,src_err or snk_err
- end
+ local chunk,src_err=src()
+ local ret,snk_err=snk(chunk,src_err)
+ if chunk and ret then
+ return 1
+ else
+ return nil,src_err or snk_err
+ end
end
function pump.all(src,snk,step)
- if not step then
- step=pump.step
- end
- while true do
- local ret,err=step(src,snk)
- if not ret then
- if err then
- return nil,err
- else
- return 1
- end
- end
+ if not step then
+ step=pump.step
+ end
+ while true do
+ local ret,err=step(src,snk)
+ if not ret then
+ if err then
+ return nil,err
+ else
+ return 1
+ end
end
+ end
end
package.loaded["ltn12"]=ltn12
@@ -10603,7 +10603,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true
--- original size: 2328, stripped down to: 1930
+-- original size: 2328, stripped down to: 1874
local type,tostring=type,tostring
@@ -10611,17 +10611,17 @@ local mime=require("mime.core")
local ltn12=ltn12 or require("ltn12")
local filtercycle=ltn12.filter.cycle
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("mime")
- report(fmt,first,...)
- elseif fmt then
- fmt="mime: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("mime")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="mime: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
mime.report=report
local encodet={}
@@ -10639,48 +10639,48 @@ local mime_qpwrp=mime.qpwrp
local mime_eol=mime_eol
local mime_dot=mime_dot
encodet['base64']=function()
- return filtercycle(mime_b64,"")
+ return filtercycle(mime_b64,"")
end
encodet['quoted-printable']=function(mode)
- return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n")
+ return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n")
end
decodet['base64']=function()
- return filtercycle(mime_unb64,"")
+ return filtercycle(mime_unb64,"")
end
decodet['quoted-printable']=function()
- return filtercycle(mime_unqp,"")
+ return filtercycle(mime_unqp,"")
end
local wraptext=function(length)
- if not length then
- length=76
- end
- return filtercycle(mime_wrp,length,length)
+ if not length then
+ length=76
+ end
+ return filtercycle(mime_wrp,length,length)
end
local wrapquoted=function()
- return filtercycle(mime_qpwrp,76,76)
+ return filtercycle(mime_qpwrp,76,76)
end
wrapt['text']=wraptext
wrapt['base64']=wraptext
wrapt['default']=wraptext
wrapt['quoted-printable']=wrapquoted
function mime.normalize(marker)
- return filtercycle(mime_eol,0,marker)
+ return filtercycle(mime_eol,0,marker)
end
function mime.stuff()
- return filtercycle(mime_dot,2)
+ return filtercycle(mime_dot,2)
end
local function choose(list)
- return function(name,opt1,opt2)
- if type(name)~="string" then
- name,opt1,opt2="default",name,opt1
- end
- local filter=list[name or "nil"]
- if filter then
- return filter(opt1,opt2)
- else
- report("error: unknown key '%s'",tostring(name))
- end
+ return function(name,opt1,opt2)
+ if type(name)~="string" then
+ name,opt1,opt2="default",name,opt1
+ end
+ local filter=list[name or "nil"]
+ if filter then
+ return filter(opt1,opt2)
+ else
+ report("error: unknown key '%s'",tostring(name))
end
+ end
end
mime.encode=choose(encodet)
mime.decode=choose(decodet)
@@ -10694,7 +10694,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true
--- original size: 6863, stripped down to: 5657
+-- original size: 6863, stripped down to: 5269
local tonumber,tostring,type=tonumber,tostring,type
@@ -10702,246 +10702,246 @@ local gsub,sub,match,find,format,byte,char=string.gsub,string.sub,string.match,s
local insert=table.insert
local socket=socket or require("socket")
local url={
- _VERSION="URL 1.0.3",
+ _VERSION="URL 1.0.3",
}
socket.url=url
function url.escape(s)
- return (gsub(s,"([^A-Za-z0-9_])",function(c)
- return format("%%%02x",byte(c))
- end))
+ return (gsub(s,"([^A-Za-z0-9_])",function(c)
+ return format("%%%02x",byte(c))
+ end))
end
local function make_set(t)
- local s={}
- for i=1,#t do
- s[t[i]]=true
- end
- return s
+ local s={}
+ for i=1,#t do
+ s[t[i]]=true
+ end
+ return s
end
local segment_set=make_set {
- "-","_",".","!","~","*","'","(",
- ")",":","@","&","=","+","$",",",
+ "-","_",".","!","~","*","'","(",
+ ")",":","@","&","=","+","$",",",
}
local function protect_segment(s)
- return gsub(s,"([^A-Za-z0-9_])",function(c)
- if segment_set[c] then
- return c
- else
- return format("%%%02X",byte(c))
- end
- end)
+ return gsub(s,"([^A-Za-z0-9_])",function(c)
+ if segment_set[c] then
+ return c
+ else
+ return format("%%%02X",byte(c))
+ end
+ end)
end
function url.unescape(s)
- return (gsub(s,"%%(%x%x)",function(hex)
- return char(tonumber(hex,16))
- end))
+ return (gsub(s,"%%(%x%x)",function(hex)
+ return char(tonumber(hex,16))
+ end))
end
local function absolute_path(base_path,relative_path)
- if find(relative_path,"^/") then
- return relative_path
- end
- local path=gsub(base_path,"[^/]*$","")
- path=path..relative_path
- path=gsub(path,"([^/]*%./)",function (s)
- if s~="./" then
- return s
- else
- return ""
- end
+ if find(relative_path,"^/") then
+ return relative_path
+ end
+ local path=gsub(base_path,"[^/]*$","")
+ path=path..relative_path
+ path=gsub(path,"([^/]*%./)",function (s)
+ if s~="./" then
+ return s
+ else
+ return ""
+ end
+ end)
+ path=gsub(path,"/%.$","/")
+ local reduced
+ while reduced~=path do
+ reduced=path
+ path=gsub(reduced,"([^/]*/%.%./)",function (s)
+ if s~="../../" then
+ return ""
+ else
+ return s
+ end
end)
- path=gsub(path,"/%.$","/")
- local reduced
- while reduced~=path do
- reduced=path
- path=gsub(reduced,"([^/]*/%.%./)",function (s)
- if s~="../../" then
- return ""
- else
- return s
- end
- end)
+ end
+ path=gsub(reduced,"([^/]*/%.%.)$",function (s)
+ if s~="../.." then
+ return ""
+ else
+ return s
end
- path=gsub(reduced,"([^/]*/%.%.)$",function (s)
- if s~="../.." then
- return ""
- else
- return s
- end
- end)
- return path
+ end)
+ return path
end
function url.parse(url,default)
- local parsed={}
- for k,v in next,default or parsed do
- parsed[k]=v
- end
- if not url or url=="" then
- return nil,"invalid url"
- end
- url=gsub(url,"#(.*)$",function(f)
- parsed.fragment=f
- return ""
- end)
- url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s)
- parsed.scheme=s
- return ""
- end)
- url=gsub(url,"^//([^/]*)",function(n)
- parsed.authority=n
- return ""
- end)
- url=gsub(url,"%?(.*)",function(q)
- parsed.query=q
- return ""
- end)
- url=gsub(url,"%;(.*)",function(p)
- parsed.params=p
- return ""
- end)
- if url~="" then
- parsed.path=url
- end
- local authority=parsed.authority
- if not authority then
- return parsed
- end
- authority=gsub(authority,"^([^@]*)@",function(u)
- parsed.userinfo=u
- return ""
- end)
- authority=gsub(authority,":([^:%]]*)$",function(p)
- parsed.port=p
- return ""
- end)
- if authority~="" then
- parsed.host=match(authority,"^%[(.+)%]$") or authority
- end
- local userinfo=parsed.userinfo
- if not userinfo then
- return parsed
- end
- userinfo=gsub(userinfo,":([^:]*)$",function(p)
- parsed.password=p
- return ""
- end)
- parsed.user=userinfo
+ local parsed={}
+ for k,v in next,default or parsed do
+ parsed[k]=v
+ end
+ if not url or url=="" then
+ return nil,"invalid url"
+ end
+ url=gsub(url,"#(.*)$",function(f)
+ parsed.fragment=f
+ return ""
+ end)
+ url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s)
+ parsed.scheme=s
+ return ""
+ end)
+ url=gsub(url,"^//([^/]*)",function(n)
+ parsed.authority=n
+ return ""
+ end)
+ url=gsub(url,"%?(.*)",function(q)
+ parsed.query=q
+ return ""
+ end)
+ url=gsub(url,"%;(.*)",function(p)
+ parsed.params=p
+ return ""
+ end)
+ if url~="" then
+ parsed.path=url
+ end
+ local authority=parsed.authority
+ if not authority then
return parsed
+ end
+ authority=gsub(authority,"^([^@]*)@",function(u)
+ parsed.userinfo=u
+ return ""
+ end)
+ authority=gsub(authority,":([^:%]]*)$",function(p)
+ parsed.port=p
+ return ""
+ end)
+ if authority~="" then
+ parsed.host=match(authority,"^%[(.+)%]$") or authority
+ end
+ local userinfo=parsed.userinfo
+ if not userinfo then
+ return parsed
+ end
+ userinfo=gsub(userinfo,":([^:]*)$",function(p)
+ parsed.password=p
+ return ""
+ end)
+ parsed.user=userinfo
+ return parsed
end
function url.build(parsed)
- local url=parsed.path or ""
- if parsed.params then
- url=url..";"..parsed.params
- end
- if parsed.query then
- url=url.."?"..parsed.query
- end
- local authority=parsed.authority
- if parsed.host then
- authority=parsed.host
- if find(authority,":") then
- authority="["..authority.."]"
- end
- if parsed.port then
- authority=authority..":"..tostring(parsed.port)
- end
- local userinfo=parsed.userinfo
- if parsed.user then
- userinfo=parsed.user
- if parsed.password then
- userinfo=userinfo..":"..parsed.password
- end
- end
- if userinfo then authority=userinfo.."@"..authority end
+ local url=parsed.path or ""
+ if parsed.params then
+ url=url..";"..parsed.params
+ end
+ if parsed.query then
+ url=url.."?"..parsed.query
+ end
+ local authority=parsed.authority
+ if parsed.host then
+ authority=parsed.host
+ if find(authority,":") then
+ authority="["..authority.."]"
+ end
+ if parsed.port then
+ authority=authority..":"..tostring(parsed.port)
end
- if authority then
- url="//"..authority..url
- end
- if parsed.scheme then
- url=parsed.scheme..":"..url
- end
- if parsed.fragment then
- url=url.."#"..parsed.fragment
+ local userinfo=parsed.userinfo
+ if parsed.user then
+ userinfo=parsed.user
+ if parsed.password then
+ userinfo=userinfo..":"..parsed.password
+ end
end
- return url
+ if userinfo then authority=userinfo.."@"..authority end
+ end
+ if authority then
+ url="//"..authority..url
+ end
+ if parsed.scheme then
+ url=parsed.scheme..":"..url
+ end
+ if parsed.fragment then
+ url=url.."#"..parsed.fragment
+ end
+ return url
end
function url.absolute(base_url,relative_url)
- local base_parsed
- if type(base_url)=="table" then
- base_parsed=base_url
- base_url=url.build(base_parsed)
- else
- base_parsed=url.parse(base_url)
- end
- local relative_parsed=url.parse(relative_url)
- if not base_parsed then
- return relative_url
- elseif not relative_parsed then
- return base_url
- elseif relative_parsed.scheme then
- return relative_url
- else
- relative_parsed.scheme=base_parsed.scheme
- if not relative_parsed.authority then
- relative_parsed.authority=base_parsed.authority
- if not relative_parsed.path then
- relative_parsed.path=base_parsed.path
- if not relative_parsed.params then
- relative_parsed.params=base_parsed.params
- if not relative_parsed.query then
- relative_parsed.query=base_parsed.query
- end
- end
- else
- relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path)
- end
+ local base_parsed
+ if type(base_url)=="table" then
+ base_parsed=base_url
+ base_url=url.build(base_parsed)
+ else
+ base_parsed=url.parse(base_url)
+ end
+ local relative_parsed=url.parse(relative_url)
+ if not base_parsed then
+ return relative_url
+ elseif not relative_parsed then
+ return base_url
+ elseif relative_parsed.scheme then
+ return relative_url
+ else
+ relative_parsed.scheme=base_parsed.scheme
+ if not relative_parsed.authority then
+ relative_parsed.authority=base_parsed.authority
+ if not relative_parsed.path then
+ relative_parsed.path=base_parsed.path
+ if not relative_parsed.params then
+ relative_parsed.params=base_parsed.params
+ if not relative_parsed.query then
+ relative_parsed.query=base_parsed.query
+ end
end
- return url.build(relative_parsed)
+ else
+ relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path)
+ end
end
+ return url.build(relative_parsed)
+ end
end
function url.parse_path(path)
- local parsed={}
- path=path or ""
- gsub(path,"([^/]+)",function (s)
- insert(parsed,s)
- end)
- for i=1,#parsed do
- parsed[i]=url.unescape(parsed[i])
- end
- if sub(path,1,1)=="/" then
- parsed.is_absolute=1
- end
- if sub(path,-1,-1)=="/" then
- parsed.is_directory=1
- end
- return parsed
+ local parsed={}
+ path=path or ""
+ gsub(path,"([^/]+)",function (s)
+ insert(parsed,s)
+ end)
+ for i=1,#parsed do
+ parsed[i]=url.unescape(parsed[i])
+ end
+ if sub(path,1,1)=="/" then
+ parsed.is_absolute=1
+ end
+ if sub(path,-1,-1)=="/" then
+ parsed.is_directory=1
+ end
+ return parsed
end
function url.build_path(parsed,unsafe)
- local path=""
- local n=#parsed
- if unsafe then
- for i=1,n-1 do
- path=path..parsed[i].."/"
- end
- if n>0 then
- path=path..parsed[n]
- if parsed.is_directory then
- path=path.."/"
- end
- end
- else
- for i=1,n-1 do
- path=path..protect_segment(parsed[i]).."/"
- end
- if n>0 then
- path=path..protect_segment(parsed[n])
- if parsed.is_directory then
- path=path.."/"
- end
- end
+ local path=""
+ local n=#parsed
+ if unsafe then
+ for i=1,n-1 do
+ path=path..parsed[i].."/"
end
- if parsed.is_absolute then
- path="/"..path
+ if n>0 then
+ path=path..parsed[n]
+ if parsed.is_directory then
+ path=path.."/"
+ end
end
- return path
+ else
+ for i=1,n-1 do
+ path=path..protect_segment(parsed[i]).."/"
+ end
+ if n>0 then
+ path=path..protect_segment(parsed[n])
+ if parsed.is_directory then
+ path=path.."/"
+ end
+ end
+ end
+ if parsed.is_absolute then
+ path="/"..path
+ end
+ return path
end
package.loaded["socket.url"]=url
@@ -10952,7 +10952,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true
--- original size: 5721, stripped down to: 3878
+-- original size: 5721, stripped down to: 3754
local next=next
@@ -10962,128 +10962,128 @@ local socket=socket or require("socket")
local headers={}
socket.headers=headers
local canonic={
- ["accept"]="Accept",
- ["accept-charset"]="Accept-Charset",
- ["accept-encoding"]="Accept-Encoding",
- ["accept-language"]="Accept-Language",
- ["accept-ranges"]="Accept-Ranges",
- ["action"]="Action",
- ["alternate-recipient"]="Alternate-Recipient",
- ["age"]="Age",
- ["allow"]="Allow",
- ["arrival-date"]="Arrival-Date",
- ["authorization"]="Authorization",
- ["bcc"]="Bcc",
- ["cache-control"]="Cache-Control",
- ["cc"]="Cc",
- ["comments"]="Comments",
- ["connection"]="Connection",
- ["content-description"]="Content-Description",
- ["content-disposition"]="Content-Disposition",
- ["content-encoding"]="Content-Encoding",
- ["content-id"]="Content-ID",
- ["content-language"]="Content-Language",
- ["content-length"]="Content-Length",
- ["content-location"]="Content-Location",
- ["content-md5"]="Content-MD5",
- ["content-range"]="Content-Range",
- ["content-transfer-encoding"]="Content-Transfer-Encoding",
- ["content-type"]="Content-Type",
- ["cookie"]="Cookie",
- ["date"]="Date",
- ["diagnostic-code"]="Diagnostic-Code",
- ["dsn-gateway"]="DSN-Gateway",
- ["etag"]="ETag",
- ["expect"]="Expect",
- ["expires"]="Expires",
- ["final-log-id"]="Final-Log-ID",
- ["final-recipient"]="Final-Recipient",
- ["from"]="From",
- ["host"]="Host",
- ["if-match"]="If-Match",
- ["if-modified-since"]="If-Modified-Since",
- ["if-none-match"]="If-None-Match",
- ["if-range"]="If-Range",
- ["if-unmodified-since"]="If-Unmodified-Since",
- ["in-reply-to"]="In-Reply-To",
- ["keywords"]="Keywords",
- ["last-attempt-date"]="Last-Attempt-Date",
- ["last-modified"]="Last-Modified",
- ["location"]="Location",
- ["max-forwards"]="Max-Forwards",
- ["message-id"]="Message-ID",
- ["mime-version"]="MIME-Version",
- ["original-envelope-id"]="Original-Envelope-ID",
- ["original-recipient"]="Original-Recipient",
- ["pragma"]="Pragma",
- ["proxy-authenticate"]="Proxy-Authenticate",
- ["proxy-authorization"]="Proxy-Authorization",
- ["range"]="Range",
- ["received"]="Received",
- ["received-from-mta"]="Received-From-MTA",
- ["references"]="References",
- ["referer"]="Referer",
- ["remote-mta"]="Remote-MTA",
- ["reply-to"]="Reply-To",
- ["reporting-mta"]="Reporting-MTA",
- ["resent-bcc"]="Resent-Bcc",
- ["resent-cc"]="Resent-Cc",
- ["resent-date"]="Resent-Date",
- ["resent-from"]="Resent-From",
- ["resent-message-id"]="Resent-Message-ID",
- ["resent-reply-to"]="Resent-Reply-To",
- ["resent-sender"]="Resent-Sender",
- ["resent-to"]="Resent-To",
- ["retry-after"]="Retry-After",
- ["return-path"]="Return-Path",
- ["sender"]="Sender",
- ["server"]="Server",
- ["smtp-remote-recipient"]="SMTP-Remote-Recipient",
- ["status"]="Status",
- ["subject"]="Subject",
- ["te"]="TE",
- ["to"]="To",
- ["trailer"]="Trailer",
- ["transfer-encoding"]="Transfer-Encoding",
- ["upgrade"]="Upgrade",
- ["user-agent"]="User-Agent",
- ["vary"]="Vary",
- ["via"]="Via",
- ["warning"]="Warning",
- ["will-retry-until"]="Will-Retry-Until",
- ["www-authenticate"]="WWW-Authenticate",
- ["x-mailer"]="X-Mailer",
+ ["accept"]="Accept",
+ ["accept-charset"]="Accept-Charset",
+ ["accept-encoding"]="Accept-Encoding",
+ ["accept-language"]="Accept-Language",
+ ["accept-ranges"]="Accept-Ranges",
+ ["action"]="Action",
+ ["alternate-recipient"]="Alternate-Recipient",
+ ["age"]="Age",
+ ["allow"]="Allow",
+ ["arrival-date"]="Arrival-Date",
+ ["authorization"]="Authorization",
+ ["bcc"]="Bcc",
+ ["cache-control"]="Cache-Control",
+ ["cc"]="Cc",
+ ["comments"]="Comments",
+ ["connection"]="Connection",
+ ["content-description"]="Content-Description",
+ ["content-disposition"]="Content-Disposition",
+ ["content-encoding"]="Content-Encoding",
+ ["content-id"]="Content-ID",
+ ["content-language"]="Content-Language",
+ ["content-length"]="Content-Length",
+ ["content-location"]="Content-Location",
+ ["content-md5"]="Content-MD5",
+ ["content-range"]="Content-Range",
+ ["content-transfer-encoding"]="Content-Transfer-Encoding",
+ ["content-type"]="Content-Type",
+ ["cookie"]="Cookie",
+ ["date"]="Date",
+ ["diagnostic-code"]="Diagnostic-Code",
+ ["dsn-gateway"]="DSN-Gateway",
+ ["etag"]="ETag",
+ ["expect"]="Expect",
+ ["expires"]="Expires",
+ ["final-log-id"]="Final-Log-ID",
+ ["final-recipient"]="Final-Recipient",
+ ["from"]="From",
+ ["host"]="Host",
+ ["if-match"]="If-Match",
+ ["if-modified-since"]="If-Modified-Since",
+ ["if-none-match"]="If-None-Match",
+ ["if-range"]="If-Range",
+ ["if-unmodified-since"]="If-Unmodified-Since",
+ ["in-reply-to"]="In-Reply-To",
+ ["keywords"]="Keywords",
+ ["last-attempt-date"]="Last-Attempt-Date",
+ ["last-modified"]="Last-Modified",
+ ["location"]="Location",
+ ["max-forwards"]="Max-Forwards",
+ ["message-id"]="Message-ID",
+ ["mime-version"]="MIME-Version",
+ ["original-envelope-id"]="Original-Envelope-ID",
+ ["original-recipient"]="Original-Recipient",
+ ["pragma"]="Pragma",
+ ["proxy-authenticate"]="Proxy-Authenticate",
+ ["proxy-authorization"]="Proxy-Authorization",
+ ["range"]="Range",
+ ["received"]="Received",
+ ["received-from-mta"]="Received-From-MTA",
+ ["references"]="References",
+ ["referer"]="Referer",
+ ["remote-mta"]="Remote-MTA",
+ ["reply-to"]="Reply-To",
+ ["reporting-mta"]="Reporting-MTA",
+ ["resent-bcc"]="Resent-Bcc",
+ ["resent-cc"]="Resent-Cc",
+ ["resent-date"]="Resent-Date",
+ ["resent-from"]="Resent-From",
+ ["resent-message-id"]="Resent-Message-ID",
+ ["resent-reply-to"]="Resent-Reply-To",
+ ["resent-sender"]="Resent-Sender",
+ ["resent-to"]="Resent-To",
+ ["retry-after"]="Retry-After",
+ ["return-path"]="Return-Path",
+ ["sender"]="Sender",
+ ["server"]="Server",
+ ["smtp-remote-recipient"]="SMTP-Remote-Recipient",
+ ["status"]="Status",
+ ["subject"]="Subject",
+ ["te"]="TE",
+ ["to"]="To",
+ ["trailer"]="Trailer",
+ ["transfer-encoding"]="Transfer-Encoding",
+ ["upgrade"]="Upgrade",
+ ["user-agent"]="User-Agent",
+ ["vary"]="Vary",
+ ["via"]="Via",
+ ["warning"]="Warning",
+ ["will-retry-until"]="Will-Retry-Until",
+ ["www-authenticate"]="WWW-Authenticate",
+ ["x-mailer"]="X-Mailer",
}
headers.canonic=setmetatable(canonic,{
- __index=function(t,k)
- socket.report("invalid header: %s",k)
- t[k]=k
- return k
- end
+ __index=function(t,k)
+ socket.report("invalid header: %s",k)
+ t[k]=k
+ return k
+ end
})
function headers.normalize(headers)
- if not headers then
- return {}
- end
- local normalized={}
- for k,v in next,headers do
- normalized[#normalized+1]=canonic[k]..": "..v
- end
- normalized[#normalized+1]=""
- normalized[#normalized+1]=""
- return concat(normalized,"\r\n")
+ if not headers then
+ return {}
+ end
+ local normalized={}
+ for k,v in next,headers do
+ normalized[#normalized+1]=canonic[k]..": "..v
+ end
+ normalized[#normalized+1]=""
+ normalized[#normalized+1]=""
+ return concat(normalized,"\r\n")
end
function headers.lower(lowered,headers)
- if not lowered then
- return {}
- end
- if not headers then
- lowered,headers={},lowered
- end
- for k,v in next,headers do
- lowered[lower(k)]=v
- end
- return lowered
+ if not lowered then
+ return {}
+ end
+ if not headers then
+ lowered,headers={},lowered
+ end
+ for k,v in next,headers do
+ lowered[lower(k)]=v
+ end
+ return lowered
end
socket.headers=headers
package.loaded["socket.headers"]=headers
@@ -11095,13 +11095,13 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true
--- original size: 3116, stripped down to: 2643
+-- original size: 3116, stripped down to: 2533
local setmetatable,next,type,tonumber=setmetatable,next,type,tonumber
local find,upper=string.find,string.upper
local socket=socket or require("socket")
-local ltn12=ltn12 or require("ltn12")
+local ltn12=ltn12 or require("ltn12")
local skipsocket=socket.skip
local sinksocket=socket.sink
local tcpsocket=socket.tcp
@@ -11109,111 +11109,111 @@ local ltn12pump=ltn12.pump
local pumpall=ltn12pump.all
local pumpstep=ltn12pump.step
local tp={
- TIMEOUT=60,
+ TIMEOUT=60,
}
socket.tp=tp
local function get_reply(c)
- local line,err=c:receive()
- local reply=line
- if err then return
- nil,err
- end
- local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
- if not code then
- return nil,"invalid server reply"
- end
- if sep=="-" then
- local current
- repeat
- line,err=c:receive()
- if err then
- return nil,err
- end
- current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
- reply=reply.."\n"..line
- until code==current and sep==" "
- end
- return code,reply
+ local line,err=c:receive()
+ local reply=line
+ if err then return
+ nil,err
+ end
+ local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
+ if not code then
+ return nil,"invalid server reply"
+ end
+ if sep=="-" then
+ local current
+ repeat
+ line,err=c:receive()
+ if err then
+ return nil,err
+ end
+ current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
+ reply=reply.."\n"..line
+ until code==current and sep==" "
+ end
+ return code,reply
end
local methods={}
local mt={ __index=methods }
function methods.getpeername(self)
- return self.c:getpeername()
+ return self.c:getpeername()
end
function methods.getsockname(self)
- return self.c:getpeername()
+ return self.c:getpeername()
end
function methods.check(self,ok)
- local code,reply=get_reply(self.c)
- if not code then
- return nil,reply
- end
- local c=tonumber(code)
- local t=type(ok)
- if t=="function" then
- return ok(c,reply)
- elseif t=="table" then
- for i=1,#ok do
- if find(code,ok[i]) then
- return c,reply
- end
- end
- return nil,reply
- elseif find(code,ok) then
+ local code,reply=get_reply(self.c)
+ if not code then
+ return nil,reply
+ end
+ local c=tonumber(code)
+ local t=type(ok)
+ if t=="function" then
+ return ok(c,reply)
+ elseif t=="table" then
+ for i=1,#ok do
+ if find(code,ok[i]) then
return c,reply
- else
- return nil,reply
+ end
end
+ return nil,reply
+ elseif find(code,ok) then
+ return c,reply
+ else
+ return nil,reply
+ end
end
function methods.command(self,cmd,arg)
- cmd=upper(cmd)
- if arg then
- cmd=cmd.." "..arg.."\r\n"
- else
- cmd=cmd.."\r\n"
- end
- return self.c:send(cmd)
+ cmd=upper(cmd)
+ if arg then
+ cmd=cmd.." "..arg.."\r\n"
+ else
+ cmd=cmd.."\r\n"
+ end
+ return self.c:send(cmd)
end
function methods.sink(self,snk,pat)
- local chunk,err=self.c:receive(pat)
- return snk(chunk,err)
+ local chunk,err=self.c:receive(pat)
+ return snk(chunk,err)
end
function methods.send(self,data)
- return self.c:send(data)
+ return self.c:send(data)
end
function methods.receive(self,pat)
- return self.c:receive(pat)
+ return self.c:receive(pat)
end
function methods.getfd(self)
- return self.c:getfd()
+ return self.c:getfd()
end
function methods.dirty(self)
- return self.c:dirty()
+ return self.c:dirty()
end
function methods.getcontrol(self)
- return self.c
+ return self.c
end
function methods.source(self,source,step)
- local sink=sinksocket("keep-open",self.c)
- local ret,err=pumpall(source,sink,step or pumpstep)
- return ret,err
+ local sink=sinksocket("keep-open",self.c)
+ local ret,err=pumpall(source,sink,step or pumpstep)
+ return ret,err
end
function methods.close(self)
- self.c:close()
- return 1
+ self.c:close()
+ return 1
end
function tp.connect(host,port,timeout,create)
- local c,e=(create or tcpsocket)()
- if not c then
- return nil,e
- end
- c:settimeout(timeout or tp.TIMEOUT)
- local r,e=c:connect(host,port)
- if not r then
- c:close()
- return nil,e
- end
- return setmetatable({ c=c },mt)
+ local c,e=(create or tcpsocket)()
+ if not c then
+ return nil,e
+ end
+ c:settimeout(timeout or tp.TIMEOUT)
+ local r,e=c:connect(host,port)
+ if not r then
+ c:close()
+ return nil,e
+ end
+ return setmetatable({ c=c },mt)
end
package.loaded["socket.tp"]=tp
@@ -11224,16 +11224,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true
--- original size: 12577, stripped down to: 10069
+-- original size: 12577, stripped down to: 9577
local tostring,tonumber,setmetatable,next,type=tostring,tonumber,setmetatable,next,type
local find,lower,format,gsub,match=string.find,string.lower,string.format,string.gsub,string.match
local concat=table.concat
-local socket=socket or require("socket")
-local url=socket.url or require("socket.url")
-local ltn12=ltn12 or require("ltn12")
-local mime=mime or require("mime")
+local socket=socket or require("socket")
+local url=socket.url or require("socket.url")
+local ltn12=ltn12 or require("ltn12")
+local mime=mime or require("mime")
local headers=socket.headers or require("socket.headers")
local normalizeheaders=headers.normalize
local parseurl=url.parse
@@ -11257,345 +11257,345 @@ local sinktable=ltn12.sink.table
local lowerheaders=headers.lower
local mimeb64=mime.b64
local http={
- TIMEOUT=60,
- USERAGENT=socket._VERSION,
+ TIMEOUT=60,
+ USERAGENT=socket._VERSION,
}
socket.http=http
local PORT=80
local SCHEMES={
- http=true,
+ http=true,
}
local function receiveheaders(sock,headers)
- if not headers then
- headers={}
- end
- local line,err=sock:receive()
+ if not headers then
+ headers={}
+ end
+ local line,err=sock:receive()
+ if err then
+ return nil,err
+ end
+ while line~="" do
+ local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
+ if not (name and value) then
+ return nil,"malformed reponse headers"
+ end
+ name=lower(name)
+ line,err=sock:receive()
if err then
+ return nil,err
+ end
+ while find(line,"^%s") do
+ value=value..line
+ line=sock:receive()
+ if err then
return nil,err
+ end
end
- while line~="" do
- local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
- if not (name and value) then
- return nil,"malformed reponse headers"
- end
- name=lower(name)
- line,err=sock:receive()
+ local found=headers[name]
+ if found then
+ value=found..", "..value
+ end
+ headers[name]=value
+ end
+ return headers
+end
+socket.sourcet["http-chunked"]=function(sock,headers)
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },{
+ __call=function()
+ local line,err=sock:receive()
if err then
- return nil,err
+ return nil,err
end
- while find(line,"^%s") do
- value=value..line
- line=sock:receive()
- if err then
- return nil,err
- end
+ local size=tonumber(gsub(line,";.*",""),16)
+ if not size then
+ return nil,"invalid chunk size"
end
- local found=headers[name]
- if found then
- value=found..", "..value
+ if size>0 then
+ local chunk,err,part=sock:receive(size)
+ if chunk then
+ sock:receive()
+ end
+ return chunk,err
+ else
+ headers,err=receiveheaders(sock,headers)
+ if not headers then
+ return nil,err
+ end
end
- headers[name]=value
- end
- return headers
-end
-socket.sourcet["http-chunked"]=function(sock,headers)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function()
- local line,err=sock:receive()
- if err then
- return nil,err
- end
- local size=tonumber(gsub(line,";.*",""),16)
- if not size then
- return nil,"invalid chunk size"
- end
- if size>0 then
- local chunk,err,part=sock:receive(size)
- if chunk then
- sock:receive()
- end
- return chunk,err
- else
- headers,err=receiveheaders(sock,headers)
- if not headers then
- return nil,err
- end
- end
- end
- }
- )
+ end
+ }
+ )
end
socket.sinkt["http-chunked"]=function(sock)
- return setmetatable(
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function(self,chunk,err)
- if not chunk then
- chunk=""
- end
- return sock:send(format("%X\r\n%s\r\n",#chunk,chunk))
- end
- })
+ return setmetatable(
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },
+ {
+ __call=function(self,chunk,err)
+ if not chunk then
+ chunk=""
+ end
+ return sock:send(format("%X\r\n%s\r\n",#chunk,chunk))
+ end
+ })
end
local methods={}
local mt={ __index=methods }
local function openhttp(host,port,create)
- local c=trysocket((create or tcpsocket)())
- local h=setmetatable({ c=c },mt)
- local try=newtrysocket(function() h:close() end)
- h.try=try
- try(c:settimeout(http.TIMEOUT))
- try(c:connect(host,port or PORT))
- return h
+ local c=trysocket((create or tcpsocket)())
+ local h=setmetatable({ c=c },mt)
+ local try=newtrysocket(function() h:close() end)
+ h.try=try
+ try(c:settimeout(http.TIMEOUT))
+ try(c:connect(host,port or PORT))
+ return h
end
http.open=openhttp
function methods.sendrequestline(self,method,uri)
- local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri)
- return self.try(self.c:send(requestline))
+ local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri)
+ return self.try(self.c:send(requestline))
end
function methods.sendheaders(self,headers)
- self.try(self.c:send(normalizeheaders(headers)))
- return 1
+ self.try(self.c:send(normalizeheaders(headers)))
+ return 1
end
function methods.sendbody(self,headers,source,step)
- if not source then
- source=emptysource()
- end
- if not step then
- step=pumpstep
- end
- local mode="http-chunked"
- if headers["content-length"] then
- mode="keep-open"
- end
- return self.try(pumpall(source,sinksocket(mode,self.c),step))
+ if not source then
+ source=emptysource()
+ end
+ if not step then
+ step=pumpstep
+ end
+ local mode="http-chunked"
+ if headers["content-length"] then
+ mode="keep-open"
+ end
+ return self.try(pumpall(source,sinksocket(mode,self.c),step))
end
function methods.receivestatusline(self)
- local try=self.try
- local status=try(self.c:receive(5))
- if status~="HTTP/" then
- return nil,status
- end
- status=try(self.c:receive("*l",status))
- local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)"))
- return try(tonumber(code),status)
+ local try=self.try
+ local status=try(self.c:receive(5))
+ if status~="HTTP/" then
+ return nil,status
+ end
+ status=try(self.c:receive("*l",status))
+ local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)"))
+ return try(tonumber(code),status)
end
function methods.receiveheaders(self)
- return self.try(receiveheaders(self.c))
+ return self.try(receiveheaders(self.c))
end
function methods.receivebody(self,headers,sink,step)
- if not sink then
- sink=sinknull()
- end
- if not step then
- step=pumpstep
- end
- local length=tonumber(headers["content-length"])
- local encoding=headers["transfer-encoding"]
- local mode="default"
- if encoding and encoding~="identity" then
- mode="http-chunked"
- elseif length then
- mode="by-length"
- end
- return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step))
+ if not sink then
+ sink=sinknull()
+ end
+ if not step then
+ step=pumpstep
+ end
+ local length=tonumber(headers["content-length"])
+ local encoding=headers["transfer-encoding"]
+ local mode="default"
+ if encoding and encoding~="identity" then
+ mode="http-chunked"
+ elseif length then
+ mode="by-length"
+ end
+ return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step))
end
function methods.receive09body(self,status,sink,step)
- local source=rewindsource(sourcesocket("until-closed",self.c))
- source(status)
- return self.try(pumpall(source,sink,step))
+ local source=rewindsource(sourcesocket("until-closed",self.c))
+ source(status)
+ return self.try(pumpall(source,sink,step))
end
function methods.close(self)
- return self.c:close()
+ return self.c:close()
end
local function adjusturi(request)
- if not request.proxy and not http.PROXY then
- request={
- path=trysocket(request.path,"invalid path 'nil'"),
- params=request.params,
- query=request.query,
- fragment=request.fragment,
- }
- end
- return buildurl(request)
+ if not request.proxy and not http.PROXY then
+ request={
+ path=trysocket(request.path,"invalid path 'nil'"),
+ params=request.params,
+ query=request.query,
+ fragment=request.fragment,
+ }
+ end
+ return buildurl(request)
end
local function adjustheaders(request)
- local headers={
- ["user-agent"]=http.USERAGENT,
- ["host"]=gsub(request.authority,"^.-@",""),
- ["connection"]="close, TE",
- ["te"]="trailers"
- }
- local username=request.user
- local password=request.password
+ local headers={
+ ["user-agent"]=http.USERAGENT,
+ ["host"]=gsub(request.authority,"^.-@",""),
+ ["connection"]="close, TE",
+ ["te"]="trailers"
+ }
+ local username=request.user
+ local password=request.password
+ if username and password then
+ headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password)))
+ end
+ local proxy=request.proxy or http.PROXY
+ if proxy then
+ proxy=parseurl(proxy)
+ local username=proxy.user
+ local password=proxy.password
if username and password then
- headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password)))
- end
- local proxy=request.proxy or http.PROXY
- if proxy then
- proxy=parseurl(proxy)
- local username=proxy.user
- local password=proxy.password
- if username and password then
- headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password))
- end
- end
- local requestheaders=request.headers
- if requestheaders then
- headers=lowerheaders(headers,requestheaders)
+ headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password))
end
- return headers
+ end
+ local requestheaders=request.headers
+ if requestheaders then
+ headers=lowerheaders(headers,requestheaders)
+ end
+ return headers
end
local default={
- host="",
- port=PORT,
- path="/",
- scheme="http"
+ host="",
+ port=PORT,
+ path="/",
+ scheme="http"
}
local function adjustrequest(originalrequest)
- local url=originalrequest.url
- local request=url and parseurl(url,default) or {}
- for k,v in next,originalrequest do
- request[k]=v
- end
- local host=request.host
- local port=request.port
- local uri=request.uri
- if not host or host=="" then
- trysocket(nil,"invalid host '"..tostring(host).."'")
- end
- if port=="" then
- request.port=PORT
- end
- if not uri or uri=="" then
- request.uri=adjusturi(request)
- end
- request.headers=adjustheaders(request)
- local proxy=request.proxy or http.PROXY
- if proxy then
- proxy=parseurl(proxy)
- request.host=proxy.host
- request.port=proxy.port or 3128
- end
- return request
+ local url=originalrequest.url
+ local request=url and parseurl(url,default) or {}
+ for k,v in next,originalrequest do
+ request[k]=v
+ end
+ local host=request.host
+ local port=request.port
+ local uri=request.uri
+ if not host or host=="" then
+ trysocket(nil,"invalid host '"..tostring(host).."'")
+ end
+ if port=="" then
+ request.port=PORT
+ end
+ if not uri or uri=="" then
+ request.uri=adjusturi(request)
+ end
+ request.headers=adjustheaders(request)
+ local proxy=request.proxy or http.PROXY
+ if proxy then
+ proxy=parseurl(proxy)
+ request.host=proxy.host
+ request.port=proxy.port or 3128
+ end
+ return request
end
local maxredericts=4
local validredirects={ [301]=true,[302]=true,[303]=true,[307]=true }
local validmethods={ [false]=true,GET=true,HEAD=true }
local function shouldredirect(request,code,headers)
- local location=headers.location
- if not location then
- return false
- end
- location=gsub(location,"%s","")
- if location=="" then
- return false
- end
- local scheme=match(location,"^([%w][%w%+%-%.]*)%:")
- if scheme and not SCHEMES[scheme] then
- return false
- end
- local method=request.method
- local redirect=request.redirect
- local redirects=request.nredirects or 0
- return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts
+ local location=headers.location
+ if not location then
+ return false
+ end
+ location=gsub(location,"%s","")
+ if location=="" then
+ return false
+ end
+ local scheme=match(location,"^([%w][%w%+%-%.]*)%:")
+ if scheme and not SCHEMES[scheme] then
+ return false
+ end
+ local method=request.method
+ local redirect=request.redirect
+ local redirects=request.nredirects or 0
+ return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts
end
local function shouldreceivebody(request,code)
- if request.method=="HEAD" then
- return nil
- end
- if code==204 or code==304 then
- return nil
- end
- if code>=100 and code<200 then
- return nil
- end
- return 1
+ if request.method=="HEAD" then
+ return nil
+ end
+ if code==204 or code==304 then
+ return nil
+ end
+ if code>=100 and code<200 then
+ return nil
+ end
+ return 1
end
local tredirect,trequest,srequest
tredirect=function(request,location)
- local result,code,headers,status=trequest {
- url=absoluteurl(request.url,location),
- source=request.source,
- sink=request.sink,
- headers=request.headers,
- proxy=request.proxy,
- nredirects=(request.nredirects or 0)+1,
- create=request.create,
- }
- if not headers then
- headers={}
- end
- if not headers.location then
- headers.location=location
- end
- return result,code,headers,status
+ local result,code,headers,status=trequest {
+ url=absoluteurl(request.url,location),
+ source=request.source,
+ sink=request.sink,
+ headers=request.headers,
+ proxy=request.proxy,
+ nredirects=(request.nredirects or 0)+1,
+ create=request.create,
+ }
+ if not headers then
+ headers={}
+ end
+ if not headers.location then
+ headers.location=location
+ end
+ return result,code,headers,status
end
trequest=function(originalrequest)
- local request=adjustrequest(originalrequest)
- local connection=openhttp(request.host,request.port,request.create)
- local headers=request.headers
- connection:sendrequestline(request.method,request.uri)
- connection:sendheaders(headers)
- if request.source then
- connection:sendbody(headers,request.source,request.step)
- end
- local code,status=connection:receivestatusline()
- if not code then
- connection:receive09body(status,request.sink,request.step)
- return 1,200
- end
- while code==100 do
- headers=connection:receiveheaders()
- code,status=connection:receivestatusline()
- end
+ local request=adjustrequest(originalrequest)
+ local connection=openhttp(request.host,request.port,request.create)
+ local headers=request.headers
+ connection:sendrequestline(request.method,request.uri)
+ connection:sendheaders(headers)
+ if request.source then
+ connection:sendbody(headers,request.source,request.step)
+ end
+ local code,status=connection:receivestatusline()
+ if not code then
+ connection:receive09body(status,request.sink,request.step)
+ return 1,200
+ end
+ while code==100 do
headers=connection:receiveheaders()
- if shouldredirect(request,code,headers) and not request.source then
- connection:close()
- return tredirect(originalrequest,headers.location)
- end
- if shouldreceivebody(request,code) then
- connection:receivebody(headers,request.sink,request.step)
- end
+ code,status=connection:receivestatusline()
+ end
+ headers=connection:receiveheaders()
+ if shouldredirect(request,code,headers) and not request.source then
connection:close()
- return 1,code,headers,status
+ return tredirect(originalrequest,headers.location)
+ end
+ if shouldreceivebody(request,code) then
+ connection:receivebody(headers,request.sink,request.step)
+ end
+ connection:close()
+ return 1,code,headers,status
end
local function genericform(url,body)
- local buffer={}
- local request={
- url=url,
- sink=sinktable(buffer),
- target=buffer,
+ local buffer={}
+ local request={
+ url=url,
+ sink=sinktable(buffer),
+ target=buffer,
+ }
+ if body then
+ request.source=stringsource(body)
+ request.method="POST"
+ request.headers={
+ ["content-length"]=#body,
+ ["content-type"]="application/x-www-form-urlencoded"
}
- if body then
- request.source=stringsource(body)
- request.method="POST"
- request.headers={
- ["content-length"]=#body,
- ["content-type"]="application/x-www-form-urlencoded"
- }
- end
- return request
+ end
+ return request
end
http.genericform=genericform
srequest=function(url,body)
- local request=genericform(url,body)
- local _,code,headers,status=trequest(request)
- return concat(request.target),code,headers,status
+ local request=genericform(url,body)
+ local _,code,headers,status=trequest(request)
+ return concat(request.target),code,headers,status
end
http.request=protectsocket(function(request,body)
- if type(request)=="string" then
- return srequest(request,body)
- else
- return trequest(request)
- end
+ if type(request)=="string" then
+ return srequest(request,body)
+ else
+ return trequest(request)
+ end
end)
package.loaded["socket.http"]=http
@@ -11606,16 +11606,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true
--- original size: 10357, stripped down to: 8900
+-- original size: 10357, stripped down to: 8548
local setmetatable,type,next=setmetatable,type,next
local find,format,gsub,match=string.find,string.format,string.gsub,string.match
local concat=table.concat
local mod=math.mod
-local socket=socket or require("socket")
+local socket=socket or require("socket")
local url=socket.url or require("socket.url")
-local tp=socket.tp or require("socket.tp")
+local tp=socket.tp or require("socket.tp")
local ltn12=ltn12 or require("ltn12")
local tcpsocket=socket.tcp
local trysocket=socket.try
@@ -11633,341 +11633,341 @@ local pumpstep=ltn12.pump.step
local sourcestring=ltn12.source.string
local sinktable=ltn12.sink.table
local ftp={
- TIMEOUT=60,
- USER="ftp",
- PASSWORD="anonymous@anonymous.org",
+ TIMEOUT=60,
+ USER="ftp",
+ PASSWORD="anonymous@anonymous.org",
}
socket.ftp=ftp
local PORT=21
local methods={}
local mt={ __index=methods }
function ftp.open(server,port,create)
- local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create))
- local f=setmetatable({ tp=tp },metat)
- f.try=newtrysocket(function() f:close() end)
- return f
+ local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create))
+ local f=setmetatable({ tp=tp },metat)
+ f.try=newtrysocket(function() f:close() end)
+ return f
end
function methods.portconnect(self)
- local try=self.try
- local server=self.server
- try(server:settimeout(ftp.TIMEOUT))
- self.data=try(server:accept())
- try(self.data:settimeout(ftp.TIMEOUT))
+ local try=self.try
+ local server=self.server
+ try(server:settimeout(ftp.TIMEOUT))
+ self.data=try(server:accept())
+ try(self.data:settimeout(ftp.TIMEOUT))
end
function methods.pasvconnect(self)
- local try=self.try
- self.data=try(tcpsocket())
- self(self.data:settimeout(ftp.TIMEOUT))
- self(self.data:connect(self.pasvt.address,self.pasvt.port))
+ local try=self.try
+ self.data=try(tcpsocket())
+ self(self.data:settimeout(ftp.TIMEOUT))
+ self(self.data:connect(self.pasvt.address,self.pasvt.port))
end
function methods.login(self,user,password)
- local try=self.try
- local tp=self.tp
- try(tp:command("user",user or ftp.USER))
- local code,reply=try(tp:check{"2..",331})
- if code==331 then
- try(tp:command("pass",password or ftp.PASSWORD))
- try(tp:check("2.."))
- end
- return 1
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("user",user or ftp.USER))
+ local code,reply=try(tp:check{"2..",331})
+ if code==331 then
+ try(tp:command("pass",password or ftp.PASSWORD))
+ try(tp:check("2.."))
+ end
+ return 1
end
function methods.pasv(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("pasv"))
- local code,reply=try(self.tp:check("2.."))
- local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
- local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern))
- try(a and b and c and d and p1 and p2,reply)
- local address=format("%d.%d.%d.%d",a,b,c,d)
- local port=p1*256+p2
- local server=self.server
- self.pasvt={
- address=address,
- port=port,
- }
- if server then
- server:close()
- self.server=nil
- end
- return address,port
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("pasv"))
+ local code,reply=try(self.tp:check("2.."))
+ local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
+ local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern))
+ try(a and b and c and d and p1 and p2,reply)
+ local address=format("%d.%d.%d.%d",a,b,c,d)
+ local port=p1*256+p2
+ local server=self.server
+ self.pasvt={
+ address=address,
+ port=port,
+ }
+ if server then
+ server:close()
+ self.server=nil
+ end
+ return address,port
end
function methods.epsv(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("epsv"))
- local code,reply=try(tp:check("229"))
- local pattern="%((.)(.-)%1(.-)%1(.-)%1%)"
- local d,prt,address,port=match(reply,pattern)
- try(port,"invalid epsv response")
- local address=tp:getpeername()
- local server=self.server
- self.pasvt={
- address=address,
- port=port,
- }
- if self.server then
- server:close()
- self.server=nil
- end
- return address,port
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("epsv"))
+ local code,reply=try(tp:check("229"))
+ local pattern="%((.)(.-)%1(.-)%1(.-)%1%)"
+ local d,prt,address,port=match(reply,pattern)
+ try(port,"invalid epsv response")
+ local address=tp:getpeername()
+ local server=self.server
+ self.pasvt={
+ address=address,
+ port=port,
+ }
+ if self.server then
+ server:close()
+ self.server=nil
+ end
+ return address,port
end
function methods.port(self,address,port)
- local try=self.try
- local tp=self.tp
- self.pasvt=nil
- if not address then
- address,port=try(tp:getsockname())
- self.server=try(bindsocket(address,0))
- address,port=try(self.server:getsockname())
- try(self.server:settimeout(ftp.TIMEOUT))
- end
- local pl=mod(port,256)
- local ph=(port-pl)/256
- local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",")
- try(tp:command("port",arg))
- try(tp:check("2.."))
- return 1
+ local try=self.try
+ local tp=self.tp
+ self.pasvt=nil
+ if not address then
+ address,port=try(tp:getsockname())
+ self.server=try(bindsocket(address,0))
+ address,port=try(self.server:getsockname())
+ try(self.server:settimeout(ftp.TIMEOUT))
+ end
+ local pl=mod(port,256)
+ local ph=(port-pl)/256
+ local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",")
+ try(tp:command("port",arg))
+ try(tp:check("2.."))
+ return 1
end
function methods.eprt(self,family,address,port)
- local try=self.try
- local tp=self.tp
- self.pasvt=nil
- if not address then
- address,port=try(tp:getsockname())
- self.server=try(bindsocket(address,0))
- address,port=try(self.server:getsockname())
- try(self.server:settimeout(ftp.TIMEOUT))
- end
- local arg=format("|%s|%s|%d|",family,address,port)
- try(tp:command("eprt",arg))
- try(tp:check("2.."))
- return 1
+ local try=self.try
+ local tp=self.tp
+ self.pasvt=nil
+ if not address then
+ address,port=try(tp:getsockname())
+ self.server=try(bindsocket(address,0))
+ address,port=try(self.server:getsockname())
+ try(self.server:settimeout(ftp.TIMEOUT))
+ end
+ local arg=format("|%s|%s|%d|",family,address,port)
+ try(tp:command("eprt",arg))
+ try(tp:check("2.."))
+ return 1
end
function methods.send(self,sendt)
- local try=self.try
- local tp=self.tp
- try(self.pasvt or self.server,"need port or pasv first")
- if self.pasvt then
- self:pasvconnect()
- end
- local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]",""))
- if argument=="" then
- argument=nil
- end
- local command=sendt.command or "stor"
- try(tp:command(command,argument))
- local code,reply=try(tp:check{"2..","1.."})
- if not self.pasvt then
- self:portconnect()
- end
- local step=sendt.step or pumpstep
- local readt={ tp }
- local checkstep=function(src,snk)
- local readyt=selectsocket(readt,nil,0)
- if readyt[tp] then
- code=try(tp:check("2.."))
- end
- return step(src,snk)
- end
- local sink=sinksocket("close-when-done",self.data)
- try(pumpall(sendt.source,sink,checkstep))
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- self.data:close()
- local sent=skipsocket(1,self.data:getstats())
- self.data=nil
- return sent
+ local try=self.try
+ local tp=self.tp
+ try(self.pasvt or self.server,"need port or pasv first")
+ if self.pasvt then
+ self:pasvconnect()
+ end
+ local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]",""))
+ if argument=="" then
+ argument=nil
+ end
+ local command=sendt.command or "stor"
+ try(tp:command(command,argument))
+ local code,reply=try(tp:check{"2..","1.."})
+ if not self.pasvt then
+ self:portconnect()
+ end
+ local step=sendt.step or pumpstep
+ local readt={ tp }
+ local checkstep=function(src,snk)
+ local readyt=selectsocket(readt,nil,0)
+ if readyt[tp] then
+ code=try(tp:check("2.."))
+ end
+ return step(src,snk)
+ end
+ local sink=sinksocket("close-when-done",self.data)
+ try(pumpall(sendt.source,sink,checkstep))
+ if find(code,"1..") then
+ try(tp:check("2.."))
+ end
+ self.data:close()
+ local sent=skipsocket(1,self.data:getstats())
+ self.data=nil
+ return sent
end
function methods.receive(self,recvt)
- local try=self.try
- local tp=self.tp
- try(self.pasvt or self.server,"need port or pasv first")
- if self.pasvt then self:pasvconnect() end
- local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]",""))
- if argument=="" then
- argument=nil
- end
- local command=recvt.command or "retr"
- try(tp:command(command,argument))
- local code,reply=try(tp:check{"1..","2.."})
- if code>=200 and code<=299 then
- recvt.sink(reply)
- return 1
- end
- if not self.pasvt then
- self:portconnect()
- end
- local source=sourcesocket("until-closed",self.data)
- local step=recvt.step or pumpstep
- try(pumpall(source,recvt.sink,step))
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- self.data:close()
- self.data=nil
+ local try=self.try
+ local tp=self.tp
+ try(self.pasvt or self.server,"need port or pasv first")
+ if self.pasvt then self:pasvconnect() end
+ local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]",""))
+ if argument=="" then
+ argument=nil
+ end
+ local command=recvt.command or "retr"
+ try(tp:command(command,argument))
+ local code,reply=try(tp:check{"1..","2.."})
+ if code>=200 and code<=299 then
+ recvt.sink(reply)
return 1
+ end
+ if not self.pasvt then
+ self:portconnect()
+ end
+ local source=sourcesocket("until-closed",self.data)
+ local step=recvt.step or pumpstep
+ try(pumpall(source,recvt.sink,step))
+ if find(code,"1..") then
+ try(tp:check("2.."))
+ end
+ self.data:close()
+ self.data=nil
+ return 1
end
function methods.cwd(self,dir)
- local try=self.try
- local tp=self.tp
- try(tp:command("cwd",dir))
- try(tp:check(250))
- return 1
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("cwd",dir))
+ try(tp:check(250))
+ return 1
end
function methods.type(self,typ)
- local try=self.try
- local tp=self.tp
- try(tp:command("type",typ))
- try(tp:check(200))
- return 1
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("type",typ))
+ try(tp:check(200))
+ return 1
end
function methods.greet(self)
- local try=self.try
- local tp=self.tp
- local code=try(tp:check{"1..","2.."})
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- return 1
+ local try=self.try
+ local tp=self.tp
+ local code=try(tp:check{"1..","2.."})
+ if find(code,"1..") then
+ try(tp:check("2.."))
+ end
+ return 1
end
function methods.quit(self)
- local try=self.try
- try(self.tp:command("quit"))
- try(self.tp:check("2.."))
- return 1
+ local try=self.try
+ try(self.tp:command("quit"))
+ try(self.tp:check("2.."))
+ return 1
end
function methods.close(self)
- local data=self.data
- if data then
- data:close()
- end
- local server=self.server
- if server then
- server:close()
- end
- local tp=self.tp
- if tp then
- tp:close()
- end
+ local data=self.data
+ if data then
+ data:close()
+ end
+ local server=self.server
+ if server then
+ server:close()
+ end
+ local tp=self.tp
+ if tp then
+ tp:close()
+ end
end
local function override(t)
- if t.url then
- local u=parseurl(t.url)
- for k,v in next,t do
- u[k]=v
- end
- return u
- else
- return t
+ if t.url then
+ local u=parseurl(t.url)
+ for k,v in next,t do
+ u[k]=v
end
+ return u
+ else
+ return t
+ end
end
local function tput(putt)
- putt=override(putt)
- local host=putt.host
- trysocket(host,"missing hostname")
- local f=ftp.open(host,putt.port,putt.create)
- f:greet()
- f:login(putt.user,putt.password)
- local typ=putt.type
- if typ then
- f:type(typ)
- end
- f:epsv()
- local sent=f:send(putt)
- f:quit()
- f:close()
- return sent
+ putt=override(putt)
+ local host=putt.host
+ trysocket(host,"missing hostname")
+ local f=ftp.open(host,putt.port,putt.create)
+ f:greet()
+ f:login(putt.user,putt.password)
+ local typ=putt.type
+ if typ then
+ f:type(typ)
+ end
+ f:epsv()
+ local sent=f:send(putt)
+ f:quit()
+ f:close()
+ return sent
end
local default={
- path="/",
- scheme="ftp",
+ path="/",
+ scheme="ftp",
}
local function genericform(u)
- local t=trysocket(parseurl(u,default))
- trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'")
- trysocket(t.host,"missing hostname")
- local pat="^type=(.)$"
- if t.params then
- local typ=skipsocket(2,find(t.params,pat))
- t.type=typ
- trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'")
- end
- return t
+ local t=trysocket(parseurl(u,default))
+ trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'")
+ trysocket(t.host,"missing hostname")
+ local pat="^type=(.)$"
+ if t.params then
+ local typ=skipsocket(2,find(t.params,pat))
+ t.type=typ
+ trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'")
+ end
+ return t
end
ftp.genericform=genericform
local function sput(u,body)
- local putt=genericform(u)
- putt.source=sourcestring(body)
- return tput(putt)
+ local putt=genericform(u)
+ putt.source=sourcestring(body)
+ return tput(putt)
end
ftp.put=protectsocket(function(putt,body)
- if type(putt)=="string" then
- return sput(putt,body)
- else
- return tput(putt)
- end
+ if type(putt)=="string" then
+ return sput(putt,body)
+ else
+ return tput(putt)
+ end
end)
local function tget(gett)
- gett=override(gett)
- local host=gett.host
- trysocket(host,"missing hostname")
- local f=ftp.open(host,gett.port,gett.create)
- f:greet()
- f:login(gett.user,gett.password)
- if gett.type then
- f:type(gett.type)
- end
- f:epsv()
- f:receive(gett)
- f:quit()
- return f:close()
+ gett=override(gett)
+ local host=gett.host
+ trysocket(host,"missing hostname")
+ local f=ftp.open(host,gett.port,gett.create)
+ f:greet()
+ f:login(gett.user,gett.password)
+ if gett.type then
+ f:type(gett.type)
+ end
+ f:epsv()
+ f:receive(gett)
+ f:quit()
+ return f:close()
end
local function sget(u)
- local gett=genericform(u)
- local t={}
- gett.sink=sinktable(t)
- tget(gett)
- return concat(t)
+ local gett=genericform(u)
+ local t={}
+ gett.sink=sinktable(t)
+ tget(gett)
+ return concat(t)
end
ftp.command=protectsocket(function(cmdt)
- cmdt=override(cmdt)
- local command=cmdt.command
- local argument=cmdt.argument
- local check=cmdt.check
- local host=cmdt.host
- trysocket(host,"missing hostname")
- trysocket(command,"missing command")
- local f=ftp.open(host,cmdt.port,cmdt.create)
- local try=f.try
- local tp=f.tp
- f:greet()
- f:login(cmdt.user,cmdt.password)
- if type(command)=="table" then
- local argument=argument or {}
- for i=1,#command do
- local cmd=command[i]
- try(tp:command(cmd,argument[i]))
- if check and check[i] then
- try(tp:check(check[i]))
- end
- end
- else
- try(tp:command(command,argument))
- if check then
- try(tp:check(check))
- end
+ cmdt=override(cmdt)
+ local command=cmdt.command
+ local argument=cmdt.argument
+ local check=cmdt.check
+ local host=cmdt.host
+ trysocket(host,"missing hostname")
+ trysocket(command,"missing command")
+ local f=ftp.open(host,cmdt.port,cmdt.create)
+ local try=f.try
+ local tp=f.tp
+ f:greet()
+ f:login(cmdt.user,cmdt.password)
+ if type(command)=="table" then
+ local argument=argument or {}
+ for i=1,#command do
+ local cmd=command[i]
+ try(tp:command(cmd,argument[i]))
+ if check and check[i] then
+ try(tp:check(check[i]))
+ end
end
- f:quit()
- return f:close()
+ else
+ try(tp:command(command,argument))
+ if check then
+ try(tp:check(check))
+ end
+ end
+ f:quit()
+ return f:close()
end)
ftp.get=protectsocket(function(gett)
- if type(gett)=="string" then
- return sget(gett)
- else
- return tget(gett)
- end
+ if type(gett)=="string" then
+ return sget(gett)
+ else
+ return tget(gett)
+ end
end)
package.loaded["socket.ftp"]=ftp
@@ -11978,18 +11978,18 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true
--- original size: 7018, stripped down to: 6095
+-- original size: 7018, stripped down to: 5883
local type,setmetatable,next=type,setmetatable,next
local find,lower,format=string.find,string.lower,string.format
local osdate,osgetenv=os.date,os.getenv
local random=math.random
-local socket=socket or require("socket")
+local socket=socket or require("socket")
local headers=socket.headers or require("socket.headers")
-local ltn12=ltn12 or require("ltn12")
+local ltn12=ltn12 or require("ltn12")
local tp=socket.tp or require("socket.tp")
-local mime=mime or require("mime")
+local mime=mime or require("mime")
local mimeb64=mime.b64
local mimestuff=mime.stuff
local skipsocket=socket.skip
@@ -12002,212 +12002,212 @@ local createcoroutine=coroutine.create
local resumecoroutine=coroutine.resume
local yieldcoroutine=coroutine.resume
local smtp={
- TIMEOUT=60,
- SERVER="localhost",
- PORT=25,
- DOMAIN=osgetenv("SERVER_NAME") or "localhost",
- ZONE="-0000",
+ TIMEOUT=60,
+ SERVER="localhost",
+ PORT=25,
+ DOMAIN=osgetenv("SERVER_NAME") or "localhost",
+ ZONE="-0000",
}
socket.smtp=smtp
local methods={}
local mt={ __index=methods }
function methods.greet(self,domain)
- local try=self.try
- local tp=self.tp
- try(tp:check("2.."))
- try(tp:command("EHLO",domain or _M.DOMAIN))
- return skipsocket(1,try(tp:check("2..")))
+ local try=self.try
+ local tp=self.tp
+ try(tp:check("2.."))
+ try(tp:command("EHLO",domain or _M.DOMAIN))
+ return skipsocket(1,try(tp:check("2..")))
end
function methods.mail(self,from)
- local try=self.try
- local tp=self.tp
- try(tp:command("MAIL","FROM:"..from))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("MAIL","FROM:"..from))
+ return try(tp:check("2.."))
end
function methods.rcpt(self,to)
- local try=self.try
- local tp=self.tp
- try(tp:command("RCPT","TO:"..to))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("RCPT","TO:"..to))
+ return try(tp:check("2.."))
end
function methods.data(self,src,step)
- local try=self.try
- local tp=self.tp
- try(tp:command("DATA"))
- try(tp:check("3.."))
- try(tp:source(src,step))
- try(tp:send("\r\n.\r\n"))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("DATA"))
+ try(tp:check("3.."))
+ try(tp:source(src,step))
+ try(tp:send("\r\n.\r\n"))
+ return try(tp:check("2.."))
end
function methods.quit(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("QUIT"))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("QUIT"))
+ return try(tp:check("2.."))
end
function methods.close(self)
- return self.tp:close()
+ return self.tp:close()
end
function methods.login(self,user,password)
- local try=self.try
- local tp=self.tp
- try(tp:command("AUTH","LOGIN"))
- try(tp:check("3.."))
- try(tp:send(mimeb64(user).."\r\n"))
- try(tp:check("3.."))
- try(tp:send(mimeb64(password).."\r\n"))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("AUTH","LOGIN"))
+ try(tp:check("3.."))
+ try(tp:send(mimeb64(user).."\r\n"))
+ try(tp:check("3.."))
+ try(tp:send(mimeb64(password).."\r\n"))
+ return try(tp:check("2.."))
end
function methods.plain(self,user,password)
- local try=self.try
- local tp=self.tp
- local auth="PLAIN "..mimeb64("\0"..user.."\0"..password)
- try(tp:command("AUTH",auth))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ local auth="PLAIN "..mimeb64("\0"..user.."\0"..password)
+ try(tp:command("AUTH",auth))
+ return try(tp:check("2.."))
end
function methods.auth(self,user,password,ext)
- if not user or not password then
- return 1
- end
- local try=self.try
- if find(ext,"AUTH[^\n]+LOGIN") then
- return self:login(user,password)
- elseif find(ext,"AUTH[^\n]+PLAIN") then
- return self:plain(user,password)
- else
- try(nil,"authentication not supported")
- end
+ if not user or not password then
+ return 1
+ end
+ local try=self.try
+ if find(ext,"AUTH[^\n]+LOGIN") then
+ return self:login(user,password)
+ elseif find(ext,"AUTH[^\n]+PLAIN") then
+ return self:plain(user,password)
+ else
+ try(nil,"authentication not supported")
+ end
end
function methods.send(self,mail)
- self:mail(mail.from)
- local receipt=mail.rcpt
- if type(receipt)=="table" then
- for i=1,#receipt do
- self:rcpt(receipt[i])
- end
- elseif receipt then
- self:rcpt(receipt)
+ self:mail(mail.from)
+ local receipt=mail.rcpt
+ if type(receipt)=="table" then
+ for i=1,#receipt do
+ self:rcpt(receipt[i])
end
- self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step)
+ elseif receipt then
+ self:rcpt(receipt)
+ end
+ self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step)
end
local function opensmtp(self,server,port,create)
- if not server or server=="" then
- server=smtp.SERVER
- end
- if not port or port=="" then
- port=smtp.PORT
- end
- local s={
- tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)),
- try=newtrysocket(function()
- s:close()
- end),
- }
- setmetatable(s,mt)
- return s
+ if not server or server=="" then
+ server=smtp.SERVER
+ end
+ if not port or port=="" then
+ port=smtp.PORT
+ end
+ local s={
+ tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)),
+ try=newtrysocket(function()
+ s:close()
+ end),
+ }
+ setmetatable(s,mt)
+ return s
end
smtp.open=opensmtp
local nofboundaries=0
local function newboundary()
- nofboundaries=nofboundaries+1
- return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries)
+ nofboundaries=nofboundaries+1
+ return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries)
end
local send_message
local function send_headers(headers)
- yieldcoroutine(normalizeheaders(headers))
+ yieldcoroutine(normalizeheaders(headers))
end
local function send_multipart(message)
- local boundary=newboundary()
- local headers=lowerheaders(message.headers)
- local body=message.body
- local preamble=body.preamble
- local epilogue=body.epilogue
- local content=headers['content-type'] or 'multipart/mixed'
- headers['content-type']=content..'; boundary="'..boundary..'"'
- send_headers(headers)
- if preamble then
- yieldcoroutine(preamble)
- yieldcoroutine("\r\n")
- end
- for i=1,#body do
- yieldcoroutine("\r\n--"..boundary.."\r\n")
- send_message(body[i])
- end
- yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n")
- if epilogue then
- yieldcoroutine(epilogue)
- yieldcoroutine("\r\n")
- end
+ local boundary=newboundary()
+ local headers=lowerheaders(message.headers)
+ local body=message.body
+ local preamble=body.preamble
+ local epilogue=body.epilogue
+ local content=headers['content-type'] or 'multipart/mixed'
+ headers['content-type']=content..'; boundary="'..boundary..'"'
+ send_headers(headers)
+ if preamble then
+ yieldcoroutine(preamble)
+ yieldcoroutine("\r\n")
+ end
+ for i=1,#body do
+ yieldcoroutine("\r\n--"..boundary.."\r\n")
+ send_message(body[i])
+ end
+ yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n")
+ if epilogue then
+ yieldcoroutine(epilogue)
+ yieldcoroutine("\r\n")
+ end
end
local default_content_type='text/plain; charset="UTF-8"'
local function send_source(message)
- local headers=lowerheaders(message.headers)
- if not headers['content-type'] then
- headers['content-type']=default_content_type
- end
- send_headers(headers)
- local getchunk=message.body
- while true do
- local chunk,err=getchunk()
- if err then
- yieldcoroutine(nil,err)
- elseif chunk then
- yieldcoroutine(chunk)
- else
- break
- end
+ local headers=lowerheaders(message.headers)
+ if not headers['content-type'] then
+ headers['content-type']=default_content_type
+ end
+ send_headers(headers)
+ local getchunk=message.body
+ while true do
+ local chunk,err=getchunk()
+ if err then
+ yieldcoroutine(nil,err)
+ elseif chunk then
+ yieldcoroutine(chunk)
+ else
+ break
end
+ end
end
local function send_string(message)
- local headers=lowerheaders(message.headers)
- if not headers['content-type'] then
- headers['content-type']=default_content_type
- end
- send_headers(headers)
- yieldcoroutine(message.body)
+ local headers=lowerheaders(message.headers)
+ if not headers['content-type'] then
+ headers['content-type']=default_content_type
+ end
+ send_headers(headers)
+ yieldcoroutine(message.body)
end
function send_message(message)
- local body=message.body
- if type(body)=="table" then
- send_multipart(message)
- elseif type(body)=="function" then
- send_source(message)
- else
- send_string(message)
- end
+ local body=message.body
+ if type(body)=="table" then
+ send_multipart(message)
+ elseif type(body)=="function" then
+ send_source(message)
+ else
+ send_string(message)
+ end
end
local function adjust_headers(message)
- local headers=lowerheaders(message.headers)
- if not headers["date"] then
- headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE)
- end
- if not headers["x-mailer"] then
- headers["x-mailer"]=socket._VERSION
- end
- headers["mime-version"]="1.0"
- return headers
+ local headers=lowerheaders(message.headers)
+ if not headers["date"] then
+ headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE)
+ end
+ if not headers["x-mailer"] then
+ headers["x-mailer"]=socket._VERSION
+ end
+ headers["mime-version"]="1.0"
+ return headers
end
function smtp.message(message)
- message.headers=adjust_headers(message)
- local action=createcoroutine(function()
- send_message(message)
- end)
- return function()
- local ret,a,b=resumecoroutine(action)
- if ret then
- return a,b
- else
- return nil,a
- end
+ message.headers=adjust_headers(message)
+ local action=createcoroutine(function()
+ send_message(message)
+ end)
+ return function()
+ local ret,a,b=resumecoroutine(action)
+ if ret then
+ return a,b
+ else
+ return nil,a
end
+ end
end
smtp.send=protectsocket(function(mail)
- local snd=opensmtp(smtp,mail.server,mail.port,mail.create)
- local ext=snd:greet(mail.domain)
- snd:auth(mail.user,mail.password,ext)
- snd:send(mail)
- snd:quit()
- return snd:close()
+ local snd=opensmtp(smtp,mail.server,mail.port,mail.create)
+ local ext=snd:greet(mail.domain)
+ snd:auth(mail.user,mail.password,ext)
+ snd:send(mail)
+ snd:quit()
+ return snd:close()
end)
package.loaded["socket.smtp"]=smtp
@@ -12218,14 +12218,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-set"] = package.loaded["trac-set"] or true
--- original size: 13340, stripped down to: 9459
+-- original size: 13340, stripped down to: 8826
if not modules then modules={} end modules ['trac-set']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber=type,next,tostring,tonumber
local concat,sortedhash=table.concat,table.sortedhash
@@ -12240,317 +12240,317 @@ utilities.setters=setters
local data={}
local trace_initialize=false
function setters.initialize(filename,name,values)
- local setter=data[name]
- if setter then
- frozen=true
- local data=setter.data
- if data then
- for key,newvalue in sortedhash(values) do
- local newvalue=is_boolean(newvalue,newvalue,true)
- local functions=data[key]
- if functions then
- local oldvalue=functions.value
- if functions.frozen then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
- end
- elseif #functions>0 and not oldvalue then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
- end
- for i=1,#functions do
- functions[i](newvalue)
- end
- functions.value=newvalue
- functions.frozen=functions.frozen or frozen
- else
- if trace_initialize then
- setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
- end
- end
- else
- functions={ default=newvalue,frozen=frozen }
- data[key]=functions
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
- end
- end
+ local setter=data[name]
+ if setter then
+ frozen=true
+ local data=setter.data
+ if data then
+ for key,newvalue in sortedhash(values) do
+ local newvalue=is_boolean(newvalue,newvalue,true)
+ local functions=data[key]
+ if functions then
+ local oldvalue=functions.value
+ if functions.frozen then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
+ end
+ elseif #functions>0 and not oldvalue then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
+ end
+ for i=1,#functions do
+ functions[i](newvalue)
+ end
+ functions.value=newvalue
+ functions.frozen=functions.frozen or frozen
+ else
+ if trace_initialize then
+ setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
end
- return true
+ end
+ else
+ functions={ default=newvalue,frozen=frozen }
+ data[key]=functions
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
+ end
end
+ end
+ return true
end
+ end
end
local function set(t,what,newvalue)
- local data=t.data
- if not data.frozen then
- local done=t.done
- if type(what)=="string" then
- what=settings_to_hash(what)
- end
- if type(what)~="table" then
- return
- end
- if not done then
- done={}
- t.done=done
- end
- for w,value in sortedhash(what) do
- if value=="" then
- value=newvalue
- elseif not value then
- value=false
- else
- value=is_boolean(value,value,true)
- end
- w=topattern(w,true,true)
- for name,functions in sortedhash(data) do
- if done[name] then
- elseif find(name,w) then
- done[name]=true
- for i=1,#functions do
- functions[i](value)
- end
- functions.value=value
- end
- end
+ local data=t.data
+ if not data.frozen then
+ local done=t.done
+ if type(what)=="string" then
+ what=settings_to_hash(what)
+ end
+ if type(what)~="table" then
+ return
+ end
+ if not done then
+ done={}
+ t.done=done
+ end
+ for w,value in sortedhash(what) do
+ if value=="" then
+ value=newvalue
+ elseif not value then
+ value=false
+ else
+ value=is_boolean(value,value,true)
+ end
+ w=topattern(w,true,true)
+ for name,functions in sortedhash(data) do
+ if done[name] then
+ elseif find(name,w) then
+ done[name]=true
+ for i=1,#functions do
+ functions[i](value)
+ end
+ functions.value=value
end
+ end
end
+ end
end
local function reset(t)
- local data=t.data
- if not data.frozen then
- for name,functions in sortedthash(data) do
- for i=1,#functions do
- functions[i](false)
- end
- functions.value=false
- end
+ local data=t.data
+ if not data.frozen then
+ for name,functions in sortedthash(data) do
+ for i=1,#functions do
+ functions[i](false)
+ end
+ functions.value=false
end
+ end
end
local function enable(t,what)
- set(t,what,true)
+ set(t,what,true)
end
local function disable(t,what)
- local data=t.data
- if not what or what=="" then
- t.done={}
- reset(t)
- else
- set(t,what,false)
- end
+ local data=t.data
+ if not what or what=="" then
+ t.done={}
+ reset(t)
+ else
+ set(t,what,false)
+ end
end
function setters.register(t,what,...)
- local data=t.data
- what=lower(what)
- local functions=data[what]
- if not functions then
- functions={}
- data[what]=functions
- if trace_initialize then
- t.report("defining %a",what)
- end
- end
- local default=functions.default
- for i=1,select("#",...) do
- local fnc=select(i,...)
- local typ=type(fnc)
- if typ=="string" then
- if trace_initialize then
- t.report("coupling %a to %a",what,fnc)
- end
- local s=fnc
- fnc=function(value) set(t,s,value) end
- elseif typ~="function" then
- fnc=nil
- end
- if fnc then
- functions[#functions+1]=fnc
- local value=functions.value or default
- if value~=nil then
- fnc(value)
- functions.value=value
- end
- end
+ local data=t.data
+ what=lower(what)
+ local functions=data[what]
+ if not functions then
+ functions={}
+ data[what]=functions
+ if trace_initialize then
+ t.report("defining %a",what)
+ end
+ end
+ local default=functions.default
+ for i=1,select("#",...) do
+ local fnc=select(i,...)
+ local typ=type(fnc)
+ if typ=="string" then
+ if trace_initialize then
+ t.report("coupling %a to %a",what,fnc)
+ end
+ local s=fnc
+ fnc=function(value) set(t,s,value) end
+ elseif typ~="function" then
+ fnc=nil
+ end
+ if fnc then
+ functions[#functions+1]=fnc
+ local value=functions.value or default
+ if value~=nil then
+ fnc(value)
+ functions.value=value
+ end
end
- return false
+ end
+ return false
end
function setters.enable(t,what)
- local e=t.enable
- t.enable,t.done=enable,{}
- enable(t,what)
- t.enable,t.done=e,{}
+ local e=t.enable
+ t.enable,t.done=enable,{}
+ enable(t,what)
+ t.enable,t.done=e,{}
end
function setters.disable(t,what)
- local e=t.disable
- t.disable,t.done=disable,{}
- disable(t,what)
- t.disable,t.done=e,{}
+ local e=t.disable
+ t.disable,t.done=disable,{}
+ disable(t,what)
+ t.disable,t.done=e,{}
end
function setters.reset(t)
- t.done={}
- reset(t)
+ t.done={}
+ reset(t)
end
function setters.list(t)
- local list=table.sortedkeys(t.data)
- local user,system={},{}
- for l=1,#list do
- local what=list[l]
- if find(what,"^%*") then
- system[#system+1]=what
- else
- user[#user+1]=what
- end
+ local list=table.sortedkeys(t.data)
+ local user,system={},{}
+ for l=1,#list do
+ local what=list[l]
+ if find(what,"^%*") then
+ system[#system+1]=what
+ else
+ user[#user+1]=what
end
- return user,system
+ end
+ return user,system
end
function setters.show(t)
- local list=setters.list(t)
- t.report()
- for k=1,#list do
- local name=list[k]
- local functions=t.data[name]
- if functions then
- local value=functions.value
- local default=functions.default
- local modules=#functions
- if default==nil then
- default="unset"
- elseif type(default)=="table" then
- default=concat(default,"|")
- else
- default=tostring(default)
- end
- if value==nil then
- value="unset"
- elseif type(value)=="table" then
- value=concat(value,"|")
- else
- value=tostring(value)
- end
- t.report(name)
- t.report(" modules : %i",modules)
- t.report(" default : %s",default)
- t.report(" value : %s",value)
- t.report()
- end
+ local list=setters.list(t)
+ t.report()
+ for k=1,#list do
+ local name=list[k]
+ local functions=t.data[name]
+ if functions then
+ local value=functions.value
+ local default=functions.default
+ local modules=#functions
+ if default==nil then
+ default="unset"
+ elseif type(default)=="table" then
+ default=concat(default,"|")
+ else
+ default=tostring(default)
+ end
+ if value==nil then
+ value="unset"
+ elseif type(value)=="table" then
+ value=concat(value,"|")
+ else
+ value=tostring(value)
+ end
+ t.report(name)
+ t.report(" modules : %i",modules)
+ t.report(" default : %s",default)
+ t.report(" value : %s",value)
+ t.report()
end
+ end
end
local enable,disable,register,list,show=setters.enable,setters.disable,setters.register,setters.list,setters.show
function setters.report(setter,...)
- print(format("%-15s : %s\n",setter.name,format(...)))
+ print(format("%-15s : %s\n",setter.name,format(...)))
end
local function default(setter,name)
- local d=setter.data[name]
- return d and d.default
+ local d=setter.data[name]
+ return d and d.default
end
local function value(setter,name)
- local d=setter.data[name]
- return d and (d.value or d.default)
+ local d=setter.data[name]
+ return d and (d.value or d.default)
end
function setters.new(name)
- local setter
- setter={
- data=allocate(),
- name=name,
- report=function(...) setters.report (setter,...) end,
- enable=function(...) enable (setter,...) end,
- disable=function(...) disable (setter,...) end,
- reset=function(...) reset (setter,...) end,
- register=function(...) register(setter,...) end,
- list=function(...) list (setter,...) end,
- show=function(...) show (setter,...) end,
- default=function(...) return default (setter,...) end,
- value=function(...) return value (setter,...) end,
- }
- data[name]=setter
- return setter
+ local setter
+ setter={
+ data=allocate(),
+ name=name,
+ report=function(...) setters.report (setter,...) end,
+ enable=function(...) enable (setter,...) end,
+ disable=function(...) disable (setter,...) end,
+ reset=function(...) reset (setter,...) end,
+ register=function(...) register(setter,...) end,
+ list=function(...) list (setter,...) end,
+ show=function(...) show (setter,...) end,
+ default=function(...) return default (setter,...) end,
+ value=function(...) return value (setter,...) end,
+ }
+ data[name]=setter
+ return setter
end
trackers=setters.new("trackers")
directives=setters.new("directives")
experiments=setters.new("experiments")
-local t_enable,t_disable=trackers .enable,trackers .disable
+local t_enable,t_disable=trackers .enable,trackers .disable
local d_enable,d_disable=directives .enable,directives .disable
local e_enable,e_disable=experiments.enable,experiments.disable
-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 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)
function directives.enable(...)
- if trace_directives then
- directives.report("enabling: % t",{...})
- end
- d_enable(...)
+ if trace_directives then
+ directives.report("enabling: % t",{...})
+ end
+ d_enable(...)
end
function directives.disable(...)
- if trace_directives then
- directives.report("disabling: % t",{...})
- end
- d_disable(...)
+ if trace_directives then
+ directives.report("disabling: % t",{...})
+ end
+ d_disable(...)
end
function experiments.enable(...)
- if trace_experiments then
- experiments.report("enabling: % t",{...})
- end
- e_enable(...)
+ if trace_experiments then
+ experiments.report("enabling: % t",{...})
+ end
+ e_enable(...)
end
function experiments.disable(...)
- if trace_experiments then
- experiments.report("disabling: % t",{...})
- end
- e_disable(...)
+ if trace_experiments then
+ experiments.report("disabling: % t",{...})
+ end
+ e_disable(...)
end
directives.register("system.nostatistics",function(v)
- if statistics then
- statistics.enable=not v
- else
- end
+ if statistics then
+ statistics.enable=not v
+ else
+ end
end)
directives.register("system.nolibraries",function(v)
- if libraries then
- libraries=nil
- else
- end
+ if libraries then
+ libraries=nil
+ else
+ end
end)
if environment then
- local engineflags=environment.engineflags
- if engineflags then
- local list=engineflags["c:trackers"] or engineflags["trackers"]
- if type(list)=="string" then
- setters.initialize("commandline flags","trackers",settings_to_hash(list))
- end
- local list=engineflags["c:directives"] or engineflags["directives"]
- if type(list)=="string" then
- setters.initialize("commandline flags","directives",settings_to_hash(list))
- end
+ local engineflags=environment.engineflags
+ if engineflags then
+ local list=engineflags["c:trackers"] or engineflags["trackers"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","trackers",settings_to_hash(list))
end
+ local list=engineflags["c:directives"] or engineflags["directives"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","directives",settings_to_hash(list))
+ end
+ end
end
if texconfig then
- local function set(k,v)
- v=tonumber(v)
- if v then
- texconfig[k]=v
- end
- end
- directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
- directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
- directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
- directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
- directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
- directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
- directives.register("luatex.paramsize",function(v) set("param_size",v) end)
- directives.register("luatex.savesize",function(v) set("save_size",v) end)
- directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
+ local function set(k,v)
+ v=tonumber(v)
+ if v then
+ texconfig[k]=v
+ end
+ end
+ directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
+ directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
+ directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
+ directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
+ directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
+ directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
+ directives.register("luatex.paramsize",function(v) set("param_size",v) end)
+ directives.register("luatex.savesize",function(v) set("save_size",v) end)
+ directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
end
local data=table.setmetatableindex("table")
updaters={
- register=function(what,f)
- local d=data[what]
- d[#d+1]=f
- end,
- apply=function(what,...)
- local d=data[what]
- for i=1,#d do
- d[i](...)
- end
- end,
+ register=function(what,f)
+ local d=data[what]
+ d[#d+1]=f
+ end,
+ apply=function(what,...)
+ local d=data[what]
+ for i=1,#d do
+ d[i](...)
+ end
+ end,
}
@@ -12560,14 +12560,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-log"] = package.loaded["trac-log"] or true
--- original size: 32608, stripped down to: 22574
+-- original size: 32608, stripped down to: 20925
if not modules then modules={} end modules ['trac-log']={
- version=1.001,
- comment="companion to trac-log.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,select,print=next,type,select,print
local format,gmatch,find=string.format,string.gmatch,string.find
@@ -12578,7 +12578,7 @@ local datetime=os.date
local openfile=io.open
local runningtex=tex and (tex.jobname or tex.formatname)
local write_nl=runningtex and texio and texio.write_nl or print
-local write=runningtex and texio and texio.write or io.write
+local write=runningtex and texio and texio.write or io.write
local setmetatableindex=table.setmetatableindex
local formatters=string.formatters
local settings_to_hash=utilities.parsers.settings_to_hash
@@ -12594,404 +12594,404 @@ webpage : http://www.pragma-ade.nl / http://tex.aanhet.net
wiki : http://contextgarden.net
]]
formatters.add (
- formatters,"unichr",
- [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
+ formatters,"unichr",
+ [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
)
formatters.add (
- formatters,"chruni",
- [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
+ formatters,"chruni",
+ [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
)
local function ignore() end
setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end)
local report,subreport,status,settarget,setformats,settranslations
local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters,newline
if runningtex then
- if texio.setescape then
- texio.setescape(0)
- end
- if arg then
- for k,v in next,arg do
- if v=="--ansi" or v=="--c:ansi" then
- variant="ansi"
- break
- end
- end
- end
- local function useluawrites()
- local texio_write_nl=texio.write_nl
- local texio_write=texio.write
- local io_write=io.write
- write_nl=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write_nl("log",...)
- texio_write_nl("term","")
- io_write(...)
- elseif target=="log" then
- texio_write_nl("log",...)
- elseif target=="term" then
- texio_write_nl("term","")
- io_write(...)
- elseif type(target)=="number" then
- texio_write_nl(target,...)
- elseif target~="none" then
- texio_write_nl("log",target,...)
- texio_write_nl("term","")
- io_write(target,...)
- end
- end
- write=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write("log",...)
- io_write(...)
- elseif target=="log" then
- texio_write("log",...)
- elseif target=="term" then
- io_write(...)
- elseif type(target)=="number" then
- texio_write(target,...)
- elseif target~="none" then
- texio_write("log",target,...)
- io_write(target,...)
- end
- end
- texio.write=write
- texio.write_nl=write_nl
- useluawrites=ignore
- end
- local whereto="both"
- local target=nil
- local targets=nil
- local formats=table.setmetatableindex("self")
- local translations=table.setmetatableindex("self")
- local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
- local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="log",
- log="log",
- file="log",
- console="term",
- terminal="term",
- both="term and log",
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="none",
- log="none",
- file="none",
- console="term",
- terminal="term",
- both="term",
- },
- }
- }
- logs.flush=io.flush
- writer=function(...)
- write_nl(target,...)
- end
- newline=function()
- write_nl(target,"\n")
- end
- report=function(a,b,c,...)
- if c~=nil then
- write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,report_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,report_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
- end
- direct=function(a,b,c,...)
- if c~=nil then
- return direct_yes(translations[a],formatters[formats[b]](c,...))
- elseif b then
- return direct_yes(translations[a],formats[b])
- elseif a then
- return direct_nop(translations[a])
- else
- return ""
- end
- end
- subreport=function(a,s,b,c,...)
- if c~=nil then
- write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
- elseif a then
- write_nl(target,subreport_nop(translations[a],translations[s]))
- else
- write_nl(target,"\n")
- end
- end
- subdirect=function(a,s,b,c,...)
- if c~=nil then
- return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
- elseif b then
- return subdirect_yes(translations[a],translations[s],formats[b])
- elseif a then
- return subdirect_nop(translations[a],translations[s])
- else
- return ""
- end
+ if texio.setescape then
+ texio.setescape(0)
+ end
+ if arg then
+ for k,v in next,arg do
+ if v=="--ansi" or v=="--c:ansi" then
+ variant="ansi"
+ break
+ end
end
- status=function(a,b,c,...)
- if c~=nil then
- write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,status_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,status_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
+ end
+ local function useluawrites()
+ local texio_write_nl=texio.write_nl
+ local texio_write=texio.write
+ local io_write=io.write
+ write_nl=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write_nl("log",...)
+ texio_write_nl("term","")
+ io_write(...)
+ elseif target=="log" then
+ texio_write_nl("log",...)
+ elseif target=="term" then
+ texio_write_nl("term","")
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write_nl(target,...)
+ elseif target~="none" then
+ texio_write_nl("log",target,...)
+ texio_write_nl("term","")
+ io_write(target,...)
+ end
end
- settarget=function(askedwhereto)
- whereto=askedwhereto or whereto or "both"
- target=targets[whereto]
- if not target then
- whereto="both"
- target=targets[whereto]
- end
- if target=="term" or target=="term and log" then
- logs.flush=io.flush
- else
- logs.flush=ignore
- end
+ write=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write("log",...)
+ io_write(...)
+ elseif target=="log" then
+ texio_write("log",...)
+ elseif target=="term" then
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write(target,...)
+ elseif target~="none" then
+ texio_write("log",target,...)
+ io_write(target,...)
+ end
end
- local stack={}
- pushtarget=function(newtarget)
- insert(stack,target)
- settarget(newtarget)
+ texio.write=write
+ texio.write_nl=write_nl
+ useluawrites=ignore
+ end
+ local whereto="both"
+ local target=nil
+ local targets=nil
+ local formats=table.setmetatableindex("self")
+ local translations=table.setmetatableindex("self")
+ local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
+ local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="log",
+ log="log",
+ file="log",
+ console="term",
+ terminal="term",
+ both="term and log",
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="none",
+ log="none",
+ file="none",
+ console="term",
+ terminal="term",
+ both="term",
+ },
+ }
+ }
+ logs.flush=io.flush
+ writer=function(...)
+ write_nl(target,...)
+ end
+ newline=function()
+ write_nl(target,"\n")
+ end
+ report=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,report_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,report_nop(translations[a]))
+ else
+ write_nl(target,"\n")
end
- poptarget=function()
- if #stack>0 then
- settarget(remove(stack))
- end
+ end
+ direct=function(a,b,c,...)
+ if c~=nil then
+ return direct_yes(translations[a],formatters[formats[b]](c,...))
+ elseif b then
+ return direct_yes(translations[a],formats[b])
+ elseif a then
+ return direct_nop(translations[a])
+ else
+ return ""
end
- setformats=function(f)
- formats=f
+ end
+ subreport=function(a,s,b,c,...)
+ if c~=nil then
+ write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
+ elseif a then
+ write_nl(target,subreport_nop(translations[a],translations[s]))
+ else
+ write_nl(target,"\n")
end
- settranslations=function(t)
- translations=t
+ end
+ subdirect=function(a,s,b,c,...)
+ if c~=nil then
+ return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
+ elseif b then
+ return subdirect_yes(translations[a],translations[s],formats[b])
+ elseif a then
+ return subdirect_nop(translations[a],translations[s])
+ else
+ return ""
end
- setprocessor=function(f)
- local writeline=write_nl
- write_nl=function(target,...)
- writeline(target,f(...))
- end
+ end
+ status=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,status_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,status_nop(translations[a]))
+ else
+ write_nl(target,"\n")
+ end
+ end
+ settarget=function(askedwhereto)
+ whereto=askedwhereto or whereto or "both"
+ target=targets[whereto]
+ if not target then
+ whereto="both"
+ target=targets[whereto]
+ end
+ if target=="term" or target=="term and log" then
+ logs.flush=io.flush
+ else
+ logs.flush=ignore
+ end
+ end
+ local stack={}
+ pushtarget=function(newtarget)
+ insert(stack,target)
+ settarget(newtarget)
+ end
+ poptarget=function()
+ if #stack>0 then
+ settarget(remove(stack))
+ end
+ end
+ setformats=function(f)
+ formats=f
+ end
+ settranslations=function(t)
+ translations=t
+ end
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(target,...)
+ writeline(target,f(...))
+ end
+ end
+ setformatters=function(specification)
+ local t=nil
+ local f=nil
+ local d=variants.default
+ if not specification then
+ elseif type(specification)=="table" then
+ t=specification.targets
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ t=v.targets
+ f=v.formats
+ variant=specification
+ end
end
- setformatters=function(specification)
- local t=nil
- local f=nil
- local d=variants.default
- if not specification then
- elseif type(specification)=="table" then
- t=specification.targets
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- t=v.targets
- f=v.formats
- variant=specification
- end
- end
- targets=t or d.targets
- target=targets[whereto] or target
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- direct_yes=f.direct_yes
- direct_nop=f.direct_nop
- subdirect_yes=f.subdirect_yes
- subdirect_nop=f.subdirect_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- if variant=="ansi" then
- useluawrites()
- end
- settarget(whereto)
- end
- setformatters(variant)
- setlogfile=ignore
- settimedlog=ignore
+ targets=t or d.targets
+ target=targets[whereto] or target
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ direct_yes=f.direct_yes
+ direct_nop=f.direct_nop
+ subdirect_yes=f.subdirect_yes
+ subdirect_nop=f.subdirect_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ if variant=="ansi" then
+ useluawrites()
+ end
+ settarget(whereto)
+ end
+ setformatters(variant)
+ setlogfile=ignore
+ settimedlog=ignore
else
- local report_yes,subreport_yes,status_yes
- local report_nop,subreport_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- }
- logs.flush=ignore
- writer=function(s)
- write_nl(s)
- end
- newline=function()
- write_nl("\n")
+ local report_yes,subreport_yes,status_yes
+ local report_nop,subreport_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ }
+ logs.flush=ignore
+ writer=function(s)
+ write_nl(s)
+ end
+ newline=function()
+ write_nl("\n")
+ end
+ report=function(a,b,c,...)
+ if c then
+ write_nl(report_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(report_yes(a,b))
+ elseif a then
+ write_nl(report_nop(a))
+ else
+ write_nl("")
end
- report=function(a,b,c,...)
- if c then
- write_nl(report_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(report_yes(a,b))
- elseif a then
- write_nl(report_nop(a))
- else
- write_nl("")
- end
+ end
+ subreport=function(a,sub,b,c,...)
+ if c then
+ write_nl(subreport_yes(a,sub,formatters[b](c,...)))
+ elseif b then
+ write_nl(subreport_yes(a,sub,b))
+ elseif a then
+ write_nl(subreport_nop(a,sub))
+ else
+ write_nl("")
end
- subreport=function(a,sub,b,c,...)
- if c then
- write_nl(subreport_yes(a,sub,formatters[b](c,...)))
- elseif b then
- write_nl(subreport_yes(a,sub,b))
- elseif a then
- write_nl(subreport_nop(a,sub))
- else
- write_nl("")
+ end
+ status=function(a,b,c,...)
+ if c then
+ write_nl(status_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(status_yes(a,b))
+ elseif a then
+ write_nl(status_nop(a))
+ else
+ write_nl("\n")
+ end
+ end
+ direct=ignore
+ subdirect=ignore
+ settarget=ignore
+ pushtarget=ignore
+ poptarget=ignore
+ setformats=ignore
+ settranslations=ignore
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(f(s))
+ end
+ end
+ setformatters=function(specification)
+ local f=nil
+ local d=variants.default
+ if specification then
+ if type(specification)=="table" then
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ f=v.formats
end
+ end
end
- status=function(a,b,c,...)
- if c then
- write_nl(status_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(status_yes(a,b))
- elseif a then
- write_nl(status_nop(a))
- else
- write_nl("\n")
- end
- end
- direct=ignore
- subdirect=ignore
- settarget=ignore
- pushtarget=ignore
- poptarget=ignore
- setformats=ignore
- settranslations=ignore
- setprocessor=function(f)
- local writeline=write_nl
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ end
+ setformatters(variant)
+ setlogfile=function(name,keepopen)
+ if name and name~="" then
+ local localtime=os.localtime
+ local writeline=write_nl
+ if keepopen then
+ local f=io.open(name,"ab")
write_nl=function(s)
- writeline(f(s))
+ writeline(s)
+ f:write(localtime()," | ",s,"\n")
end
- end
- setformatters=function(specification)
- local f=nil
- local d=variants.default
- if specification then
- if type(specification)=="table" then
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- f=v.formats
- end
- end
- end
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- end
- setformatters(variant)
- setlogfile=function(name,keepopen)
- if name and name~="" then
- local localtime=os.localtime
- local writeline=write_nl
- if keepopen then
- local f=io.open(name,"ab")
- write_nl=function(s)
- writeline(s)
- f:write(localtime()," | ",s,"\n")
- end
- else
- write_nl=function(s)
- writeline(s)
- local f=io.open(name,"ab")
- f:write(localtime()," | ",s,"\n")
- f:close()
- end
- end
- end
- setlogfile=ignore
- end
- settimedlog=function()
- local localtime=os.localtime
- local writeline=write_nl
+ else
write_nl=function(s)
- writeline(localtime().." | "..s)
+ writeline(s)
+ local f=io.open(name,"ab")
+ f:write(localtime()," | ",s,"\n")
+ f:close()
end
- settimedlog=ignore
+ end
end
+ setlogfile=ignore
+ end
+ settimedlog=function()
+ local localtime=os.localtime
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(localtime().." | "..s)
+ end
+ settimedlog=ignore
+ end
end
logs.report=report
logs.subreport=subreport
@@ -13013,186 +13013,186 @@ local data={}
local states=nil
local force=false
function logs.reporter(category,subcategory)
- local logger=data[category]
- if not logger then
- local state=states==true
- if not state and type(states)=="table" then
- for c,_ in next,states do
- if find(category,c) then
- state=true
- break
- end
- end
+ local logger=data[category]
+ if not logger then
+ local state=states==true
+ if not state and type(states)=="table" then
+ for c,_ in next,states do
+ if find(category,c) then
+ state=true
+ break
end
- logger={
- reporters={},
- state=state,
- }
- data[category]=logger
- end
- local reporter=logger.reporters[subcategory or "default"]
- if not reporter then
- if subcategory then
- reporter=function(...)
- if force or not logger.state then
- subreport(category,subcategory,...)
- end
- end
- logger.reporters[subcategory]=reporter
- else
- local tag=category
- reporter=function(...)
- if force or not logger.state then
- report(category,...)
- end
- end
- logger.reporters.default=reporter
+ end
+ end
+ logger={
+ reporters={},
+ state=state,
+ }
+ data[category]=logger
+ end
+ local reporter=logger.reporters[subcategory or "default"]
+ if not reporter then
+ if subcategory then
+ reporter=function(...)
+ if force or not logger.state then
+ subreport(category,subcategory,...)
+ end
+ end
+ logger.reporters[subcategory]=reporter
+ else
+ local tag=category
+ reporter=function(...)
+ if force or not logger.state then
+ report(category,...)
end
+ end
+ logger.reporters.default=reporter
end
- return reporter
+ end
+ return reporter
end
logs.new=logs.reporter
local ctxreport=logs.writer
function logs.setmessenger(m)
- ctxreport=m
+ ctxreport=m
end
function logs.messenger(category,subcategory)
- if subcategory then
- return function(...)
- ctxreport(subdirect(category,subcategory,...))
- end
- else
- return function(...)
- ctxreport(direct(category,...))
- end
+ if subcategory then
+ return function(...)
+ ctxreport(subdirect(category,subcategory,...))
end
+ else
+ return function(...)
+ ctxreport(direct(category,...))
+ end
+ end
end
local function setblocked(category,value)
- if category==true or category=="all" then
- category,value="*",true
- elseif category==false then
- category,value="*",false
- elseif value==nil then
- value=true
- end
- if category=="*" then
- states=value
+ if category==true or category=="all" then
+ category,value="*",true
+ elseif category==false then
+ category,value="*",false
+ elseif value==nil then
+ value=true
+ end
+ if category=="*" then
+ states=value
+ for k,v in next,data do
+ v.state=value
+ end
+ else
+ alllocked=false
+ states=settings_to_hash(category,type(states)=="table" and states or nil)
+ for c in next,states do
+ local v=data[c]
+ if v then
+ v.state=value
+ else
+ c=topattern(c,true,true)
for k,v in next,data do
+ if find(k,c) then
v.state=value
+ end
end
- else
- alllocked=false
- states=settings_to_hash(category,type(states)=="table" and states or nil)
- for c in next,states do
- local v=data[c]
- if v then
- v.state=value
- else
- c=topattern(c,true,true)
- for k,v in next,data do
- if find(k,c) then
- v.state=value
- end
- end
- end
- end
+ end
end
+ end
end
function logs.disable(category,value)
- setblocked(category,value==nil and true or value)
+ setblocked(category,value==nil and true or value)
end
function logs.enable(category)
- setblocked(category,false)
+ setblocked(category,false)
end
function logs.categories()
- return sortedkeys(data)
+ return sortedkeys(data)
end
function logs.show()
- local n,c,s,max=0,0,0,0
- for category,v in table.sortedpairs(data) do
- n=n+1
- local state=v.state
- local reporters=v.reporters
- local nc=#category
- if nc>c then
- c=nc
- end
- for subcategory,_ in next,reporters do
- local ns=#subcategory
- if ns>c then
- s=ns
- end
- local m=nc+ns
- if m>max then
- max=m
- end
- end
- local subcategories=concat(sortedkeys(reporters),", ")
- if state==true then
- state="disabled"
- elseif state==false then
- state="enabled"
- else
- state="unknown"
- end
- report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ local n,c,s,max=0,0,0,0
+ for category,v in table.sortedpairs(data) do
+ n=n+1
+ local state=v.state
+ local reporters=v.reporters
+ local nc=#category
+ if nc>c then
+ c=nc
+ end
+ for subcategory,_ in next,reporters do
+ local ns=#subcategory
+ if ns>c then
+ s=ns
+ end
+ local m=nc+ns
+ if m>max then
+ max=m
+ end
+ end
+ local subcategories=concat(sortedkeys(reporters),", ")
+ if state==true then
+ state="disabled"
+ elseif state==false then
+ state="enabled"
+ else
+ state="unknown"
end
- report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
+ report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ end
+ report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
end
local delayed_reporters={}
setmetatableindex(delayed_reporters,function(t,k)
- local v=logs.reporter(k.name)
- t[k]=v
- return v
+ local v=logs.reporter(k.name)
+ t[k]=v
+ return v
end)
function utilities.setters.report(setter,...)
- delayed_reporters[setter](...)
+ delayed_reporters[setter](...)
end
directives.register("logs.blocked",function(v)
- setblocked(v,true)
+ setblocked(v,true)
end)
directives.register("logs.target",function(v)
- settarget(v)
+ settarget(v)
end)
if tex then
- local report=logs.reporter("pages")
- local texgetcount=tex and tex.getcount
- local real,user,sub=0,0,0
- function logs.start_page_number()
- real=texgetcount("realpageno")
- user=texgetcount("userpageno")
- sub=texgetcount("subpageno")
- end
- local timing=false
- local lasttime=nil
- trackers.register("pages.timing",function(v)
- timing=""
- end)
- function logs.stop_page_number()
- if timing then
- local elapsed=statistics.currenttime(statistics)
- local average,page
- if not lasttime or real<2 then
- average=elapsed
- page=elapsed
- else
- average=elapsed/(real-1)
- page=elapsed-lasttime
- end
- lasttime=elapsed
- timing=formatters[", total %0.03f, page %0.03f, average %0.03f"](elapsed,page,average)
- end
- if real<=0 then
- report("flushing page%s",timing)
- elseif user<=0 then
- report("flushing realpage %s%s",real,timing)
- elseif sub<=0 then
- report("flushing realpage %s, userpage %s%s",real,user,timing)
- else
- report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
- end
- logs.flush()
+ local report=logs.reporter("pages")
+ local texgetcount=tex and tex.getcount
+ local real,user,sub=0,0,0
+ function logs.start_page_number()
+ real=texgetcount("realpageno")
+ user=texgetcount("userpageno")
+ sub=texgetcount("subpageno")
+ end
+ local timing=false
+ local lasttime=nil
+ trackers.register("pages.timing",function(v)
+ timing=""
+ end)
+ function logs.stop_page_number()
+ if timing then
+ local elapsed=statistics.currenttime(statistics)
+ local average,page
+ if not lasttime or real<2 then
+ average=elapsed
+ page=elapsed
+ else
+ average=elapsed/(real-1)
+ page=elapsed-lasttime
+ end
+ lasttime=elapsed
+ timing=formatters[", total %0.03f, page %0.03f, average %0.03f"](elapsed,page,average)
end
+ if real<=0 then
+ report("flushing page%s",timing)
+ elseif user<=0 then
+ report("flushing realpage %s%s",real,timing)
+ elseif sub<=0 then
+ report("flushing realpage %s, userpage %s%s",real,user,timing)
+ else
+ report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
+ end
+ logs.flush()
+ end
end
local nesting=0
local verbose=false
@@ -13216,222 +13216,222 @@ logs.help=ignore
local Carg,C,lpegmatch=lpeg.Carg,lpeg.C,lpeg.match
local p_newline=lpeg.patterns.newline
local linewise=(
- Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
+ Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
)^1
local function reportlines(t,str)
- if str then
- lpegmatch(linewise,str,1,t)
- end
+ if str then
+ lpegmatch(linewise,str,1,t)
+ end
end
local function reportbanner(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- t.report()
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ t.report()
+ end
end
local function reportversion(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ end
end
local function reporthelp(t,...)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="string" then
- reportlines(t,helpinfo)
- elseif type(helpinfo)=="table" then
- for i=1,select("#",...) do
- reportlines(t,t.helpinfo[select(i,...)])
- if i<n then
- t.report()
- end
- end
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="string" then
+ reportlines(t,helpinfo)
+ elseif type(helpinfo)=="table" then
+ for i=1,select("#",...) do
+ reportlines(t,t.helpinfo[select(i,...)])
+ if i<n then
+ t.report()
+ end
end
+ end
end
local function reportinfo(t)
- t.report()
- reportlines(t,t.moreinfo)
+ t.report()
+ reportlines(t,t.moreinfo)
end
local function reportexport(t,method)
- report(t.helpinfo)
+ report(t.helpinfo)
end
local reporters={
- lines=reportlines,
- banner=reportbanner,
- version=reportversion,
- help=reporthelp,
- info=reportinfo,
- export=reportexport,
+ lines=reportlines,
+ banner=reportbanner,
+ version=reportversion,
+ help=reporthelp,
+ info=reportinfo,
+ export=reportexport,
}
local exporters={
}
logs.reporters=reporters
logs.exporters=exporters
function logs.application(t)
- t.name=t.name or "unknown"
- t.banner=t.banner
- t.moreinfo=moreinfo
- t.report=logs.reporter(t.name)
- t.help=function(...)
- reporters.banner(t)
- reporters.help(t,...)
- reporters.info(t)
- end
- t.export=function(...)
- reporters.export(t,...)
- end
- t.identify=function()
- reporters.banner(t)
- end
- t.version=function()
- reporters.version(t)
- end
- return t
+ t.name=t.name or "unknown"
+ t.banner=t.banner
+ t.moreinfo=moreinfo
+ t.report=logs.reporter(t.name)
+ t.help=function(...)
+ reporters.banner(t)
+ reporters.help(t,...)
+ reporters.info(t)
+ end
+ t.export=function(...)
+ reporters.export(t,...)
+ end
+ t.identify=function()
+ reporters.banner(t)
+ end
+ t.version=function()
+ reporters.version(t)
+ end
+ return t
end
local f_syslog=formatters["%s %s => %s => %s => %s\r"]
function logs.system(whereto,process,jobname,category,fmt,arg,...)
- local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
- for i=1,10 do
- local f=openfile(whereto,"a")
- if f then
- f:write(message)
- f:close()
- break
- else
- sleep(0.1)
- end
+ local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
+ for i=1,10 do
+ local f=openfile(whereto,"a")
+ if f then
+ f:write(message)
+ f:close()
+ break
+ else
+ sleep(0.1)
end
+ end
end
local report_system=logs.reporter("system","logs")
function logs.obsolete(old,new)
- local o=loadstring("return "..new)()
- if type(o)=="function" then
- return function(...)
- report_system("function %a is obsolete, use %a",old,new)
- loadstring(old.."="..new.." return "..old)()(...)
- end
- elseif type(o)=="table" then
- local t,m={},{}
- m.__index=function(t,k)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- return o[k]
- end
- m.__newindex=function(t,k,v)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- o[k]=v
- end
- if libraries then
- libraries.obsolete[old]=t
- end
- setmetatable(t,m)
- return t
+ local o=loadstring("return "..new)()
+ if type(o)=="function" then
+ return function(...)
+ report_system("function %a is obsolete, use %a",old,new)
+ loadstring(old.."="..new.." return "..old)()(...)
+ end
+ elseif type(o)=="table" then
+ local t,m={},{}
+ m.__index=function(t,k)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ return o[k]
+ end
+ m.__newindex=function(t,k,v)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ o[k]=v
+ end
+ if libraries then
+ libraries.obsolete[old]=t
end
+ setmetatable(t,m)
+ return t
+ end
end
if utilities then
- utilities.report=report_system
+ utilities.report=report_system
end
if tex and tex.error then
- function logs.texerrormessage(...)
- tex.error(format(...))
- end
+ function logs.texerrormessage(...)
+ tex.error(format(...))
+ end
else
- function logs.texerrormessage(...)
- print(format(...))
- end
+ function logs.texerrormessage(...)
+ print(format(...))
+ end
end
io.stdout:setvbuf('no')
io.stderr:setvbuf('no')
if package.helpers.report then
- package.helpers.report=logs.reporter("package loader")
+ package.helpers.report=logs.reporter("package loader")
end
if tex then
- local finalactions={}
- local fatalerrors={}
- local possiblefatal={}
- local loggingerrors=false
- function logs.loggingerrors()
- return loggingerrors
- end
- directives.register("logs.errors",function(v)
- loggingerrors=v
- if type(v)=="string" then
- fatalerrors=settings_to_hash(v)
- else
- fatalerrors={}
- end
- end)
- function logs.registerfinalactions(...)
- insert(finalactions,...)
- end
- local what=nil
- local report=nil
- local state=nil
- local target=nil
- local function startlogging(t,r,w,s)
- target=t
- state=force
- force=true
- report=type(r)=="function" and r or logs.reporter(r)
- what=w
- pushtarget(target)
+ local finalactions={}
+ local fatalerrors={}
+ local possiblefatal={}
+ local loggingerrors=false
+ function logs.loggingerrors()
+ return loggingerrors
+ end
+ directives.register("logs.errors",function(v)
+ loggingerrors=v
+ if type(v)=="string" then
+ fatalerrors=settings_to_hash(v)
+ else
+ fatalerrors={}
+ end
+ end)
+ function logs.registerfinalactions(...)
+ insert(finalactions,...)
+ end
+ local what=nil
+ local report=nil
+ local state=nil
+ local target=nil
+ local function startlogging(t,r,w,s)
+ target=t
+ state=force
+ force=true
+ report=type(r)=="function" and r or logs.reporter(r)
+ what=w
+ pushtarget(target)
+ newline()
+ if s then
+ report("start %s: %s",what,s)
+ else
+ report("start %s",what)
+ end
+ if target=="logfile" then
+ newline()
+ end
+ return report
+ end
+ local function stoplogging()
+ if target=="logfile" then
+ newline()
+ end
+ report("stop %s",what)
+ if target=="logfile" then
+ newline()
+ end
+ poptarget()
+ state=oldstate
+ end
+ function logs.startfilelogging(...)
+ return startlogging("logfile",...)
+ end
+ logs.stopfilelogging=stoplogging
+ local done=false
+ function logs.starterrorlogging(r,w,...)
+ if not done then
+ pushtarget("terminal")
+ newline()
+ logs.report("error logging","start possible issues")
+ poptarget()
+ done=true
+ end
+ if fatalerrors[w] then
+ possiblefatal[w]=true
+ end
+ return startlogging("terminal",r,w,...)
+ end
+ logs.stoperrorlogging=stoplogging
+ function logs.finalactions()
+ if #finalactions>0 then
+ for i=1,#finalactions do
+ finalactions[i]()
+ end
+ if done then
+ pushtarget("terminal")
newline()
- if s then
- report("start %s: %s",what,s)
- else
- report("start %s",what)
- end
- if target=="logfile" then
- newline()
- end
- return report
- end
- local function stoplogging()
- if target=="logfile" then
- newline()
- end
- report("stop %s",what)
- if target=="logfile" then
- newline()
- end
+ logs.report("error logging","stop possible issues")
poptarget()
- state=oldstate
- end
- function logs.startfilelogging(...)
- return startlogging("logfile",...)
- end
- logs.stopfilelogging=stoplogging
- local done=false
- function logs.starterrorlogging(r,w,...)
- if not done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","start possible issues")
- poptarget()
- done=true
- end
- if fatalerrors[w] then
- possiblefatal[w]=true
- end
- return startlogging("terminal",r,w,...)
- end
- logs.stoperrorlogging=stoplogging
- function logs.finalactions()
- if #finalactions>0 then
- for i=1,#finalactions do
- finalactions[i]()
- end
- if done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","stop possible issues")
- poptarget()
- end
- return next(possiblefatal) and sortedkeys(possiblefatal) or false
- end
+ end
+ return next(possiblefatal) and sortedkeys(possiblefatal) or false
end
+ end
end
@@ -13441,14 +13441,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
--- original size: 8684, stripped down to: 6000
+-- original size: 9000, stripped down to: 6003
if not modules then modules={} end modules ['trac-inf']={
- version=1.001,
- comment="companion to trac-inf.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-inf.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber,select=type,tonumber,select
local format,lower,find=string.format,string.lower,string.find
@@ -13463,86 +13463,86 @@ statistics.enable=true
statistics.threshold=0.01
local statusinfo,n,registered,timers={},0,{},{}
setmetatableindex(timers,function(t,k)
- local v={ timing=0,loadtime=0 }
- t[k]=v
- return v
+ local v={ timing=0,loadtime=0 }
+ t[k]=v
+ return v
end)
local function hastiming(instance)
- return instance and timers[instance]
+ return instance and timers[instance]
end
local function resettiming(instance)
- timers[instance or "notimer"]={ timing=0,loadtime=0 }
+ timers[instance or "notimer"]={ timing=0,loadtime=0 }
end
local ticks=clock
local seconds=function(n) return n or 0 end
local function starttiming(instance,reset)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if reset then
- it=0
- timer.loadtime=0
- end
- if it==0 then
- timer.starttime=ticks()
- if not timer.loadtime then
- timer.loadtime=0
- end
- end
- timer.timing=it+1
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if reset then
+ it=0
+ timer.loadtime=0
+ end
+ if it==0 then
+ timer.starttime=ticks()
+ if not timer.loadtime then
+ timer.loadtime=0
+ end
+ end
+ timer.timing=it+1
end
local function stoptiming(instance)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it>1 then
- timer.timing=it-1
- else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- local stoptime=ticks()
- local loadtime=stoptime-starttime
- timer.stoptime=stoptime
- timer.loadtime=timer.loadtime+loadtime
- timer.timing=0
- timer.starttime=0
- return loadtime
- end
- end
- return 0
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
+ timer.timing=it-1
+ else
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ local stoptime=ticks()
+ local loadtime=stoptime-starttime
+ timer.stoptime=stoptime
+ timer.loadtime=timer.loadtime+loadtime
+ timer.timing=0
+ timer.starttime=0
+ return loadtime
+ end
+ end
+ return 0
end
local function elapsed(instance)
- if type(instance)=="number" then
- return instance
- else
- local timer=timers[instance or "notimer"]
- return timer and seconds(timer.loadtime) or 0
- end
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ return timer and seconds(timer.loadtime) or 0
+ end
end
local function currenttime(instance)
- if type(instance)=="number" then
- return instance
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
else
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it>1 then
- else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- return seconds(timer.loadtime+ticks()-starttime)
- end
- end
- return 0
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ return seconds(timer.loadtime+ticks()-starttime)
+ end
end
+ return 0
+ end
end
local function elapsedtime(instance)
- return format("%0.3f",elapsed(instance))
+ return format("%0.3f",elapsed(instance))
end
local function elapsedindeed(instance)
- return elapsed(instance)>statistics.threshold
+ return elapsed(instance)>statistics.threshold
end
local function elapsedseconds(instance,rest)
- if elapsedindeed(instance) then
- return format("%0.3f seconds %s",elapsed(instance),rest or "")
- end
+ if elapsedindeed(instance) then
+ return format("%0.3f seconds %s",elapsed(instance),rest or "")
+ end
end
statistics.hastiming=hastiming
statistics.resettiming=resettiming
@@ -13554,91 +13554,98 @@ statistics.elapsedtime=elapsedtime
statistics.elapsedindeed=elapsedindeed
statistics.elapsedseconds=elapsedseconds
function statistics.register(tag,fnc)
- if statistics.enable and type(fnc)=="function" then
- local rt=registered[tag] or (#statusinfo+1)
- statusinfo[rt]={ tag,fnc }
- registered[tag]=rt
- if #tag>n then n=#tag end
- end
+ if statistics.enable and type(fnc)=="function" then
+ local rt=registered[tag] or (#statusinfo+1)
+ statusinfo[rt]={ tag,fnc }
+ registered[tag]=rt
+ if #tag>n then n=#tag end
+ end
end
local report=logs.reporter("mkiv lua stats")
function statistics.show()
- if statistics.enable then
- local register=statistics.register
- register("used platform",function()
- return format("%s, type: %s, binary subtree: %s",
- os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
- end)
- register("used engine",function()
- return format("%s version %s with functionality level %s, banner: %s",
- LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
- end)
- register("control sequences",function()
- return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
- end)
- register("callbacks",statistics.callbacks)
- if TEXENGINE=="luajittex" and JITSUPPORTED then
- local jitstatus=jit.status
- if jitstatus then
- local jitstatus={ jitstatus() }
- if jitstatus[1] then
- register("luajit options",concat(jitstatus," ",2))
- end
- end
- end
- register("lua properties",function()
- local hashchar=tonumber(status.luatex_hashchars)
- local hashtype=status.luatex_hashtype
- local mask=lua.mask or "ascii"
- return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
- jit and "luajit" or "lua",
- LUAVERSION,
- statistics.memused(),
- hashtype or "default",
- hashchar and 2^hashchar or "unknown",
- mask,
- mask=="utf" and "τεχ" or "tex")
- end)
- register("runtime",statistics.runtime)
- logs.newline()
- for i=1,#statusinfo do
- local s=statusinfo[i]
- local r=s[2]()
- if r then
- report("%s: %s",s[1],r)
- end
+ if statistics.enable then
+ local register=statistics.register
+ register("used platform",function()
+ return format("%s, type: %s, binary subtree: %s",
+ os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
+ end)
+ register("used engine",function()
+ return format("%s version %s with functionality level %s, banner: %s",
+ LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
+ end)
+ register("control sequences",function()
+ return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
+ end)
+ register("callbacks",statistics.callbacks)
+ if TEXENGINE=="luajittex" and JITSUPPORTED then
+ local jitstatus=jit.status
+ if jitstatus then
+ local jitstatus={ jitstatus() }
+ if jitstatus[1] then
+ register("luajit options",concat(jitstatus," ",2))
end
- statistics.enable=false
+ end
+ end
+ register("lua properties",function()
+ local hashchar=tonumber(status.luatex_hashchars)
+ local hashtype=status.luatex_hashtype
+ local mask=lua.mask or "ascii"
+ return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
+ jit and "luajit" or "lua",
+ LUAVERSION,
+ statistics.memused(),
+ hashtype or "default",
+ hashchar and 2^hashchar or "unknown",
+ mask,
+ mask=="utf" and "τεχ" or "tex")
+ end)
+ register("runtime",statistics.runtime)
+ logs.newline()
+ for i=1,#statusinfo do
+ local s=statusinfo[i]
+ local r=s[2]()
+ if r then
+ report("%s: %s",s[1],r)
+ end
end
+ statistics.enable=false
+ end
end
function statistics.memused()
- local round=math.round or math.floor
- return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
+ local round=math.round or math.floor
+ return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
end
starttiming(statistics)
function statistics.formatruntime(runtime)
- return format("%s seconds",runtime)
+ return format("%s seconds",runtime)
end
function statistics.runtime()
- stoptiming(statistics)
- return statistics.formatruntime(elapsedtime(statistics))
+ stoptiming(statistics)
+ local runtime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
end
local report=logs.reporter("system")
-function statistics.timed(action)
- starttiming("run")
- action()
- stoptiming("run")
- report("total runtime: %s seconds",elapsedtime("run"))
+function statistics.timed(action,all)
+ starttiming("run")
+ action()
+ stoptiming("run")
+ local runtime=tonumber(elapsedtime("run"))
+ if all then
+ local alltime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime)
+ else
+ report("total runtime: %0.3f seconds",runtime)
+ end
end
function statistics.tracefunction(base,tag,...)
- for i=1,select("#",...) do
- local name=select(i,...)
- local stat={}
- local func=base[name]
- setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
- base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
- statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
- end
+ for i=1,select("#",...) do
+ local name=select(i,...)
+ local stat={}
+ local func=base[name]
+ setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
+ base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
+ statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
+ end
end
@@ -13648,144 +13655,144 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
--- original size: 5841, stripped down to: 3511
+-- original size: 5841, stripped down to: 3352
if not modules then modules={} end modules ['trac-pro']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
-local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
+local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
local report_system=logs.reporter("system","protection")
namespaces=namespaces or {}
local namespaces=namespaces
local registered={}
local function report_index(k,name)
- if trace_namespaces then
- report_system("reference to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("reference to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("reference to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("reference to %a in protected namespace %a",k,name)
+ end
end
local function report_newindex(k,name)
- if trace_namespaces then
- report_system("assignment to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("assignment to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("assignment to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("assignment to %a in protected namespace %a",k,name)
+ end
end
local function register(name)
- local data=name=="global" and _G or _G[name]
- if not data then
- return
- end
- registered[name]=data
- local m=getmetatable(data)
- if not m then
- m={}
- setmetatable(data,m)
- end
- local index,newindex={},{}
- m.__saved__index=m.__index
- m.__no__index=function(t,k)
- if not index[k] then
- index[k]=true
- report_index(k,name)
- end
- return nil
+ local data=name=="global" and _G or _G[name]
+ if not data then
+ return
+ end
+ registered[name]=data
+ local m=getmetatable(data)
+ if not m then
+ m={}
+ setmetatable(data,m)
+ end
+ local index,newindex={},{}
+ m.__saved__index=m.__index
+ m.__no__index=function(t,k)
+ if not index[k] then
+ index[k]=true
+ report_index(k,name)
end
- m.__saved__newindex=m.__newindex
- m.__no__newindex=function(t,k,v)
- if not newindex[k] then
- newindex[k]=true
- report_newindex(k,name)
- end
- rawset(t,k,v)
+ return nil
+ end
+ m.__saved__newindex=m.__newindex
+ m.__no__newindex=function(t,k,v)
+ if not newindex[k] then
+ newindex[k]=true
+ report_newindex(k,name)
end
- m.__protection__depth=0
+ rawset(t,k,v)
+ end
+ m.__protection__depth=0
end
local function private(name)
- local data=registered[name]
+ local data=registered[name]
+ if not data then
+ data=_G[name]
if not data then
- data=_G[name]
- if not data then
- data={}
- _G[name]=data
- end
- register(name)
+ data={}
+ _G[name]=data
end
- return data
+ register(name)
+ end
+ return data
end
local function protect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>0 then
- m.__protection__depth=pd+1
- else
- m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
- m.__index,m.__newindex=m.__no__index,m.__no__newindex
- m.__protection__depth=1
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>0 then
+ m.__protection__depth=pd+1
+ else
+ m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
+ m.__index,m.__newindex=m.__no__index,m.__no__newindex
+ m.__protection__depth=1
+ end
end
local function unprotect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>1 then
- m.__protection__depth=pd-1
- else
- m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
- m.__protection__depth=0
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>1 then
+ m.__protection__depth=pd-1
+ else
+ m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
+ m.__protection__depth=0
+ end
end
local function protectall()
- for name,_ in next,registered do
- if name~="global" then
- protect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ protect(name)
end
+ end
end
local function unprotectall()
- for name,_ in next,registered do
- if name~="global" then
- unprotect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ unprotect(name)
end
+ end
end
-namespaces.register=register
-namespaces.private=private
+namespaces.register=register
+namespaces.private=private
namespaces.protect=protect
namespaces.unprotect=unprotect
namespaces.protectall=protectall
namespaces.unprotectall=unprotectall
namespaces.private("namespaces") registered={} register("global")
directives.register("system.protect",function(v)
- if v then
- protectall()
- else
- unprotectall()
- end
+ if v then
+ protectall()
+ else
+ unprotectall()
+ end
end)
directives.register("system.checkglobals",function(v)
- if v then
- report_system("enabling global namespace guard")
- protect("global")
- else
- report_system("disabling global namespace guard")
- unprotect("global")
- end
+ if v then
+ report_system("enabling global namespace guard")
+ protect("global")
+ else
+ report_system("disabling global namespace guard")
+ unprotect("global")
+ end
end)
@@ -13795,15 +13802,15 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lua"] = package.loaded["util-lua"] or true
--- original size: 6664, stripped down to: 4800
+-- original size: 6664, stripped down to: 4589
if not modules then modules={} end modules ['util-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment="the strip code is written by Peter Cawley",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ comment="the strip code is written by Peter Cawley",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format
local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage
@@ -13814,151 +13821,151 @@ local report_lua=logs.reporter("system","lua")
local report_mem=logs.reporter("system","lua memory")
local tracestripping=false
local tracememory=false
-luautilities.stripcode=true
+luautilities.stripcode=true
luautilities.alwaysstripcode=false
luautilities.nofstrippedchunks=0
luautilities.nofstrippedbytes=0
local strippedchunks={}
luautilities.strippedchunks=strippedchunks
luautilities.suffixes={
- tma="tma",
- tmc=jit and "tmb" or "tmc",
- lua="lua",
- luc=jit and "lub" or "luc",
- lui="lui",
- luv="luv",
- luj="luj",
- tua="tua",
- tuc="tuc",
+ tma="tma",
+ tmc=jit and "tmb" or "tmc",
+ lua="lua",
+ luc=jit and "lub" or "luc",
+ lui="lui",
+ luv="luv",
+ luj="luj",
+ tua="tua",
+ tuc="tuc",
}
local function register(name)
- if tracestripping then
- report_lua("stripped bytecode from %a",name or "unknown")
- end
- strippedchunks[#strippedchunks+1]=name
- luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
+ if tracestripping then
+ report_lua("stripped bytecode from %a",name or "unknown")
+ end
+ strippedchunks[#strippedchunks+1]=name
+ luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
end
local function stupidcompile(luafile,lucfile,strip)
- local code=io.loaddata(luafile)
- if code and code~="" then
- code=load(code)
- if code then
- code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
- if code and code~="" then
- register(name)
- io.savedata(lucfile,code)
- return true,0
- end
- else
- report_lua("fatal error %a in file %a",1,luafile)
- end
- else
- report_lua("fatal error %a in file %a",2,luafile)
- end
- return false,0
-end
-function luautilities.loadedluacode(fullname,forcestrip,name,macros)
- name=name or fullname
- if macros then
- macros=lua.macros
- end
- local code,message
- if macros then
- code,message=macros.loaded(fullname,true,false)
- else
- code,message=loadfile(fullname)
- end
+ local code=io.loaddata(luafile)
+ if code and code~="" then
+ code=load(code)
if code then
- code()
- else
- report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
- code,message=loadfile(fullname)
- end
- if forcestrip and luautilities.stripcode then
- if type(forcestrip)=="function" then
- forcestrip=forcestrip(fullname)
- end
- if forcestrip or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
- elseif luautilities.alwaysstripcode then
+ code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
+ if code and code~="" then
register(name)
- return load(dump(code,true)),0
+ io.savedata(lucfile,code)
+ return true,0
+ end
else
- return code,0
+ report_lua("fatal error %a in file %a",1,luafile)
end
+ else
+ report_lua("fatal error %a in file %a",2,luafile)
+ end
+ return false,0
+end
+function luautilities.loadedluacode(fullname,forcestrip,name,macros)
+ name=name or fullname
+ if macros then
+ macros=lua.macros
+ end
+ local code,message
+ if macros then
+ code,message=macros.loaded(fullname,true,false)
+ else
+ code,message=loadfile(fullname)
+ end
+ if code then
+ code()
+ else
+ report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
+ code,message=loadfile(fullname)
+ end
+ if forcestrip and luautilities.stripcode then
+ if type(forcestrip)=="function" then
+ forcestrip=forcestrip(fullname)
+ end
+ if forcestrip or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
+ elseif luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.strippedloadstring(code,name,forcestrip)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.loadstring(code,name)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- return code,0
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ return code,0
end
function luautilities.compile(luafile,lucfile,cleanup,strip,fallback)
- report_lua("compiling %a into %a",luafile,lucfile)
- os.remove(lucfile)
- local done=stupidcompile(luafile,lucfile,strip~=false)
- if done then
- report_lua("dumping %a into %a stripped",luafile,lucfile)
- if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
- report_lua("removing %a",luafile)
- os.remove(luafile)
- end
- end
- return done
+ report_lua("compiling %a into %a",luafile,lucfile)
+ os.remove(lucfile)
+ local done=stupidcompile(luafile,lucfile,strip~=false)
+ if done then
+ report_lua("dumping %a into %a stripped",luafile,lucfile)
+ if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+ report_lua("removing %a",luafile)
+ os.remove(luafile)
+ end
+ end
+ return done
end
function luautilities.loadstripped(...)
- local l=load(...)
- if l then
- return load(dump(l,true))
- end
+ local l=load(...)
+ if l then
+ return load(dump(l,true))
+ end
end
local finalizers={}
setmetatable(finalizers,{
- __gc=function(t)
- for i=1,#t do
- pcall(t[i])
- end
+ __gc=function(t)
+ for i=1,#t do
+ pcall(t[i])
end
+ end
} )
function luautilities.registerfinalizer(f)
- finalizers[#finalizers+1]=f
+ finalizers[#finalizers+1]=f
end
function luautilities.checkmemory(previous,threshold,trace)
- local current=collectgarbage("count")
- if previous then
- local checked=(threshold or 64)*1024
- local delta=current-previous
- if current-previous>checked then
- collectgarbage("collect")
- local afterwards=collectgarbage("count")
- if trace or tracememory then
- report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
- previous/1024,current/1024,delta/1024,threshold,afterwards)
- end
- return afterwards
- elseif trace or tracememory then
- report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
- previous/1024,current/1024,delta/1024,threshold)
- end
+ local current=collectgarbage("count")
+ if previous then
+ local checked=(threshold or 64)*1024
+ local delta=current-previous
+ if current-previous>checked then
+ collectgarbage("collect")
+ local afterwards=collectgarbage("count")
+ if trace or tracememory then
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
+ previous/1024,current/1024,delta/1024,threshold,afterwards)
+ end
+ return afterwards
+ elseif trace or tracememory then
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
+ previous/1024,current/1024,delta/1024,threshold)
end
- return current
+ end
+ return current
end
@@ -13968,14 +13975,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-deb"] = package.loaded["util-deb"] or true
--- original size: 9955, stripped down to: 7311
+-- original size: 9955, stripped down to: 6693
if not modules then modules={} end modules ['util-deb']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber=type,next,tostring,tonumber
local format,find,sub,gsub=string.format,string.find,string.sub,string.gsub
@@ -13994,266 +14001,266 @@ local names={}
local initialize=false
if not (FFISUPPORTED and ffi) then
elseif os.type=="windows" then
- initialize=function()
- local kernel=ffilib("kernel32","system")
- if kernel then
- local tonumber=ffi.number or tonumber
- ffi.cdef[[
+ initialize=function()
+ local kernel=ffilib("kernel32","system")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ ffi.cdef[[
int QueryPerformanceFrequency(int64_t *lpFrequency);
int QueryPerformanceCounter(int64_t *lpPerformanceCount);
]]
- local target=ffi.new("__int64[1]")
- ticks=function()
- if kernel.QueryPerformanceCounter(target)==1 then
- return tonumber(target[0])
- else
- return 0
- end
- end
- local target=ffi.new("__int64[1]")
- seconds=function(ticks)
- if kernel.QueryPerformanceFrequency(target)==1 then
- return ticks/tonumber(target[0])
- else
- return 0
- end
- end
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
end
- initialize=false
+ end
end
+ initialize=false
+ end
elseif os.type=="unix" then
- initialize=function()
- local C=ffi.C
- local tonumber=ffi.number or tonumber
- ffi.cdef [[
+ initialize=function()
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ ffi.cdef [[
/* what a mess */
typedef int clk_id_t;
typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
typedef struct timespec { long sec; long nsec; } ctx_timespec;
int clock_gettime(clk_id_t timerid, struct timespec *t);
]]
- local target=ffi.new("ctx_timespec[?]",1)
- local clock=C.CLOCK_PROCESS_CPUTIME_ID
- ticks=function ()
- C.clock_gettime(clock,target)
- return tonumber(target[0].sec*1000000000+target[0].nsec)
- end
- seconds=function(ticks)
- return ticks/1000000000
- end
- initialize=false
+ local target=ffi.new("ctx_timespec[?]",1)
+ local clock=C.CLOCK_PROCESS_CPUTIME_ID
+ ticks=function ()
+ C.clock_gettime(clock,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
end
+ seconds=function(ticks)
+ return ticks/1000000000
+ end
+ initialize=false
+ end
end
setmetatableindex(names,function(t,name)
- local v=setmetatableindex(function(t,source)
- local v=setmetatableindex(function(t,line)
- local v={ total=0,count=0,nesting=0 }
- t[line]=v
- return v
- end)
- t[source]=v
- return v
+ local v=setmetatableindex(function(t,source)
+ local v=setmetatableindex(function(t,line)
+ local v={ total=0,count=0,nesting=0 }
+ t[line]=v
+ return v
end)
- t[name]=v
+ t[source]=v
return v
+ end)
+ t[name]=v
+ return v
end)
local getinfo=nil
local sethook=nil
local function hook(where)
- local f=getinfo(2,"nSl")
- if f then
- local source=f.short_src
- if not source then
- return
- end
- local line=f.linedefined or 0
- local name=f.name
- if not name then
- local what=f.what
- if what=="C" then
- name="<anonymous>"
- else
- name=f.namewhat or what or "<unknown>"
- end
- end
- local data=names[name][source][line]
- if where=="call" then
- local nesting=data.nesting
- if nesting==0 then
- data.count=data.count+1
- insert(data,ticks())
- data.nesting=1
- else
- data.nesting=nesting+1
- end
- elseif where=="return" then
- local nesting=data.nesting
- if nesting==1 then
- local t=remove(data)
- if t then
- data.total=data.total+ticks()-t
- end
- data.nesting=0
- else
- data.nesting=nesting-1
- end
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
+ end
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ local nesting=data.nesting
+ if nesting==0 then
+ data.count=data.count+1
+ insert(data,ticks())
+ data.nesting=1
+ else
+ data.nesting=nesting+1
+ end
+ elseif where=="return" then
+ local nesting=data.nesting
+ if nesting==1 then
+ local t=remove(data)
+ if t then
+ data.total=data.total+ticks()-t
end
+ data.nesting=0
+ else
+ data.nesting=nesting-1
+ end
end
+ end
end
function debugger.showstats(printer,threshold)
- local printer=printer or report
- local calls=0
- local functions=0
- local dataset={}
- local length=0
- local realtime=0
- local totaltime=0
- local threshold=threshold or 0
- for name,sources in next,names do
- for source,lines in next,sources do
- for line,data in next,lines do
- local count=data.count
- if count>threshold then
- if #name>length then
- length=#name
- end
- local total=data.total
- local real=total
- if real>0 then
- real=total-(count*overhead/dummycalls)
- if real<0 then
- real=0
- end
- realtime=realtime+real
- end
- totaltime=totaltime+total
- if line<0 then
- line=0
- end
- dataset[#dataset+1]={ real,total,count,name,source,line }
- end
- end
+ local printer=printer or report
+ local calls=0
+ local functions=0
+ local dataset={}
+ local length=0
+ local realtime=0
+ local totaltime=0
+ local threshold=threshold or 0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ local count=data.count
+ if count>threshold then
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ realtime=realtime+real
+ end
+ totaltime=totaltime+total
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
end
+ end
end
- sort(dataset,function(a,b)
- if a[1]==b[1] then
- if a[2]==b[2] then
- if a[3]==b[3] then
- if a[4]==b[4] then
- if a[5]==b[5] then
- return a[6]<b[6]
- else
- return a[5]<b[5]
- end
- else
- return a[4]<b[4]
- end
- else
- return b[3]<a[3]
- end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
else
- return b[2]<a[2]
+ return a[5]<b[5]
end
+ else
+ return a[4]<b[4]
+ end
else
- return b[1]<a[1]
+ return b[3]<a[3]
end
- end)
- if length>50 then
- length=50
- end
- local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
- for i=1,#dataset do
- local data=dataset[i]
- local real=data[1]
- local total=data[2]
- local count=data[3]
- local name=data[4]
- local source=data[5]
- local line=data[6]
- calls=calls+count
- functions=functions+1
- name=gsub(name,"%s+"," ")
- if #name>length then
- name=sub(name,1,length)
- end
- printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
- end
- printer("")
- printer(format("functions : %i",functions))
- printer(format("calls : %i",calls))
- printer(format("overhead : %f",seconds(overhead/1000)))
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
+ end
+ local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
+ for i=1,#dataset do
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ calls=calls+count
+ functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
+ end
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
end
local function getdebug()
- if sethook and getinfo then
- return
- end
- if not debug then
- local okay
- okay,debug=pcall(require,"debug")
- end
- if type(debug)~="table" then
- return
- end
- getinfo=debug.getinfo
- sethook=debug.sethook
- if type(getinfo)~="function" then
- getinfo=nil
- end
- if type(sethook)~="function" then
- sethook=nil
- end
+ if sethook and getinfo then
+ return
+ end
+ if not debug then
+ local okay
+ okay,debug=pcall(require,"debug")
+ end
+ if type(debug)~="table" then
+ return
+ end
+ getinfo=debug.getinfo
+ sethook=debug.sethook
+ if type(getinfo)~="function" then
+ getinfo=nil
+ end
+ if type(sethook)~="function" then
+ sethook=nil
+ end
end
function debugger.savestats(filename,threshold)
- local f=io.open(filename,'w')
- if f then
- debugger.showstats(function(str) f:write(str,"\n") end,threshold)
- f:close()
- end
+ local f=io.open(filename,'w')
+ if f then
+ debugger.showstats(function(str) f:write(str,"\n") end,threshold)
+ f:close()
+ end
end
function debugger.enable()
- getdebug()
- if sethook and getinfo and nesting==0 then
- running=true
- if initialize then
- initialize()
- end
- sethook(hook,"cr")
- local function dummy() end
- local t=ticks()
- for i=1,dummycalls do
- dummy()
- end
- overhead=ticks()-t
- end
- if nesting>0 then
- nesting=nesting+1
- end
+ getdebug()
+ if sethook and getinfo and nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
end
function debugger.disable()
- if nesting>0 then
- nesting=nesting-1
- end
- if sethook and getinfo and nesting==0 then
- sethook()
- end
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if sethook and getinfo and nesting==0 then
+ sethook()
+ end
end
local function showtraceback(rep)
- getdebug()
- if getinfo then
- local level=2
- local reporter=rep or report
- while true do
- local info=getinfo(level,"Sl")
- if not info then
- break
- elseif info.what=="C" then
- reporter("%2i : %s",level-1,"C function")
- else
- reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
- end
- level=level+1
- end
+ getdebug()
+ if getinfo then
+ local level=2
+ local reporter=rep or report
+ while true do
+ local info=getinfo(level,"Sl")
+ if not info then
+ break
+ elseif info.what=="C" then
+ reporter("%2i : %s",level-1,"C function")
+ else
+ reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
+ end
+ level=level+1
end
+ end
end
debugger.showtraceback=showtraceback
@@ -14264,91 +14271,91 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
--- original size: 7112, stripped down to: 3988
+-- original size: 7112, stripped down to: 3887
if not modules then modules={} end modules ['util-tpl']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities.templates=utilities.templates or {}
local templates=utilities.templates
-local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
+local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
local report_template=logs.reporter("template")
local tostring,next=tostring,next
local format,sub,byte=string.format,string.sub,string.byte
local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
local replacer
local function replacekey(k,t,how,recursive)
- local v=t[k]
- if not v then
- if trace_template then
- report_template("unknown key %a",k)
- end
- return ""
+ local v=t[k]
+ if not v then
+ if trace_template then
+ report_template("unknown key %a",k)
+ end
+ return ""
+ else
+ v=tostring(v)
+ if trace_template then
+ report_template("setting key %a to value %a",k,v)
+ end
+ if recursive then
+ return lpegmatch(replacer,v,1,t,how,recursive)
else
- v=tostring(v)
- if trace_template then
- report_template("setting key %a to value %a",k,v)
- end
- if recursive then
- return lpegmatch(replacer,v,1,t,how,recursive)
- else
- return v
- end
+ return v
end
+ end
end
local sqlescape=lpeg.replacer {
- { "'","''" },
- { "\\","\\\\" },
- { "\r\n","\\n" },
- { "\r","\\n" },
+ { "'","''" },
+ { "\\","\\\\" },
+ { "\r\n","\\n" },
+ { "\r","\\n" },
}
local sqlquoted=Cs(Cc("'")*sqlescape*Cc("'"))
lpegpatterns.sqlescape=sqlescape
lpegpatterns.sqlquoted=sqlquoted
local luaescape=lpegpatterns.luaescape
local escapers={
- lua=function(s)
- return lpegmatch(luaescape,s)
- end,
- sql=function(s)
- return lpegmatch(sqlescape,s)
- end,
+ lua=function(s)
+ return lpegmatch(luaescape,s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlescape,s)
+ end,
}
local quotedescapers={
- lua=function(s)
- return format("%q",s)
- end,
- sql=function(s)
- return lpegmatch(sqlquoted,s)
- end,
+ lua=function(s)
+ return format("%q",s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlquoted,s)
+ end,
}
local luaescaper=escapers.lua
local quotedluaescaper=quotedescapers.lua
local function replacekeyunquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and escapers[how] or luaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and escapers[how] or luaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replacekeyquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and quotedescapers[how] or quotedluaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and quotedescapers[how] or quotedluaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replaceoptional(l,m,r,t,how,recurse)
- local v=t[l]
- return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
+ local v=t[l]
+ return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
end
-local single=P("%")
+local single=P("%")
local double=P("%%")
local lquoted=P("%[")
local rquoted=P("]%")
@@ -14365,41 +14372,41 @@ local noloptional=P("%?")/''
local noroptional=P("?%")/''
local nomoptional=P(":")/''
local args=Carg(1)*Carg(2)*Carg(3)
-local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
-local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
-local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
+local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
+local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
+local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
local optional=noloptional*((C((1-nomoptional)^1)*nomoptional*C((1-noroptional)^1)*args)/replaceoptional)*noroptional
local any=P(1)
replacer=Cs((unquoted+quoted+escape+optional+key+any)^0)
local function replace(str,mapping,how,recurse)
- if mapping and str then
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
- return str
- end
+ if mapping and str then
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ else
+ return str
+ end
end
templates.replace=replace
function templates.replacer(str,how,recurse)
- return function(mapping)
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- end
+ return function(mapping)
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ end
end
function templates.load(filename,mapping,how,recurse)
- local data=io.loaddata(filename) or ""
- if mapping and next(mapping) then
- return replace(data,mapping,how,recurse)
- else
- return data
- end
+ local data=io.loaddata(filename) or ""
+ if mapping and next(mapping) then
+ return replace(data,mapping,how,recurse)
+ else
+ return data
+ end
end
function templates.resolve(t,mapping,how,recurse)
- if not mapping then
- mapping=t
- end
- for k,v in next,t do
- t[k]=replace(v,mapping,how,recurse)
- end
- return t
+ if not mapping then
+ mapping=t
+ end
+ for k,v in next,t do
+ t[k]=replace(v,mapping,how,recurse)
+ end
+ return t
end
@@ -14409,14 +14416,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sbx"] = package.loaded["util-sbx"] or true
--- original size: 20393, stripped down to: 13924
+-- original size: 20393, stripped down to: 13121
if not modules then modules={} end modules ['util-sbx']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not sandbox then require("l-sandbox") end
local next,type=next,type
@@ -14449,144 +14456,144 @@ local report=logs.reporter("sandbox")
trackers.register("sandbox",function(v) trace=v end)
sandbox.setreporter(report)
sandbox.finalizer {
- category="files",
- action=function()
- finalized=true
- end
+ category="files",
+ action=function()
+ finalized=true
+ end
}
local function registerroot(root,what)
- if finalized then
- report("roots are already finalized")
- else
- if type(root)=="table" then
- root,what=root[1],root[2]
- end
- if type(root)=="string" and root~="" then
- root=collapsepath(expandname(root))
- if what=="r" or what=="ro" or what=="readable" then
- what="read"
- elseif what=="w" or what=="wo" or what=="writable" then
- what="write"
- end
- validroots[root]=what=="write" or false
- end
+ if finalized then
+ report("roots are already finalized")
+ else
+ if type(root)=="table" then
+ root,what=root[1],root[2]
+ end
+ if type(root)=="string" and root~="" then
+ root=collapsepath(expandname(root))
+ if what=="r" or what=="ro" or what=="readable" then
+ what="read"
+ elseif what=="w" or what=="wo" or what=="writable" then
+ what="write"
+ end
+ validroots[root]=what=="write" or false
end
+ end
end
sandbox.finalizer {
- category="files",
- action=function()
+ category="files",
+ action=function()
+ if p_validroot then
+ report("roots are already initialized")
+ else
+ sandbox.registerroot(".","write")
+ for name in sortedhash(validroots) do
if p_validroot then
- report("roots are already initialized")
+ p_validroot=P(name)+p_validroot
else
- sandbox.registerroot(".","write")
- for name in sortedhash(validroots) do
- if p_validroot then
- p_validroot=P(name)+p_validroot
- else
- p_validroot=P(name)
- end
- end
- p_validroot=p_validroot/validroots
+ p_validroot=P(name)
end
+ end
+ p_validroot=p_validroot/validroots
end
+ end
}
local function registerbinary(name)
- if finalized then
- report("binaries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validbinaries then
- return
- end
- if validbinaries==true then
- validbinaries={ [name]=true }
- else
- validbinaries[name]=true
- end
- elseif name==true then
- validbinaries={}
+ if finalized then
+ report("binaries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validbinaries then
+ return
end
+ if validbinaries==true then
+ validbinaries={ [name]=true }
+ else
+ validbinaries[name]=true
+ end
+ elseif name==true then
+ validbinaries={}
+ end
end
local function registerlibrary(name)
- if finalized then
- report("libraries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validlibraries then
- return
- end
- if validlibraries==true then
- validlibraries={ [nameonly(name)]=true }
- else
- validlibraries[nameonly(name)]=true
- end
- elseif name==true then
- validlibraries={}
+ if finalized then
+ report("libraries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validlibraries then
+ return
end
+ if validlibraries==true then
+ validlibraries={ [nameonly(name)]=true }
+ else
+ validlibraries[nameonly(name)]=true
+ end
+ elseif name==true then
+ validlibraries={}
+ end
end
local p_write=S("wa") p_write=(1-p_write)^0*p_write
-local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
+local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
local function normalized(name)
- if platform=="windows" then
- name=gsub(name,"/","\\")
- end
- return name
+ if platform=="windows" then
+ name=gsub(name,"/","\\")
+ end
+ return name
end
function sandbox.possiblepath(name)
- return lpegmatch(p_path,name) and true or false
+ return lpegmatch(p_path,name) and true or false
end
local filenamelogger=false
function sandbox.setfilenamelogger(l)
- filenamelogger=type(l)=="function" and l or false
+ filenamelogger=type(l)=="function" and l or false
end
local function validfilename(name,what)
- if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
- local asked=collapsepath(expandname(name))
- local okay=lpegmatch(p_validroot,asked)
- if okay==true then
- if filenamelogger then
- filenamelogger(name,"w",asked,true)
- end
- return name
- elseif okay==false then
- if not what then
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- elseif lpegmatch(p_write,what) then
- if filenamelogger then
- filenamelogger(name,"w",asked,false)
- end
- return
- else
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- end
- elseif filenamelogger then
- filenamelogger(name,"*",name,false)
+ if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
+ local asked=collapsepath(expandname(name))
+ local okay=lpegmatch(p_validroot,asked)
+ if okay==true then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,true)
+ end
+ return name
+ elseif okay==false then
+ if not what then
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
+ end
+ return name
+ elseif lpegmatch(p_write,what) then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,false)
+ end
+ return
+ else
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
end
- else
return name
+ end
+ elseif filenamelogger then
+ filenamelogger(name,"*",name,false)
end
+ else
+ return name
+ end
end
local function readable(name,finalized)
- return validfilename(name,"r")
+ return validfilename(name,"r")
end
local function normalizedreadable(name,finalized)
- local valid=validfilename(name,"r")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"r")
+ if valid then
+ return normalized(valid)
+ end
end
local function writeable(name,finalized)
- return validfilename(name,"w")
+ return validfilename(name,"w")
end
local function normalizedwriteable(name,finalized)
- local valid=validfilename(name,"w")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"w")
+ if valid then
+ return normalized(valid)
+ end
end
validators.readable=readable
validators.writeable=normalizedwriteable
@@ -14594,316 +14601,316 @@ validators.normalizedreadable=normalizedreadable
validators.normalizedwriteable=writeable
validators.filename=readable
table.setmetatableindex(validators,function(t,k)
- if k then
- t[k]=readable
- end
- return readable
+ if k then
+ t[k]=readable
+ end
+ return readable
end)
function validators.string(s,finalized)
- if finalized and suspicious(s) then
- return ""
- else
- return s
- end
+ if finalized and suspicious(s) then
+ return ""
+ else
+ return s
+ end
end
function validators.cache(s)
- if finalized then
- return basename(s)
- else
- return s
- end
+ if finalized then
+ return basename(s)
+ else
+ return s
+ end
end
function validators.url(s)
- if finalized and find("^file:") then
- return ""
- else
- return s
- end
+ if finalized and find("^file:") then
+ return ""
+ else
+ return s
+ end
end
local function filehandlerone(action,one,...)
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
+ else
+ end
end
local function filehandlertwo(action,one,two,...)
- local checkedone=validfilename(one)
- if checkedone then
- local checkedtwo=validfilename(two)
- if checkedtwo then
- return action(one,two,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ local checkedtwo=validfilename(two)
+ if checkedtwo then
+ return action(one,two,...)
else
end
+ else
+ end
end
local function iohandler(action,one,...)
- if type(one)=="string" then
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- end
- elseif one then
- return action(one,...)
- else
- return action()
+ if type(one)=="string" then
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
end
+ elseif one then
+ return action(one,...)
+ else
+ return action()
+ end
end
local osexecute=sandbox.original(os.execute)
local iopopen=sandbox.original(io.popen)
local reported={}
local function validcommand(name,program,template,checkers,defaults,variables,reporter,strict)
- if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
- if variables then
- for variable,value in next,variables do
- local checker=validators[checkers[variable]]
- if checker then
- value=checker(unquoted(value),strict)
- if value then
- variables[variable]=optionalquoted(value)
- else
- report("variable %a with value %a fails the check",variable,value)
- return
- end
- else
- report("variable %a has no checker",variable)
- return
- end
- end
- for variable,default in next,defaults do
- local value=variables[variable]
- if not value or value=="" then
- local checker=validators[checkers[variable]]
- if checker then
- default=checker(unquoted(default),strict)
- if default then
- variables[variable]=optionalquoted(default)
- else
- report("variable %a with default %a fails the check",variable,default)
- return
- end
- end
- end
- end
- end
- local command=program.." "..replace(template,variables)
- if reporter then
- reporter("executing runner %a: %s",name,command)
- elseif trace then
- report("executing runner %a: %s",name,command)
- end
- return command
- elseif not reported[name] then
- report("executing program %a of runner %a is not permitted",program,name)
- reported[name]=true
- end
-end
-local runners={
- resultof=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("resultof: %s",command)
- end
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- end
- end
- end,
- execute=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("execute: %s",command)
- end
- return osexecute(command)
+ if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
+ if variables then
+ for variable,value in next,variables do
+ local checker=validators[checkers[variable]]
+ if checker then
+ value=checker(unquoted(value),strict)
+ if value then
+ variables[variable]=optionalquoted(value)
+ else
+ report("variable %a with value %a fails the check",variable,value)
+ return
+ end
+ else
+ report("variable %a has no checker",variable)
+ return
end
- end,
- pipeto=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("pipeto: %s",command)
+ end
+ for variable,default in next,defaults do
+ local value=variables[variable]
+ if not value or value=="" then
+ local checker=validators[checkers[variable]]
+ if checker then
+ default=checker(unquoted(default),strict)
+ if default then
+ variables[variable]=optionalquoted(default)
+ else
+ report("variable %a with default %a fails the check",variable,default)
+ return
end
- return iopopen(command,"w")
- end
- end,
-}
-function sandbox.registerrunner(specification)
- if type(specification)=="string" then
- local wrapped=validrunners[specification]
- inspect(table.sortedkeys(validrunners))
- if wrapped then
- return wrapped
- else
- report("unknown predefined runner %a",specification)
- return
+ end
end
+ end
end
- if type(specification)~="table" then
- report("specification should be a table (or string)")
- return
- end
- local name=specification.name
- if type(name)~="string" then
- report("invalid name, string expected",name)
- return
- end
- if validrunners[name] then
- report("invalid name, runner %a already defined")
- return
- end
- local program=specification.program
- if type(program)=="string" then
- elseif type(program)=="table" then
- program=program[platform] or program.default or program.unix
- end
- if type(program)~="string" or program=="" then
- report("invalid runner %a specified for platform %a",name,platform)
- return
+ local command=program.." "..replace(template,variables)
+ if reporter then
+ reporter("executing runner %a: %s",name,command)
+ elseif trace then
+ report("executing runner %a: %s",name,command)
end
- local template=specification.template
- if not template then
- report("missing template for runner %a",name)
- return
+ return command
+ elseif not reported[name] then
+ report("executing program %a of runner %a is not permitted",program,name)
+ reported[name]=true
+ end
+end
+local runners={
+ resultof=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("resultof: %s",command)
+ end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ end
end
- local method=specification.method or "execute"
- local checkers=specification.checkers or {}
- local defaults=specification.defaults or {}
- local runner=runners[method]
- if runner then
- local finalized=finalized
- local wrapped=function(variables)
- return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
- end
- validrunners[name]=wrapped
- return wrapped
- else
- validrunners[name]=nil
- report("invalid method for runner %a",name)
+ end,
+ execute=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("execute: %s",command)
+ end
+ return osexecute(command)
+ end
+ end,
+ pipeto=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("pipeto: %s",command)
+ end
+ return iopopen(command,"w")
end
+ end,
+}
+function sandbox.registerrunner(specification)
+ if type(specification)=="string" then
+ local wrapped=validrunners[specification]
+ inspect(table.sortedkeys(validrunners))
+ if wrapped then
+ return wrapped
+ else
+ report("unknown predefined runner %a",specification)
+ return
+ end
+ end
+ if type(specification)~="table" then
+ report("specification should be a table (or string)")
+ return
+ end
+ local name=specification.name
+ if type(name)~="string" then
+ report("invalid name, string expected",name)
+ return
+ end
+ if validrunners[name] then
+ report("invalid name, runner %a already defined")
+ return
+ end
+ local program=specification.program
+ if type(program)=="string" then
+ elseif type(program)=="table" then
+ program=program[platform] or program.default or program.unix
+ end
+ if type(program)~="string" or program=="" then
+ report("invalid runner %a specified for platform %a",name,platform)
+ return
+ end
+ local template=specification.template
+ if not template then
+ report("missing template for runner %a",name)
+ return
+ end
+ local method=specification.method or "execute"
+ local checkers=specification.checkers or {}
+ local defaults=specification.defaults or {}
+ local runner=runners[method]
+ if runner then
+ local finalized=finalized
+ local wrapped=function(variables)
+ return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
+ end
+ validrunners[name]=wrapped
+ return wrapped
+ else
+ validrunners[name]=nil
+ report("invalid method for runner %a",name)
+ end
end
function sandbox.getrunner(name)
- return name and validrunners[name]
+ return name and validrunners[name]
end
local function suspicious(str)
- return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
+ return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
end
local function binaryrunner(action,command,...)
- if validbinaries==false then
- report("no binaries permitted, ignoring command: %s",command)
- return
- end
- if type(command)~="string" then
- report("command should be a string")
- return
- end
- local program=lpegmatch(p_split,command)
- if not program or program=="" then
- report("unable to filter binary from command: %s",command)
- return
- end
- if validbinaries==true then
- elseif not validbinaries[program] then
- report("binary not permitted, ignoring command: %s",command)
- return
- elseif suspicious(command) then
- report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
- return
- end
- return action(command,...)
+ if validbinaries==false then
+ report("no binaries permitted, ignoring command: %s",command)
+ return
+ end
+ if type(command)~="string" then
+ report("command should be a string")
+ return
+ end
+ local program=lpegmatch(p_split,command)
+ if not program or program=="" then
+ report("unable to filter binary from command: %s",command)
+ return
+ end
+ if validbinaries==true then
+ elseif not validbinaries[program] then
+ report("binary not permitted, ignoring command: %s",command)
+ return
+ elseif suspicious(command) then
+ report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
+ return
+ end
+ return action(command,...)
end
local function dummyrunner(action,command,...)
- if type(command)=="table" then
- command=concat(command," ",command[0] and 0 or 1)
- end
- report("ignoring command: %s",command)
+ if type(command)=="table" then
+ command=concat(command," ",command[0] and 0 or 1)
+ end
+ report("ignoring command: %s",command)
end
sandbox.filehandlerone=filehandlerone
sandbox.filehandlertwo=filehandlertwo
sandbox.iohandler=iohandler
function sandbox.disablerunners()
- validbinaries=false
+ validbinaries=false
end
function sandbox.disablelibraries()
- validlibraries=false
+ validlibraries=false
end
if FFISUPPORTED and ffi then
- function sandbox.disablelibraries()
- validlibraries=false
- for k,v in next,ffi do
- if k~="gc" then
- ffi[k]=nil
- end
- end
+ function sandbox.disablelibraries()
+ validlibraries=false
+ for k,v in next,ffi do
+ if k~="gc" then
+ ffi[k]=nil
+ end
end
- local fiiload=ffi.load
- if fiiload then
- local reported={}
- function ffi.load(name,...)
- if validlibraries==false then
- elseif validlibraries==true then
- return fiiload(name,...)
- elseif validlibraries[nameonly(name)] then
- return fiiload(name,...)
- else
- end
- if not reported[name] then
- report("using library %a is not permitted",name)
- reported[name]=true
- end
- return nil
- end
+ end
+ local fiiload=ffi.load
+ if fiiload then
+ local reported={}
+ function ffi.load(name,...)
+ if validlibraries==false then
+ elseif validlibraries==true then
+ return fiiload(name,...)
+ elseif validlibraries[nameonly(name)] then
+ return fiiload(name,...)
+ else
+ end
+ if not reported[name] then
+ report("using library %a is not permitted",name)
+ reported[name]=true
+ end
+ return nil
end
+ end
end
local overload=sandbox.overload
local register=sandbox.register
- overload(loadfile,filehandlerone,"loadfile")
+ overload(loadfile,filehandlerone,"loadfile")
if io then
- overload(io.open,filehandlerone,"io.open")
- overload(io.popen,binaryrunner,"io.popen")
- overload(io.input,iohandler,"io.input")
- overload(io.output,iohandler,"io.output")
- overload(io.lines,filehandlerone,"io.lines")
+ overload(io.open,filehandlerone,"io.open")
+ overload(io.popen,binaryrunner,"io.popen")
+ overload(io.input,iohandler,"io.input")
+ overload(io.output,iohandler,"io.output")
+ overload(io.lines,filehandlerone,"io.lines")
end
if os then
- overload(os.execute,binaryrunner,"os.execute")
- overload(os.spawn,dummyrunner,"os.spawn")
- overload(os.exec,dummyrunner,"os.exec")
- overload(os.resultof,binaryrunner,"os.resultof")
- overload(os.pipeto,binaryrunner,"os.pipeto")
- overload(os.rename,filehandlertwo,"os.rename")
- overload(os.remove,filehandlerone,"os.remove")
+ overload(os.execute,binaryrunner,"os.execute")
+ overload(os.spawn,dummyrunner,"os.spawn")
+ overload(os.exec,dummyrunner,"os.exec")
+ overload(os.resultof,binaryrunner,"os.resultof")
+ overload(os.pipeto,binaryrunner,"os.pipeto")
+ overload(os.rename,filehandlertwo,"os.rename")
+ overload(os.remove,filehandlerone,"os.remove")
end
if lfs then
- overload(lfs.chdir,filehandlerone,"lfs.chdir")
- overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
- overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
- overload(lfs.isfile,filehandlerone,"lfs.isfile")
- overload(lfs.isdir,filehandlerone,"lfs.isdir")
- overload(lfs.attributes,filehandlerone,"lfs.attributes")
- overload(lfs.dir,filehandlerone,"lfs.dir")
- overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
- overload(lfs.touch,filehandlerone,"lfs.touch")
- overload(lfs.link,filehandlertwo,"lfs.link")
- overload(lfs.setmode,filehandlerone,"lfs.setmode")
- overload(lfs.readlink,filehandlerone,"lfs.readlink")
- overload(lfs.shortname,filehandlerone,"lfs.shortname")
- overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
+ overload(lfs.chdir,filehandlerone,"lfs.chdir")
+ overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
+ overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
+ overload(lfs.isfile,filehandlerone,"lfs.isfile")
+ overload(lfs.isdir,filehandlerone,"lfs.isdir")
+ overload(lfs.attributes,filehandlerone,"lfs.attributes")
+ overload(lfs.dir,filehandlerone,"lfs.dir")
+ overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
+ overload(lfs.touch,filehandlerone,"lfs.touch")
+ overload(lfs.link,filehandlertwo,"lfs.link")
+ overload(lfs.setmode,filehandlerone,"lfs.setmode")
+ overload(lfs.readlink,filehandlerone,"lfs.readlink")
+ overload(lfs.shortname,filehandlerone,"lfs.shortname")
+ overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
end
if zip then
- zip.open=register(zip.open,filehandlerone,"zip.open")
+ zip.open=register(zip.open,filehandlerone,"zip.open")
end
if fontloader then
- fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
- fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
+ fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
+ fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
end
if epdf then
- epdf.open=register(epdf.open,filehandlerone,"epdf.open")
+ epdf.open=register(epdf.open,filehandlerone,"epdf.open")
end
sandbox.registerroot=registerroot
sandbox.registerbinary=registerbinary
@@ -14917,14 +14924,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-mrg"] = package.loaded["util-mrg"] or true
--- original size: 7757, stripped down to: 6015
+-- original size: 7819, stripped down to: 5881
if not modules then modules={} end modules ['util-mrg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local gsub,format=string.gsub,string.format
local concat=table.concat
@@ -14952,19 +14959,19 @@ local m_report=[[
]]
local m_preloaded=[[package.loaded[%q] = package.loaded[%q] or true]]
local function self_fake()
- return m_faked
+ return m_faked
end
local function self_nothing()
- return ""
+ return ""
end
local function self_load(name)
- local data=io.loaddata(name) or ""
- if data=="" then
- report("unknown file %a",name)
- else
- report("inserting file %a",name)
- end
- return data or ""
+ local data=io.loaddata(name) or ""
+ if data=="" then
+ report("unknown file %a",name)
+ else
+ report("inserting file %a",name)
+ end
+ return data or ""
end
local space=patterns.space
local eol=patterns.newline
@@ -14993,98 +15000,99 @@ local mandatespacing=(eol+space)^1/""
local pack=digit*space^1*operator4*optionalspacing+optionalspacing*operator1*optionalspacing+optionalspacing*operator2*optionalspaces+mandatespacing*operator3*mandatespaces+optionalspaces*separator*optionalspaces
local lines=emptyline^2/"\n"
local spaces=(space*space)/" "
+local spaces=(space*space*space*space)/" "
local compact=Cs ((
- ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
+ ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
)^1 )
local strip=Cs((emptyline^2/"\n"+1)^0)
local stripreturn=Cs((1-P("return")*space^1*P(1-space-eol)^1*(space+eol)^0*P(-1))^1)
function merger.compact(data)
- return lpegmatch(strip,lpegmatch(compact,data))
+ return lpegmatch(strip,lpegmatch(compact,data))
end
local function self_compact(data)
- local delta=0
- if merger.strip_comment then
- local before=#data
- data=lpegmatch(compact,data)
- data=lpegmatch(strip,data)
- local after=#data
- delta=before-after
- report("original size %s, compacted to %s, stripped %s",before,after,delta)
- data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
- end
- return lpegmatch(stripreturn,data) or data,delta
+ local delta=0
+ if merger.strip_comment then
+ local before=#data
+ data=lpegmatch(compact,data)
+ data=lpegmatch(strip,data)
+ local after=#data
+ delta=before-after
+ report("original size %s, compacted to %s, stripped %s",before,after,delta)
+ data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
+ end
+ return lpegmatch(stripreturn,data) or data,delta
end
local function self_save(name,data)
- if data~="" then
- io.savedata(name,data)
- report("saving %s with size %s",name,#data)
- end
+ if data~="" then
+ io.savedata(name,data)
+ report("saving %s with size %s",name,#data)
+ end
end
local function self_swap(data,code)
- return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
+ return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
end
local function self_libs(libs,list)
- local result,f,frozen,foundpath={},nil,false,nil
- result[#result+1]="\n"
- if type(libs)=='string' then libs={ libs } end
- if type(list)=='string' then list={ list } end
+ local result,f,frozen,foundpath={},nil,false,nil
+ result[#result+1]="\n"
+ if type(libs)=='string' then libs={ libs } end
+ if type(list)=='string' then list={ list } end
+ for i=1,#libs do
+ local lib=libs[i]
+ for j=1,#list do
+ local pth=gsub(list[j],"\\","/")
+ report("checking library path %a",pth)
+ local name=pth.."/"..lib
+ if lfs.isfile(name) then
+ foundpath=pth
+ end
+ end
+ if foundpath then break end
+ end
+ if foundpath then
+ report("using library path %a",foundpath)
+ local right,wrong,original,stripped={},{},0,0
for i=1,#libs do
- local lib=libs[i]
- for j=1,#list do
- local pth=gsub(list[j],"\\","/")
- report("checking library path %a",pth)
- local name=pth.."/"..lib
- if lfs.isfile(name) then
- foundpath=pth
- end
- end
- if foundpath then break end
- end
- if foundpath then
- report("using library path %a",foundpath)
- local right,wrong,original,stripped={},{},0,0
- for i=1,#libs do
- local lib=libs[i]
- local fullname=foundpath.."/"..lib
- if lfs.isfile(fullname) then
- report("using library %a",fullname)
- local preloaded=file.nameonly(lib)
- local data=io.loaddata(fullname,true)
- original=original+#data
- local data,delta=self_compact(data)
- right[#right+1]=lib
- result[#result+1]=m_begin_closure
- result[#result+1]=format(m_preloaded,preloaded,preloaded)
- result[#result+1]=data
- result[#result+1]=m_end_closure
- stripped=stripped+delta
- else
- report("skipping library %a",fullname)
- wrong[#wrong+1]=lib
- end
- end
- right=#right>0 and concat(right," ") or "-"
- wrong=#wrong>0 and concat(wrong," ") or "-"
- report("used libraries: %a",right)
- report("skipped libraries: %a",wrong)
- report("original bytes: %a",original)
- report("stripped bytes: %a",stripped)
- result[#result+1]=format(m_report,right,wrong,original,stripped)
- else
- report("no valid library path found")
+ local lib=libs[i]
+ local fullname=foundpath.."/"..lib
+ if lfs.isfile(fullname) then
+ report("using library %a",fullname)
+ local preloaded=file.nameonly(lib)
+ local data=io.loaddata(fullname,true)
+ original=original+#data
+ local data,delta=self_compact(data)
+ right[#right+1]=lib
+ result[#result+1]=m_begin_closure
+ result[#result+1]=format(m_preloaded,preloaded,preloaded)
+ result[#result+1]=data
+ result[#result+1]=m_end_closure
+ stripped=stripped+delta
+ else
+ report("skipping library %a",fullname)
+ wrong[#wrong+1]=lib
+ end
end
- return concat(result,"\n\n")
+ right=#right>0 and concat(right," ") or "-"
+ wrong=#wrong>0 and concat(wrong," ") or "-"
+ report("used libraries: %a",right)
+ report("skipped libraries: %a",wrong)
+ report("original bytes: %a",original)
+ report("stripped bytes: %a",stripped)
+ result[#result+1]=format(m_report,right,wrong,original,stripped)
+ else
+ report("no valid library path found")
+ end
+ return concat(result,"\n\n")
end
function merger.selfcreate(libs,list,target)
- if target then
- self_save(target,self_swap(self_fake(),self_libs(libs,list)))
- end
+ if target then
+ self_save(target,self_swap(self_fake(),self_libs(libs,list)))
+ end
end
function merger.selfmerge(name,libs,list,target)
- self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
+ self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
end
function merger.selfclean(name)
- self_save(name,self_swap(self_load(name),self_nothing()))
+ self_save(name,self_swap(self_load(name),self_nothing()))
end
@@ -15094,14 +15102,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-env"] = package.loaded["util-env"] or true
--- original size: 9634, stripped down to: 5673
+-- original size: 9634, stripped down to: 5360
if not modules then modules={} end modules ['util-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate,mark=utilities.storage.allocate,utilities.storage.mark
local format,sub,match,gsub,find=string.format,string.sub,string.match,string.gsub,string.find
@@ -15113,185 +15121,185 @@ local setlocale=os.setlocale
setlocale(nil,nil)
local report=logs.reporter("system")
function os.setlocale(a,b)
- if a or b then
- if report then
- report()
- report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
- report("now on are on your own and without support. Crashes or unexpected side effects")
- report("can happen but don't bother the luatex and context developer team with it.")
- report()
- report=nil
- end
- setlocale(a,b)
- end
+ if a or b then
+ if report then
+ report()
+ report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
+ report("now on are on your own and without support. Crashes or unexpected side effects")
+ report("can happen but don't bother the luatex and context developer team with it.")
+ report()
+ report=nil
+ end
+ setlocale(a,b)
+ end
end
local validengines=allocate {
- ["luatex"]=true,
- ["luajittex"]=true,
+ ["luatex"]=true,
+ ["luajittex"]=true,
}
local basicengines=allocate {
- ["luatex"]="luatex",
- ["texlua"]="luatex",
- ["texluac"]="luatex",
- ["luajittex"]="luajittex",
- ["texluajit"]="luajittex",
+ ["luatex"]="luatex",
+ ["texlua"]="luatex",
+ ["texluac"]="luatex",
+ ["luajittex"]="luajittex",
+ ["texluajit"]="luajittex",
}
local luaengines=allocate {
- ["lua"]=true,
- ["luajit"]=true,
+ ["lua"]=true,
+ ["luajit"]=true,
}
environment.validengines=validengines
environment.basicengines=basicengines
if not arg then
- environment.used_as_library=true
+ environment.used_as_library=true
elseif luaengines[file.removesuffix(arg[-1])] then
elseif validengines[file.removesuffix(arg[0])] then
- if arg[1]=="--luaonly" then
- arg[-1]=arg[0]
- arg[ 0]=arg[2]
- for k=3,#arg do
- arg[k-2]=arg[k]
- end
- remove(arg)
- remove(arg)
- else
- end
- local originalzero=file.basename(arg[0])
- local specialmapping={ luatools=="base" }
- if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
+ if arg[1]=="--luaonly" then
+ arg[-1]=arg[0]
+ arg[ 0]=arg[2]
+ for k=3,#arg do
+ arg[k-2]=arg[k]
+ end
+ remove(arg)
+ remove(arg)
+ else
+ end
+ local originalzero=file.basename(arg[0])
+ local specialmapping={ luatools=="base" }
+ if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
arg[0]=specialmapping[originalzero] or originalzero
insert(arg,0,"--script")
insert(arg,0,"mtxrun")
- end
+ end
end
environment.arguments=allocate()
environment.files=allocate()
environment.sortedflags=nil
function environment.initializearguments(arg)
- local arguments,files={},{}
- environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
- for index=1,#arg do
- local argument=arg[index]
- if index>0 then
- local flag,value=match(argument,"^%-+(.-)=(.-)$")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=unquoted(value or "")
- else
- flag=match(argument,"^%-+(.+)")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=true
- else
- files[#files+1]=argument
- end
- end
+ local arguments,files={},{}
+ environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
+ for index=1,#arg do
+ local argument=arg[index]
+ if index>0 then
+ local flag,value=match(argument,"^%-+(.-)=(.-)$")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=unquoted(value or "")
+ else
+ flag=match(argument,"^%-+(.+)")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=true
+ else
+ files[#files+1]=argument
end
+ end
end
- environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
+ end
+ environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
end
function environment.setargument(name,value)
- environment.arguments[name]=value
+ environment.arguments[name]=value
end
function environment.getargument(name,partial)
- local arguments,sortedflags=environment.arguments,environment.sortedflags
- if arguments[name] then
- return arguments[name]
- elseif partial then
- if not sortedflags then
- sortedflags=allocate(table.sortedkeys(arguments))
- for k=1,#sortedflags do
- sortedflags[k]="^"..sortedflags[k]
- end
- environment.sortedflags=sortedflags
- end
- for k=1,#sortedflags do
- local v=sortedflags[k]
- if find(name,v) then
- return arguments[sub(v,2,#v)]
- end
- end
+ local arguments,sortedflags=environment.arguments,environment.sortedflags
+ if arguments[name] then
+ return arguments[name]
+ elseif partial then
+ if not sortedflags then
+ sortedflags=allocate(table.sortedkeys(arguments))
+ for k=1,#sortedflags do
+ sortedflags[k]="^"..sortedflags[k]
+ end
+ environment.sortedflags=sortedflags
end
- return nil
+ for k=1,#sortedflags do
+ local v=sortedflags[k]
+ if find(name,v) then
+ return arguments[sub(v,2,#v)]
+ end
+ end
+ end
+ return nil
end
environment.argument=environment.getargument
function environment.splitarguments(separator)
- local done,before,after=false,{},{}
- local originalarguments=environment.originalarguments
- for k=1,#originalarguments do
- local v=originalarguments[k]
- if not done and v==separator then
- done=true
- elseif done then
- after[#after+1]=v
- else
- before[#before+1]=v
- end
+ local done,before,after=false,{},{}
+ local originalarguments=environment.originalarguments
+ for k=1,#originalarguments do
+ local v=originalarguments[k]
+ if not done and v==separator then
+ done=true
+ elseif done then
+ after[#after+1]=v
+ else
+ before[#before+1]=v
end
- return before,after
+ end
+ return before,after
end
function environment.reconstructcommandline(arg,noquote)
- local resolveprefix=resolvers.resolve
- arg=arg or environment.originalarguments
- if noquote and #arg==1 then
- return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
- elseif #arg>0 then
- local result={}
- for i=1,#arg do
- result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
- end
- return concat(result," ")
- else
- return ""
+ local resolveprefix=resolvers.resolve
+ arg=arg or environment.originalarguments
+ if noquote and #arg==1 then
+ return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
+ elseif #arg>0 then
+ local result={}
+ for i=1,#arg do
+ result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
end
+ return concat(result," ")
+ else
+ return ""
+ end
end
function environment.relativepath(path,root)
- if not path then
- path=""
+ if not path then
+ path=""
+ end
+ if not file.is_rootbased_path(path) then
+ if not root then
+ root=file.pathpart(environment.ownscript or environment.ownname or ".")
end
- if not file.is_rootbased_path(path) then
- if not root then
- root=file.pathpart(environment.ownscript or environment.ownname or ".")
- end
- if root=="" then
- root="."
- end
- path=root.."/"..path
+ if root=="" then
+ root="."
end
- return file.collapsepath(path,true)
+ path=root.."/"..path
+ end
+ return file.collapsepath(path,true)
end
if arg then
- local newarg,instring={},false
- for index=1,#arg do
- local argument=arg[index]
- if find(argument,"^\"") then
- if find(argument,"\"$") then
- newarg[#newarg+1]=gsub(argument,"^\"(.-)\"$","%1")
- instring=false
- else
- newarg[#newarg+1]=gsub(argument,"^\"","")
- instring=true
- end
- elseif find(argument,"\"$") then
- if instring then
- newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
- instring=false
- else
- newarg[#newarg+1]=argument
- end
- elseif instring then
- newarg[#newarg]=newarg[#newarg].." "..argument
- else
- newarg[#newarg+1]=argument
- end
- end
- for i=1,-5,-1 do
- newarg[i]=arg[i]
+ local newarg,instring={},false
+ for index=1,#arg do
+ local argument=arg[index]
+ if find(argument,"^\"") then
+ if find(argument,"\"$") then
+ newarg[#newarg+1]=gsub(argument,"^\"(.-)\"$","%1")
+ instring=false
+ else
+ newarg[#newarg+1]=gsub(argument,"^\"","")
+ instring=true
+ end
+ elseif find(argument,"\"$") then
+ if instring then
+ newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
+ instring=false
+ else
+ newarg[#newarg+1]=argument
+ end
+ elseif instring then
+ newarg[#newarg]=newarg[#newarg].." "..argument
+ else
+ newarg[#newarg+1]=argument
end
- environment.initializearguments(newarg)
- environment.originalarguments=mark(newarg)
- environment.rawarguments=mark(arg)
- arg={}
+ end
+ for i=1,-5,-1 do
+ newarg[i]=arg[i]
+ end
+ environment.initializearguments(newarg)
+ environment.originalarguments=mark(newarg)
+ environment.rawarguments=mark(arg)
+ arg={}
end
@@ -15301,18 +15309,18 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-env"] = package.loaded["luat-env"] or true
--- original size: 6134, stripped down to: 4402
+-- original size: 6134, stripped down to: 4118
if not modules then modules={} end modules ['luat-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local rawset,rawget,loadfile=rawset,rawget,loadfile
local gsub=string.gsub
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_lua=logs.reporter("resolvers","lua")
local luautilities=utilities.lua
local luasuffixes=luautilities.suffixes
@@ -15320,145 +15328,145 @@ local texgettoks=tex and tex.gettoks
environment=environment or {}
local environment=environment
local mt={
- __index=function(_,k)
- if k=="version" then
- local version=texgettoks and texgettoks("contextversiontoks")
- if version and version~="" then
- rawset(environment,"version",version)
- return version
- else
- return "unknown"
- end
- elseif k=="kind" then
- local kind=texgettoks and texgettoks("contextkindtoks")
- if kind and kind~="" then
- rawset(environment,"kind",kind)
- return kind
- else
- return "unknown"
- end
- elseif k=="jobname" or k=="formatname" then
- local name=tex and tex[k]
- if name or name=="" then
- rawset(environment,k,name)
- return name
- else
- return "unknown"
- end
- elseif k=="outputfilename" then
- local name=environment.jobname
- rawset(environment,k,name)
- return name
- end
+ __index=function(_,k)
+ if k=="version" then
+ local version=texgettoks and texgettoks("contextversiontoks")
+ if version and version~="" then
+ rawset(environment,"version",version)
+ return version
+ else
+ return "unknown"
+ end
+ elseif k=="kind" then
+ local kind=texgettoks and texgettoks("contextkindtoks")
+ if kind and kind~="" then
+ rawset(environment,"kind",kind)
+ return kind
+ else
+ return "unknown"
+ end
+ elseif k=="jobname" or k=="formatname" then
+ local name=tex and tex[k]
+ if name or name=="" then
+ rawset(environment,k,name)
+ return name
+ else
+ return "unknown"
+ end
+ elseif k=="outputfilename" then
+ local name=environment.jobname
+ rawset(environment,k,name)
+ return name
end
+ end
}
setmetatable(environment,mt)
function environment.texfile(filename)
- return resolvers.findfile(filename,'tex')
+ return resolvers.findfile(filename,'tex')
end
function environment.luafile(filename)
- local resolved=resolvers.findfile(filename,'tex') or ""
- if resolved~="" then
- return resolved
- end
- resolved=resolvers.findfile(filename,'texmfscripts') or ""
- if resolved~="" then
- return resolved
- end
- return resolvers.findfile(filename,'luatexlibs') or ""
-end
-local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
+ local resolved=resolvers.findfile(filename,'tex') or ""
+ if resolved~="" then
+ return resolved
+ end
+ resolved=resolvers.findfile(filename,'texmfscripts') or ""
+ if resolved~="" then
+ return resolved
+ end
+ return resolvers.findfile(filename,'luatexlibs') or ""
+end
+local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
local function strippable(filename)
- if stripindeed then
- local modu=modules[file.nameonly(filename)]
- return modu and modu.dataonly
- else
- return false
- end
+ if stripindeed then
+ local modu=modules[file.nameonly(filename)]
+ return modu and modu.dataonly
+ else
+ return false
+ end
end
function environment.luafilechunk(filename,silent,macros)
- filename=file.replacesuffix(filename,"lua")
- local fullname=environment.luafile(filename)
- if fullname and fullname~="" then
- local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
- if not silent then
- report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
- end
- return data
- else
- if not silent then
- report_lua("unknown file %a",filename)
- end
- return nil
+ filename=file.replacesuffix(filename,"lua")
+ local fullname=environment.luafile(filename)
+ if fullname and fullname~="" then
+ local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
+ if not silent then
+ report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
+ end
+ return data
+ else
+ if not silent then
+ report_lua("unknown file %a",filename)
end
+ return nil
+ end
end
function environment.loadluafile(filename,version)
- local lucname,luaname,chunk
- local basename=file.removesuffix(filename)
- if basename==filename then
- luaname=file.addsuffix(basename,luasuffixes.lua)
- lucname=file.addsuffix(basename,luasuffixes.luc)
- else
- luaname=filename
- lucname=nil
- end
- local fullname=(lucname and environment.luafile(lucname)) or ""
- if fullname~="" then
+ local lucname,luaname,chunk
+ local basename=file.removesuffix(filename)
+ if basename==filename then
+ luaname=file.addsuffix(basename,luasuffixes.lua)
+ lucname=file.addsuffix(basename,luasuffixes.luc)
+ else
+ luaname=filename
+ lucname=nil
+ end
+ local fullname=(lucname and environment.luafile(lucname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
+ end
+ chunk=loadfile(fullname)
+ end
+ if chunk then
+ chunk()
+ if version then
+ local v=version
+ if modules and modules[filename] then
+ v=modules[filename].version
+ elseif versions and versions[filename] then
+ v=versions[filename]
+ end
+ if v==version then
+ return true
+ else
if trace_locating then
- report_lua("loading %a",fullname)
+ report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
end
- chunk=loadfile(fullname)
+ environment.loadluafile(filename)
+ end
+ else
+ return true
end
- if chunk then
- chunk()
- if version then
- local v=version
- if modules and modules[filename] then
- v=modules[filename].version
- elseif versions and versions[filename] then
- v=versions[filename]
- end
- if v==version then
- return true
- else
- if trace_locating then
- report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
- end
- environment.loadluafile(filename)
- end
- else
- return true
- end
+ end
+ fullname=(luaname and environment.luafile(luaname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
end
- fullname=(luaname and environment.luafile(luaname)) or ""
- if fullname~="" then
- if trace_locating then
- report_lua("loading %a",fullname)
- end
- chunk=loadfile(fullname)
- if not chunk then
- if trace_locating then
- report_lua("unknown file %a",filename)
- end
- else
- chunk()
- return true
- end
+ chunk=loadfile(fullname)
+ if not chunk then
+ if trace_locating then
+ report_lua("unknown file %a",filename)
+ end
+ else
+ chunk()
+ return true
end
- return false
+ end
+ return false
end
environment.filenames=setmetatable({},{
- __index=function(t,k)
- local v=environment.files[k]
- if v then
- return (gsub(v,"%.+$",""))
- end
- end,
- __newindex=function(t,k)
- end,
- __len=function(t)
- return #environment.files
- end,
+ __index=function(t,k)
+ local v=environment.files[k]
+ if v then
+ return (gsub(v,"%.+$",""))
+ end
+ end,
+ __newindex=function(t,k)
+ end,
+ __len=function(t)
+ return #environment.files
+ end,
} )
@@ -15468,16 +15476,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true
--- original size: 60383, stripped down to: 38562
+-- original size: 60383, stripped down to: 35698
if not modules then modules={} end modules ['lxml-tab']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
+local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end
if lpeg.setmaxstack then lpeg.setmaxstack(1000) end
xml=xml or {}
@@ -15495,17 +15503,17 @@ xml.xmlns=xml.xmlns or {}
local check=P(false)
local parse=check
function xml.registerns(namespace,pattern)
- check=check+C(P(lower(pattern)))/namespace
- parse=P { P(check)+1*V(1) }
+ check=check+C(P(lower(pattern)))/namespace
+ parse=P { P(check)+1*V(1) }
end
function xml.checkns(namespace,url)
- local ns=lpegmatch(parse,lower(url))
- if ns and namespace~=ns then
- xml.xmlns[namespace]=ns
- end
+ local ns=lpegmatch(parse,lower(url))
+ if ns and namespace~=ns then
+ xml.xmlns[namespace]=ns
+ end
end
function xml.resolvens(url)
- return lpegmatch(parse,lower(url)) or ""
+ return lpegmatch(parse,lower(url)) or ""
end
end
local nsremap,resolvens=xml.xmlns,xml.resolvens
@@ -15523,661 +15531,661 @@ local handle_dec_entity
local handle_any_entity_dtd
local handle_any_entity_text
local function preparexmlstate(settings)
- if settings then
- linenumbers=settings.linenumbers
- stack={}
- level=0
- top={}
- at={}
- mt={}
- dt={}
- nt=0
- xmlns={}
- errorstr=nil
- strip=settings.strip_cm_and_dt
- utfize=settings.utfize_entities
- resolve=settings.resolve_entities
- resolve_predefined=settings.resolve_predefined_entities
- unify_predefined=settings.unify_predefined_entities
- cleanup=settings.text_cleanup
- entities=settings.entities or {}
- currentfilename=settings.currentresource
- currentline=1
- parameters={}
- reported_at_errors={}
- dcache={}
- hcache={}
- acache={}
- if utfize==nil then
- settings.utfize_entities=true
- utfize=true
- end
- if resolve_predefined==nil then
- settings.resolve_predefined_entities=true
- resolve_predefined=true
- end
- else
- linenumbers=false
- stack=nil
- level=nil
- top=nil
- at=nil
- mt=nil
- dt=nil
- nt=nil
- xmlns=nil
- errorstr=nil
- strip=nil
- utfize=nil
- resolve=nil
- resolve_predefined=nil
- unify_predefined=nil
- cleanup=nil
- entities=nil
- parameters=nil
- reported_at_errors=nil
- dcache=nil
- hcache=nil
- acache=nil
- currentfilename=nil
- currentline=1
- end
+ if settings then
+ linenumbers=settings.linenumbers
+ stack={}
+ level=0
+ top={}
+ at={}
+ mt={}
+ dt={}
+ nt=0
+ xmlns={}
+ errorstr=nil
+ strip=settings.strip_cm_and_dt
+ utfize=settings.utfize_entities
+ resolve=settings.resolve_entities
+ resolve_predefined=settings.resolve_predefined_entities
+ unify_predefined=settings.unify_predefined_entities
+ cleanup=settings.text_cleanup
+ entities=settings.entities or {}
+ currentfilename=settings.currentresource
+ currentline=1
+ parameters={}
+ reported_at_errors={}
+ dcache={}
+ hcache={}
+ acache={}
+ if utfize==nil then
+ settings.utfize_entities=true
+ utfize=true
+ end
+ if resolve_predefined==nil then
+ settings.resolve_predefined_entities=true
+ resolve_predefined=true
+ end
+ else
+ linenumbers=false
+ stack=nil
+ level=nil
+ top=nil
+ at=nil
+ mt=nil
+ dt=nil
+ nt=nil
+ xmlns=nil
+ errorstr=nil
+ strip=nil
+ utfize=nil
+ resolve=nil
+ resolve_predefined=nil
+ unify_predefined=nil
+ cleanup=nil
+ entities=nil
+ parameters=nil
+ reported_at_errors=nil
+ dcache=nil
+ hcache=nil
+ acache=nil
+ currentfilename=nil
+ currentline=1
+ end
end
local function initialize_mt(root)
- mt={ __index=root }
+ mt={ __index=root }
end
function xml.setproperty(root,k,v)
- getmetatable(root).__index[k]=v
+ getmetatable(root).__index[k]=v
end
function xml.checkerror(top,toclose)
- return ""
+ return ""
end
local checkns=xml.checkns
local function add_attribute(namespace,tag,value)
- if cleanup and value~="" then
- value=cleanup(value)
- end
- if tag=="xmlns" then
- xmlns[#xmlns+1]=resolvens(value)
- at[tag]=value
- elseif namespace=="" then
- at[tag]=value
- elseif namespace=="xmlns" then
- checkns(tag,value)
- at["xmlns:"..tag]=value
- else
- at[namespace..":"..tag]=value
- end
+ if cleanup and value~="" then
+ value=cleanup(value)
+ end
+ if tag=="xmlns" then
+ xmlns[#xmlns+1]=resolvens(value)
+ at[tag]=value
+ elseif namespace=="" then
+ at[tag]=value
+ elseif namespace=="xmlns" then
+ checkns(tag,value)
+ at["xmlns:"..tag]=value
+ else
+ at[namespace..":"..tag]=value
+ end
end
local function add_empty(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- top=stack[level]
- dt=top.dt
- nt=#dt+1
- local t=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- cf=currentfilename,
- cl=currentline,
- __p__=top,
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- __p__=top,
- }
- dt[nt]=t
- setmetatable(t,mt)
- if at.xmlns then
- remove(xmlns)
- end
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ top=stack[level]
+ dt=top.dt
+ nt=#dt+1
+ local t=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=top,
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ __p__=top,
+ }
+ dt[nt]=t
+ setmetatable(t,mt)
+ if at.xmlns then
+ remove(xmlns)
+ end
+ at={}
end
local function add_begin(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- dt={}
- top=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- cf=currentfilename,
- cl=currentline,
- __p__=stack[level],
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- __p__=stack[level],
- }
- setmetatable(top,mt)
- nt=0
- level=level+1
- stack[level]=top
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ dt={}
+ top=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=stack[level],
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ __p__=stack[level],
+ }
+ setmetatable(top,mt)
+ nt=0
+ level=level+1
+ stack[level]=top
+ at={}
end
local function add_end(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local toclose=stack[level]
- level=level-1
- top=stack[level]
- if level<1 then
- errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- elseif toclose.tg~=tag then
- errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- end
- dt=top.dt
- nt=#dt+1
- dt[nt]=toclose
- toclose.ni=nt
- if toclose.at.xmlns then
- remove(xmlns)
- end
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local toclose=stack[level]
+ level=level-1
+ top=stack[level]
+ if level<1 then
+ errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ elseif toclose.tg~=tag then
+ errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ end
+ dt=top.dt
+ nt=#dt+1
+ dt[nt]=toclose
+ toclose.ni=nt
+ if toclose.at.xmlns then
+ remove(xmlns)
+ end
end
local function add_text(text)
- if text=="" then
- return
- end
- if cleanup then
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..cleanup(text)
- else
- nt=nt+1
- dt[nt]=cleanup(text)
- end
- else
- nt=1
- dt[1]=cleanup(text)
- end
+ if text=="" then
+ return
+ end
+ if cleanup then
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..cleanup(text)
+ else
+ nt=nt+1
+ dt[nt]=cleanup(text)
+ end
else
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..text
- else
- nt=nt+1
- dt[nt]=text
- end
- else
- nt=1
- dt[1]=text
- end
+ nt=1
+ dt[1]=cleanup(text)
end
-end
-local function add_special(what,spacing,text)
- if spacing~="" then
+ else
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..text
+ else
nt=nt+1
- dt[nt]=spacing
- end
- if strip and (what=="@cm@" or what=="@dt@") then
+ dt[nt]=text
+ end
else
- nt=nt+1
- dt[nt]=linenumbers and {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- cf=currentfilename,
- cl=currentline,
- } or {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- }
+ nt=1
+ dt[1]=text
end
+ end
+end
+local function add_special(what,spacing,text)
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ if strip and (what=="@cm@" or what=="@dt@") then
+ else
+ nt=nt+1
+ dt[nt]=linenumbers and {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ cf=currentfilename,
+ cl=currentline,
+ } or {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ }
+ end
end
local function set_message(txt)
- errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
+ errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
end
local function attribute_value_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute value %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute value %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
local function attribute_specification_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute specification %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute specification %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
do
- local badentity="&"
- xml.placeholders={
- unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
- unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
- unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
- }
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return utfchar(n)
- else
- return formatters["h:%s"](s),true
+ local badentity="&"
+ xml.placeholders={
+ unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
+ unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
+ unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
+ }
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local p_rest=(1-P(";"))^0
+ local p_many=P(1)^0
+ local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
+ xml.parsedentitylpeg=parsedentity
+ local predefined_unified={
+ [38]="&amp;",
+ [42]="&quot;",
+ [47]="&apos;",
+ [74]="&lt;",
+ [76]="&gt;",
+ }
+ local predefined_simplified={
+ [38]="&",amp="&",
+ [42]='"',quot='"',
+ [47]="'",apos="'",
+ [74]="<",lt="<",
+ [76]=">",gt=">",
+ }
+ local nofprivates=0xF0000
+ local privates_u={
+ [ [[&]] ]="&amp;",
+ [ [["]] ]="&quot;",
+ [ [[']] ]="&apos;",
+ [ [[<]] ]="&lt;",
+ [ [[>]] ]="&gt;",
+ }
+ local privates_p={
+ }
+ local privates_s={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[&]] ]="&U+26;",
+ [ [[']] ]="&U+27;",
+ [ [[<]] ]="&U+3C;",
+ [ [[>]] ]="&U+3E;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_x={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[']] ]="&U+27;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_n={
+ }
+ local escaped=utf.remapper(privates_u,"dynamic")
+ local unprivatized=utf.remapper(privates_p,"dynamic")
+ local unspecialized=utf.remapper(privates_s,"dynamic")
+ local despecialized=utf.remapper(privates_x,"dynamic")
+ xml.unprivatized=unprivatized
+ xml.unspecialized=unspecialized
+ xml.despecialized=despecialized
+ xml.escaped=escaped
+ local function unescaped(s)
+ local p=privates_n[s]
+ if not p then
+ nofprivates=nofprivates+1
+ p=utfchar(nofprivates)
+ privates_n[s]=p
+ s="&"..s..";"
+ privates_u[p]=s
+ privates_p[p]=s
+ privates_s[p]=s
+ end
+ return p
+ end
+ xml.privatetoken=unescaped
+ xml.privatecodes=privates_n
+ xml.specialcodes=privates_s
+ function xml.addspecialcode(key,value)
+ privates_s[key]=value or "&"..s..";"
+ end
+ handle_hex_entity=function(str)
+ local h=hcache[str]
+ if not h then
+ local n=tonumber(str,16)
+ h=unify_predefined and predefined_unified[n]
+ if h then
+ if trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+ end
+ elseif utfize then
+ h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring hex entity &#x%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
end
+ else
+ if trace_entities then
+ report_xml("found entity &#x%s;",str)
+ end
+ h="&#x"..str..";"
+ end
+ hcache[str]=h
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return utfchar(n)
- else
- return formatters["d:%s"](s),true
- end
- end
- local p_rest=(1-P(";"))^0
- local p_many=P(1)^0
- local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
- xml.parsedentitylpeg=parsedentity
- local predefined_unified={
- [38]="&amp;",
- [42]="&quot;",
- [47]="&apos;",
- [74]="&lt;",
- [76]="&gt;",
- }
- local predefined_simplified={
- [38]="&",amp="&",
- [42]='"',quot='"',
- [47]="'",apos="'",
- [74]="<",lt="<",
- [76]=">",gt=">",
- }
- local nofprivates=0xF0000
- local privates_u={
- [ [[&]] ]="&amp;",
- [ [["]] ]="&quot;",
- [ [[']] ]="&apos;",
- [ [[<]] ]="&lt;",
- [ [[>]] ]="&gt;",
- }
- local privates_p={
- }
- local privates_s={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[&]] ]="&U+26;",
- [ [[']] ]="&U+27;",
- [ [[<]] ]="&U+3C;",
- [ [[>]] ]="&U+3E;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_x={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[']] ]="&U+27;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_n={
- }
- local escaped=utf.remapper(privates_u,"dynamic")
- local unprivatized=utf.remapper(privates_p,"dynamic")
- local unspecialized=utf.remapper(privates_s,"dynamic")
- local despecialized=utf.remapper(privates_x,"dynamic")
- xml.unprivatized=unprivatized
- xml.unspecialized=unspecialized
- xml.despecialized=despecialized
- xml.escaped=escaped
- local function unescaped(s)
- local p=privates_n[s]
- if not p then
- nofprivates=nofprivates+1
- p=utfchar(nofprivates)
- privates_n[s]=p
- s="&"..s..";"
- privates_u[p]=s
- privates_p[p]=s
- privates_s[p]=s
- end
- return p
- end
- xml.privatetoken=unescaped
- xml.privatecodes=privates_n
- xml.specialcodes=privates_s
- function xml.addspecialcode(key,value)
- privates_s[key]=value or "&"..s..";"
- end
- handle_hex_entity=function(str)
- local h=hcache[str]
- if not h then
- local n=tonumber(str,16)
- h=unify_predefined and predefined_unified[n]
- if h then
- if trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- elseif utfize then
- h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring hex entity &#x%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- else
- if trace_entities then
- report_xml("found entity &#x%s;",str)
- end
- h="&#x"..str..";"
- end
- hcache[str]=h
- end
- return h
- end
- handle_dec_entity=function(str)
- local d=dcache[str]
- if not d then
- local n=tonumber(str)
- d=unify_predefined and predefined_unified[n]
- if d then
- if trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- elseif utfize then
- d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring dec entity &#%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- else
- if trace_entities then
- report_xml("found entity &#%s;",str)
- end
- d="&#"..str..";"
- end
- dcache[str]=d
+ return h
+ end
+ handle_dec_entity=function(str)
+ local d=dcache[str]
+ if not d then
+ local n=tonumber(str)
+ d=unify_predefined and predefined_unified[n]
+ if d then
+ if trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ elseif utfize then
+ d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring dec entity &#%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ else
+ if trace_entities then
+ report_xml("found entity &#%s;",str)
end
- return d
+ d="&#"..str..";"
+ end
+ dcache[str]=d
end
- handle_any_entity_dtd=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
- end
- return a
+ return d
+ end
+ handle_any_entity_dtd=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
- end
- return a
+ a=entities[str]
end
- end
- handle_any_entity_text=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(grammar_parsed_text_two,a) or a
- if type(a)=="number" then
- return ""
- else
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- end
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
end
- return a
+ a=a(str) or ""
+ end
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
end
- return a
- end
- end
- local p_rest=(1-P(";"))^1
- local spec={
- [0x23]="\\Ux{23}",
- [0x24]="\\Ux{24}",
- [0x25]="\\Ux{25}",
- [0x5C]="\\Ux{5C}",
- [0x7B]="\\Ux{7B}",
- [0x7C]="\\Ux{7C}",
- [0x7D]="\\Ux{7D}",
- [0x7E]="\\Ux{7E}",
- }
- local hash=table.setmetatableindex(spec,function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
- else
- return formatters["u:%s"](s),true
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
- end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
+ end
+ return a
+ end
+ end
+ handle_any_entity_text=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- return formatters["d:%s"](s),true
+ a=entities[str]
end
- end
- local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- local hash=table.setmetatableindex(function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
+ end
+ a=a(str) or ""
+ end
+ a=lpegmatch(grammar_parsed_text_two,a) or a
+ if type(a)=="number" then
+ return ""
+ else
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
+ end
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- return formatters["u:%s"](s),true
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
+ end
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
+ end
+ return a
+ end
+ end
+ local p_rest=(1-P(";"))^1
+ local spec={
+ [0x23]="\\Ux{23}",
+ [0x24]="\\Ux{24}",
+ [0x25]="\\Ux{25}",
+ [0x5C]="\\Ux{5C}",
+ [0x7B]="\\Ux{7B}",
+ [0x7C]="\\Ux{7C}",
+ [0x7D]="\\Ux{7D}",
+ [0x7E]="\\Ux{7E}",
+ }
+ local hash=table.setmetatableindex(spec,function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
- else
- return formatters["d:%s"](s),true
- end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ local hash=table.setmetatableindex(function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
+ end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
end
- local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- xml.reparsedentitylpeg=reparsedentity
- xml.unescapedentitylpeg=unescapedentity
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ xml.reparsedentitylpeg=reparsedentity
+ xml.unescapedentitylpeg=unescapedentity
end
local escaped=xml.escaped
local unescaped=xml.unescaped
local placeholders=xml.placeholders
local function handle_end_entity(str)
- report_xml("error in entity, %a found without ending %a",str,";")
- return str
+ report_xml("error in entity, %a found without ending %a",str,";")
+ return str
end
local function handle_crap_error(chr)
- report_xml("error in parsing, unexpected %a found ",chr)
- add_text(chr)
- return chr
+ report_xml("error in parsing, unexpected %a found ",chr)
+ add_text(chr)
+ return chr
end
local function handlenewline()
- currentline=currentline+1
+ currentline=currentline+1
end
local spacetab=S(' \t')
local space=S(' \r\n\t')
@@ -16202,141 +16210,141 @@ local space_nl=spacetab+newline
local spacing_nl=Cs((space_nl)^0)
local anything_nl=newline+P(1)
local function weirdentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","weird",k,v)
- end
- parameters[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","weird",k,v)
+ end
+ parameters[k]=v
end
local function normalentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","normal",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","normal",k,v)
+ end
+ entities[k]=v
end
local function systementity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","system",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","system",k,v)
+ end
+ entities[k]=v
end
local function publicentity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","public",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","public",k,v)
+ end
+ entities[k]=v
end
local function entityfile(pattern,k,v,n)
- if n then
- local okay,data
- if resolvers then
- okay,data=resolvers.loadbinfile(n)
- else
- data=io.loaddata(n)
- okay=data and data~=""
- end
- if okay then
- if trace_entities then
- report_xml("loading public entities %a as %a from %a",k,v,n)
- end
- lpegmatch(pattern,data)
- return
- end
+ if n then
+ local okay,data
+ if resolvers then
+ okay,data=resolvers.loadbinfile(n)
+ else
+ data=io.loaddata(n)
+ okay=data and data~=""
end
- report_xml("ignoring public entities %a as %a from %a",k,v,n)
+ if okay then
+ if trace_entities then
+ report_xml("loading public entities %a as %a from %a",k,v,n)
+ end
+ lpegmatch(pattern,data)
+ return
+ end
+ end
+ report_xml("ignoring public entities %a as %a from %a",k,v,n)
end
local function install(spacenewline,spacing,anything)
- local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
- local hexentitycontent=R("AF","af","09")^1
- local decentitycontent=R("09")^1
- local parsedentity=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_dtd)
- local parsedentity_text=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_text)
- local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local text_unparsed=Cs((anything-open)^1)
- local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
- local somespace=(spacenewline)^1
- local optionalspace=(spacenewline)^0
- local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
- local endofattributes=slash*close+close
- local whatever=space*name*optionalspace*equal
- local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
- local attributevalue=value+wrongvalue
- local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
- local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
- local parsedtext=text_parsed
- local unparsedtext=text_unparsed/add_text
- local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
- local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
- local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
- local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
- local begincomment=open*P("!--")
- local endcomment=P("--")*close
- local begininstruction=open*P("?")
- local endinstruction=P("?")*close
- local begincdata=open*P("![CDATA[")
- local endcdata=P("]]")*close
- local someinstruction=C((anything-endinstruction)^0)
- local somecomment=C((anything-endcomment )^0)
- local somecdata=C((anything-endcdata )^0)
- local begindoctype=open*P("!DOCTYPE")
- local enddoctype=close
- local beginset=P("[")
- local endset=P("]")
- local wrdtypename=C((anything-somespace-P(";"))^1)
- local doctypename=C((anything-somespace-close)^0)
- local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
- local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
- local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
- local normalentitytype=(doctypename*somespace*value)/normalentity
- local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
- local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
- local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
- local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
- entityfile(entitydoctype,...)
- end
- local function weirdresolve(s)
- lpegmatch(entitydoctype,parameters[s])
- end
- local function normalresolve(s)
- lpegmatch(entitydoctype,entities[s])
- end
- local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
- entitydoctype=entitydoctype+entityresolve
- local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
- local definitiondoctype=doctypename*somespace*doctypeset
- local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
- local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
- local simpledoctype=(anything-close)^1
- local somedoctype=C((somespace*(
+ local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
+ local hexentitycontent=R("AF","af","09")^1
+ local decentitycontent=R("09")^1
+ local parsedentity=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_dtd)
+ local parsedentity_text=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_text)
+ local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local text_unparsed=Cs((anything-open)^1)
+ local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
+ local somespace=(spacenewline)^1
+ local optionalspace=(spacenewline)^0
+ local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
+ local endofattributes=slash*close+close
+ local whatever=space*name*optionalspace*equal
+ local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
+ local attributevalue=value+wrongvalue
+ local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
+ local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
+ local parsedtext=text_parsed
+ local unparsedtext=text_unparsed/add_text
+ local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
+ local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
+ local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
+ local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
+ local begincomment=open*P("!--")
+ local endcomment=P("--")*close
+ local begininstruction=open*P("?")
+ local endinstruction=P("?")*close
+ local begincdata=open*P("![CDATA[")
+ local endcdata=P("]]")*close
+ local someinstruction=C((anything-endinstruction)^0)
+ local somecomment=C((anything-endcomment )^0)
+ local somecdata=C((anything-endcdata )^0)
+ local begindoctype=open*P("!DOCTYPE")
+ local enddoctype=close
+ local beginset=P("[")
+ local endset=P("]")
+ local wrdtypename=C((anything-somespace-P(";"))^1)
+ local doctypename=C((anything-somespace-close)^0)
+ local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
+ local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
+ local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
+ local normalentitytype=(doctypename*somespace*value)/normalentity
+ local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
+ local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
+ local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
+ local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
+ entityfile(entitydoctype,...)
+ end
+ local function weirdresolve(s)
+ lpegmatch(entitydoctype,parameters[s])
+ end
+ local function normalresolve(s)
+ lpegmatch(entitydoctype,entities[s])
+ end
+ local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
+ entitydoctype=entitydoctype+entityresolve
+ local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
+ local definitiondoctype=doctypename*somespace*doctypeset
+ local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
+ local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
+ local simpledoctype=(anything-close)^1
+ local somedoctype=C((somespace*(
publicentityfile+publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0)
- local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
- local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
- local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
- local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
- local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
- local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
- local trailer=space^0*(text_unparsed/set_message)^0
- local grammar_parsed_text_one=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
- }
- local grammar_parsed_text_two=P { "followup",
- followup=V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
- }
- local grammar_unparsed_text=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
- }
- return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
+ local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
+ local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
+ local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
+ local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
+ local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
+ local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
+ local trailer=space^0*(text_unparsed/set_message)^0
+ local grammar_parsed_text_one=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
+ }
+ local grammar_parsed_text_two=P { "followup",
+ followup=V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
+ }
+ local grammar_unparsed_text=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
+ }
+ return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
end
grammar_parsed_text_one_nop,
grammar_parsed_text_two_nop,
@@ -16345,576 +16353,576 @@ grammar_parsed_text_one_yes,
grammar_parsed_text_two_yes,
grammar_unparsed_text_yes=install(space_nl,spacing_nl,anything_nl)
local function _xmlconvert_(data,settings,detail)
- settings=settings or {}
- preparexmlstate(settings)
- if settings.linenumbers then
- grammar_parsed_text_one=grammar_parsed_text_one_yes
- grammar_parsed_text_two=grammar_parsed_text_two_yes
- grammar_unparsed_text=grammar_unparsed_text_yes
- else
- grammar_parsed_text_one=grammar_parsed_text_one_nop
- grammar_parsed_text_two=grammar_parsed_text_two_nop
- grammar_unparsed_text=grammar_unparsed_text_nop
- end
- local preprocessor=settings.preprocessor
- if data and data~="" and type(preprocessor)=="function" then
- data=preprocessor(data,settings) or data
+ settings=settings or {}
+ preparexmlstate(settings)
+ if settings.linenumbers then
+ grammar_parsed_text_one=grammar_parsed_text_one_yes
+ grammar_parsed_text_two=grammar_parsed_text_two_yes
+ grammar_unparsed_text=grammar_unparsed_text_yes
+ else
+ grammar_parsed_text_one=grammar_parsed_text_one_nop
+ grammar_parsed_text_two=grammar_parsed_text_two_nop
+ grammar_unparsed_text=grammar_unparsed_text_nop
+ end
+ local preprocessor=settings.preprocessor
+ if data and data~="" and type(preprocessor)=="function" then
+ data=preprocessor(data,settings) or data
+ end
+ if settings.parent_root then
+ mt=getmetatable(settings.parent_root)
+ else
+ initialize_mt(top)
+ end
+ level=level+1
+ stack[level]=top
+ top.dt={}
+ dt=top.dt
+ nt=0
+ if not data or data=="" then
+ errorstr="empty xml file"
+ elseif data==true then
+ errorstr=detail or "problematic xml file"
+ elseif utfize or resolve then
+ local m=lpegmatch(grammar_parsed_text_one,data)
+ if m then
+ m=lpegmatch(grammar_parsed_text_two,data,m)
end
- if settings.parent_root then
- mt=getmetatable(settings.parent_root)
- else
- initialize_mt(top)
- end
- level=level+1
- stack[level]=top
- top.dt={}
- dt=top.dt
- nt=0
- if not data or data=="" then
- errorstr="empty xml file"
- elseif data==true then
- errorstr=detail or "problematic xml file"
- elseif utfize or resolve then
- local m=lpegmatch(grammar_parsed_text_one,data)
- if m then
- m=lpegmatch(grammar_parsed_text_two,data,m)
- end
- if m then
- else
- errorstr="invalid xml file - parsed text"
- end
- elseif type(data)=="string" then
- if lpegmatch(grammar_unparsed_text,data) then
- errorstr=""
- else
- errorstr="invalid xml file - unparsed text"
- end
+ if m then
else
- errorstr="invalid xml file - no text at all"
- end
- local result
- if errorstr and errorstr~="" then
- result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
- setmetatable(result,mt)
- setmetatable(result.dt[1],mt)
- setmetatable(stack,mt)
- local errorhandler=settings.error_handler
- if errorhandler==false then
+ errorstr="invalid xml file - parsed text"
+ end
+ elseif type(data)=="string" then
+ if lpegmatch(grammar_unparsed_text,data) then
+ errorstr=""
+ else
+ errorstr="invalid xml file - unparsed text"
+ end
+ else
+ errorstr="invalid xml file - no text at all"
+ end
+ local result
+ if errorstr and errorstr~="" then
+ result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
+ setmetatable(result,mt)
+ setmetatable(result.dt[1],mt)
+ setmetatable(stack,mt)
+ local errorhandler=settings.error_handler
+ if errorhandler==false then
+ else
+ errorhandler=errorhandler or xml.errorhandler
+ if errorhandler then
+ local currentresource=settings.currentresource
+ if currentresource and currentresource~="" then
+ xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
else
- errorhandler=errorhandler or xml.errorhandler
- if errorhandler then
- local currentresource=settings.currentresource
- if currentresource and currentresource~="" then
- xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
- else
- xml.errorhandler(formatters["load error: %s"](errorstr))
- end
- end
- end
- else
- result=stack[1]
- end
- if not settings.no_root then
- result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
- setmetatable(result,mt)
- local rdt=result.dt
- for k=1,#rdt do
- local v=rdt[k]
- if type(v)=="table" and not v.special then
- result.ri=k
- v.__p__=result
- break
- end
+ xml.errorhandler(formatters["load error: %s"](errorstr))
end
+ end
end
- if errorstr and errorstr~="" then
- result.error=true
- else
- errorstr=nil
- end
- result.statistics={
- errormessage=errorstr,
- entities={
- decimals=dcache,
- hexadecimals=hcache,
- names=acache,
- intermediates=parameters,
- }
+ else
+ result=stack[1]
+ end
+ if not settings.no_root then
+ result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
+ setmetatable(result,mt)
+ local rdt=result.dt
+ for k=1,#rdt do
+ local v=rdt[k]
+ if type(v)=="table" and not v.special then
+ result.ri=k
+ v.__p__=result
+ break
+ end
+ end
+ end
+ if errorstr and errorstr~="" then
+ result.error=true
+ else
+ errorstr=nil
+ end
+ result.statistics={
+ errormessage=errorstr,
+ entities={
+ decimals=dcache,
+ hexadecimals=hcache,
+ names=acache,
+ intermediates=parameters,
}
- preparexmlstate()
- return result
+ }
+ preparexmlstate()
+ return result
end
local function xmlconvert(data,settings)
- local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
- if ok then
- return result
- elseif type(result)=="string" then
- return _xmlconvert_(true,settings,result)
- else
- return _xmlconvert_(true,settings)
- end
+ local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
+ if ok then
+ return result
+ elseif type(result)=="string" then
+ return _xmlconvert_(true,settings,result)
+ else
+ return _xmlconvert_(true,settings)
+ end
end
xml.convert=xmlconvert
function xml.inheritedconvert(data,xmldata)
- local settings=xmldata.settings
- if settings then
- settings.parent_root=xmldata
- end
- local xc=xmlconvert(data,settings)
- return xc
+ local settings=xmldata.settings
+ if settings then
+ settings.parent_root=xmldata
+ end
+ local xc=xmlconvert(data,settings)
+ return xc
end
function xml.is_valid(root)
- return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
+ return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
end
function xml.package(tag,attributes,data)
- local ns,tg=match(tag,"^(.-):?([^:]+)$")
- local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
- setmetatable(t,mt)
- return t
+ local ns,tg=match(tag,"^(.-):?([^:]+)$")
+ local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
+ setmetatable(t,mt)
+ return t
end
function xml.is_valid(root)
- return root and not root.error
+ return root and not root.error
end
xml.errorhandler=report_xml
function xml.load(filename,settings)
- local data=""
- if type(filename)=="string" then
- local f=io.open(filename,'r')
- if f then
- data=f:read("*all")
- f:close()
- end
- elseif filename then
- data=filename:read("*all")
- end
- if settings then
- settings.currentresource=filename
- local result=xmlconvert(data,settings)
- settings.currentresource=nil
- return result
- else
- return xmlconvert(data,{ currentresource=filename })
- end
+ local data=""
+ if type(filename)=="string" then
+ local f=io.open(filename,'r')
+ if f then
+ data=f:read("*all")
+ f:close()
+ end
+ elseif filename then
+ data=filename:read("*all")
+ end
+ if settings then
+ settings.currentresource=filename
+ local result=xmlconvert(data,settings)
+ settings.currentresource=nil
+ return result
+ else
+ return xmlconvert(data,{ currentresource=filename })
+ end
end
local no_root={ no_root=true }
function xml.toxml(data)
- if type(data)=="string" then
- local root={ xmlconvert(data,no_root) }
- return (#root>1 and root) or root[1]
- else
- return data
- end
+ if type(data)=="string" then
+ local root={ xmlconvert(data,no_root) }
+ return (#root>1 and root) or root[1]
+ else
+ return data
+ end
end
local function copy(old,p)
- if old then
- local new={}
- for k,v in next,old do
- local t=type(v)=="table"
- if k=="at" then
- local t={}
- for k,v in next,v do
- t[k]=v
- end
- new[k]=t
- elseif k=="dt" then
- v.__p__=nil
- v=copy(v,new)
- new[k]=v
- v.__p__=p
- else
- new[k]=v
- end
- end
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ local t=type(v)=="table"
+ if k=="at" then
+ local t={}
+ for k,v in next,v do
+ t[k]=v
+ end
+ new[k]=t
+ elseif k=="dt" then
+ v.__p__=nil
+ v=copy(v,new)
+ new[k]=v
+ v.__p__=p
+ else
+ new[k]=v
+ end
+ end
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
end
+ return new
+ else
+ return {}
+ end
end
xml.copy=copy
function xml.checkbom(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@" and find(v.dt[1],"xml.*version=") then
- return
- end
- end
- insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
- insert(dt,2,"\n" )
+ 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@" and find(v.dt[1],"xml.*version=") then
+ return
+ end
end
+ insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
+ insert(dt,2,"\n" )
+ end
end
local f_attribute=formatters['%s=%q']
local function verbose_element(e,handlers,escape)
- local handle=handlers.handle
- local serialize=handlers.serialize
- local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
- local ats=eat and next(eat) and {}
- if ats then
- local n=0
- for k in next,eat do
- n=n+1
- ats[n]=k
- end
- if n==1 then
- local k=ats[1]
- ats=f_attribute(k,escaped(eat[k]))
- else
- sort(ats)
- for i=1,n do
- local k=ats[i]
- ats[i]=f_attribute(k,escaped(eat[k]))
- end
- ats=concat(ats," ")
- end
- end
- if ern and trace_entities and ern~=ens then
- ens=ern
+ local handle=handlers.handle
+ local serialize=handlers.serialize
+ local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
+ local ats=eat and next(eat) and {}
+ if ats then
+ local n=0
+ for k in next,eat do
+ n=n+1
+ ats[n]=k
end
- local n=edt and #edt
- if ens~="" then
- if n and n>0 then
- if ats then
- handle("<",ens,":",etg," ",ats,">")
- else
- handle("<",ens,":",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",ens,":",etg,">")
+ if n==1 then
+ local k=ats[1]
+ ats=f_attribute(k,escaped(eat[k]))
+ else
+ sort(ats)
+ for i=1,n do
+ local k=ats[i]
+ ats[i]=f_attribute(k,escaped(eat[k]))
+ end
+ ats=concat(ats," ")
+ end
+ end
+ if ern and trace_entities and ern~=ens then
+ ens=ern
+ end
+ local n=edt and #edt
+ if ens~="" then
+ if n and n>0 then
+ if ats then
+ handle("<",ens,":",etg," ",ats,">")
+ else
+ handle("<",ens,":",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",ens,":",etg," ",ats,"/>")
- else
- handle("<",ens,":",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",ens,":",etg,">")
else
- if n and n>0 then
- if ats then
- handle("<",etg," ",ats,">")
- else
- handle("<",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",etg,">")
+ if ats then
+ handle("<",ens,":",etg," ",ats,"/>")
+ else
+ handle("<",ens,":",etg,"/>")
+ end
+ end
+ else
+ if n and n>0 then
+ if ats then
+ handle("<",etg," ",ats,">")
+ else
+ handle("<",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",etg," ",ats,"/>")
- else
- handle("<",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",etg,">")
+ else
+ if ats then
+ handle("<",etg," ",ats,"/>")
+ else
+ handle("<",etg,"/>")
+ end
end
+ end
end
local function verbose_pi(e,handlers)
- handlers.handle("<?",e.dt[1],"?>")
+ handlers.handle("<?",e.dt[1],"?>")
end
local function verbose_comment(e,handlers)
- handlers.handle("<!--",e.dt[1],"-->")
+ handlers.handle("<!--",e.dt[1],"-->")
end
local function verbose_cdata(e,handlers)
- handlers.handle("<![CDATA[",e.dt[1],"]]>")
+ handlers.handle("<![CDATA[",e.dt[1],"]]>")
end
local function verbose_doctype(e,handlers)
- handlers.handle("<!DOCTYPE",e.dt[1],">")
+ handlers.handle("<!DOCTYPE",e.dt[1],">")
end
local function verbose_root(e,handlers)
- handlers.serialize(e.dt,handlers)
+ handlers.serialize(e.dt,handlers)
end
local function verbose_text(e,handlers)
- handlers.handle(escaped(e))
+ handlers.handle(escaped(e))
end
local function verbose_document(e,handlers)
- local serialize=handlers.serialize
- local functions=handlers.functions
- for i=1,#e do
- local ei=e[i]
- if type(ei)=="string" then
- functions["@tx@"](ei,handlers)
- else
- serialize(ei,handlers)
- end
+ local serialize=handlers.serialize
+ local functions=handlers.functions
+ for i=1,#e do
+ local ei=e[i]
+ if type(ei)=="string" then
+ functions["@tx@"](ei,handlers)
+ else
+ serialize(ei,handlers)
end
+ end
end
local function serialize(e,handlers,...)
- if e then
- local initialize=handlers.initialize
- local finalize=handlers.finalize
- local functions=handlers.functions
- if initialize then
- local state=initialize(...)
- if not state==true then
- return state
- end
- end
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
- if finalize then
- return finalize()
- end
+ if e then
+ local initialize=handlers.initialize
+ local finalize=handlers.finalize
+ local functions=handlers.functions
+ if initialize then
+ local state=initialize(...)
+ if not state==true then
+ return state
+ end
+ end
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
end
+ if finalize then
+ return finalize()
+ end
+ end
end
local function xserialize(e,handlers)
- if e then
- local functions=handlers.functions
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
+ if e then
+ local functions=handlers.functions
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
end
+ end
end
local handlers={}
local function newhandlers(settings)
- local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
- if settings then
- for k,v in next,settings do
- if type(v)=="table" then
- local tk=t[k] if not tk then tk={} t[k]=tk end
- for kk,vv in next,v do
- tk[kk]=vv
- end
- else
- t[k]=v
- end
- end
- if settings.name then
- handlers[settings.name]=t
- end
+ local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
+ if settings then
+ for k,v in next,settings do
+ if type(v)=="table" then
+ local tk=t[k] if not tk then tk={} t[k]=tk end
+ for kk,vv in next,v do
+ tk[kk]=vv
+ end
+ else
+ t[k]=v
+ end
end
- utilities.storage.mark(t)
- return t
+ if settings.name then
+ handlers[settings.name]=t
+ end
+ end
+ utilities.storage.mark(t)
+ return t
end
local nofunction=function() end
function xml.sethandlersfunction(handler,name,fnc)
- handler.functions[name]=fnc or nofunction
+ handler.functions[name]=fnc or nofunction
end
function xml.gethandlersfunction(handler,name)
- return handler.functions[name]
+ return handler.functions[name]
end
function xml.gethandlers(name)
- return handlers[name]
+ return handlers[name]
end
newhandlers {
- name="verbose",
- initialize=false,
- finalize=false,
- serialize=xserialize,
- handle=print,
- functions={
- ["@dc@"]=verbose_document,
- ["@dt@"]=verbose_doctype,
- ["@rt@"]=verbose_root,
- ["@el@"]=verbose_element,
- ["@pi@"]=verbose_pi,
- ["@cm@"]=verbose_comment,
- ["@cd@"]=verbose_cdata,
- ["@tx@"]=verbose_text,
- }
+ name="verbose",
+ initialize=false,
+ finalize=false,
+ serialize=xserialize,
+ handle=print,
+ functions={
+ ["@dc@"]=verbose_document,
+ ["@dt@"]=verbose_doctype,
+ ["@rt@"]=verbose_root,
+ ["@el@"]=verbose_element,
+ ["@pi@"]=verbose_pi,
+ ["@cm@"]=verbose_comment,
+ ["@cd@"]=verbose_cdata,
+ ["@tx@"]=verbose_text,
+ }
}
local result
local xmlfilehandler=newhandlers {
- name="file",
- initialize=function(name)
- result=io.open(name,"wb")
- return result
- end,
- finalize=function()
- result:close()
- return true
- end,
- handle=function(...)
- result:write(...)
- end,
+ name="file",
+ initialize=function(name)
+ result=io.open(name,"wb")
+ return result
+ end,
+ finalize=function()
+ result:close()
+ return true
+ end,
+ handle=function(...)
+ result:write(...)
+ end,
}
function xml.save(root,name)
- serialize(root,xmlfilehandler,name)
+ serialize(root,xmlfilehandler,name)
end
local result,r,threshold={},0,512
local xmlstringhandler=newhandlers {
- name="string",
- initialize=function()
- r=0
- return result
- end,
- finalize=function()
- local done=concat(result,"",1,r)
- r=0
- if r>threshold then
- result={}
- end
- return done
- end,
- handle=function(...)
- for i=1,select("#",...) do
- r=r+1
- result[r]=select(i,...)
- end
- end,
+ name="string",
+ initialize=function()
+ r=0
+ return result
+ end,
+ finalize=function()
+ local done=concat(result,"",1,r)
+ r=0
+ if r>threshold then
+ result={}
+ end
+ return done
+ end,
+ handle=function(...)
+ for i=1,select("#",...) do
+ r=r+1
+ result[r]=select(i,...)
+ end
+ end,
}
local function xmltostring(root)
- if not root then
- return ""
- elseif type(root)=="string" then
- return root
- else
- return serialize(root,xmlstringhandler) or ""
- end
+ if not root then
+ return ""
+ elseif type(root)=="string" then
+ return root
+ else
+ return serialize(root,xmlstringhandler) or ""
+ end
end
local function __tostring(root)
- return (root and xmltostring(root)) or ""
+ return (root and xmltostring(root)) or ""
end
initialize_mt=function(root)
- mt={ __tostring=__tostring,__index=root }
+ mt={ __tostring=__tostring,__index=root }
end
xml.defaulthandlers=handlers
xml.newhandlers=newhandlers
xml.serialize=serialize
xml.tostring=xmltostring
local function xmlstring(e,handle)
- if not handle or (e.special and e.tg~="@rt@") then
- elseif e.tg then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- xmlstring(edt[i],handle)
- end
- end
- else
- handle(e)
+ if not handle or (e.special and e.tg~="@rt@") then
+ elseif e.tg then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ xmlstring(edt[i],handle)
+ end
end
+ else
+ handle(e)
+ end
end
xml.string=xmlstring
function xml.settings(e)
- while e do
- local s=e.settings
- if s then
- return s
- else
- e=e.__p__
- end
+ while e do
+ local s=e.settings
+ if s then
+ return s
+ else
+ e=e.__p__
end
- return nil
+ end
+ return nil
end
function xml.root(e)
- local r=e
- while e do
- e=e.__p__
- if e then
- r=e
- end
+ local r=e
+ while e do
+ e=e.__p__
+ if e then
+ r=e
end
- return r
+ end
+ return r
end
function xml.parent(root)
- return root.__p__
+ return root.__p__
end
function xml.body(root)
- return root.ri and root.dt[root.ri] or root
+ return root.ri and root.dt[root.ri] or root
end
function xml.name(root)
- if not root then
- return ""
- end
- local ns=root.ns
- local tg=root.tg
- if ns=="" then
- return tg
- else
- return ns..":"..tg
- end
+ if not root then
+ return ""
+ end
+ local ns=root.ns
+ local tg=root.tg
+ if ns=="" then
+ return tg
+ else
+ return ns..":"..tg
+ end
end
function xml.erase(dt,k)
- if dt then
- if k then
- dt[k]=""
- else for k=1,#dt do
- dt[1]={ "" }
- end end
- end
+ if dt then
+ if k then
+ dt[k]=""
+ else for k=1,#dt do
+ dt[1]={ "" }
+ end end
+ end
end
function xml.assign(dt,k,root)
- if dt and k then
- dt[k]=type(root)=="table" and xml.body(root) or root
- return dt[k]
- else
- return xml.body(root)
- end
+ if dt and k then
+ dt[k]=type(root)=="table" and xml.body(root) or root
+ return dt[k]
+ else
+ return xml.body(root)
+ end
end
function xml.tocdata(e,wrapper)
- local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
- if wrapper then
- whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
- end
- local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
- setmetatable(t,getmetatable(e))
- e.dt={ t }
+ local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
+ if wrapper then
+ whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
+ end
+ local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
+ setmetatable(t,getmetatable(e))
+ 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
+ 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
- return root
+ end
+ return root
end
function xml.kind(e)
- local dt=e and e.dt
- if dt then
- local n=#dt
- if n==1 then
- local d=dt[1]
- if d.special then
- local tg=d.tg
- if tg=="@cd@" then
- return "cdata"
- elseif tg=="@cm" then
- return "comment"
- elseif tg=="@pi@" then
- return "instruction"
- elseif tg=="@dt@" then
- return "declaration"
- end
- elseif type(d)=="string" then
- return "text"
- end
- return "element"
- elseif n>0 then
- return "mixed"
- end
+ local dt=e and e.dt
+ if dt then
+ local n=#dt
+ if n==1 then
+ local d=dt[1]
+ if d.special then
+ local tg=d.tg
+ if tg=="@cd@" then
+ return "cdata"
+ elseif tg=="@cm" then
+ return "comment"
+ elseif tg=="@pi@" then
+ return "instruction"
+ elseif tg=="@dt@" then
+ return "declaration"
+ end
+ elseif type(d)=="string" then
+ return "text"
+ end
+ return "element"
+ elseif n>0 then
+ return "mixed"
end
- return "empty"
+ end
+ return "empty"
end
@@ -16924,14 +16932,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true
--- original size: 54551, stripped down to: 33353
+-- original size: 54551, stripped down to: 30745
if not modules then modules={} end modules ['lxml-lpt']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local concat,remove,insert=table.concat,table.remove,table.insert
local type,next,tonumber,tostring,setmetatable,load,select=type,next,tonumber,tostring,setmetatable,load,select
@@ -16944,21 +16952,21 @@ local trace_lparse=false
local trace_lprofile=false
local report_lpath=logs.reporter("xml","lpath")
if trackers then
- trackers.register("xml.path",function(v)
- trace_lpath=v
- end)
- trackers.register("xml.parse",function(v)
- trace_lparse=v
- end)
- trackers.register("xml.profile",function(v)
- trace_lpath=v
- trace_lparse=v
- trace_lprofile=v
- end)
+ trackers.register("xml.path",function(v)
+ trace_lpath=v
+ end)
+ trackers.register("xml.parse",function(v)
+ trace_lparse=v
+ end)
+ trackers.register("xml.profile",function(v)
+ trace_lpath=v
+ trace_lparse=v
+ trace_lprofile=v
+ end)
end
local xml=xml
-local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
-local lpathcached=0 function xml.lpathcached() return lpathcached end
+local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
+local lpathcached=0 function xml.lpathcached() return lpathcached end
xml.functions=xml.functions or {}
local functions=xml.functions
xml.expressions=xml.expressions or {}
@@ -16972,262 +16980,262 @@ local xmlpatterns=lpegpatterns.xml
finalizers.xml=finalizers.xml or {}
finalizers.tex=finalizers.tex or {}
local function fallback (t,name)
- local fn=finalizers[name]
- if fn then
- t[name]=fn
- else
- report_lpath("unknown sub finalizer %a",name)
- fn=function() end
- end
- return fn
+ local fn=finalizers[name]
+ if fn then
+ t[name]=fn
+ else
+ report_lpath("unknown sub finalizer %a",name)
+ fn=function() end
+ end
+ return fn
end
setmetatableindex(finalizers.xml,fallback)
setmetatableindex(finalizers.tex,fallback)
xml.defaultprotocol="xml"
local apply_axis={}
apply_axis['root']=function(list)
- local collected={}
- for l=1,#list do
- local ll=list[l]
- local rt=ll
- while ll do
- ll=ll.__p__
- if ll then
- rt=ll
- end
- end
- collected[l]=rt
+ local collected={}
+ for l=1,#list do
+ local ll=list[l]
+ local rt=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
+ rt=ll
+ end
end
- return collected
+ collected[l]=rt
+ end
+ return collected
end
apply_axis['self']=function(list)
- return list
+ return list
end
apply_axis['child']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local dt=ll.dt
- if dt then
- local n=#dt
- if n==0 then
- ll.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- ll.en=1
- end
- else
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- end
- end
- ll.en=en
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local dt=ll.dt
+ if dt then
+ local n=#dt
+ if n==0 then
+ ll.en=0
+ elseif n==1 then
+ local dk=dt[1]
+ if dk.tg then
+ c=c+1
+ collected[c]=dk
+ dk.ni=1
+ dk.ei=1
+ ll.en=1
+ end
+ else
+ local en=0
+ for k=1,#dt do
+ local dk=dt[k]
+ if dk.tg then
+ c=c+1
+ en=en+1
+ collected[c]=dk
+ dk.ni=k
+ dk.ei=en
+ end
end
+ ll.en=en
+ end
end
- return collected
+ end
+ return collected
end
local function collect(list,collected,c)
- local dt=list.dt
- if dt then
- local n=#dt
- if n==0 then
- list.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- c=collect(dk,collected,c)
- list.en=1
- else
- list.en=0
- end
- else
- local en=0
- for k=1,n do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- c=collect(dk,collected,c)
- end
- end
- list.en=en
+ local dt=list.dt
+ if dt then
+ local n=#dt
+ if n==0 then
+ list.en=0
+ elseif n==1 then
+ local dk=dt[1]
+ if dk.tg then
+ c=c+1
+ collected[c]=dk
+ dk.ni=1
+ dk.ei=1
+ c=collect(dk,collected,c)
+ list.en=1
+ else
+ list.en=0
+ end
+ else
+ local en=0
+ for k=1,n do
+ local dk=dt[k]
+ if dk.tg then
+ c=c+1
+ en=en+1
+ collected[c]=dk
+ dk.ni=k
+ dk.ei=en
+ c=collect(dk,collected,c)
end
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant']=function(list)
- local collected,c={},0
- for l=1,#list do
- c=collect(list[l],collected,c)
- end
- return collected
+ local collected,c={},0
+ for l=1,#list do
+ c=collect(list[l],collected,c)
+ end
+ return collected
end
local function collect(list,collected,c)
- local dt=list.dt
- if dt then
- local n=#dt
- if n==0 then
- list.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- c=collect(dk,collected,c)
- list.en=1
- end
- else
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- c=collect(dk,collected,c)
- end
- end
- list.en=en
+ local dt=list.dt
+ if dt then
+ local n=#dt
+ if n==0 then
+ list.en=0
+ elseif n==1 then
+ local dk=dt[1]
+ if dk.tg then
+ c=c+1
+ collected[c]=dk
+ dk.ni=1
+ dk.ei=1
+ c=collect(dk,collected,c)
+ list.en=1
+ end
+ else
+ local en=0
+ for k=1,#dt do
+ local dk=dt[k]
+ if dk.tg then
+ c=c+1
+ en=en+1
+ collected[c]=dk
+ dk.ni=k
+ dk.ei=en
+ c=collect(dk,collected,c)
end
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- if ll.special~=true then
- c=c+1
- collected[c]=ll
- end
- c=collect(ll,collected,c)
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ if ll.special~=true then
+ c=c+1
+ collected[c]=ll
end
- return collected
+ c=collect(ll,collected,c)
+ end
+ return collected
end
apply_axis['ancestor']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ while ll do
+ ll=ll.__p__
+ if ll then
+ c=c+1
+ collected[c]=ll
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['ancestor-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ c=c+1
+ collected[c]=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
c=c+1
collected[c]=ll
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['parent']=function(list)
- local collected,c={},0
- for l=1,#list do
- local pl=list[l].__p__
- if pl then
- c=c+1
- collected[c]=pl
- end
+ local collected,c={},0
+ for l=1,#list do
+ local pl=list[l].__p__
+ if pl then
+ c=c+1
+ collected[c]=pl
end
- return collected
+ end
+ return collected
end
apply_axis['attribute']=function(list)
- return {}
+ return {}
end
apply_axis['namespace']=function(list)
- return {}
+ return {}
end
apply_axis['following']=function(list)
- return {}
+ return {}
end
apply_axis['preceding']=function(list)
- return {}
+ return {}
end
apply_axis['following-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=ll.ni+1,#d do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=ll.ni+1,#d do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['preceding-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=1,ll.ni-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=1,ll.ni-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['reverse-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=ll.ni-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=ll.ni-1,1,-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['auto-descendant-or-self']=apply_axis['descendant-or-self']
apply_axis['auto-descendant']=apply_axis['descendant']
@@ -17235,130 +17243,130 @@ apply_axis['auto-child']=apply_axis['child']
apply_axis['auto-self']=apply_axis['self']
apply_axis['initial-child']=apply_axis['child']
local function apply_nodes(list,directive,nodes)
- local maxn=#nodes
- if maxn==3 then
- local nns,ntg=nodes[2],nodes[3]
- if not nns and not ntg then
+ local maxn=#nodes
+ if maxn==3 then
+ local nns,ntg=nodes[2],nodes[3]
+ if not nns and not ntg then
+ if directive then
+ return list
+ else
+ return {}
+ end
+ else
+ local collected,c,m,p={},0,0,nil
+ if not nns then
+ for l=1,#list do
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
if directive then
- return list
- else
- return {}
+ if ntg==ltg then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif ntg~=ltg then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
end
- else
- local collected,c,m,p={},0,0,nil
- if not nns then
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- if directive then
- if ntg==ltg then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif ntg~=ltg then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- elseif not ntg then
- for l=1,#list do
- local ll=list[l]
- local lns=ll.rn or ll.ns
- if lns then
- if directive then
- if lns==nns then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif lns~=nns then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- else
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=ltg==ntg and lns==nns
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
+ end
+ end
+ elseif not ntg then
+ for l=1,#list do
+ local ll=list[l]
+ local lns=ll.rn or ll.ns
+ if lns then
+ if directive then
+ if lns==nns then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif lns~=nns then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
end
- return collected
+ end
end
- else
- local collected,c,m,p={},0,0,nil
+ else
for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=false
- for n=1,maxn,3 do
- local nns,ntg=nodes[n+1],nodes[n+2]
- ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
- if ok then
- break
- end
- end
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=ltg==ntg and lns==nns
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
end
+ end
end
- return collected
+ end
+ return collected
end
-end
-local quit_expression=false
-local function apply_expression(list,expression,order)
- local collected,c={},0
- quit_expression=false
+ else
+ local collected,c,m,p={},0,0,nil
for l=1,#list do
- local ll=list[l]
- if expression(list,ll,l,order) then
- c=c+1
- collected[c]=ll
- end
- if quit_expression then
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=false
+ for n=1,maxn,3 do
+ local nns,ntg=nodes[n+1],nodes[n+2]
+ ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
+ if ok then
break
+ end
end
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ end
end
return collected
+ end
end
-local function apply_selector(list,specification)
- if xml.applyselector then
- apply_selector=xml.applyselector
- return apply_selector(list,specification)
- else
- return list
+local quit_expression=false
+local function apply_expression(list,expression,order)
+ local collected,c={},0
+ quit_expression=false
+ for l=1,#list do
+ local ll=list[l]
+ if expression(list,ll,l,order) then
+ c=c+1
+ collected[c]=ll
+ end
+ if quit_expression then
+ break
end
+ end
+ return collected
+end
+local function apply_selector(list,specification)
+ if xml.applyselector then
+ apply_selector=xml.applyselector
+ return apply_selector(list,specification)
+ else
+ return list
+ end
end
local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb
local spaces=S(" \n\r\t\f")^0
@@ -17369,24 +17377,24 @@ local lp_doequal=P("=")/"=="
local lp_or=P("|")/" or "
local lp_and=P("&")/" and "
local builtin={
- text="(ll.dt[1] or '')",
- content="ll.dt",
- name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
- tag="ll.tg",
- position="l",
- firstindex="1",
- firstelement="1",
- first="1",
- lastindex="(#ll.__p__.dt or 1)",
- lastelement="(ll.__p__.en or 1)",
- last="#list",
- rootposition="order",
- order="order",
- element="(ll.ei or 1)",
- index="(ll.ni or 1)",
- match="(ll.mi or 1)",
- namespace="ll.ns",
- ns="ll.ns",
+ text="(ll.dt[1] or '')",
+ content="ll.dt",
+ name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
+ tag="ll.tg",
+ position="l",
+ firstindex="1",
+ firstelement="1",
+ first="1",
+ lastindex="(#ll.__p__.dt or 1)",
+ lastelement="(ll.__p__.en or 1)",
+ last="#list",
+ rootposition="order",
+ order="order",
+ element="(ll.ei or 1)",
+ index="(ll.ni or 1)",
+ match="(ll.mi or 1)",
+ namespace="ll.ns",
+ ns="ll.ns",
}
local lp_builtin=lpeg.utfchartabletopattern(builtin)/builtin*((spaces*P("(")*spaces*P(")"))/"")
local lp_attribute=(P("@")+P("attribute::"))/""*Cc("(ll.at and ll.at['")*((R("az","AZ")+S("-_:"))^1)*Cc("'])")
@@ -17396,11 +17404,11 @@ local lp_fastpos=lp_fastpos_n+lp_fastpos_p
local lp_reserved=C("and")+C("or")+C("not")+C("div")+C("mod")+C("true")+C("false")
local lp_lua_function=Cs((R("az","AZ","__")^1*(P(".")*R("az","AZ","__")^1)^1)*("("))/"%0"
local lp_function=C(R("az","AZ","__")^1)*P("(")/function(t)
- if expressions[t] then
- return "expr."..t.."("
- else
- return "expr.error("
- end
+ if expressions[t] then
+ return "expr."..t.."("
+ else
+ return "expr.error("
+ end
end
local lparent=P("(")
local rparent=P(")")
@@ -17413,24 +17421,24 @@ local lp_string=Cc("'")*R("az","AZ","--","__")^1*Cc("'")
local lp_content=(P("'")*(1-P("'"))^0*P("'")+P('"')*(1-P('"'))^0*P('"'))
local cleaner
local lp_special=(C(P("name")+P("text")+P("tag")+P("count")+P("child")))*value/function(t,s)
- if expressions[t] then
- s=s and s~="" and lpegmatch(cleaner,s)
- if s and s~="" then
- return "expr."..t.."(ll,"..s..")"
- else
- return "expr."..t.."(ll)"
- end
+ if expressions[t] then
+ s=s and s~="" and lpegmatch(cleaner,s)
+ if s and s~="" then
+ return "expr."..t.."(ll,"..s..")"
else
- return "expr.error("..t..")"
+ return "expr."..t.."(ll)"
end
+ else
+ return "expr.error("..t..")"
+ end
end
local content=lp_builtin+lp_attribute+lp_special+lp_noequal+lp_doequal+lp_or+lp_and+lp_reserved+lp_lua_function+lp_function+lp_content+
- lp_child+lp_any
+ lp_child+lp_any
local converter=Cs (
- lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
+ lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
)
cleaner=Cs ((
- lp_reserved+lp_number+lp_string+1 )^1 )
+ lp_reserved+lp_number+lp_string+1 )^1 )
local template_e=[[
local expr = xml.expressions
return function(list,ll,l,order)
@@ -17446,75 +17454,75 @@ local template_f_y=[[
local template_f_n=[[
return xml.finalizers['%s']['%s']
]]
-local register_last_match={ kind="axis",axis="last-match" }
-local register_self={ kind="axis",axis="self" }
-local register_parent={ kind="axis",axis="parent" }
-local register_descendant={ kind="axis",axis="descendant" }
-local register_child={ kind="axis",axis="child" }
+local register_last_match={ kind="axis",axis="last-match" }
+local register_self={ kind="axis",axis="self" }
+local register_parent={ kind="axis",axis="parent" }
+local register_descendant={ kind="axis",axis="descendant" }
+local register_child={ kind="axis",axis="child" }
local register_descendant_or_self={ kind="axis",axis="descendant-or-self" }
-local register_root={ kind="axis",axis="root" }
-local register_ancestor={ kind="axis",axis="ancestor" }
-local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
-local register_attribute={ kind="axis",axis="attribute" }
-local register_namespace={ kind="axis",axis="namespace" }
-local register_following={ kind="axis",axis="following" }
+local register_root={ kind="axis",axis="root" }
+local register_ancestor={ kind="axis",axis="ancestor" }
+local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
+local register_attribute={ kind="axis",axis="attribute" }
+local register_namespace={ kind="axis",axis="namespace" }
+local register_following={ kind="axis",axis="following" }
local register_following_sibling={ kind="axis",axis="following-sibling" }
-local register_preceding={ kind="axis",axis="preceding" }
+local register_preceding={ kind="axis",axis="preceding" }
local register_preceding_sibling={ kind="axis",axis="preceding-sibling" }
-local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
+local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
local register_auto_descendant_or_self={ kind="axis",axis="auto-descendant-or-self" }
-local register_auto_descendant={ kind="axis",axis="auto-descendant" }
-local register_auto_self={ kind="axis",axis="auto-self" }
-local register_auto_child={ kind="axis",axis="auto-child" }
-local register_initial_child={ kind="axis",axis="initial-child" }
+local register_auto_descendant={ kind="axis",axis="auto-descendant" }
+local register_auto_self={ kind="axis",axis="auto-self" }
+local register_auto_child={ kind="axis",axis="auto-child" }
+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)
- if not skip[str] then
- report_lpath("error in expression: %s => %s",str,cnv)
- skip[str]=cnv or str
- end
- return false
+ if not skip[str] then
+ report_lpath("error in expression: %s => %s",str,cnv)
+ skip[str]=cnv or str
+ end
+ return false
end
local function errorrunner_f(str,arg)
- report_lpath("error in finalizer: %s(%s)",str,arg or "")
- return false
+ report_lpath("error in finalizer: %s(%s)",str,arg or "")
+ return false
end
local function register_nodes(nodetest,nodes)
- return { kind="nodes",nodetest=nodetest,nodes=nodes }
+ return { kind="nodes",nodetest=nodetest,nodes=nodes }
end
local function register_selector(specification)
- return { kind="selector",specification=specification }
+ return { kind="selector",specification=specification }
end
local function register_expression(expression)
- local converted=lpegmatch(converter,expression)
- local runner=load(format(template_e,converted))
- runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
- return { kind="expression",expression=expression,converted=converted,evaluator=runner }
+ local converted=lpegmatch(converter,expression)
+ local runner=load(format(template_e,converted))
+ runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
+ return { kind="expression",expression=expression,converted=converted,evaluator=runner }
end
local function register_finalizer(protocol,name,arguments)
- local runner
- if arguments and arguments~="" then
- runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
- else
- runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
- end
- runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
- return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
+ local runner
+ if arguments and arguments~="" then
+ runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
+ else
+ runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
+ end
+ runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
+ return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
end
local expression=P { "ex",
- ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
- sq="'"*(1-S("'"))^0*"'",
- dq='"'*(1-S('"'))^0*'"',
+ ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
+ sq="'"*(1-S("'"))^0*"'",
+ dq='"'*(1-S('"'))^0*'"',
}
local arguments=P { "ar",
- ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
- nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
- sq=P("'")*(1-P("'"))^0*P("'"),
- dq=P('"')*(1-P('"'))^0*P('"'),
+ ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
+ nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
+ sq=P("'")*(1-P("'"))^0*P("'"),
+ dq=P('"')*(1-P('"'))^0*P('"'),
}
local function register_error(str)
- return { kind="error",error=format("unparsed: %s",str) }
+ return { kind="error",error=format("unparsed: %s",str) }
end
local special_1=P("*")*Cc(register_auto_descendant)*Cc(register_all_nodes)
local special_2=P("/")*Cc(register_auto_self)
@@ -17522,367 +17530,367 @@ local special_3=P("")*Cc(register_auto_self)
local no_nextcolon=P(-1)+#(1-P(":"))
local no_nextlparent=P(-1)+#(1-P("("))
local pathparser=Ct { "patterns",
- patterns=spaces*V("protocol")*spaces*(
- (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
- ),
- protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
- step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
- axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
- special=special_1+special_2+special_3,
- initial=(P("/")*spaces*Cc(register_initial_child))^-1,
- error=(P(1)^1)/register_error,
- shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
- shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
- s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
- s_descendant=P("**")*Cc(register_descendant),
- s_child=P("*")*no_nextcolon*Cc(register_child),
- s_parent=P("..")*Cc(register_parent),
- s_self=P("." )*Cc(register_self),
- s_root=P("^^")*Cc(register_root),
- s_ancestor=P("^")*Cc(register_ancestor),
- s_lastmatch=P("=")*Cc(register_last_match),
- descendant=P("descendant::")*Cc(register_descendant),
- child=P("child::")*Cc(register_child),
- parent=P("parent::")*Cc(register_parent),
- self=P("self::")*Cc(register_self),
- root=P('root::')*Cc(register_root),
- ancestor=P('ancestor::')*Cc(register_ancestor),
- descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
- ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
- following=P('following::')*Cc(register_following),
- following_sibling=P('following-sibling::')*Cc(register_following_sibling),
- preceding=P('preceding::')*Cc(register_preceding),
- preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
- reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
- last_match=P('last-match::')*Cc(register_last_match),
- selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
- nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
- expressions=expression/register_expression,
- letters=R("az")^1,
- name=(1-S("/[]()|:*!"))^1,
- negate=P("!")*Cc(false),
- nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
- nodetest=V("negate")+Cc(true),
- nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
- wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
- nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
- finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
+ patterns=spaces*V("protocol")*spaces*(
+ (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
+ ),
+ protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
+ step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
+ axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
+ special=special_1+special_2+special_3,
+ initial=(P("/")*spaces*Cc(register_initial_child))^-1,
+ error=(P(1)^1)/register_error,
+ shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
+ shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
+ s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
+ s_descendant=P("**")*Cc(register_descendant),
+ s_child=P("*")*no_nextcolon*Cc(register_child),
+ s_parent=P("..")*Cc(register_parent),
+ s_self=P("." )*Cc(register_self),
+ s_root=P("^^")*Cc(register_root),
+ s_ancestor=P("^")*Cc(register_ancestor),
+ s_lastmatch=P("=")*Cc(register_last_match),
+ descendant=P("descendant::")*Cc(register_descendant),
+ child=P("child::")*Cc(register_child),
+ parent=P("parent::")*Cc(register_parent),
+ self=P("self::")*Cc(register_self),
+ root=P('root::')*Cc(register_root),
+ ancestor=P('ancestor::')*Cc(register_ancestor),
+ descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
+ ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
+ following=P('following::')*Cc(register_following),
+ following_sibling=P('following-sibling::')*Cc(register_following_sibling),
+ preceding=P('preceding::')*Cc(register_preceding),
+ preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
+ reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
+ last_match=P('last-match::')*Cc(register_last_match),
+ selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
+ nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
+ expressions=expression/register_expression,
+ letters=R("az")^1,
+ name=(1-S("/[]()|:*!"))^1,
+ negate=P("!")*Cc(false),
+ nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
+ nodetest=V("negate")+Cc(true),
+ nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
+ wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
+ nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
+ finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
}
xmlpatterns.pathparser=pathparser
local cache={}
local function nodesettostring(set,nodetest)
- local t={}
- for i=1,#set,3 do
- local directive,ns,tg=set[i],set[i+1],set[i+2]
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- t[#t+1]=(directive and tg) or format("not(%s)",tg)
- end
- if nodetest==false then
- return format("not(%s)",concat(t,"|"))
- else
- return concat(t,"|")
- end
+ local t={}
+ for i=1,#set,3 do
+ local directive,ns,tg=set[i],set[i+1],set[i+2]
+ if not ns or ns=="" then ns="*" end
+ if not tg or tg=="" then tg="*" end
+ tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
+ t[#t+1]=(directive and tg) or format("not(%s)",tg)
+ end
+ if nodetest==false then
+ return format("not(%s)",concat(t,"|"))
+ else
+ return concat(t,"|")
+ end
end
local function tagstostring(list)
- if #list==0 then
- return "no elements"
- else
- local t={}
- for i=1,#list do
- local li=list[i]
- local ns,tg=li.ns,li.tg
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- t[i]=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- end
- return concat(t," ")
+ if #list==0 then
+ return "no elements"
+ else
+ local t={}
+ for i=1,#list do
+ local li=list[i]
+ local ns,tg=li.ns,li.tg
+ if not ns or ns=="" then ns="*" end
+ if not tg or tg=="" then tg="*" end
+ t[i]=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
end
+ return concat(t," ")
+ end
end
xml.nodesettostring=nodesettostring
local lpath
local function lshow(parsed)
- if type(parsed)=="string" then
- parsed=lpath(parsed)
- end
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
- table.serialize(parsed,false))
+ if type(parsed)=="string" then
+ parsed=lpath(parsed)
+ end
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
+ table.serialize(parsed,false))
end
xml.lshow=lshow
local function add_comment(p,str)
- local pc=p.comment
- if not pc then
- p.comment={ str }
- else
- pc[#pc+1]=str
- end
+ local pc=p.comment
+ if not pc then
+ p.comment={ str }
+ else
+ pc[#pc+1]=str
+ end
end
lpath=function (pattern)
- lpathcalls=lpathcalls+1
- if type(pattern)=="table" then
- return pattern
- else
- local parsed=cache[pattern]
- if parsed then
- lpathcached=lpathcached+1
+ lpathcalls=lpathcalls+1
+ if type(pattern)=="table" then
+ return pattern
+ else
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcached=lpathcached+1
+ else
+ parsed=lpegmatch(pathparser,pattern)
+ if parsed then
+ parsed.pattern=pattern
+ local np=#parsed
+ if np==0 then
+ parsed={ pattern=pattern,register_self,state="parsing error" }
+ report_lpath("parsing error in pattern: %s",pattern)
+ lshow(parsed)
else
- parsed=lpegmatch(pathparser,pattern)
- if parsed then
- parsed.pattern=pattern
- local np=#parsed
- if np==0 then
- parsed={ pattern=pattern,register_self,state="parsing error" }
- report_lpath("parsing error in pattern: %s",pattern)
- lshow(parsed)
- else
- local pi=parsed[1]
- if pi.axis=="auto-child" then
- if false then
- add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
- parsed[1]=register_auto_descendant_or_self
- else
- add_comment(parsed,"auto-child replaced by auto-descendant")
- parsed[1]=register_auto_descendant
- end
- elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
- add_comment(parsed,"initial-child removed")
- remove(parsed,1)
- end
- local np=#parsed
- if np>1 then
- local pnp=parsed[np]
- if pnp.kind=="nodes" and pnp.nodetest==true then
- local nodes=pnp.nodes
- if nodes[1]==true and nodes[2]==false and nodes[3]==false then
- add_comment(parsed,"redundant final wildcard filter removed")
- remove(parsed,np)
- end
- end
- end
- end
+ local pi=parsed[1]
+ if pi.axis=="auto-child" then
+ if false then
+ add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
+ parsed[1]=register_auto_descendant_or_self
else
- parsed={ pattern=pattern }
+ add_comment(parsed,"auto-child replaced by auto-descendant")
+ parsed[1]=register_auto_descendant
end
- cache[pattern]=parsed
- if trace_lparse and not trace_lprofile then
- lshow(parsed)
+ elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
+ add_comment(parsed,"initial-child removed")
+ remove(parsed,1)
+ end
+ local np=#parsed
+ if np>1 then
+ local pnp=parsed[np]
+ if pnp.kind=="nodes" and pnp.nodetest==true then
+ local nodes=pnp.nodes
+ if nodes[1]==true and nodes[2]==false and nodes[3]==false then
+ add_comment(parsed,"redundant final wildcard filter removed")
+ remove(parsed,np)
+ end
end
+ end
end
- return parsed
+ else
+ parsed={ pattern=pattern }
+ end
+ cache[pattern]=parsed
+ if trace_lparse and not trace_lprofile then
+ lshow(parsed)
+ end
end
+ return parsed
+ end
end
xml.lpath=lpath
do
- local profiled={}
- xml.profiled=profiled
- local lastmatch=nil
- local keepmatch=nil
- if directives then
- directives.register("xml.path.keeplastmatch",function(v)
- keepmatch=v
- lastmatch=nil
- end)
- end
- apply_axis["last-match"]=function()
- return lastmatch or {}
- end
- local function profiled_apply(list,parsed,nofparsed,order)
- local p=profiled[parsed.pattern]
- if p then
- p.tested=p.tested+1
- else
- p={ tested=1,matched=0,finalized=0 }
- profiled[parsed.pattern]=p
- end
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- p.matched=p.matched+1
- p.finalized=p.finalized+1
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- p.finalized=p.finalized+1
- return collected
- end
- return nil
- end
- end
- if collected then
- p.matched=p.matched+1
- end
- return collected
- end
- local function traced_apply(list,parsed,nofparsed,order)
- if trace_lparse then
- lshow(parsed)
- end
- report_lpath("collecting: %s",parsed.pattern)
- report_lpath("root tags : %s",tagstostring(list))
- report_lpath("order : %s",order or "unset")
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
- return collected
- end
- return nil
- end
- end
+ local profiled={}
+ xml.profiled=profiled
+ local lastmatch=nil
+ local keepmatch=nil
+ if directives then
+ directives.register("xml.path.keeplastmatch",function(v)
+ keepmatch=v
+ lastmatch=nil
+ end)
+ end
+ apply_axis["last-match"]=function()
+ return lastmatch or {}
+ end
+ local function profiled_apply(list,parsed,nofparsed,order)
+ local p=profiled[parsed.pattern]
+ if p then
+ p.tested=p.tested+1
+ else
+ p={ tested=1,matched=0,finalized=0 }
+ profiled[parsed.pattern]=p
+ end
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ p.matched=p.matched+1
+ p.finalized=p.finalized+1
return collected
- end
- local function normal_apply(list,parsed,nofparsed,order)
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- local axis=pi.axis
- if axis~="self" then
- collected=apply_axis[axis](collected)
- end
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- return pi.finalizer(collected)
- end
- if not collected or #collected==0 then
- local pf=i<nofparsed and parsed[nofparsed].finalizer
- if pf then
- return pf(collected)
- end
- return nil
- end
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ p.finalized=p.finalized+1
+ return collected
end
- return collected
+ return nil
+ end
end
- local apply=normal_apply
- if trackers then
- trackers.register("xml.path,xml.parse,xml.profile",function()
- if trace_lprofile then
- apply=profiled_apply
- elseif trace_lpath then
- apply=traced_apply
- else
- apply=normal_apply
- end
- end)
+ if collected then
+ p.matched=p.matched+1
end
- function xml.applylpath(list,pattern)
- if not list then
- lastmatch=nil
- return
- end
- local parsed=cache[pattern]
- if parsed then
- lpathcalls=lpathcalls+1
- lpathcached=lpathcached+1
- elseif type(pattern)=="table" then
- lpathcalls=lpathcalls+1
- parsed=pattern
- else
- parsed=lpath(pattern) or pattern
- end
- if not parsed then
- lastmatch=nil
- return
- end
- local nofparsed=#parsed
- if nofparsed==0 then
- lastmatch=nil
- return
- end
- local collected=apply({ list },parsed,nofparsed,list.mi)
- lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ local function traced_apply(list,parsed,nofparsed,order)
+ if trace_lparse then
+ lshow(parsed)
+ end
+ report_lpath("collecting: %s",parsed.pattern)
+ report_lpath("root tags : %s",tagstostring(list))
+ report_lpath("order : %s",order or "unset")
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
return collected
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
+ return collected
+ end
+ return nil
+ end
end
- function xml.lastmatch()
- return lastmatch
- end
- local stack={}
- function xml.pushmatch()
- insert(stack,lastmatch)
- end
- function xml.popmatch()
- lastmatch=remove(stack)
+ return collected
+ end
+ local function normal_apply(list,parsed,nofparsed,order)
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ local axis=pi.axis
+ if axis~="self" then
+ collected=apply_axis[axis](collected)
+ end
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ return pi.finalizer(collected)
+ end
+ if not collected or #collected==0 then
+ local pf=i<nofparsed and parsed[nofparsed].finalizer
+ if pf then
+ return pf(collected)
+ end
+ return nil
+ end
end
+ return collected
+ end
+ local apply=normal_apply
+ if trackers then
+ trackers.register("xml.path,xml.parse,xml.profile",function()
+ if trace_lprofile then
+ apply=profiled_apply
+ elseif trace_lpath then
+ apply=traced_apply
+ else
+ apply=normal_apply
+ end
+ end)
+ end
+ function xml.applylpath(list,pattern)
+ if not list then
+ lastmatch=nil
+ return
+ end
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcalls=lpathcalls+1
+ lpathcached=lpathcached+1
+ elseif type(pattern)=="table" then
+ lpathcalls=lpathcalls+1
+ parsed=pattern
+ else
+ parsed=lpath(pattern) or pattern
+ end
+ if not parsed then
+ lastmatch=nil
+ return
+ end
+ local nofparsed=#parsed
+ if nofparsed==0 then
+ lastmatch=nil
+ return
+ end
+ local collected=apply({ list },parsed,nofparsed,list.mi)
+ lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ function xml.lastmatch()
+ return lastmatch
+ end
+ local stack={}
+ function xml.pushmatch()
+ insert(stack,lastmatch)
+ end
+ function xml.popmatch()
+ lastmatch=remove(stack)
+ end
end
local applylpath=xml.applylpath
function xml.filter(root,pattern)
- return applylpath(root,pattern)
+ return applylpath(root,pattern)
end
expressions.child=function(e,pattern)
- return applylpath(e,pattern)
+ return applylpath(e,pattern)
end
expressions.count=function(e,pattern)
- local collected=applylpath(e,pattern)
- return pattern and (collected and #collected) or 0
+ local collected=applylpath(e,pattern)
+ return pattern and (collected and #collected) or 0
end
expressions.oneof=function(s,...)
- for i=1,select("#",...) do
- if s==select(i,...) then
- return true
- end
+ for i=1,select("#",...) do
+ if s==select(i,...) then
+ return true
end
- return false
+ end
+ return false
end
expressions.error=function(str)
- xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
- return false
+ xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
+ return false
end
expressions.undefined=function(s)
- return s==nil
+ return s==nil
end
expressions.quit=function(s)
- if s or s==nil then
- quit_expression=true
- end
- return true
+ if s or s==nil then
+ quit_expression=true
+ end
+ return true
end
expressions.print=function(...)
- print(...)
- return true
+ print(...)
+ return true
end
expressions.find=find
expressions.upper=upper
@@ -17890,233 +17898,233 @@ expressions.lower=lower
expressions.number=tonumber
expressions.boolean=toboolean
function expressions.contains(str,pattern)
- local t=type(str)
- if t=="string" then
- if find(str,pattern) then
- return true
- end
- elseif t=="table" then
- for i=1,#str do
- local d=str[i]
- if type(d)=="string" and find(d,pattern) then
- return true
- end
- end
+ local t=type(str)
+ if t=="string" then
+ if find(str,pattern) then
+ return true
end
- return false
+ elseif t=="table" then
+ for i=1,#str do
+ local d=str[i]
+ if type(d)=="string" and find(d,pattern) then
+ return true
+ end
+ end
+ end
+ return false
end
function xml.expressions.idstring(str)
- return type(str)=="string" and gsub(str,"^#","") or ""
+ return type(str)=="string" and gsub(str,"^#","") or ""
end
local function traverse(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local r=e.__p__
- handle(r,r.dt,e.ni)
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local r=e.__p__
+ handle(r,r.dt,e.ni)
end
+ end
end
local function selection(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- if handle then
- for c=1,#collected do
- handle(collected[c])
- end
- else
- return collected
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ if handle then
+ for c=1,#collected do
+ handle(collected[c])
+ end
+ else
+ return collected
end
+ end
end
-xml.traverse=traverse
+xml.traverse=traverse
xml.selection=selection
local function dofunction(collected,fnc,...)
- if collected then
- local f=functions[fnc]
- if f then
- for c=1,#collected do
- f(collected[c],...)
- end
- else
- report_lpath("unknown function %a",fnc)
- end
+ if collected then
+ local f=functions[fnc]
+ if f then
+ for c=1,#collected do
+ f(collected[c],...)
+ end
+ else
+ report_lpath("unknown function %a",fnc)
end
+ end
end
finalizers.xml["function"]=dofunction
finalizers.tex["function"]=dofunction
expressions.text=function(e,n)
- local rdt=e.__p__.dt
- return rdt and rdt[n] or ""
+ local rdt=e.__p__.dt
+ return rdt and rdt[n] or ""
end
expressions.name=function(e,n)
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=type(e)=="table" and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=type(e)=="table" and e
+ elseif n<0 then
+ local d,k=e.__p__.dt,e.ni
+ for i=k-1,1,-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
end
+ end
end
- if found then
- local ns,tg=found.rn or found.ns or "",found.tg
- if ns~="" then
- return ns..":"..tg
+ else
+ local d,k=e.__p__.dt,e.ni
+ for i=k+1,#d,1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==1 then
+ found=di
+ break
else
- return tg
+ n=n-1
end
+ end
+ end
+ end
+ if found then
+ local ns,tg=found.rn or found.ns or "",found.tg
+ if ns~="" then
+ return ns..":"..tg
else
- return ""
+ return tg
end
+ else
+ return ""
+ end
end
expressions.tag=function(e,n)
- if not e then
- return ""
+ if not e then
+ return ""
+ else
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=(type(e)=="table") and e
+ elseif n<0 then
+ local d,k=e.__p__.dt,e.ni
+ for i=k-1,1,-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
+ end
+ end
+ end
else
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=(type(e)=="table") and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
- end
+ local d,k=e.__p__.dt,e.ni
+ for i=k+1,#d,1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==1 then
+ found=di
+ break
+ else
+ n=n-1
+ end
end
- return (found and found.tg) or ""
+ end
end
+ return (found and found.tg) or ""
+ end
end
local dummy=function() end
function xml.elements(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
+ end
end
function xml.collected(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ return collected[c]
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- return collected[c]
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- return collected[c]
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ return collected[c]
+ end
end
+ end
end
function xml.inspect(collection,pattern)
- pattern=pattern or "."
- for e in xml.collected(collection,pattern or ".") do
- report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
- end
+ pattern=pattern or "."
+ for e in xml.collected(collection,pattern or ".") do
+ report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
+ end
end
local function split(e)
- local dt=e.dt
- if dt then
- for i=1,#dt do
- local dti=dt[i]
- if type(dti)=="string" then
- dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
- dti=gsub(dti,"[\n\r]+","\n\n")
- dt[i]=dti
- else
- split(dti)
- end
- end
+ local dt=e.dt
+ if dt then
+ for i=1,#dt do
+ local dti=dt[i]
+ if type(dti)=="string" then
+ dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
+ dti=gsub(dti,"[\n\r]+","\n\n")
+ dt[i]=dti
+ else
+ split(dti)
+ end
end
- return e
+ end
+ return e
end
function xml.finalizers.paragraphs(c)
- for i=1,#c do
- split(c[i])
- end
- return c
+ for i=1,#c do
+ split(c[i])
+ end
+ return c
end
@@ -18126,14 +18134,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-mis"] = package.loaded["lxml-mis"] or true
--- original size: 3574, stripped down to: 1863
+-- original size: 3574, stripped down to: 1808
if not modules then modules={} end modules ['lxml-mis']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local xml,lpeg,string=xml,lpeg,string
local type=type
@@ -18144,26 +18152,26 @@ local P,S,R,C,V,Cc,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.Cc,lpeg.Cs
lpegpatterns.xml=lpegpatterns.xml or {}
local xmlpatterns=lpegpatterns.xml
local function xmlgsub(t,old,new)
- local dt=t.dt
- if dt then
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="string" then
- dt[k]=gsub(v,old,new)
- else
- xmlgsub(v,old,new)
- end
- end
+ local dt=t.dt
+ if dt then
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="string" then
+ dt[k]=gsub(v,old,new)
+ else
+ xmlgsub(v,old,new)
+ end
end
+ end
end
function xml.stripleadingspaces(dk,d,k)
- if d and k then
- local dkm=d[k-1]
- if dkm and type(dkm)=="string" then
- local s=match(dkm,"\n(%s+)")
- xmlgsub(dk,"\n"..rep(" ",#s),"\n")
- end
+ if d and k then
+ local dkm=d[k-1]
+ if dkm and type(dkm)=="string" then
+ local s=match(dkm,"\n(%s+)")
+ xmlgsub(dk,"\n"..rep(" ",#s),"\n")
end
+ end
end
local normal=(1-S("<&>"))^0
local special=P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"
@@ -18175,17 +18183,17 @@ local cleansed=Cs(((P("<")*(1-P(">"))^0*P(">"))/""+1)^0)
xmlpatterns.escaped=escaped
xmlpatterns.unescaped=unescaped
xmlpatterns.cleansed=cleansed
-function xml.escaped (str) return lpegmatch(escaped,str) end
+function xml.escaped (str) return lpegmatch(escaped,str) end
function xml.unescaped(str) return lpegmatch(unescaped,str) end
-function xml.cleansed (str) return lpegmatch(cleansed,str) end
+function xml.cleansed (str) return lpegmatch(cleansed,str) end
function xml.fillin(root,pattern,str,check)
- local e=xml.first(root,pattern)
- if e then
- local n=#e.dt
- if not check or n==0 or (n==1 and e.dt[1]=="") then
- e.dt={ str }
- end
+ local e=xml.first(root,pattern)
+ if e then
+ local n=#e.dt
+ if not check or n==0 or (n==1 and e.dt[1]=="") then
+ e.dt={ str }
end
+ end
end
@@ -18195,17 +18203,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-aux"] = package.loaded["lxml-aux"] or true
--- original size: 30650, stripped down to: 21793
+-- original size: 30650, stripped down to: 19621
if not modules then modules={} end modules ['lxml-aux']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
-local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
+local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
+local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
local report_xml=logs.reporter("xml")
local xml=xml
local xmlcopy,xmlname=xml.copy,xml.name
@@ -18218,308 +18226,308 @@ local utfbyte=utf.byte
local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
local striplinepatterns=utilities.strings.striplinepatterns
local function report(what,pattern,c,e)
- report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
+ report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
end
local function withelements(e,handle,depth)
- if e and handle then
- local edt=e.dt
- if edt then
- depth=depth or 0
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- handle(e,depth)
- withelements(e,handle,depth+1)
- end
- end
+ if e and handle then
+ local edt=e.dt
+ if edt then
+ depth=depth or 0
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ handle(e,depth)
+ withelements(e,handle,depth+1)
end
+ end
end
+ end
end
xml.withelements=withelements
function xml.withelement(e,n,handle)
- if e and n~=0 and handle then
- local edt=e.dt
- if edt then
- if n>0 then
- for i=1,#edt do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==1 then
- handle(ei)
- return
- else
- n=n-1
- end
- end
- end
- elseif n<0 then
- for i=#edt,1,-1 do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==-1 then
- handle(ei)
- return
- else
- n=n+1
- end
- end
- end
+ if e and n~=0 and handle then
+ local edt=e.dt
+ if edt then
+ if n>0 then
+ for i=1,#edt do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==1 then
+ handle(ei)
+ return
+ else
+ n=n-1
end
+ end
end
- end
-end
-function xml.each(root,pattern,handle,reverse)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- if handle then
- if reverse then
- for c=#collected,1,-1 do
- handle(collected[c])
- end
+ elseif n<0 then
+ for i=#edt,1,-1 do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==-1 then
+ handle(ei)
+ return
else
- for c=1,#collected do
- handle(collected[c])
- end
+ n=n+1
end
+ end
end
- return collected
+ end
end
+ end
end
-function xml.processattributes(root,pattern,handle)
- local collected=xmlapplylpath(root,pattern)
- if collected and handle then
+function xml.each(root,pattern,handle,reverse)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ if handle then
+ if reverse then
+ for c=#collected,1,-1 do
+ handle(collected[c])
+ end
+ else
for c=1,#collected do
- handle(collected[c].at)
+ handle(collected[c])
end
+ end
end
return collected
+ end
+end
+function xml.processattributes(root,pattern,handle)
+ local collected=xmlapplylpath(root,pattern)
+ if collected and handle then
+ for c=1,#collected do
+ handle(collected[c].at)
+ end
+ end
+ return collected
end
function xml.collect(root,pattern)
- return xmlapplylpath(root,pattern)
+ return xmlapplylpath(root,pattern)
end
function xml.collecttexts(root,pattern,flatten)
- local collected=xmlapplylpath(root,pattern)
- if collected and flatten then
- local xmltostring=xml.tostring
- for c=1,#collected do
- collected[c]=xmltostring(collected[c].dt)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected and flatten then
+ local xmltostring=xml.tostring
+ for c=1,#collected do
+ collected[c]=xmltostring(collected[c].dt)
end
- return collected or {}
+ end
+ return collected or {}
end
function xml.collect_tags(root,pattern,nonamespace)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- local t,n={},0
- for c=1,#collected do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace then
- t[n]=tg
- elseif ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
- end
- return t
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ local t,n={},0
+ for c=1,#collected do
+ local e=collected[c]
+ local ns,tg=e.ns,e.tg
+ n=n+1
+ if nonamespace then
+ t[n]=tg
+ elseif ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
+ end
end
+ return t
+ end
end
local no_root={ no_root=true }
local function redo_ni(d)
- for k=1,#d do
- local dk=d[k]
- if type(dk)=="table" then
- dk.ni=k
- end
+ for k=1,#d do
+ local dk=d[k]
+ if type(dk)=="table" then
+ dk.ni=k
end
+ end
end
xml.reindex=redo_ni
local function xmltoelement(whatever,root)
- if not whatever then
- return nil
- end
- local element
- if type(whatever)=="string" then
- element=xmlinheritedconvert(whatever,root)
- else
- element=whatever
- end
- if element.error then
- return whatever
- end
- if element then
- end
- return element
+ if not whatever then
+ return nil
+ end
+ local element
+ if type(whatever)=="string" then
+ element=xmlinheritedconvert(whatever,root)
+ else
+ element=whatever
+ end
+ if element.error then
+ return whatever
+ end
+ if element then
+ end
+ return element
end
xml.toelement=xmltoelement
local function copiedelement(element,newparent)
- if type(element)=="string" then
- return element
- else
- element=xmlcopy(element).dt
- if newparent and type(element)=="table" then
- element.__p__=newparent
- end
- return element
+ if type(element)=="string" then
+ return element
+ else
+ element=xmlcopy(element).dt
+ if newparent and type(element)=="table" then
+ element.__p__=newparent
end
+ return element
+ end
end
function xml.delete(root,pattern)
- if not pattern or pattern=="" then
- local p=root.__p__
+ if not pattern or pattern=="" then
+ local p=root.__p__
+ if p then
+ if trace_manipulations then
+ report('deleting',"--",c,root)
+ end
+ local d=p.dt
+ remove(d,root.ni)
+ redo_ni(d)
+ end
+ else
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
if p then
- if trace_manipulations then
- report('deleting',"--",c,root)
- end
- local d=p.dt
- remove(d,root.ni)
- redo_ni(d)
- end
- else
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('deleting',pattern,c,e)
- end
- local d=p.dt
- local ni=e.ni
- if ni<=#d then
- if false then
- p.dt[ni]=""
- else
- remove(d,ni)
- redo_ni(d)
- end
- else
- end
- end
+ if trace_manipulations then
+ report('deleting',pattern,c,e)
+ end
+ local d=p.dt
+ local ni=e.ni
+ if ni<=#d then
+ if false then
+ p.dt[ni]=""
+ else
+ remove(d,ni)
+ redo_ni(d)
end
+ else
+ end
end
+ end
end
+ end
end
function xml.replace(root,pattern,whatever)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('replacing',pattern,c,e)
- end
- local d=p.dt
- local n=e.ni
- local t=copiedelement(element,p)
- if type(t)=="table" then
- d[n]=t[1]
- for i=2,#t do
- n=n+1
- insert(d,n,t[i])
- end
- else
- d[n]=t
- end
- redo_ni(d)
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
+ if p then
+ if trace_manipulations then
+ report('replacing',pattern,c,e)
end
+ local d=p.dt
+ local n=e.ni
+ local t=copiedelement(element,p)
+ if type(t)=="table" then
+ d[n]=t[1]
+ for i=2,#t do
+ n=n+1
+ insert(d,n,t[i])
+ end
+ else
+ d[n]=t
+ end
+ redo_ni(d)
+ end
end
+ end
end
local function wrap(e,wrapper)
- local t={
- rn=e.rn,
- tg=e.tg,
- ns=e.ns,
- at=e.at,
- dt=e.dt,
- __p__=e,
- }
- setmetatable(t,getmetatable(e))
- e.rn=wrapper.rn or e.rn or ""
- e.tg=wrapper.tg or e.tg or ""
- e.ns=wrapper.ns or e.ns or ""
- e.at=fastcopy(wrapper.at)
- e.dt={ t }
+ local t={
+ rn=e.rn,
+ tg=e.tg,
+ ns=e.ns,
+ at=e.at,
+ dt=e.dt,
+ __p__=e,
+ }
+ setmetatable(t,getmetatable(e))
+ e.rn=wrapper.rn or e.rn or ""
+ e.tg=wrapper.tg or e.tg or ""
+ e.ns=wrapper.ns or e.ns or ""
+ e.at=fastcopy(wrapper.at)
+ e.dt={ t }
end
function xml.wrap(root,pattern,whatever)
- if whatever then
- local wrapper=xmltoelement(whatever,root)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if trace_manipulations then
- report('wrapping',pattern,c,e)
- end
- wrap(e,wrapper)
- end
+ if whatever then
+ local wrapper=xmltoelement(whatever,root)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if trace_manipulations then
+ report('wrapping',pattern,c,e)
end
- else
- wrap(root,xmltoelement(pattern))
+ wrap(e,wrapper)
+ end
end
+ else
+ wrap(root,xmltoelement(pattern))
+ end
end
local function inject_element(root,pattern,whatever,prepend)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function inject_e(e)
- local r=e.__p__
- local d,k,rri=r.dt,e.ni,r.ri
- local edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
- if edt then
- local be,af
- local cp=copiedelement(element,e)
- if prepend then
- be,af=cp,edt
- else
- be,af=edt,cp
- end
- local bn=#be
- for i=1,#af do
- bn=bn+1
- be[bn]=af[i]
- end
- if rri then
- r.dt[rri].dt=be
- else
- d[k].dt=be
- end
- redo_ni(d)
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ local function inject_e(e)
+ local r=e.__p__
+ local d,k,rri=r.dt,e.ni,r.ri
+ local edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
+ if edt then
+ local be,af
+ local cp=copiedelement(element,e)
+ if prepend then
+ be,af=cp,edt
+ else
+ be,af=edt,cp
+ end
+ local bn=#be
+ for i=1,#af do
+ bn=bn+1
+ be[bn]=af[i]
+ end
+ if rri then
+ r.dt[rri].dt=be
+ else
+ d[k].dt=be
+ end
+ redo_ni(d)
end
- if not collected then
- elseif collected.tg then
- inject_e(collected)
- else
- for c=1,#collected do
- inject_e(collected[c])
- end
+ end
+ if not collected then
+ elseif collected.tg then
+ inject_e(collected)
+ else
+ for c=1,#collected do
+ inject_e(collected[c])
end
+ end
end
local function insert_element(root,pattern,whatever,before)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function insert_e(e)
- local r=e.__p__
- local d,k=r.dt,e.ni
- if not before then
- k=k+1
- end
- insert(d,k,copiedelement(element,r))
- redo_ni(d)
- end
- if not collected then
- elseif collected.tg then
- insert_e(collected)
- else
- for c=1,#collected do
- insert_e(collected[c])
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ local function insert_e(e)
+ local r=e.__p__
+ local d,k=r.dt,e.ni
+ if not before then
+ k=k+1
+ end
+ insert(d,k,copiedelement(element,r))
+ redo_ni(d)
+ end
+ if not collected then
+ elseif collected.tg then
+ insert_e(collected)
+ else
+ for c=1,#collected do
+ insert_e(collected[c])
end
+ end
end
xml.insert_element=insert_element
xml.insertafter=insert_element
@@ -18527,124 +18535,124 @@ xml.insertbefore=function(r,p,e) insert_element(r,p,e,true) end
xml.injectafter=inject_element
xml.injectbefore=function(r,p,e) inject_element(r,p,e,true) end
local function include(xmldata,pattern,attribute,recursive,loaddata,level)
- pattern=pattern or 'include'
- loaddata=loaddata or io.loaddata
- local collected=xmlapplylpath(xmldata,pattern)
- if collected then
- if not level then
- level=1
- end
- for c=1,#collected do
- local ek=collected[c]
- local name=nil
- local ekdt=ek.dt
- if ekdt then
- local ekat=ek.at
- local ekrt=ek.__p__
- if ekrt then
- local epdt=ekrt.dt
- if not attribute or attribute=="" then
- name=(type(ekdt)=="table" and ekdt[1]) or ekdt
- end
- if not name then
- for a in gmatch(attribute or "href","([^|]+)") do
- name=ekat[a]
- if name then
- break
- end
- end
- end
- local data=nil
- if name and name~="" then
- local d,n=loaddata(name)
- data=d or ""
- name=n or name
- if trace_inclusions then
- report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
- end
- end
- if not data or data=="" then
- epdt[ek.ni]=""
- elseif ekat["parse"]=="text" then
- epdt[ek.ni]=xml.escaped(data)
- else
+ pattern=pattern or 'include'
+ loaddata=loaddata or io.loaddata
+ local collected=xmlapplylpath(xmldata,pattern)
+ if collected then
+ if not level then
+ level=1
+ end
+ for c=1,#collected do
+ local ek=collected[c]
+ local name=nil
+ local ekdt=ek.dt
+ if ekdt then
+ local ekat=ek.at
+ local ekrt=ek.__p__
+ if ekrt then
+ local epdt=ekrt.dt
+ if not attribute or attribute=="" then
+ name=(type(ekdt)=="table" and ekdt[1]) or ekdt
+ end
+ if not name then
+ for a in gmatch(attribute or "href","([^|]+)") do
+ name=ekat[a]
+ if name then
+ break
+ end
+ end
+ end
+ local data=nil
+ if name and name~="" then
+ local d,n=loaddata(name)
+ data=d or ""
+ name=n or name
+ if trace_inclusions then
+ report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
+ end
+ end
+ if not data or data=="" then
+ epdt[ek.ni]=""
+ elseif ekat["parse"]=="text" then
+ epdt[ek.ni]=xml.escaped(data)
+ else
local settings=xmldata.settings
local savedresource=settings.currentresource
settings.currentresource=name
- local xi=xmlinheritedconvert(data,xmldata)
- if not xi then
- epdt[ek.ni]=""
- else
- if recursive then
- include(xi,pattern,attribute,recursive,loaddata,level+1)
- end
- local child=xml.body(xi)
- child.__p__=ekrt
- child.__f__=name
+ local xi=xmlinheritedconvert(data,xmldata)
+ if not xi then
+ epdt[ek.ni]=""
+ else
+ if recursive then
+ include(xi,pattern,attribute,recursive,loaddata,level+1)
+ end
+ local child=xml.body(xi)
+ child.__p__=ekrt
+ child.__f__=name
child.cf=name
- epdt[ek.ni]=child
- local settings=xmldata.settings
- local inclusions=settings and settings.inclusions
- if inclusions then
- inclusions[#inclusions+1]=name
- elseif settings then
- settings.inclusions={ name }
- else
- settings={ inclusions={ name } }
- xmldata.settings=settings
- end
- if child.er then
- local badinclusions=settings.badinclusions
- if badinclusions then
- badinclusions[#badinclusions+1]=name
- else
- settings.badinclusions={ name }
- end
- end
- end
-settings.currentresource=savedresource
- end
+ epdt[ek.ni]=child
+ local settings=xmldata.settings
+ local inclusions=settings and settings.inclusions
+ if inclusions then
+ inclusions[#inclusions+1]=name
+ elseif settings then
+ settings.inclusions={ name }
+ else
+ settings={ inclusions={ name } }
+ xmldata.settings=settings
+ end
+ if child.er then
+ local badinclusions=settings.badinclusions
+ if badinclusions then
+ badinclusions[#badinclusions+1]=name
+ else
+ settings.badinclusions={ name }
end
+ end
end
+settings.currentresource=savedresource
+ end
end
+ end
end
+ end
end
xml.include=include
function xml.inclusion(e,default)
- while e do
- local f=e.__f__
- if f then
- return f
- else
- e=e.__p__
- end
+ while e do
+ local f=e.__f__
+ if f then
+ return f
+ else
+ e=e.__p__
end
- return default
+ end
+ return default
end
local function getinclusions(key,e,sorted)
- while e do
- local settings=e.settings
- if settings then
- local inclusions=settings[key]
- if inclusions then
- inclusions=table.unique(inclusions)
- if sorted then
- table.sort(inclusions)
- end
- return inclusions
- else
- e=e.__p__
- end
- else
- e=e.__p__
- end
+ while e do
+ local settings=e.settings
+ if settings then
+ local inclusions=settings[key]
+ if inclusions then
+ inclusions=table.unique(inclusions)
+ if sorted then
+ table.sort(inclusions)
+ end
+ return inclusions
+ else
+ e=e.__p__
+ end
+ else
+ e=e.__p__
end
+ end
end
function xml.inclusions(e,sorted)
- return getinclusions("inclusions",e,sorted)
+ return getinclusions("inclusions",e,sorted)
end
function xml.badinclusions(e,sorted)
- return getinclusions("badinclusions",e,sorted)
+ return getinclusions("badinclusions",e,sorted)
end
local b_collapser=lpegpatterns.b_collapser
local m_collapser=lpegpatterns.m_collapser
@@ -18653,194 +18661,194 @@ local b_stripper=lpegpatterns.b_stripper
local m_stripper=lpegpatterns.m_stripper
local e_stripper=lpegpatterns.e_stripper
local function stripelement(e,nolines,anywhere)
- local edt=e.dt
- if edt then
- local n=#edt
- if n==0 then
- return e
- elseif anywhere then
- local t={}
- local m=0
- for e=1,n do
- local str=edt[e]
- if type(str)~="string" then
- m=m+1
- t[m]=str
- elseif str~="" then
- if nolines then
- str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
- else
- str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
- end
- if str~="" then
- m=m+1
- t[m]=str
- end
- end
- end
- e.dt=t
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==0 then
+ return e
+ elseif anywhere then
+ local t={}
+ local m=0
+ for e=1,n do
+ local str=edt[e]
+ if type(str)~="string" then
+ m=m+1
+ t[m]=str
+ elseif str~="" then
+ if nolines then
+ str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
+ else
+ str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
+ end
+ if str~="" then
+ m=m+1
+ t[m]=str
+ end
+ end
+ end
+ e.dt=t
+ else
+ local str=edt[1]
+ if type(str)=="string" then
+ if str~="" then
+ str=lpegmatch(nolines and b_collapser or b_stripper,str)
+ end
+ if str=="" then
+ remove(edt,1)
+ n=n-1
else
- local str=edt[1]
- if type(str)=="string" then
- if str~="" then
- str=lpegmatch(nolines and b_collapser or b_stripper,str)
- end
- if str=="" then
- remove(edt,1)
- n=n-1
- else
- edt[1]=str
- end
- end
- if n>0 then
- str=edt[n]
- if type(str)=="string" then
- if str=="" then
- remove(edt)
- else
- str=lpegmatch(nolines and e_collapser or e_stripper,str)
- if str=="" then
- remove(edt)
- else
- edt[n]=str
- end
- end
- end
+ edt[1]=str
+ end
+ end
+ if n>0 then
+ str=edt[n]
+ if type(str)=="string" then
+ if str=="" then
+ remove(edt)
+ else
+ str=lpegmatch(nolines and e_collapser or e_stripper,str)
+ if str=="" then
+ remove(edt)
+ else
+ edt[n]=str
end
+ end
end
+ end
end
- return e
+ end
+ return e
end
xml.stripelement=stripelement
function xml.strip(root,pattern,nolines,anywhere)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for i=1,#collected do
- stripelement(collected[i],nolines,anywhere)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for i=1,#collected do
+ stripelement(collected[i],nolines,anywhere)
end
+ end
end
local function renamespace(root,oldspace,newspace)
- local ndt=#root.dt
- for i=1,ndt or 0 do
- local e=root[i]
- if type(e)=="table" then
- if e.ns==oldspace then
- e.ns=newspace
- if e.rn then
- e.rn=newspace
- end
- end
- local edt=e.dt
- if edt then
- renamespace(edt,oldspace,newspace)
- end
+ local ndt=#root.dt
+ for i=1,ndt or 0 do
+ local e=root[i]
+ if type(e)=="table" then
+ if e.ns==oldspace then
+ e.ns=newspace
+ if e.rn then
+ e.rn=newspace
end
+ end
+ local edt=e.dt
+ if edt then
+ renamespace(edt,oldspace,newspace)
+ end
end
+ end
end
xml.renamespace=renamespace
function xml.remaptag(root,pattern,newtg)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].tg=newtg
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].tg=newtg
end
+ end
end
function xml.remapnamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].ns=newns
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].ns=newns
end
+ end
end
function xml.checknamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if (not e.rn or e.rn=="") and e.ns=="" then
- e.rn=newns
- end
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if (not e.rn or e.rn=="") and e.ns=="" then
+ e.rn=newns
+ end
end
+ end
end
function xml.remapname(root,pattern,newtg,newns,newrn)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- e.tg,e.ns,e.rn=newtg,newns,newrn
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ e.tg,e.ns,e.rn=newtg,newns,newrn
end
+ end
end
function xml.cdatatotext(e)
- local dt=e.dt
- if #dt==1 then
- local first=dt[1]
- if first.tg=="@cd@" then
- e.dt=first.dt
- end
- else
+ local dt=e.dt
+ if #dt==1 then
+ local first=dt[1]
+ if first.tg=="@cd@" then
+ e.dt=first.dt
end
+ else
+ end
end
function xml.texttocdata(e)
- local dt=e.dt
- local s=xml.tostring(dt)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(dt)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
function xml.elementtocdata(e)
- local dt=e.dt
- local s=xml.tostring(e)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(e)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
xml.builtinentities=table.tohash { "amp","quot","apos","lt","gt" }
local entities=characters and characters.entities or nil
local builtinentities=xml.builtinentities
function xml.addentitiesdoctype(root,option)
- if not entities then
- require("char-ent")
- entities=characters.entities
- end
- if entities and root and root.tg=="@rt@" and root.statistics then
- local list={}
- local hexify=option=="hexadecimal"
- for k,v in table.sortedhash(root.statistics.entities.names) do
- if not builtinentities[k] then
- local e=entities[k]
- if not e then
- e=format("[%s]",k)
- elseif hexify then
- e=format("&#%05X;",utfbyte(k))
- end
- list[#list+1]=format(" <!ENTITY %s %q >",k,e)
- end
- end
- local dt=root.dt
- local n=dt[1].tg=="@pi@" and 2 or 1
- if #list>0 then
- insert(dt,n,{ "\n" })
- insert(dt,n,{
- tg="@dt@",
- dt={ format("Something [\n%s\n] ",concat(list)) },
- ns="",
- special=true,
- })
- insert(dt,n,{ "\n\n" })
- else
- end
+ if not entities then
+ require("char-ent")
+ entities=characters.entities
+ end
+ if entities and root and root.tg=="@rt@" and root.statistics then
+ local list={}
+ local hexify=option=="hexadecimal"
+ for k,v in table.sortedhash(root.statistics.entities.names) do
+ if not builtinentities[k] then
+ local e=entities[k]
+ if not e then
+ e=format("[%s]",k)
+ elseif hexify then
+ e=format("&#%05X;",utfbyte(k))
+ end
+ list[#list+1]=format(" <!ENTITY %s %q >",k,e)
+ end
end
+ local dt=root.dt
+ local n=dt[1].tg=="@pi@" and 2 or 1
+ if #list>0 then
+ insert(dt,n,{ "\n" })
+ insert(dt,n,{
+ tg="@dt@",
+ dt={ format("Something [\n%s\n] ",concat(list)) },
+ ns="",
+ special=true,
+ })
+ insert(dt,n,{ "\n\n" })
+ else
+ end
+ end
end
xml.all=xml.each
xml.insert=xml.insertafter
@@ -18850,239 +18858,239 @@ xml.before=xml.insertbefore
xml.process=xml.each
xml.obsolete=xml.obsolete or {}
local obsolete=xml.obsolete
-xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
-xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
-xml.delete_element=xml.delete obsolete.delete_element=xml.delete
-xml.replace_element=xml.replace obsolete.replace_element=xml.replace
-xml.each_element=xml.each obsolete.each_element=xml.each
-xml.process_elements=xml.process obsolete.process_elements=xml.process
-xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
-xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
-xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
-xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
-xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
-xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
-xml.inject_element=xml.inject obsolete.inject_element=xml.inject
-xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
-xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
-xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
+xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
+xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
+xml.delete_element=xml.delete obsolete.delete_element=xml.delete
+xml.replace_element=xml.replace obsolete.replace_element=xml.replace
+xml.each_element=xml.each obsolete.each_element=xml.each
+xml.process_elements=xml.process obsolete.process_elements=xml.process
+xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
+xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
+xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
+xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
+xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
+xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
+xml.inject_element=xml.inject obsolete.inject_element=xml.inject
+xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
+xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
+xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
function xml.cdata(e)
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
end
- return ""
+ end
+ return ""
end
function xml.finalizers.xml.cdata(collected)
- if collected then
- local e=collected[1]
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
- end
+ if collected then
+ local e=collected[1]
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
+ end
end
- return ""
+ end
+ return ""
end
function xml.insertcomment(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.insertcdata(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.setcomment(e,str,n)
- e.dt={ {
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.setcdata(e,str)
- e.dt={ {
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.separate(x,pattern)
- local collected=xmlapplylpath(x,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local d=e.dt
- if d==x then
- report_xml("warning: xml.separate changes root")
- x=d
- end
- local t,n={ "\n" },1
- local i,nd=1,#d
- while i<=nd do
- while i<=nd do
- local di=d[i]
- if type(di)=="string" then
- if di=="\n" or find(di,"^%s+$") then
- i=i+1
- else
- d[i]=strip(di)
- break
- end
- else
- break
- end
- end
- if i>nd then
- break
- end
- t[n+1]="\n"
- t[n+2]=d[i]
- t[n+3]="\n"
- n=n+3
- i=i+1
+ local collected=xmlapplylpath(x,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local d=e.dt
+ if d==x then
+ report_xml("warning: xml.separate changes root")
+ x=d
+ end
+ local t,n={ "\n" },1
+ local i,nd=1,#d
+ while i<=nd do
+ while i<=nd do
+ local di=d[i]
+ if type(di)=="string" then
+ if di=="\n" or find(di,"^%s+$") then
+ i=i+1
+ else
+ d[i]=strip(di)
+ break
end
- t[n+1]="\n"
- setmetatable(t,getmetatable(d))
- e.dt=t
+ else
+ break
+ end
end
+ if i>nd then
+ break
+ end
+ t[n+1]="\n"
+ t[n+2]=d[i]
+ t[n+3]="\n"
+ n=n+3
+ i=i+1
+ end
+ t[n+1]="\n"
+ setmetatable(t,getmetatable(d))
+ e.dt=t
end
- return x
+ end
+ return x
end
local helpers=xml.helpers or {}
xml.helpers=helpers
local function normal(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)=="string" and str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)=="string" and str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
local function recurse(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)~="string" then
- recurse(str,action)
- elseif str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)~="string" then
+ recurse(str,action)
+ elseif str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
function helpers.recursetext(collected,action,recursive)
- if recursive then
- for i=1,#collected do
- recurse(collected[i],action)
- end
- else
- for i=1,#collected do
- normal(collected[i],action)
- end
+ if recursive then
+ for i=1,#collected do
+ recurse(collected[i],action)
+ end
+ else
+ for i=1,#collected do
+ normal(collected[i],action)
end
+ end
end
local specials={
- ["@rt@"]="root",
- ["@pi@"]="instruction",
- ["@cm@"]="comment",
- ["@dt@"]="declaration",
- ["@cd@"]="cdata",
+ ["@rt@"]="root",
+ ["@pi@"]="instruction",
+ ["@cm@"]="comment",
+ ["@dt@"]="declaration",
+ ["@cd@"]="cdata",
}
local function convert(x,strip,flat)
- local ns=x.ns
- local tg=x.tg
- local at=x.at
- local dt=x.dt
- local node=flat and {
- [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
- } or {
- _namespace=ns~="" and ns or nil,
- _tag=not x.special and tg or nil,
- _type=specials[tg] or "_element",
- }
- if at then
- for k,v in next,at do
- node[k]=v
+ local ns=x.ns
+ local tg=x.tg
+ local at=x.at
+ local dt=x.dt
+ local node=flat and {
+ [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
+ } or {
+ _namespace=ns~="" and ns or nil,
+ _tag=not x.special and tg or nil,
+ _type=specials[tg] or "_element",
+ }
+ if at then
+ for k,v in next,at do
+ node[k]=v
+ end
+ end
+ local n=0
+ for i=1,#dt do
+ local di=dt[i]
+ if type(di)=="table" then
+ if flat and di.special then
+ else
+ di=convert(di,strip,flat)
+ if di then
+ n=n+1
+ node[n]=di
end
+ end
+ elseif strip then
+ di=lpegmatch(strip,di)
+ if di~="" then
+ n=n+1
+ node[n]=di
+ end
+ else
+ n=n+1
+ node[n]=di
end
- local n=0
- for i=1,#dt do
- local di=dt[i]
- if type(di)=="table" then
- if flat and di.special then
- else
- di=convert(di,strip,flat)
- if di then
- n=n+1
- node[n]=di
- end
- end
- elseif strip then
- di=lpegmatch(strip,di)
- if di~="" then
- n=n+1
- node[n]=di
- end
- else
- n=n+1
- node[n]=di
- end
- end
- if next(node) then
- return node
- end
+ end
+ if next(node) then
+ return node
+ end
end
function xml.totable(x,strip,flat)
- if type(x)=="table" then
- if strip then
- strip=striplinepatterns[strip]
- end
- return convert(x,strip,flat)
+ if type(x)=="table" then
+ if strip then
+ strip=striplinepatterns[strip]
end
+ return convert(x,strip,flat)
+ end
end
function xml.rename(e,namespace,name,attributes)
- if type(e)~="table" or not e.tg then
- return
- end
- if type(name)=="table" then
- attributes=name
- name=namespace
- namespace=""
- elseif type(name)~="string" then
- attributes={}
- name=namespace
- namespace=""
- end
- if type(attributes)~="table" then
- attributes={}
- end
- e.ns=namespace
- e.rn=namespace
- e.tg=name
- e.at=attributes
+ if type(e)~="table" or not e.tg then
+ return
+ end
+ if type(name)=="table" then
+ attributes=name
+ name=namespace
+ namespace=""
+ elseif type(name)~="string" then
+ attributes={}
+ name=namespace
+ namespace=""
+ end
+ if type(attributes)~="table" then
+ attributes={}
+ end
+ e.ns=namespace
+ e.rn=namespace
+ e.tg=name
+ e.at=attributes
end
@@ -19092,14 +19100,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
--- original size: 11096, stripped down to: 8243
+-- original size: 11096, stripped down to: 7702
if not modules then modules={} end modules ['lxml-xml']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber,next=tonumber,next
local concat=table.concat
@@ -19111,241 +19119,241 @@ local xmltostring=xml.tostring
local xmlserialize=xml.serialize
local xmlcollected=xml.collected
local xmlnewhandlers=xml.newhandlers
-local reparsedentity=xml.reparsedentitylpeg
+local reparsedentity=xml.reparsedentitylpeg
local unescapedentity=xml.unescapedentitylpeg
local parsedentity=reparsedentity
local function first(collected)
- return collected and collected[1]
+ return collected and collected[1]
end
local function last(collected)
- return collected and collected[#collected]
+ return collected and collected[#collected]
end
local function all(collected)
- return collected
+ return collected
end
local reverse=table.reversed
local function attribute(collected,name)
- if collected and #collected>0 then
- local at=collected[1].at
- return at and at[name]
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ return at and at[name]
+ end
end
local function att(id,name)
- local at=id.at
- return at and at[name]
+ local at=id.at
+ return at and at[name]
end
local function count(collected)
- return collected and #collected or 0
+ return collected and #collected or 0
end
local function position(collected,n)
- if not collected then
- return 0
- end
- local nc=#collected
- if nc==0 then
- return 0
- end
- n=tonumber(n) or 0
- if n<0 then
- return collected[nc+n+1]
- elseif n>0 then
- return collected[n]
- else
- return collected[1].mi or 0
- end
+ if not collected then
+ return 0
+ end
+ local nc=#collected
+ if nc==0 then
+ return 0
+ end
+ n=tonumber(n) or 0
+ if n<0 then
+ return collected[nc+n+1]
+ elseif n>0 then
+ return collected[n]
+ else
+ return collected[1].mi or 0
+ end
end
local function match(collected)
- return collected and #collected>0 and collected[1].mi or 0
+ return collected and #collected>0 and collected[1].mi or 0
end
local function index(collected)
- return collected and #collected>0 and collected[1].ni or 0
+ return collected and #collected>0 and collected[1].ni or 0
end
local function attributes(collected,arguments)
- if collected and #collected>0 then
- local at=collected[1].at
- if arguments then
- return at[arguments]
- elseif next(at) then
- return at
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ if arguments then
+ return at[arguments]
+ elseif next(at) then
+ return at
end
+ end
end
local function chainattribute(collected,arguments)
- if collected and #collected>0 then
- local e=collected[1]
- while e do
- local at=e.at
- if at then
- local a=at[arguments]
- if a then
- return a
- end
- else
- break
- end
- e=e.__p__
+ if collected and #collected>0 then
+ local e=collected[1]
+ while e do
+ local at=e.at
+ if at then
+ local a=at[arguments]
+ if a then
+ return a
end
+ else
+ break
+ end
+ e=e.__p__
end
- return ""
+ end
+ return ""
end
local function raw(collected)
- if collected and #collected>0 then
- local e=collected[1] or collected
- return e and xmltostring(e) or ""
- else
- return ""
- end
+ if collected and #collected>0 then
+ local e=collected[1] or collected
+ return e and xmltostring(e) or ""
+ else
+ return ""
+ end
end
local xmltexthandler=xmlnewhandlers {
- name="string",
- initialize=function()
- result={}
- return result
- end,
- finalize=function()
- return concat(result)
- end,
- handle=function(...)
- result[#result+1]=concat {... }
- end,
- escape=false,
+ name="string",
+ initialize=function()
+ result={}
+ return result
+ end,
+ finalize=function()
+ return concat(result)
+ end,
+ handle=function(...)
+ result[#result+1]=concat {... }
+ end,
+ escape=false,
}
local function xmltotext(root)
- local dt=root.dt
- if not dt then
- return ""
- end
- local nt=#dt
- if nt==0 then
- return ""
- elseif nt==1 and type(dt[1])=="string" then
- return dt[1]
- else
- return xmlserialize(root,xmltexthandler) or ""
- end
+ local dt=root.dt
+ if not dt then
+ return ""
+ end
+ local nt=#dt
+ if nt==0 then
+ return ""
+ elseif nt==1 and type(dt[1])=="string" then
+ return dt[1]
+ else
+ return xmlserialize(root,xmltexthandler) or ""
+ end
end
function xml.serializetotext(root)
- return root and xmlserialize(root,xmltexthandler) or ""
+ return root and xmlserialize(root,xmltexthandler) or ""
end
local function text(collected)
- if collected then
- local e=collected[1] or collected
- return e and xmltotext(e) or ""
- else
- return ""
- end
+ if collected then
+ local e=collected[1] or collected
+ return e and xmltotext(e) or ""
+ else
+ return ""
+ end
end
local function texts(collected)
- if not collected then
- return {}
- end
- local nc=#collected
- if nc==0 then
- return {}
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- if e and e.dt then
- n=n+1
- t[n]=e.dt
- end
- end
- return t
+ if not collected then
+ return {}
+ end
+ local nc=#collected
+ if nc==0 then
+ return {}
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ if e and e.dt then
+ n=n+1
+ t[n]=e.dt
+ end
+ end
+ return t
end
local function tag(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- return c and c.tg
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ return c and c.tg
end
local function name(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- if not c then
- elseif c.ns=="" then
- return c.tg
- else
- return c.ns..":"..c.tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ if not c then
+ elseif c.ns=="" then
+ return c.tg
+ else
+ return c.ns..":"..c.tg
+ end
end
local function tags(collected,nonamespace)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace or ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ local ns,tg=e.ns,e.tg
+ n=n+1
+ if nonamespace or ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
end
- return t
+ end
+ return t
end
local function empty(collected,spacesonly)
- if not collected then
- return true
- end
- local nc=#collected
- if nc==0 then
- return true
- end
- for c=1,nc do
- local e=collected[c]
- if e then
- local edt=e.dt
- if edt then
- local n=#edt
- if n==1 then
- local edk=edt[1]
- local typ=type(edk)
- if typ=="table" then
- return false
- elseif edk~="" then
- return false
- elseif spacesonly and not find(edk,"%S") then
- return false
- end
- elseif n>1 then
- return false
- end
- end
+ if not collected then
+ return true
+ end
+ local nc=#collected
+ if nc==0 then
+ return true
+ end
+ for c=1,nc do
+ local e=collected[c]
+ if e then
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==1 then
+ local edk=edt[1]
+ local typ=type(edk)
+ if typ=="table" then
+ return false
+ elseif edk~="" then
+ return false
+ elseif spacesonly and not find(edk,"%S") then
+ return false
+ end
+ elseif n>1 then
+ return false
end
+ end
end
- return true
+ end
+ return true
end
finalizers.first=first
finalizers.last=last
@@ -19368,124 +19376,124 @@ finalizers.name=name
finalizers.tags=tags
finalizers.empty=empty
function xml.first(id,pattern)
- return first(xmlfilter(id,pattern))
+ return first(xmlfilter(id,pattern))
end
function xml.last(id,pattern)
- return last(xmlfilter(id,pattern))
+ return last(xmlfilter(id,pattern))
end
function xml.count(id,pattern)
- return count(xmlfilter(id,pattern))
+ return count(xmlfilter(id,pattern))
end
function xml.attribute(id,pattern,a,default)
- return attribute(xmlfilter(id,pattern),a,default)
+ return attribute(xmlfilter(id,pattern),a,default)
end
function xml.raw(id,pattern)
- if pattern then
- return raw(xmlfilter(id,pattern))
- else
- return raw(id)
- end
+ if pattern then
+ return raw(xmlfilter(id,pattern))
+ else
+ return raw(id)
+ end
end
function xml.text(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- return collected and #collected>0 and xmltotext(collected[1]) or ""
- elseif id then
- return xmltotext(id) or ""
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ return collected and #collected>0 and xmltotext(collected[1]) or ""
+ elseif id then
+ return xmltotext(id) or ""
+ else
+ return ""
+ end
end
function xml.pure(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- if collected and #collected>0 then
- parsedentity=unescapedentity
- local s=collected and #collected>0 and xmltotext(collected[1]) or ""
- parsedentity=reparsedentity
- return s
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ if collected and #collected>0 then
+ parsedentity=unescapedentity
+ local s=collected and #collected>0 and xmltotext(collected[1]) or ""
+ parsedentity=reparsedentity
+ return s
else
- parsedentity=unescapedentity
- local s=xmltotext(id) or ""
- parsedentity=reparsedentity
- return s
+ return ""
end
+ else
+ parsedentity=unescapedentity
+ local s=xmltotext(id) or ""
+ parsedentity=reparsedentity
+ return s
+ end
end
xml.content=text
function xml.position(id,pattern,n)
- return position(xmlfilter(id,pattern),n)
+ return position(xmlfilter(id,pattern),n)
end
function xml.match(id,pattern)
- return match(xmlfilter(id,pattern))
+ return match(xmlfilter(id,pattern))
end
function xml.empty(id,pattern,spacesonly)
- return empty(xmlfilter(id,pattern),spacesonly)
+ return empty(xmlfilter(id,pattern),spacesonly)
end
xml.all=xml.filter
xml.index=xml.position
xml.found=xml.filter
local function totable(x)
- local t={}
- for e in xmlcollected(x[1] or x,"/*") do
- t[e.tg]=xmltostring(e.dt) or ""
- end
- return next(t) and t or nil
+ local t={}
+ for e in xmlcollected(x[1] or x,"/*") do
+ t[e.tg]=xmltostring(e.dt) or ""
+ end
+ return next(t) and t or nil
end
xml.table=totable
finalizers.table=totable
local function textonly(e,t)
- if e then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- textonly(e,t)
- else
- t[#t+1]=e
- end
- end
+ if e then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ textonly(e,t)
+ else
+ t[#t+1]=e
end
+ end
end
- return t
+ end
+ return t
end
function xml.textonly(e)
- return concat(textonly(e,{}))
+ return concat(textonly(e,{}))
end
function finalizers.lowerall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=lower(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[lower(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=lower(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[lower(k)]=v
end
+ e.at=t
+ end
end
+ end
end
function finalizers.upperall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=upper(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[upper(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=upper(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[upper(k)]=v
end
+ e.at=t
+ end
end
+ end
end
@@ -19495,14 +19503,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-xml"] = package.loaded["trac-xml"] or true
--- original size: 6407, stripped down to: 4965
+-- original size: 6407, stripped down to: 4640
if not modules then modules={} end modules ['trac-xml']={
- version=1.001,
- comment="companion to trac-log.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local formatters=string.formatters
local reporters=logs.reporters
@@ -19511,152 +19519,152 @@ local xmlcollected=xml.collected
local xmltext=xml.text
local xmlfirst=xml.first
local function showhelp(specification,...)
- local root=xml.convert(specification.helpinfo or "")
- if not root then
- return
- end
- local xs=xml.gethandlers("string")
- xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
- xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
- local wantedcategories=select("#",...)==0 and true or table.tohash {... }
- local nofcategories=xml.count(root,"/application/flags/category")
- local report=specification.report
- for category in xmlcollected(root,"/application/flags/category") do
- local categoryname=category.at.name or ""
- if wantedcategories==true or wantedcategories[categoryname] then
- if nofcategories>1 then
- report("%s options:",categoryname)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for flag in xmlcollected(subcategory,"/flag") do
- local name=flag.at.name
- local value=flag.at.value
- local short=xmltext(xmlfirst(flag,"/short"))
- if value then
- report("--%-20s %s",formatters["%s=%s"](name,value),short)
- else
- report("--%-20s %s",name,short)
- end
- end
- report()
- end
- end
- end
- for category in xmlcollected(root,"/application/examples/category") do
- local title=xmltext(xmlfirst(category,"/title"))
- if title and title~="" then
- report()
- report(title)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for example in xmlcollected(subcategory,"/example") do
- local command=xmltext(xmlfirst(example,"/command"))
- local comment=xmltext(xmlfirst(example,"/comment"))
- report(command)
- end
- report()
- end
- end
- for comment in xmlcollected(root,"/application/comments/comment") do
- local comment=xmltext(comment)
+ local root=xml.convert(specification.helpinfo or "")
+ if not root then
+ return
+ end
+ local xs=xml.gethandlers("string")
+ xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
+ xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
+ local wantedcategories=select("#",...)==0 and true or table.tohash {... }
+ local nofcategories=xml.count(root,"/application/flags/category")
+ local report=specification.report
+ for category in xmlcollected(root,"/application/flags/category") do
+ local categoryname=category.at.name or ""
+ if wantedcategories==true or wantedcategories[categoryname] then
+ if nofcategories>1 then
+ report("%s options:",categoryname)
report()
- report(comment)
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for flag in xmlcollected(subcategory,"/flag") do
+ local name=flag.at.name
+ local value=flag.at.value
+ local short=xmltext(xmlfirst(flag,"/short"))
+ if value then
+ report("--%-20s %s",formatters["%s=%s"](name,value),short)
+ else
+ report("--%-20s %s",name,short)
+ end
+ end
report()
+ end
+ end
+ end
+ for category in xmlcollected(root,"/application/examples/category") do
+ local title=xmltext(xmlfirst(category,"/title"))
+ if title and title~="" then
+ report()
+ report(title)
+ report()
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for example in xmlcollected(subcategory,"/example") do
+ local command=xmltext(xmlfirst(example,"/command"))
+ local comment=xmltext(xmlfirst(example,"/comment"))
+ report(command)
+ end
+ report()
end
+ end
+ for comment in xmlcollected(root,"/application/comments/comment") do
+ local comment=xmltext(comment)
+ report()
+ report(comment)
+ report()
+ end
end
local reporthelp=reporters.help
local exporthelp=reporters.export
local function xmlfound(t)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="table" then
- return false
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="table" then
+ return false
+ end
+ if type(helpinfo)~="string" then
+ helpinfo="Warning: no helpinfo found."
+ t.helpinfo=helpinfo
+ return false
+ end
+ if string.find(helpinfo,".xml$") then
+ local ownscript=environment.ownscript
+ local helpdata=false
+ if ownscript then
+ local helpfile=file.join(file.pathpart(ownscript),helpinfo)
+ helpdata=io.loaddata(helpfile)
+ if helpdata=="" then
+ helpdata=false
+ end
end
- if type(helpinfo)~="string" then
- helpinfo="Warning: no helpinfo found."
- t.helpinfo=helpinfo
- return false
+ if not helpdata then
+ local helpfile=resolvers.findfile(helpinfo,"tex")
+ helpdata=helpfile and io.loaddata(helpfile)
end
- if string.find(helpinfo,".xml$") then
- local ownscript=environment.ownscript
- local helpdata=false
- if ownscript then
- local helpfile=file.join(file.pathpart(ownscript),helpinfo)
- helpdata=io.loaddata(helpfile)
- if helpdata=="" then
- helpdata=false
- end
- end
- if not helpdata then
- local helpfile=resolvers.findfile(helpinfo,"tex")
- helpdata=helpfile and io.loaddata(helpfile)
- end
- if helpdata and helpdata~="" then
- helpinfo=helpdata
- else
- helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
- end
+ if helpdata and helpdata~="" then
+ helpinfo=helpdata
+ else
+ helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
end
- t.helpinfo=helpinfo
- return string.find(t.helpinfo,"^<%?xml") and true or false
+ end
+ t.helpinfo=helpinfo
+ return string.find(t.helpinfo,"^<%?xml") and true or false
end
function reporters.help(t,...)
- if xmlfound(t) then
- showhelp(t,...)
- else
- reporthelp(t,...)
- end
+ if xmlfound(t) then
+ showhelp(t,...)
+ else
+ reporthelp(t,...)
+ end
end
function reporters.export(t,methods,filename)
- if not xmlfound(t) then
- return exporthelp(t)
- end
- if not methods or methods=="" then
- methods=environment.arguments["exporthelp"]
- end
- if not filename or filename=="" then
- filename=environment.files[1]
- end
- dofile(resolvers.findfile("trac-exp.lua","tex"))
- local exporters=logs.exporters
- if not exporters or not methods then
- return exporthelp(t)
- end
- if methods=="all" then
- methods=table.keys(exporters)
- elseif type(methods)=="string" then
- methods=utilities.parsers.settings_to_array(methods)
- else
- return exporthelp(t)
- end
- if type(filename)~="string" or filename=="" then
- filename=false
- elseif file.pathpart(filename)=="" then
- t.report("export file %a will not be saved on the current path (safeguard)",filename)
- return
- end
- for i=1,#methods do
- local method=methods[i]
- local exporter=exporters[method]
- if exporter then
- local result=exporter(t,method)
- if result and result~="" then
- if filename then
- local fullname=file.replacesuffix(filename,method)
- t.report("saving export in %a",fullname)
- dir.mkdirs(file.pathpart(fullname))
- io.savedata(fullname,result)
- else
- reporters.lines(t,result)
- end
- else
- t.report("no output from exporter %a",method)
- end
+ if not xmlfound(t) then
+ return exporthelp(t)
+ end
+ if not methods or methods=="" then
+ methods=environment.arguments["exporthelp"]
+ end
+ if not filename or filename=="" then
+ filename=environment.files[1]
+ end
+ dofile(resolvers.findfile("trac-exp.lua","tex"))
+ local exporters=logs.exporters
+ if not exporters or not methods then
+ return exporthelp(t)
+ end
+ if methods=="all" then
+ methods=table.keys(exporters)
+ elseif type(methods)=="string" then
+ methods=utilities.parsers.settings_to_array(methods)
+ else
+ return exporthelp(t)
+ end
+ if type(filename)~="string" or filename=="" then
+ filename=false
+ elseif file.pathpart(filename)=="" then
+ t.report("export file %a will not be saved on the current path (safeguard)",filename)
+ return
+ end
+ for i=1,#methods do
+ local method=methods[i]
+ local exporter=exporters[method]
+ if exporter then
+ local result=exporter(t,method)
+ if result and result~="" then
+ if filename then
+ local fullname=file.replacesuffix(filename,method)
+ t.report("saving export in %a",fullname)
+ dir.mkdirs(file.pathpart(fullname))
+ io.savedata(fullname,result)
else
- t.report("unknown exporter %a",method)
+ reporters.lines(t,result)
end
+ else
+ t.report("no output from exporter %a",method)
+ end
+ else
+ t.report("unknown exporter %a",method)
end
+ end
end
@@ -19666,149 +19674,149 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-ini"] = package.loaded["data-ini"] or true
--- original size: 11099, stripped down to: 7516
+-- original size: 11099, stripped down to: 7152
if not modules then modules={} end modules ['data-ini']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local next,type,getmetatable,rawset=next,type,getmetatable,rawset
local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char
local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join
local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv
local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
local report_initialization=logs.reporter("resolvers","initialization")
resolvers=resolvers or {}
local resolvers=resolvers
texconfig.kpse_init=false
texconfig.shell_escape='t'
if not (environment and environment.default_texmfcnf) and kpse and kpse.default_texmfcnf then
- local default_texmfcnf=kpse.default_texmfcnf()
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
- default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
- environment.default_texmfcnf=default_texmfcnf
+ local default_texmfcnf=kpse.default_texmfcnf()
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
+ default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
+ environment.default_texmfcnf=default_texmfcnf
end
kpse={ original=kpse }
setmetatable(kpse,{
- __index=function(kp,name)
- report_initialization("fatal error: kpse library is accessed (key: %s)",name)
- os.exit()
- end
+ __index=function(kp,name)
+ report_initialization("fatal error: kpse library is accessed (key: %s)",name)
+ os.exit()
+ end
} )
do
- local osfontdir=osgetenv("OSFONTDIR")
- if osfontdir and osfontdir~="" then
- elseif osname=="windows" then
- ossetenv("OSFONTDIR","c:/windows/fonts//")
- elseif osname=="macosx" then
- ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
- end
+ local osfontdir=osgetenv("OSFONTDIR")
+ if osfontdir and osfontdir~="" then
+ elseif osname=="windows" then
+ ossetenv("OSFONTDIR","c:/windows/fonts//")
+ elseif osname=="macosx" then
+ ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
+ end
end
do
- local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
- if not homedir or homedir=="" then
- homedir=char(127)
- end
- homedir=file.collapsepath(homedir)
- ossetenv("HOME",homedir)
- ossetenv("USERPROFILE",homedir)
- environment.homedir=homedir
+ local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
+ if not homedir or homedir=="" then
+ homedir=char(127)
+ end
+ homedir=file.collapsepath(homedir)
+ ossetenv("HOME",homedir)
+ ossetenv("USERPROFILE",homedir)
+ environment.homedir=homedir
end
do
- local args=environment.originalarguments or arg
- if not environment.ownmain then
- environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
- end
- local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
- local ownpath=environment.ownpath or os.selfdir
- ownbin=file.collapsepath(ownbin)
- ownpath=file.collapsepath(ownpath)
- if not ownpath or ownpath=="" or ownpath=="unset" then
- ownpath=args[-1] or arg[-1]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- if not ownpath or ownpath=="" then
- ownpath=args[-0] or arg[-0]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- end
- local binary=ownbin
- if not ownpath or ownpath=="" then
- ownpath=ownpath and filedirname(binary)
- end
- if not ownpath or ownpath=="" then
- if os.binsuffix~="" then
- binary=file.replacesuffix(binary,os.binsuffix)
- end
- local path=osgetenv("PATH")
- if path then
- for p in gmatch(path,"[^"..io.pathseparator.."]+") do
- local b=filejoin(p,binary)
- if lfs.isfile(b) then
- local olddir=lfs.currentdir()
- if lfs.chdir(p) then
- local pp=lfs.currentdir()
- if trace_locating and p~=pp then
- report_initialization("following symlink %a to %a",p,pp)
- end
- ownpath=pp
- lfs.chdir(olddir)
- else
- if trace_locating then
- report_initialization("unable to check path %a",p)
- end
- ownpath=p
- end
- break
- end
- end
+ local args=environment.originalarguments or arg
+ if not environment.ownmain then
+ environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
+ end
+ local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
+ local ownpath=environment.ownpath or os.selfdir
+ ownbin=file.collapsepath(ownbin)
+ ownpath=file.collapsepath(ownpath)
+ if not ownpath or ownpath=="" or ownpath=="unset" then
+ ownpath=args[-1] or arg[-1]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ if not ownpath or ownpath=="" then
+ ownpath=args[-0] or arg[-0]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ end
+ local binary=ownbin
+ if not ownpath or ownpath=="" then
+ ownpath=ownpath and filedirname(binary)
+ end
+ if not ownpath or ownpath=="" then
+ if os.binsuffix~="" then
+ binary=file.replacesuffix(binary,os.binsuffix)
+ end
+ local path=osgetenv("PATH")
+ if path then
+ for p in gmatch(path,"[^"..io.pathseparator.."]+") do
+ local b=filejoin(p,binary)
+ if lfs.isfile(b) then
+ local olddir=lfs.currentdir()
+ if lfs.chdir(p) then
+ local pp=lfs.currentdir()
+ if trace_locating and p~=pp then
+ report_initialization("following symlink %a to %a",p,pp)
+ end
+ ownpath=pp
+ lfs.chdir(olddir)
+ else
+ if trace_locating then
+ report_initialization("unable to check path %a",p)
+ end
+ ownpath=p
end
+ break
+ end
end
- if not ownpath or ownpath=="" then
- ownpath="."
- report_initialization("forcing fallback to ownpath %a",ownpath)
- elseif trace_locating then
- report_initialization("using ownpath %a",ownpath)
- end
+ end
end
- environment.ownbin=ownbin
- environment.ownpath=ownpath
+ if not ownpath or ownpath=="" then
+ ownpath="."
+ report_initialization("forcing fallback to ownpath %a",ownpath)
+ elseif trace_locating then
+ report_initialization("using ownpath %a",ownpath)
+ end
+ end
+ environment.ownbin=ownbin
+ environment.ownpath=ownpath
end
resolvers.ownpath=environment.ownpath
function resolvers.getownpath()
- return environment.ownpath
+ return environment.ownpath
end
do
- local ownpath=environment.ownpath or dir.current()
- if ownpath then
- ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
- ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
- ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
- else
- report_initialization("error: unable to locate ownpath")
- os.exit()
- end
-end
-local texos=environment.texos or osgetenv("TEXOS")
+ local ownpath=environment.ownpath or dir.current()
+ if ownpath then
+ ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
+ ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
+ ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
+ else
+ report_initialization("error: unable to locate ownpath")
+ os.exit()
+ end
+end
+local texos=environment.texos or osgetenv("TEXOS")
local texmfos=environment.texmfos or osgetenv('SELFAUTODIR')
if not texos or texos=="" then
- texos=file.basename(texmfos)
+ texos=file.basename(texmfos)
end
ossetenv('TEXMFOS',texmfos)
-ossetenv('TEXOS',texos)
-ossetenv('SELFAUTOSYSTEM',os.platform)
+ossetenv('TEXOS',texos)
+ossetenv('SELFAUTOSYSTEM',os.platform)
environment.texos=texos
environment.texmfos=texmfos
local texroot=environment.texroot or osgetenv("TEXROOT")
if not texroot or texroot=="" then
- texroot=osgetenv('SELFAUTOPARENT')
- ossetenv('TEXROOT',texroot)
+ texroot=osgetenv('SELFAUTOPARENT')
+ ossetenv('TEXROOT',texroot)
end
environment.texroot=file.collapsepath(texroot)
local prefixes=utilities.storage.allocate()
@@ -19817,30 +19825,30 @@ local resolved={}
local abstract={}
local dynamic={}
function resolvers.resetresolve(str)
- resolved,abstract={},{}
+ resolved,abstract={},{}
end
function resolvers.allprefixes(separator)
- local all=table.sortedkeys(prefixes)
- if separator then
- for i=1,#all do
- all[i]=all[i]..":"
- end
+ local all=table.sortedkeys(prefixes)
+ if separator then
+ for i=1,#all do
+ all[i]=all[i]..":"
end
- return all
+ end
+ return all
end
local function _resolve_(method,target)
- local action=prefixes[method]
- if action then
- return action(target)
- else
- return method..":"..target
- end
+ local action=prefixes[method]
+ if action then
+ return action(target)
+ else
+ return method..":"..target
+ end
end
function resolvers.unresolve(str)
- return abstract[str] or str
+ return abstract[str] or str
end
function resolvers.setdynamic(str)
- dynamic[str]=true
+ dynamic[str]=true
end
local pattern=Cs((C(R("az")^2)*P(":")*C((1-S(" \"\';,"))^1)/_resolve_+P(1))^0)
local prefix=C(R("az")^2)*P(":")
@@ -19849,65 +19857,65 @@ local notarget=(#S(";,")+P(-1))*Cc("")
local p_resolve=Cs(((prefix*(target+notarget))/_resolve_+P(1))^0)
local p_simple=prefix*P(-1)
local function resolve(str)
- if type(str)=="table" then
- local res={}
- for i=1,#str do
- res[i]=resolve(str[i])
- end
- return res
- end
- local res=resolved[str]
- if res then
- return res
+ if type(str)=="table" then
+ local res={}
+ for i=1,#str do
+ res[i]=resolve(str[i])
end
- local simple=lpegmatch(p_simple,str)
- local action=prefixes[simple]
- if action then
- local res=action(res)
- if not dynamic[simple] then
- resolved[simple]=res
- abstract[res]=simple
- end
- return res
+ return res
+ end
+ local res=resolved[str]
+ if res then
+ return res
+ end
+ local simple=lpegmatch(p_simple,str)
+ local action=prefixes[simple]
+ if action then
+ local res=action(res)
+ if not dynamic[simple] then
+ resolved[simple]=res
+ abstract[res]=simple
end
- res=lpegmatch(p_resolve,str)
- resolved[str]=res
- abstract[res]=str
return res
+ end
+ res=lpegmatch(p_resolve,str)
+ resolved[str]=res
+ abstract[res]=str
+ return res
end
resolvers.resolve=resolve
if type(osuname)=="function" then
- for k,v in next,osuname() do
- if not prefixes[k] then
- prefixes[k]=function() return v end
- end
+ for k,v in next,osuname() do
+ if not prefixes[k] then
+ prefixes[k]=function() return v end
end
+ end
end
if ostype=="unix" then
- local pattern
- local function makepattern(t,k,v)
- if t then
- rawset(t,k,v)
- end
- local colon=P(":")
- for k,v in table.sortedpairs(prefixes) do
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- pattern=Cs((p*colon+colon/";"+P(1))^0)
- end
- makepattern()
- table.setmetatablenewindex(prefixes,makepattern)
- function resolvers.repath(str)
- return lpegmatch(pattern,str)
+ local pattern
+ local function makepattern(t,k,v)
+ if t then
+ rawset(t,k,v)
+ end
+ local colon=P(":")
+ for k,v in table.sortedpairs(prefixes) do
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
end
+ pattern=Cs((p*colon+colon/";"+P(1))^0)
+ end
+ makepattern()
+ table.setmetatablenewindex(prefixes,makepattern)
+ function resolvers.repath(str)
+ return lpegmatch(pattern,str)
+ end
else
- function resolvers.repath(str)
- return str
- end
+ function resolvers.repath(str)
+ return str
+ end
end
@@ -19917,14 +19925,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-exp"] = package.loaded["data-exp"] or true
--- original size: 18105, stripped down to: 11207
+-- original size: 18105, stripped down to: 10389
if not modules then modules={} end modules ['data-exp']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub
local concat,sort=table.concat,table.sort
@@ -19934,21 +19942,21 @@ local Ct,Cs,Cc,Carg,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.P,lpeg.C,lpeg.S
local type,next=type,next
local isdir=lfs.isdir
local collapsepath,joinpath,basename=file.collapsepath,file.join,file.basename
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
local report_expansions=logs.reporter("resolvers","expansions")
local report_globbing=logs.reporter("resolvers","globbing")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
local function f_both(a,b)
- local t,n={},0
- for sb in gmatch(b,"[^,]+") do
- for sa in gmatch(a,"[^,]+") do
- n=n+1;t[n]=sa..sb
- end
+ local t,n={},0
+ for sb in gmatch(b,"[^,]+") do
+ for sa in gmatch(a,"[^,]+") do
+ n=n+1;t[n]=sa..sb
end
- return concat(t,",")
+ end
+ return concat(t,",")
end
local comma=P(",")
local nocomma=(1-comma)^1
@@ -19958,7 +19966,7 @@ local after=Cs((Carg(1)*nocomma+docomma)^0)
local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0)
local function f_first (a,b) return lpegmatch(after,b,1,a) end
local function f_second(a,b) return lpegmatch(before,a,1,b) end
-local function f_both (a,b) return lpegmatch(both,b,1,a) end
+local function f_both (a,b) return lpegmatch(both,b,1,a) end
local left=P("{")
local right=P("}")
local var=P((1-S("{}" ))^0)
@@ -19971,141 +19979,141 @@ local l_rest=Cs((left*var*(left/"")*var*(right/"")*var*right+other )^0 )
local stripper_1=lpeg.stripper ("{}@")
local replacer_1=lpeg.replacer { { ",}",",@}" },{ "{,","{@," },}
local function splitpathexpr(str,newlist,validate)
- if trace_expansions then
- report_expansions("expanding variable %a",str)
- end
- local t,ok,done=newlist or {},false,false
- local n=#t
- str=lpegmatch(replacer_1,str)
+ if trace_expansions then
+ report_expansions("expanding variable %a",str)
+ end
+ local t,ok,done=newlist or {},false,false
+ local n=#t
+ str=lpegmatch(replacer_1,str)
+ repeat
+ local old=str
repeat
- local old=str
- repeat
- local old=str
- str=lpegmatch(l_first,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_second,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_both,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_rest,str)
- until old==str
- until old==str
- str=lpegmatch(stripper_1,str)
- if validate then
- for s in gmatch(str,"[^,]+") do
- s=validate(s)
- if s then
- n=n+1
- t[n]=s
- end
- end
- else
- for s in gmatch(str,"[^,]+") do
- n=n+1
- t[n]=s
- end
+ local old=str
+ str=lpegmatch(l_first,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_second,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_both,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_rest,str)
+ until old==str
+ until old==str
+ str=lpegmatch(stripper_1,str)
+ if validate then
+ for s in gmatch(str,"[^,]+") do
+ s=validate(s)
+ if s then
+ n=n+1
+ t[n]=s
+ end
end
- if trace_expansions then
- for k=1,#t do
- report_expansions("% 4i: %s",k,t[k])
- end
+ else
+ for s in gmatch(str,"[^,]+") do
+ n=n+1
+ t[n]=s
end
- return t
+ end
+ if trace_expansions then
+ for k=1,#t do
+ report_expansions("% 4i: %s",k,t[k])
+ end
+ end
+ return t
end
local function validate(s)
- s=collapsepath(s)
- return s~="" and not find(s,"^!*unset/*$") and s
+ s=collapsepath(s)
+ return s~="" and not find(s,"^!*unset/*$") and s
end
resolvers.validatedpath=validate
function resolvers.expandedpathfromlist(pathlist)
- local newlist={}
- for k=1,#pathlist do
- splitpathexpr(pathlist[k],newlist,validate)
- end
- return newlist
+ local newlist={}
+ for k=1,#pathlist do
+ splitpathexpr(pathlist[k],newlist,validate)
+ end
+ return newlist
end
local usedhomedir=nil
-local donegation=(P("!")/"" )^0
+local donegation=(P("!")/"" )^0
local doslashes=(P("\\")/"/"+1)^0
local function expandedhome()
- if not usedhomedir then
- usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
- if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
- if trace_expansions then
- report_expansions("no home dir set, ignoring dependent path using current path")
- end
- usedhomedir="."
- end
+ if not usedhomedir then
+ usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
+ if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
+ if trace_expansions then
+ report_expansions("no home dir set, ignoring dependent path using current path")
+ end
+ usedhomedir="."
end
- return usedhomedir
+ end
+ return usedhomedir
end
local dohome=((P("~")+P("$HOME")+P("%HOME%"))/expandedhome)^0
local cleanup=Cs(donegation*dohome*doslashes)
resolvers.cleanpath=function(str)
- return str and lpegmatch(cleanup,str) or ""
+ return str and lpegmatch(cleanup,str) or ""
end
local expandhome=P("~")/"$HOME"
local dodouble=P('"')/""*(expandhome+(1-P('"')))^0*P('"')/""
local dosingle=P("'")/""*(expandhome+(1-P("'")))^0*P("'")/""
-local dostring=(expandhome+1 )^0
+local dostring=(expandhome+1 )^0
local stripper=Cs(
- lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
+ lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
)
function resolvers.checkedvariable(str)
- return type(str)=="string" and lpegmatch(stripper,str) or str
+ return type(str)=="string" and lpegmatch(stripper,str) or str
end
local cache={}
local splitter=lpeg.tsplitat(";")
local backslashswapper=lpeg.replacer("\\","/")
local function splitconfigurationpath(str)
- if str then
- local found=cache[str]
- if not found then
- if str=="" then
- found={}
- else
- local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
- found={}
- local noffound=0
- for i=1,#split do
- local s=split[i]
- if not find(s,"^{*unset}*") then
- noffound=noffound+1
- found[noffound]=s
- end
- end
- if trace_expansions then
- report_expansions("splitting path specification %a",str)
- for k=1,noffound do
- report_expansions("% 4i: %s",k,found[k])
- end
- end
- cache[str]=found
- end
+ if str then
+ local found=cache[str]
+ if not found then
+ if str=="" then
+ found={}
+ else
+ local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
+ found={}
+ local noffound=0
+ for i=1,#split do
+ local s=split[i]
+ if not find(s,"^{*unset}*") then
+ noffound=noffound+1
+ found[noffound]=s
+ end
end
- return found
+ if trace_expansions then
+ report_expansions("splitting path specification %a",str)
+ for k=1,noffound do
+ report_expansions("% 4i: %s",k,found[k])
+ end
+ end
+ cache[str]=found
+ end
end
+ return found
+ end
end
resolvers.splitconfigurationpath=splitconfigurationpath
function resolvers.splitpath(str)
- if type(str)=='table' then
- return str
- else
- return splitconfigurationpath(str)
- end
+ if type(str)=='table' then
+ return str
+ else
+ return splitconfigurationpath(str)
+ end
end
function resolvers.joinpath(str)
- if type(str)=='table' then
- return joinpath(str)
- else
- return str
- end
+ if type(str)=='table' then
+ return joinpath(str)
+ else
+ return str
+ end
end
local attributes,directory=lfs.attributes,lfs.dir
local weird=P(".")^1+lpeg.anywhere(S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t"))
@@ -20118,201 +20126,201 @@ local fullcache={}
local nofsharedscans=0
local addcasecraptoo=true
local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant)
- local full=path=="" and spec or (spec..path..'/')
- local dirlist={}
- local nofdirs=0
- local pattern=tolerant and lessweird or weird
- local filelist={}
- local noffiles=0
- for name in directory(full) do
- if not lpegmatch(pattern,name) then
- local mode=attributes(full..name,"mode")
- if mode=="file" then
- n=n+1
- noffiles=noffiles+1
- filelist[noffiles]=name
- elseif mode=="directory" then
- m=m+1
- nofdirs=nofdirs+1
- if path~="" then
- dirlist[nofdirs]=path.."/"..name
- else
- dirlist[nofdirs]=name
- end
- end
+ local full=path=="" and spec or (spec..path..'/')
+ local dirlist={}
+ local nofdirs=0
+ local pattern=tolerant and lessweird or weird
+ local filelist={}
+ local noffiles=0
+ for name in directory(full) do
+ if not lpegmatch(pattern,name) then
+ local mode=attributes(full..name,"mode")
+ if mode=="file" then
+ n=n+1
+ noffiles=noffiles+1
+ filelist[noffiles]=name
+ elseif mode=="directory" then
+ m=m+1
+ nofdirs=nofdirs+1
+ if path~="" then
+ dirlist[nofdirs]=path.."/"..name
+ else
+ dirlist[nofdirs]=name
end
+ end
end
- if noffiles>0 then
- sort(filelist)
- for i=1,noffiles do
- local name=filelist[i]
- local lower=lower(name)
- local paths=files[lower]
- if paths then
- if onlyone then
- else
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- if addcasecraptoo then
- local paths=files[name]
- if not paths then
- files[name]=path
- elseif type(paths)=="string" then
- files[name]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- end
- if type(paths)=="string" then
- files[lower]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- else
- files[lower]=path
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- end
+ end
+ if noffiles>0 then
+ sort(filelist)
+ for i=1,noffiles do
+ local name=filelist[i]
+ local lower=lower(name)
+ local paths=files[lower]
+ if paths then
+ if onlyone then
+ else
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
+ if addcasecraptoo then
+ local paths=files[name]
+ if not paths then
+ files[name]=path
+ elseif type(paths)=="string" then
+ files[name]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
+ end
+ if type(paths)=="string" then
+ files[lower]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
- end
- if nofdirs>0 then
- sort(dirlist)
- for i=1,nofdirs do
- files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
+ else
+ files[lower]=path
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
end
+ end
+ end
+ end
+ if nofdirs>0 then
+ sort(dirlist)
+ for i=1,nofdirs do
+ files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
end
- scancache[sub(full,1,-2)]=files
- return files,remap,n,m,r
+ end
+ scancache[sub(full,1,-2)]=files
+ return files,remap,n,m,r
end
function resolvers.scanfiles(path,branch,usecache,onlyonce,tolerant)
- local realpath=resolveprefix(path)
- if usecache then
- local content=fullcache[realpath]
- if content then
- if trace_locating then
- report_expansions("using cached scan of path %a, branch %a",path,branch or path)
- end
- nofsharedscans=nofsharedscans+1
- return content
- end
- end
- statistics.starttiming(timer)
+ local realpath=resolveprefix(path)
+ if usecache then
+ local content=fullcache[realpath]
+ if content then
+ if trace_locating then
+ report_expansions("using cached scan of path %a, branch %a",path,branch or path)
+ end
+ nofsharedscans=nofsharedscans+1
+ return content
+ end
+ end
+ statistics.starttiming(timer)
+ if trace_locating then
+ report_expansions("scanning path %a, branch %a",path,branch or path)
+ end
+ local content
+ if isdir(realpath) then
+ local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
+ content={
+ metadata={
+ path=path,
+ files=n,
+ directories=m,
+ remappings=r,
+ },
+ files=files,
+ remap=remap,
+ }
if trace_locating then
- report_expansions("scanning path %a, branch %a",path,branch or path)
+ report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
end
- local content
- if isdir(realpath) then
- local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
- content={
- metadata={
- path=path,
- files=n,
- directories=m,
- remappings=r,
- },
- files=files,
- remap=remap,
- }
- if trace_locating then
- report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
- end
- else
- content={
- metadata={
- path=path,
- files=0,
- directories=0,
- remappings=0,
- },
- files={},
- remap={},
- }
- if trace_locating then
- report_expansions("invalid path %a",realpath)
- end
- end
- if usecache then
- scanned[#scanned+1]=realpath
- fullcache[realpath]=content
+ else
+ content={
+ metadata={
+ path=path,
+ files=0,
+ directories=0,
+ remappings=0,
+ },
+ files={},
+ remap={},
+ }
+ if trace_locating then
+ report_expansions("invalid path %a",realpath)
end
- nofscans=nofscans+1
- statistics.stoptiming(timer)
- return content
+ end
+ if usecache then
+ scanned[#scanned+1]=realpath
+ fullcache[realpath]=content
+ end
+ nofscans=nofscans+1
+ statistics.stoptiming(timer)
+ return content
end
function resolvers.simplescanfiles(path,branch,usecache)
- return resolvers.scanfiles(path,branch,usecache,true,true)
+ return resolvers.scanfiles(path,branch,usecache,true,true)
end
function resolvers.scandata()
- table.sort(scanned)
- return {
- n=nofscans,
- shared=nofsharedscans,
- time=statistics.elapsedtime(timer),
- paths=scanned,
- }
+ table.sort(scanned)
+ return {
+ n=nofscans,
+ shared=nofsharedscans,
+ time=statistics.elapsedtime(timer),
+ paths=scanned,
+ }
end
function resolvers.get_from_content(content,path,name)
- if not content then
- return
- end
- local files=content.files
- if not files then
- return
- end
- local remap=content.remap
- if not remap then
- return
- end
- if name then
- local used=lower(name)
- return path,remap[used] or used
- else
- local name=path
- local used=lower(name)
- local path=files[used]
- if path then
- return path,remap[used] or used
- end
- end
+ if not content then
+ return
+ end
+ local files=content.files
+ if not files then
+ return
+ end
+ local remap=content.remap
+ if not remap then
+ return
+ end
+ if name then
+ local used=lower(name)
+ return path,remap[used] or used
+ else
+ local name=path
+ local used=lower(name)
+ local path=files[used]
+ if path then
+ return path,remap[used] or used
+ end
+ end
end
local nothing=function() end
function resolvers.filtered_from_content(content,pattern)
- if content and type(pattern)=="string" then
- local pattern=lower(pattern)
- local files=content.files
- local remap=content.remap
- if files and remap then
- local f=sortedkeys(files)
- local n=#f
- local i=0
- local function iterator()
- while i<n do
- i=i+1
- local k=f[i]
- if find(k,pattern) then
- return files[k],remap and remap[k] or k
- end
- end
- end
- return iterator
+ if content and type(pattern)=="string" then
+ local pattern=lower(pattern)
+ local files=content.files
+ local remap=content.remap
+ if files and remap then
+ local f=sortedkeys(files)
+ local n=#f
+ local i=0
+ local function iterator()
+ while i<n do
+ i=i+1
+ local k=f[i]
+ if find(k,pattern) then
+ return files[k],remap and remap[k] or k
+ end
end
+ end
+ return iterator
end
- return nothing
+ end
+ return nothing
end
@@ -20322,14 +20330,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-env"] = package.loaded["data-env"] or true
--- original size: 9360, stripped down to: 6903
+-- original size: 9360, stripped down to: 6312
if not modules then modules={} end modules ['data-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local lower,gsub=string.lower,string.gsub
local next=next
@@ -20349,255 +20357,255 @@ resolvers.suffixmap=suffixmap
resolvers.usertypes=usertypes
local luasuffixes=utilities.lua.suffixes
local relations=allocate {
- core={
- ofm={
- names={ "ofm","omega font metric","omega font metrics" },
- variable='OFMFONTS',
- suffixes={ 'ofm','tfm' },
- },
- ovf={
- names={ "ovf","omega virtual font","omega virtual fonts" },
- variable='OVFFONTS',
- suffixes={ 'ovf','vf' },
- },
- tfm={
- names={ "tfm","tex font metric","tex font metrics" },
- variable='TFMFONTS',
- suffixes={ 'tfm' },
- },
- vf={
- names={ "vf","virtual font","virtual fonts" },
- variable='VFFONTS',
- suffixes={ 'vf' },
- },
- otf={
- names={ "otf","opentype","opentype font","opentype fonts"},
- variable='OPENTYPEFONTS',
- suffixes={ 'otf' },
- },
- ttf={
- names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
- variable='TTFONTS',
- suffixes={ 'ttf','ttc','dfont' },
- },
- afm={
- names={ "afm","adobe font metric","adobe font metrics" },
- variable="AFMFONTS",
- suffixes={ "afm" },
- },
- pfb={
- names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
- variable='T1FONTS',
- suffixes={ 'pfb','pfa' },
- },
- fea={
- names={ "fea","font feature","font features","font feature file","font feature files" },
- variable='FONTFEATURES',
- suffixes={ 'fea' },
- },
- cid={
- names={ "cid","cid map","cid maps","cid file","cid files" },
- variable='FONTCIDMAPS',
- suffixes={ 'cid','cidmap' },
- },
- fmt={
- names={ "fmt","format","tex format" },
- variable='TEXFORMATS',
- suffixes={ 'fmt' },
- },
- mem={
- names={ 'mem',"metapost format" },
- variable='MPMEMS',
- suffixes={ 'mem' },
- },
- mp={
- names={ "mp" },
- variable='MPINPUTS',
- suffixes={ 'mp','mpvi','mpiv','mpii' },
- usertype=true,
- },
- tex={
- names={ "tex" },
- variable='TEXINPUTS',
- suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
- usertype=true,
- },
- icc={
- names={ "icc","icc profile","icc profiles" },
- variable='ICCPROFILES',
- suffixes={ 'icc' },
- },
- texmfscripts={
- names={ "texmfscript","texmfscripts","script","scripts" },
- variable='TEXMFSCRIPTS',
- suffixes={ 'lua','rb','pl','py' },
- },
- lua={
- names={ "lua" },
- variable='LUAINPUTS',
- suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
- usertype=true,
- },
- lib={
- names={ "lib" },
- variable='CLUAINPUTS',
- suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
- },
- bib={
- names={ 'bib' },
- variable='BIBINPUTS',
- suffixes={ 'bib' },
- usertype=true,
- },
- bst={
- names={ 'bst' },
- variable='BSTINPUTS',
- suffixes={ 'bst' },
- usertype=true,
- },
- fontconfig={
- names={ 'fontconfig','fontconfig file','fontconfig files' },
- variable='FONTCONFIG_PATH',
- },
- pk={
- names={ "pk" },
- variable='PKFONTS',
- suffixes={ 'pk' },
- },
+ core={
+ ofm={
+ names={ "ofm","omega font metric","omega font metrics" },
+ variable='OFMFONTS',
+ suffixes={ 'ofm','tfm' },
+ },
+ ovf={
+ names={ "ovf","omega virtual font","omega virtual fonts" },
+ variable='OVFFONTS',
+ suffixes={ 'ovf','vf' },
+ },
+ tfm={
+ names={ "tfm","tex font metric","tex font metrics" },
+ variable='TFMFONTS',
+ suffixes={ 'tfm' },
},
- obsolete={
- enc={
- names={ "enc","enc files","enc file","encoding files","encoding file" },
- variable='ENCFONTS',
- suffixes={ 'enc' },
- },
- map={
- names={ "map","map files","map file" },
- variable='TEXFONTMAPS',
- suffixes={ 'map' },
- },
- lig={
- names={ "lig files","lig file","ligature file","ligature files" },
- variable='LIGFONTS',
- suffixes={ 'lig' },
- },
- opl={
- names={ "opl" },
- variable='OPLFONTS',
- suffixes={ 'opl' },
- },
- ovp={
- names={ "ovp" },
- variable='OVPFONTS',
- suffixes={ 'ovp' },
- },
+ vf={
+ names={ "vf","virtual font","virtual fonts" },
+ variable='VFFONTS',
+ suffixes={ 'vf' },
},
- kpse={
- base={
- names={ 'base',"metafont format" },
- variable='MFBASES',
- suffixes={ 'base','bas' },
- },
- cmap={
- names={ 'cmap','cmap files','cmap file' },
- variable='CMAPFONTS',
- suffixes={ 'cmap' },
- },
- cnf={
- names={ 'cnf' },
- suffixes={ 'cnf' },
- },
- web={
- names={ 'web' },
- suffixes={ 'web','ch' }
- },
- cweb={
- names={ 'cweb' },
- suffixes={ 'w','web','ch' },
- },
- gf={
- names={ 'gf' },
- suffixes={ '<resolution>gf' },
- },
- mf={
- names={ 'mf' },
- variable='MFINPUTS',
- suffixes={ 'mf' },
- },
- mft={
- names={ 'mft' },
- suffixes={ 'mft' },
- },
- pk={
- names={ 'pk' },
- suffixes={ '<resolution>pk' },
- },
+ otf={
+ names={ "otf","opentype","opentype font","opentype fonts"},
+ variable='OPENTYPEFONTS',
+ suffixes={ 'otf' },
},
+ ttf={
+ names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
+ variable='TTFONTS',
+ suffixes={ 'ttf','ttc','dfont' },
+ },
+ afm={
+ names={ "afm","adobe font metric","adobe font metrics" },
+ variable="AFMFONTS",
+ suffixes={ "afm" },
+ },
+ pfb={
+ names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
+ variable='T1FONTS',
+ suffixes={ 'pfb','pfa' },
+ },
+ fea={
+ names={ "fea","font feature","font features","font feature file","font feature files" },
+ variable='FONTFEATURES',
+ suffixes={ 'fea' },
+ },
+ cid={
+ names={ "cid","cid map","cid maps","cid file","cid files" },
+ variable='FONTCIDMAPS',
+ suffixes={ 'cid','cidmap' },
+ },
+ fmt={
+ names={ "fmt","format","tex format" },
+ variable='TEXFORMATS',
+ suffixes={ 'fmt' },
+ },
+ mem={
+ names={ 'mem',"metapost format" },
+ variable='MPMEMS',
+ suffixes={ 'mem' },
+ },
+ mp={
+ names={ "mp" },
+ variable='MPINPUTS',
+ suffixes={ 'mp','mpvi','mpiv','mpii' },
+ usertype=true,
+ },
+ tex={
+ names={ "tex" },
+ variable='TEXINPUTS',
+ suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
+ usertype=true,
+ },
+ icc={
+ names={ "icc","icc profile","icc profiles" },
+ variable='ICCPROFILES',
+ suffixes={ 'icc' },
+ },
+ texmfscripts={
+ names={ "texmfscript","texmfscripts","script","scripts" },
+ variable='TEXMFSCRIPTS',
+ suffixes={ 'lua','rb','pl','py' },
+ },
+ lua={
+ names={ "lua" },
+ variable='LUAINPUTS',
+ suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
+ usertype=true,
+ },
+ lib={
+ names={ "lib" },
+ variable='CLUAINPUTS',
+ suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
+ },
+ bib={
+ names={ 'bib' },
+ variable='BIBINPUTS',
+ suffixes={ 'bib' },
+ usertype=true,
+ },
+ bst={
+ names={ 'bst' },
+ variable='BSTINPUTS',
+ suffixes={ 'bst' },
+ usertype=true,
+ },
+ fontconfig={
+ names={ 'fontconfig','fontconfig file','fontconfig files' },
+ variable='FONTCONFIG_PATH',
+ },
+ pk={
+ names={ "pk" },
+ variable='PKFONTS',
+ suffixes={ 'pk' },
+ },
+ },
+ obsolete={
+ enc={
+ names={ "enc","enc files","enc file","encoding files","encoding file" },
+ variable='ENCFONTS',
+ suffixes={ 'enc' },
+ },
+ map={
+ names={ "map","map files","map file" },
+ variable='TEXFONTMAPS',
+ suffixes={ 'map' },
+ },
+ lig={
+ names={ "lig files","lig file","ligature file","ligature files" },
+ variable='LIGFONTS',
+ suffixes={ 'lig' },
+ },
+ opl={
+ names={ "opl" },
+ variable='OPLFONTS',
+ suffixes={ 'opl' },
+ },
+ ovp={
+ names={ "ovp" },
+ variable='OVPFONTS',
+ suffixes={ 'ovp' },
+ },
+ },
+ kpse={
+ base={
+ names={ 'base',"metafont format" },
+ variable='MFBASES',
+ suffixes={ 'base','bas' },
+ },
+ cmap={
+ names={ 'cmap','cmap files','cmap file' },
+ variable='CMAPFONTS',
+ suffixes={ 'cmap' },
+ },
+ cnf={
+ names={ 'cnf' },
+ suffixes={ 'cnf' },
+ },
+ web={
+ names={ 'web' },
+ suffixes={ 'web','ch' }
+ },
+ cweb={
+ names={ 'cweb' },
+ suffixes={ 'w','web','ch' },
+ },
+ gf={
+ names={ 'gf' },
+ suffixes={ '<resolution>gf' },
+ },
+ mf={
+ names={ 'mf' },
+ variable='MFINPUTS',
+ suffixes={ 'mf' },
+ },
+ mft={
+ names={ 'mft' },
+ suffixes={ 'mft' },
+ },
+ pk={
+ names={ 'pk' },
+ suffixes={ '<resolution>pk' },
+ },
+ },
}
resolvers.relations=relations
function resolvers.updaterelations()
- for category,categories in next,relations do
- for name,relation in next,categories do
- local rn=relation.names
- local rv=relation.variable
- if rn and rv then
- local rs=relation.suffixes
- local ru=relation.usertype
- for i=1,#rn do
- local rni=lower(gsub(rn[i]," ",""))
- formats[rni]=rv
- if rs then
- suffixes[rni]=rs
- for i=1,#rs do
- local rsi=rs[i]
- suffixmap[rsi]=rni
- end
- end
- end
- if ru then
- usertypes[name]=true
- end
+ for category,categories in next,relations do
+ for name,relation in next,categories do
+ local rn=relation.names
+ local rv=relation.variable
+ if rn and rv then
+ local rs=relation.suffixes
+ local ru=relation.usertype
+ for i=1,#rn do
+ local rni=lower(gsub(rn[i]," ",""))
+ formats[rni]=rv
+ if rs then
+ suffixes[rni]=rs
+ for i=1,#rs do
+ local rsi=rs[i]
+ suffixmap[rsi]=rni
end
+ end
+ end
+ if ru then
+ usertypes[name]=true
end
+ end
end
+ end
end
resolvers.updaterelations()
local function simplified(t,k)
- return k and rawget(t,lower(gsub(k," ",""))) or nil
+ return k and rawget(t,lower(gsub(k," ",""))) or nil
end
setmetatableindex(formats,simplified)
setmetatableindex(suffixes,simplified)
setmetatableindex(suffixmap,simplified)
function resolvers.suffixofformat(str)
- local s=suffixes[str]
- return s and s[1] or ""
+ local s=suffixes[str]
+ return s and s[1] or ""
end
function resolvers.suffixofformat(str)
- return suffixes[str] or {}
+ return suffixes[str] or {}
end
for name,format in next,formats do
- dangerous[name]=true
+ dangerous[name]=true
end
dangerous.tex=nil
function resolvers.formatofvariable(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.formatofsuffix(str)
- return suffixmap[suffixonly(str)] or 'tex'
+ return suffixmap[suffixonly(str)] or 'tex'
end
function resolvers.variableofformat(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.variableofformatorsuffix(str)
- local v=formats[str]
- if v then
- return v
- end
- v=suffixmap[suffixonly(str)]
- if v then
- return formats[v]
- end
- return ''
+ local v=formats[str]
+ if v then
+ return v
+ end
+ v=suffixmap[suffixonly(str)]
+ if v then
+ return formats[v]
+ end
+ return ''
end
@@ -20607,14 +20615,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16116, stripped down to: 11459
+-- original size: 16116, stripped down to: 10782
if not modules then modules={} end modules ['data-tmp']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub,concat=string.format,string.lower,string.gsub,table.concat
local concat=table.concat
@@ -20622,19 +20630,19 @@ local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile
local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
local formatters=string.formatters
local next,type=next,type
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
local report_caches=logs.reporter("resolvers","caches")
local report_resolvers=logs.reporter("resolvers","caching")
local resolvers=resolvers
local cleanpath=resolvers.cleanpath
-local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
-local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
+local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
+local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
local compile=utilities.lua.compile
function utilities.lua.compile(luafile,lucfile,cleanup,strip)
- if cleanup==nil then cleanup=directive_cleanup end
- if strip==nil then strip=directive_strip end
- return compile(luafile,lucfile,cleanup,strip)
+ if cleanup==nil then cleanup=directive_cleanup end
+ if strip==nil then strip=directive_strip end
+ return compile(luafile,lucfile,cleanup,strip)
end
caches=caches or {}
local caches=caches
@@ -20649,324 +20657,324 @@ caches.relocate=false
caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
local writable,readables,usedreadables=nil,{},{}
local function identify()
- local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- cachepath=file.collapsepath(cachepath)
- local valid=isdir(cachepath)
- if valid then
- if is_readable(cachepath) then
- readables[#readables+1]=cachepath
- if not writable and is_writable(cachepath) then
- writable=cachepath
- end
- end
- elseif not writable and caches.force then
- local cacheparent=file.dirname(cachepath)
- if is_writable(cacheparent) and true then
- if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
- mkdirs(cachepath)
- if isdir(cachepath) and is_writable(cachepath) then
- report_caches("path %a created",cachepath)
- writable=cachepath
- readables[#readables+1]=cachepath
- end
- end
- end
- end
+ local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ cachepath=file.collapsepath(cachepath)
+ local valid=isdir(cachepath)
+ if valid then
+ if is_readable(cachepath) then
+ readables[#readables+1]=cachepath
+ if not writable and is_writable(cachepath) then
+ writable=cachepath
end
- end
- end
- local texmfcaches=caches.defaults
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- cachepath=resolvers.expansion(cachepath)
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- local valid=isdir(cachepath)
- if valid and is_readable(cachepath) then
- if not writable and is_writable(cachepath) then
- readables[#readables+1]=cachepath
- writable=cachepath
- break
- end
- end
+ end
+ elseif not writable and caches.force then
+ local cacheparent=file.dirname(cachepath)
+ if is_writable(cacheparent) and true then
+ if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
+ mkdirs(cachepath)
+ if isdir(cachepath) and is_writable(cachepath) then
+ report_caches("path %a created",cachepath)
+ writable=cachepath
+ readables[#readables+1]=cachepath
+ end
end
+ end
end
+ end
end
- if not writable then
- report_caches("fatal error: there is no valid writable cache path defined")
- os.exit()
- elseif #readables==0 then
- report_caches("fatal error: there is no valid readable cache path defined")
- os.exit()
- end
- writable=dir.expandname(resolvers.cleanpath(writable))
- local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
- if tree then
- caches.tree=tree
- writable=mkdirs(writable,base,more,tree)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more,tree)
- end
- else
- writable=mkdirs(writable,base,more)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more)
+ end
+ local texmfcaches=caches.defaults
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ cachepath=resolvers.expansion(cachepath)
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ local valid=isdir(cachepath)
+ if valid and is_readable(cachepath) then
+ if not writable and is_writable(cachepath) then
+ readables[#readables+1]=cachepath
+ writable=cachepath
+ break
+ end
end
+ end
end
- if trace_cache then
- for i=1,#readables do
- report_caches("using readable path %a (order %s)",readables[i],i)
- end
- report_caches("using writable path %a",writable)
+ end
+ if not writable then
+ report_caches("fatal error: there is no valid writable cache path defined")
+ os.exit()
+ elseif #readables==0 then
+ report_caches("fatal error: there is no valid readable cache path defined")
+ os.exit()
+ end
+ writable=dir.expandname(resolvers.cleanpath(writable))
+ local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
+ if tree then
+ caches.tree=tree
+ writable=mkdirs(writable,base,more,tree)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more,tree)
end
- identify=function()
- return writable,readables
+ else
+ writable=mkdirs(writable,base,more)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more)
+ end
+ end
+ if trace_cache then
+ for i=1,#readables do
+ report_caches("using readable path %a (order %s)",readables[i],i)
end
+ report_caches("using writable path %a",writable)
+ end
+ identify=function()
return writable,readables
+ end
+ return writable,readables
end
function caches.usedpaths(separator)
- local writable,readables=identify()
- if #readables>1 then
- local result={}
- local done={}
- for i=1,#readables do
- local readable=readables[i]
- if readable==writable then
- done[readable]=true
- result[#result+1]=formatters["readable+writable: %a"](readable)
- elseif usedreadables[i] then
- done[readable]=true
- result[#result+1]=formatters["readable: %a"](readable)
- end
- end
- if not done[writable] then
- result[#result+1]=formatters["writable: %a"](writable)
- end
- return concat(result,separator or " | ")
- else
- return writable or "?"
+ local writable,readables=identify()
+ if #readables>1 then
+ local result={}
+ local done={}
+ for i=1,#readables do
+ local readable=readables[i]
+ if readable==writable then
+ done[readable]=true
+ result[#result+1]=formatters["readable+writable: %a"](readable)
+ elseif usedreadables[i] then
+ done[readable]=true
+ result[#result+1]=formatters["readable: %a"](readable)
+ end
+ end
+ if not done[writable] then
+ result[#result+1]=formatters["writable: %a"](writable)
end
+ return concat(result,separator or " | ")
+ else
+ return writable or "?"
+ end
end
function caches.configfiles()
- return concat(resolvers.configurationfiles(),";")
+ return concat(resolvers.configurationfiles(),";")
end
function caches.hashed(tree)
- tree=gsub(tree,"[\\/]+$","")
- tree=lower(tree)
- local hash=md5.hex(tree)
- if trace_cache or trace_locating then
- report_caches("hashing tree %a, hash %a",tree,hash)
- end
- return hash
+ tree=gsub(tree,"[\\/]+$","")
+ tree=lower(tree)
+ local hash=md5.hex(tree)
+ if trace_cache or trace_locating then
+ report_caches("hashing tree %a, hash %a",tree,hash)
+ end
+ return hash
end
function caches.treehash()
- local tree=caches.configfiles()
- if not tree or tree=="" then
- return false
- else
- return caches.hashed(tree)
- end
+ local tree=caches.configfiles()
+ if not tree or tree=="" then
+ return false
+ else
+ return caches.hashed(tree)
+ end
end
local r_cache,w_cache={},{}
local function getreadablepaths(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=r_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done={}
- for i=1,#readables do
- done[i]=file.join(readables[i],...)
- end
- else
- done=readables
- end
- r_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=r_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done={}
+ for i=1,#readables do
+ done[i]=file.join(readables[i],...)
+ end
+ else
+ done=readables
end
- return done
+ r_cache[hash]=done
+ end
+ return done
end
local function getwritablepath(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=w_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done=mkdirs(writable,...)
- else
- done=writable
- end
- w_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=w_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done=mkdirs(writable,...)
+ else
+ done=writable
end
- return done
+ w_cache[hash]=done
+ end
+ return done
end
caches.getreadablepaths=getreadablepaths
caches.getwritablepath=getwritablepath
function caches.getfirstreadablefile(filename,...)
- local fullname,path=caches.setfirstwritablefile(filename,...)
+ local fullname,path=caches.setfirstwritablefile(filename,...)
+ if is_readable(fullname) then
+ return fullname,path
+ end
+ local rd=getreadablepaths(...)
+ for i=1,#rd do
+ local path=rd[i]
+ local fullname=file.join(path,filename)
if is_readable(fullname) then
- return fullname,path
- end
- local rd=getreadablepaths(...)
- for i=1,#rd do
- local path=rd[i]
- local fullname=file.join(path,filename)
- if is_readable(fullname) then
- usedreadables[i]=true
- return fullname,path
- end
+ usedreadables[i]=true
+ return fullname,path
end
- return fullname,path
+ end
+ return fullname,path
end
function caches.setfirstwritablefile(filename,...)
- local wr=getwritablepath(...)
- local fullname=file.join(wr,filename)
- return fullname,wr
+ local wr=getwritablepath(...)
+ local fullname=file.join(wr,filename)
+ return fullname,wr
end
function caches.define(category,subcategory)
- return function()
- return getwritablepath(category,subcategory)
- end
+ return function()
+ return getwritablepath(category,subcategory)
+ end
end
function caches.setluanames(path,name)
- return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
+ return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
end
function caches.loaddata(readables,name,writable)
- if type(readables)=="string" then
- readables={ readables }
+ if type(readables)=="string" then
+ readables={ readables }
+ end
+ for i=1,#readables do
+ local path=readables[i]
+ local loader=false
+ local tmaname,tmcname=caches.setluanames(path,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader and isfile(tmaname) then
+ local tmacrap,tmcname=caches.setluanames(writable,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ utilities.lua.compile(tmaname,tmcname)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader then
+ loader=loadfile(tmaname)
+ end
end
- for i=1,#readables do
- local path=readables[i]
- local loader=false
- local tmaname,tmcname=caches.setluanames(path,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader and isfile(tmaname) then
- local tmacrap,tmcname=caches.setluanames(writable,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- utilities.lua.compile(tmaname,tmcname)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader then
- loader=loadfile(tmaname)
- end
- end
- if loader then
- loader=loader()
- collectgarbage("step")
- return loader
- end
+ if loader then
+ loader=loader()
+ collectgarbage("step")
+ return loader
end
- return false
+ end
+ return false
end
function caches.is_writable(filepath,filename)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- return is_writable(tmaname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ return is_writable(tmaname)
end
local saveoptions={ compact=true }
function caches.savedata(filepath,filename,data,raw)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- data.cache_uuid=os.uuid()
- if caches.direct then
- file.savedata(tmaname,table.serialize(data,true,saveoptions))
- else
- table.tofile(tmaname,data,true,saveoptions)
- end
- utilities.lua.compile(tmaname,tmcname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ data.cache_uuid=os.uuid()
+ if caches.direct then
+ file.savedata(tmaname,table.serialize(data,true,saveoptions))
+ else
+ table.tofile(tmaname,data,true,saveoptions)
+ end
+ utilities.lua.compile(tmaname,tmcname)
end
local content_state={}
function caches.contentstate()
- return content_state or {}
+ return content_state or {}
end
function caches.loadcontent(cachename,dataname,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
- if blob then
- local data=blob()
- if data and data.content then
- if data.type==dataname then
- if data.version==resolvers.cacheversion then
- content_state[#content_state+1]=data.uuid
- if trace_locating then
- report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
- end
- return data.content
- else
- report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
- end
- else
- report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
- end
- elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
+ if blob then
+ local data=blob()
+ if data and data.content then
+ if data.type==dataname then
+ if data.version==resolvers.cacheversion then
+ content_state[#content_state+1]=data.uuid
+ if trace_locating then
+ report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
+ end
+ return data.content
+ else
+ report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
end
+ else
+ report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
+ end
elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
end
+ elseif trace_locating then
+ report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ end
end
function caches.collapsecontent(content)
- for k,v in next,content do
- if type(v)=="table" and #v==1 then
- content[k]=v[1]
- end
+ for k,v in next,content do
+ if type(v)=="table" and #v==1 then
+ content[k]=v[1]
end
+ end
end
function caches.savecontent(cachename,dataname,content,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local luaname=addsuffix(filename,luasuffixes.lua)
- local lucname=addsuffix(filename,luasuffixes.luc)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local luaname=addsuffix(filename,luasuffixes.lua)
+ local lucname=addsuffix(filename,luasuffixes.luc)
+ if trace_locating then
+ report_resolvers("preparing %a for %a",dataname,cachename)
+ end
+ local data={
+ type=dataname,
+ root=cachename,
+ version=resolvers.cacheversion,
+ date=os.date("%Y-%m-%d"),
+ time=os.date("%H:%M:%S"),
+ content=content,
+ uuid=os.uuid(),
+ }
+ local ok=io.savedata(luaname,table.serialize(data,true))
+ if ok then
if trace_locating then
- report_resolvers("preparing %a for %a",dataname,cachename)
- end
- local data={
- type=dataname,
- root=cachename,
- version=resolvers.cacheversion,
- date=os.date("%Y-%m-%d"),
- time=os.date("%H:%M:%S"),
- content=content,
- uuid=os.uuid(),
- }
- local ok=io.savedata(luaname,table.serialize(data,true))
- if ok then
- if trace_locating then
- report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
- end
- if utilities.lua.compile(luaname,lucname) then
- if trace_locating then
- report_resolvers("%a compiled to %a",dataname,lucname)
- end
- return true
- else
- if trace_locating then
- report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
- end
- os.remove(lucname)
- end
- elseif trace_locating then
- report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
end
+ if utilities.lua.compile(luaname,lucname) then
+ if trace_locating then
+ report_resolvers("%a compiled to %a",dataname,lucname)
+ end
+ return true
+ else
+ if trace_locating then
+ report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
+ end
+ os.remove(lucname)
+ end
+ elseif trace_locating then
+ report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ end
end
@@ -20976,14 +20984,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-met"] = package.loaded["data-met"] or true
--- original size: 5310, stripped down to: 3980
+-- original size: 5310, stripped down to: 3784
if not modules then modules={} end modules ['data-met']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local find,format=string.find,string.format
local sequenced=table.sequenced
@@ -20997,86 +21005,86 @@ local allocate=utilities.storage.allocate
local resolvers=resolvers
local registered={}
local function splitmethod(filename)
- if not filename then
- return { scheme="unknown",original=filename }
- end
- if type(filename)=="table" then
- return filename
- end
- filename=file.collapsepath(filename,".")
- if not find(filename,"://",1,true) then
- return { scheme="file",path=filename,original=filename,filename=filename }
- end
- local specification=url.hashed(filename)
- if not specification.scheme or specification.scheme=="" then
- return { scheme="file",path=filename,original=filename,filename=filename }
- else
- return specification
- end
+ if not filename then
+ return { scheme="unknown",original=filename }
+ end
+ if type(filename)=="table" then
+ return filename
+ end
+ filename=file.collapsepath(filename,".")
+ if not find(filename,"://",1,true) then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ end
+ local specification=url.hashed(filename)
+ if not specification.scheme or specification.scheme=="" then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ else
+ return specification
+ end
end
resolvers.splitmethod=splitmethod
local function methodhandler(what,first,...)
- local method=registered[what]
- if method then
- local how,namespace=method.how,method.namespace
- if how=="uri" or how=="url" then
- local specification=splitmethod(first)
- local scheme=specification.scheme
- local resolver=namespace and namespace[scheme]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
- end
- return resolver(specification,...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
- end
- return resolver(specification,...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
- end
- end
- elseif how=="tag" then
- local resolver=namespace and namespace[first]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,first)
- end
- return resolver(...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
- end
- return resolver(...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
- end
- end
+ local method=registered[what]
+ if method then
+ local how,namespace=method.how,method.namespace
+ if how=="uri" or how=="url" then
+ local specification=splitmethod(first)
+ local scheme=specification.scheme
+ local resolver=namespace and namespace[scheme]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
+ end
+ return resolver(specification,...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
+ end
+ return resolver(specification,...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
end
- else
- report_methods("resolving, invalid method %a")
+ end
+ elseif how=="tag" then
+ local resolver=namespace and namespace[first]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,first)
+ end
+ return resolver(...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
+ end
+ return resolver(...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
+ end
+ end
end
+ else
+ report_methods("resolving, invalid method %a")
+ end
end
resolvers.methodhandler=methodhandler
function resolvers.registermethod(name,namespace,how)
- registered[name]={ how=how or "tag",namespace=namespace }
- namespace["byscheme"]=function(scheme,filename,...)
- if scheme=="file" then
- return methodhandler(name,filename,...)
- else
- return methodhandler(name,addurlscheme(filename,scheme),...)
- end
+ registered[name]={ how=how or "tag",namespace=namespace }
+ namespace["byscheme"]=function(scheme,filename,...)
+ if scheme=="file" then
+ return methodhandler(name,filename,...)
+ else
+ return methodhandler(name,addurlscheme(filename,scheme),...)
end
+ end
end
-local concatinators=allocate { notfound=file.join }
-local locators=allocate { notfound=function() end }
-local hashers=allocate { notfound=function() end }
-local generators=allocate { notfound=function() end }
+local concatinators=allocate { notfound=file.join }
+local locators=allocate { notfound=function() end }
+local hashers=allocate { notfound=function() end }
+local generators=allocate { notfound=function() end }
resolvers.concatinators=concatinators
resolvers.locators=locators
resolvers.hashers=hashers
@@ -21094,14 +21102,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-res"] = package.loaded["data-res"] or true
--- original size: 68195, stripped down to: 47727
+-- original size: 68195, stripped down to: 43680
if not modules then modules={} end modules ['data-res']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local gsub,find,lower,upper,match,gmatch=string.gsub,string.find,string.lower,string.upper,string.match,string.gmatch
local concat,insert,remove=table.concat,table.insert,table.remove
@@ -21126,11 +21134,11 @@ local isfile=lfs.isfile
local isdir=lfs.isdir
local setmetatableindex=table.setmetatableindex
local luasuffixes=utilities.lua.suffixes
-local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
-local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
+local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
+local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
local report_resolving=logs.reporter("resolvers","resolving")
local resolvers=resolvers
local expandedpathfromlist=resolvers.expandedpathfromlist
@@ -21151,15 +21159,15 @@ resolvers.luacnfname="texmfcnf.lua"
resolvers.luacnffallback="contextcnf.lua"
resolvers.luacnfstate="unknown"
if environment.default_texmfcnf then
- resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
+ resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
else
- resolvers.luacnfspec=concat ({
- "home:texmf/web2c",
- "selfautoparent:/texmf-local/web2c",
- "selfautoparent:/texmf-context/web2c",
- "selfautoparent:/texmf-dist/web2c",
- "selfautoparent:/texmf/web2c",
- },";")
+ resolvers.luacnfspec=concat ({
+ "home:texmf/web2c",
+ "selfautoparent:/texmf-local/web2c",
+ "selfautoparent:/texmf-context/web2c",
+ "selfautoparent:/texmf-dist/web2c",
+ "selfautoparent:/texmf/web2c",
+ },";")
end
local unset_variable="unset"
local formats=resolvers.formats
@@ -21170,24 +21178,24 @@ local suffixmap=resolvers.suffixmap
resolvers.defaultsuffixes={ "tex" }
local instance=nil
function resolvers.setenv(key,value,raw)
- if instance then
- instance.environment[key]=value
- ossetenv(key,raw and value or resolveprefix(value))
- end
+ if instance then
+ instance.environment[key]=value
+ ossetenv(key,raw and value or resolveprefix(value))
+ end
end
local function getenv(key)
- local value=rawget(instance.environment,key)
- if value and value~="" then
- return value
- else
- local e=osgetenv(key)
- return e~=nil and e~="" and checkedvariable(e) or ""
- end
+ local value=rawget(instance.environment,key)
+ if value and value~="" then
+ return value
+ else
+ local e=osgetenv(key)
+ return e~=nil and e~="" and checkedvariable(e) or ""
+ end
end
resolvers.getenv=getenv
resolvers.env=getenv
local function resolvevariable(k)
- return instance.expansions[k]
+ return instance.expansions[k]
end
local dollarstripper=lpeg.stripper("$")
local inhibitstripper=P("!")^0*Cs(P(1)^0)
@@ -21201,1506 +21209,1506 @@ local somevariable=R("az","AZ","09","__","--")^1/resolvevariable
local variable=(P("$")/"")*(somevariable+(P("{")/"")*somevariable*(P("}")/""))
local variableresolver=Cs((variable+P(1))^0)
local function expandedvariable(var)
- return lpegmatch(variableexpander,var) or var
+ return lpegmatch(variableexpander,var) or var
end
function resolvers.reset()
- if trace_locating then
- report_resolving("creating instance")
- end
- local environment={}
- local variables={}
- local expansions={}
- local order={}
- instance={
- environment=environment,
- variables=variables,
- expansions=expansions,
- order=order,
- files={},
- setups={},
- found={},
- foundintrees={},
- hashes={},
- hashed={},
- pathlists=false,
- specification={},
- lists={},
- data={},
- fakepaths={},
- remember=true,
- diskcache=true,
- renewcache=false,
- renewtree=false,
- loaderror=false,
- savelists=true,
- pattern=nil,
- force_suffixes=true,
- pathstack={},
- }
- setmetatableindex(variables,function(t,k)
- local v
- for i=1,#order do
- v=order[i][k]
- if v~=nil then
- t[k]=v
- return v
- end
- end
- if v==nil then
- v=""
- end
+ if trace_locating then
+ report_resolving("creating instance")
+ end
+ local environment={}
+ local variables={}
+ local expansions={}
+ local order={}
+ instance={
+ environment=environment,
+ variables=variables,
+ expansions=expansions,
+ order=order,
+ files={},
+ setups={},
+ found={},
+ foundintrees={},
+ hashes={},
+ hashed={},
+ pathlists=false,
+ specification={},
+ lists={},
+ data={},
+ fakepaths={},
+ remember=true,
+ diskcache=true,
+ renewcache=false,
+ renewtree=false,
+ loaderror=false,
+ savelists=true,
+ pattern=nil,
+ force_suffixes=true,
+ pathstack={},
+ }
+ setmetatableindex(variables,function(t,k)
+ local v
+ for i=1,#order do
+ v=order[i][k]
+ if v~=nil then
t[k]=v
return v
- end)
- setmetatableindex(environment,function(t,k)
- local v=osgetenv(k)
- if v==nil then
- v=variables[k]
- end
- if v~=nil then
- v=checkedvariable(v) or ""
- end
- v=resolvers.repath(v)
- t[k]=v
- return v
- end)
- setmetatableindex(expansions,function(t,k)
- local v=environment[k]
- if type(v)=="string" then
- v=lpegmatch(variableresolver,v)
- v=lpegmatch(variablecleaner,v)
- end
- t[k]=v
- return v
- end)
+ end
+ end
+ if v==nil then
+ v=""
+ end
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(environment,function(t,k)
+ local v=osgetenv(k)
+ if v==nil then
+ v=variables[k]
+ end
+ if v~=nil then
+ v=checkedvariable(v) or ""
+ end
+ v=resolvers.repath(v)
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(expansions,function(t,k)
+ local v=environment[k]
+ if type(v)=="string" then
+ v=lpegmatch(variableresolver,v)
+ v=lpegmatch(variablecleaner,v)
+ end
+ t[k]=v
+ return v
+ end)
end
function resolvers.initialized()
- return instance~=nil
+ return instance~=nil
end
local function reset_hashes()
- instance.lists={}
- instance.pathlists=false
- instance.found={}
+ instance.lists={}
+ instance.pathlists=false
+ instance.found={}
end
local function reset_caches()
- instance.lists={}
- instance.pathlists=false
+ instance.lists={}
+ instance.pathlists=false
end
local slash=P("/")
local pathexpressionpattern=Cs (
- Cc("^")*(
- Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+ Cc("^")*(
+ Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+slash^2/"/"+(1-slash)*P(-1)*Cc("/")+P(1)
- )^1*Cc("$")
+ )^1*Cc("$")
)
local cache={}
local function makepathexpression(str)
- if str=="." then
- return "^%./$"
- else
- local c=cache[str]
- if not c then
- c=lpegmatch(pathexpressionpattern,str)
- cache[str]=c
- end
- return c
+ if str=="." then
+ return "^%./$"
+ else
+ local c=cache[str]
+ if not c then
+ c=lpegmatch(pathexpressionpattern,str)
+ cache[str]=c
end
+ return c
+ end
end
local function reportcriticalvariables(cnfspec)
- if trace_locating then
- for i=1,#resolvers.criticalvars do
- local k=resolvers.criticalvars[i]
- local v=resolvers.getenv(k) or "unknown"
- report_resolving("variable %a set to %a",k,v)
- end
- report_resolving()
- if cnfspec then
- report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
- end
- report_resolving()
+ if trace_locating then
+ for i=1,#resolvers.criticalvars do
+ local k=resolvers.criticalvars[i]
+ local v=resolvers.getenv(k) or "unknown"
+ report_resolving("variable %a set to %a",k,v)
+ end
+ report_resolving()
+ if cnfspec then
+ report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
end
- reportcriticalvariables=function() end
+ report_resolving()
+ end
+ reportcriticalvariables=function() end
end
local function identify_configuration_files()
- local specification=instance.specification
- if #specification==0 then
- local cnfspec=getenv("TEXMFCNF")
- if cnfspec=="" then
- cnfspec=resolvers.luacnfspec
- resolvers.luacnfstate="default"
- else
- resolvers.luacnfstate="environment"
- end
- reportcriticalvariables(cnfspec)
- local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
- local function locatecnf(luacnfname,kind)
- for i=1,#cnfpaths do
- local filepath=cnfpaths[i]
- local filename=collapsepath(filejoin(filepath,luacnfname))
- local realname=resolveprefix(filename)
- if trace_locating then
- local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
- local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
- report_resolving("looking for %s %a on %s path %a from specification %a",
- kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
- end
- if isfile(realname) then
- specification[#specification+1]=filename
- if trace_locating then
- report_resolving("found %s configuration file %a",kind,realname)
- end
- end
- end
- end
- locatecnf(resolvers.luacnfname,"regular")
- if #specification==0 then
- locatecnf(resolvers.luacnffallback,"fallback")
- end
+ local specification=instance.specification
+ if #specification==0 then
+ local cnfspec=getenv("TEXMFCNF")
+ if cnfspec=="" then
+ cnfspec=resolvers.luacnfspec
+ resolvers.luacnfstate="default"
+ else
+ resolvers.luacnfstate="environment"
+ end
+ reportcriticalvariables(cnfspec)
+ local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
+ local function locatecnf(luacnfname,kind)
+ for i=1,#cnfpaths do
+ local filepath=cnfpaths[i]
+ local filename=collapsepath(filejoin(filepath,luacnfname))
+ local realname=resolveprefix(filename)
if trace_locating then
- report_resolving()
+ local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
+ local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
+ report_resolving("looking for %s %a on %s path %a from specification %a",
+ kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
+ end
+ if isfile(realname) then
+ specification[#specification+1]=filename
+ if trace_locating then
+ report_resolving("found %s configuration file %a",kind,realname)
+ end
end
- elseif trace_locating then
- report_resolving("configuration files already identified")
+ end
end
+ locatecnf(resolvers.luacnfname,"regular")
+ if #specification==0 then
+ locatecnf(resolvers.luacnffallback,"fallback")
+ end
+ if trace_locating then
+ report_resolving()
+ end
+ elseif trace_locating then
+ report_resolving("configuration files already identified")
+ end
end
local function load_configuration_files()
- local specification=instance.specification
- if #specification>0 then
- local luacnfname=resolvers.luacnfname
- for i=1,#specification do
- local filename=specification[i]
- local pathname=filedirname(filename)
- local filename=filejoin(pathname,luacnfname)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local setups=instance.setups
- local data=blob()
- local parent=data and data.parent
- if parent then
- local filename=filejoin(pathname,parent)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local parentdata=blob()
- if parentdata then
- report_resolving("loading configuration file %a",filename)
- data=table.merged(parentdata,data)
- end
- end
- end
- data=data and data.content
- if data then
- if trace_locating then
- report_resolving("loading configuration file %a",filename)
- report_resolving()
- end
- local variables=data.variables or {}
- local warning=false
- for k,v in next,data do
- local variant=type(v)
- if variant=="table" then
- initializesetter(filename,k,v)
- elseif variables[k]==nil then
- if trace_locating and not warning then
- report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
- k,resolveprefix(filename))
- warning=true
- end
- variables[k]=v
- end
- end
- setups[pathname]=variables
- if resolvers.luacnfstate=="default" then
- local cnfspec=variables["TEXMFCNF"]
- if cnfspec then
- if trace_locating then
- report_resolving("reloading configuration due to TEXMF redefinition")
- end
- resolvers.setenv("TEXMFCNF",cnfspec)
- instance.specification={}
- identify_configuration_files()
- load_configuration_files()
- resolvers.luacnfstate="configuration"
- break
- end
- end
- else
- if trace_locating then
- report_resolving("skipping configuration file %a (no content)",filename)
- end
- setups[pathname]={}
- instance.loaderror=true
- end
- elseif trace_locating then
- report_resolving("skipping configuration file %a (no valid format)",filename)
+ local specification=instance.specification
+ if #specification>0 then
+ local luacnfname=resolvers.luacnfname
+ for i=1,#specification do
+ local filename=specification[i]
+ local pathname=filedirname(filename)
+ local filename=filejoin(pathname,luacnfname)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local setups=instance.setups
+ local data=blob()
+ local parent=data and data.parent
+ if parent then
+ local filename=filejoin(pathname,parent)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local parentdata=blob()
+ if parentdata then
+ report_resolving("loading configuration file %a",filename)
+ data=table.merged(parentdata,data)
end
- instance.order[#instance.order+1]=instance.setups[pathname]
- if instance.loaderror then
- break
+ end
+ end
+ data=data and data.content
+ if data then
+ if trace_locating then
+ report_resolving("loading configuration file %a",filename)
+ report_resolving()
+ end
+ local variables=data.variables or {}
+ local warning=false
+ for k,v in next,data do
+ local variant=type(v)
+ if variant=="table" then
+ initializesetter(filename,k,v)
+ elseif variables[k]==nil then
+ if trace_locating and not warning then
+ report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
+ k,resolveprefix(filename))
+ warning=true
+ end
+ variables[k]=v
+ end
+ end
+ setups[pathname]=variables
+ if resolvers.luacnfstate=="default" then
+ local cnfspec=variables["TEXMFCNF"]
+ if cnfspec then
+ if trace_locating then
+ report_resolving("reloading configuration due to TEXMF redefinition")
+ end
+ resolvers.setenv("TEXMFCNF",cnfspec)
+ instance.specification={}
+ identify_configuration_files()
+ load_configuration_files()
+ resolvers.luacnfstate="configuration"
+ break
end
+ end
+ else
+ if trace_locating then
+ report_resolving("skipping configuration file %a (no content)",filename)
+ end
+ setups[pathname]={}
+ instance.loaderror=true
end
- elseif trace_locating then
- report_resolving("warning: no lua configuration files found")
+ elseif trace_locating then
+ report_resolving("skipping configuration file %a (no valid format)",filename)
+ end
+ instance.order[#instance.order+1]=instance.setups[pathname]
+ if instance.loaderror then
+ break
+ end
end
+ elseif trace_locating then
+ report_resolving("warning: no lua configuration files found")
+ end
end
function resolvers.configurationfiles()
- return instance.specification or {}
+ return instance.specification or {}
end
local function load_file_databases()
- instance.loaderror=false
- instance.files={}
- if not instance.renewcache then
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- resolvers.hashers.byscheme(hash.type,hash.name)
- if instance.loaderror then break end
- end
+ instance.loaderror=false
+ instance.files={}
+ if not instance.renewcache then
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ resolvers.hashers.byscheme(hash.type,hash.name)
+ if instance.loaderror then break end
end
+ end
end
local function locate_file_databases()
- local texmfpaths=resolvers.expandedpathlist("TEXMF")
- if #texmfpaths>0 then
- for i=1,#texmfpaths do
- local path=collapsepath(texmfpaths[i])
- path=gsub(path,"/+$","")
- local stripped=lpegmatch(inhibitstripper,path)
- if stripped~="" then
- local runtime=stripped==path
- path=cleanpath(path)
- local spec=resolvers.splitmethod(stripped)
- if runtime and (spec.noscheme or spec.scheme=="file") then
- stripped="tree:///"..stripped
- elseif spec.scheme=="cache" or spec.scheme=="file" then
- stripped=spec.path
- end
- if trace_locating then
- if runtime then
- report_resolving("locating list of %a (runtime) (%s)",path,stripped)
- else
- report_resolving("locating list of %a (cached)",path)
- end
- end
- methodhandler('locators',stripped)
- end
+ local texmfpaths=resolvers.expandedpathlist("TEXMF")
+ if #texmfpaths>0 then
+ for i=1,#texmfpaths do
+ local path=collapsepath(texmfpaths[i])
+ path=gsub(path,"/+$","")
+ local stripped=lpegmatch(inhibitstripper,path)
+ if stripped~="" then
+ local runtime=stripped==path
+ path=cleanpath(path)
+ local spec=resolvers.splitmethod(stripped)
+ if runtime and (spec.noscheme or spec.scheme=="file") then
+ stripped="tree:///"..stripped
+ elseif spec.scheme=="cache" or spec.scheme=="file" then
+ stripped=spec.path
end
if trace_locating then
- report_resolving()
+ if runtime then
+ report_resolving("locating list of %a (runtime) (%s)",path,stripped)
+ else
+ report_resolving("locating list of %a (cached)",path)
+ end
end
- elseif trace_locating then
- report_resolving("no texmf paths are defined (using TEXMF)")
- end
-end
-local function generate_file_databases()
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- methodhandler('generators',hash.name)
+ methodhandler('locators',stripped)
+ end
end
if trace_locating then
- report_resolving()
+ report_resolving()
end
+ elseif trace_locating then
+ report_resolving("no texmf paths are defined (using TEXMF)")
+ end
+end
+local function generate_file_databases()
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ methodhandler('generators',hash.name)
+ end
+ if trace_locating then
+ report_resolving()
+ end
end
local function save_file_databases()
- for i=1,#instance.hashes do
- local hash=instance.hashes[i]
- local cachename=hash.name
- if hash.cache then
- local content=instance.files[cachename]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",cachename)
- end
- caches.savecontent(cachename,"files",content)
- elseif trace_locating then
- report_resolving("not saving runtime tree %a",cachename)
- end
+ for i=1,#instance.hashes do
+ local hash=instance.hashes[i]
+ local cachename=hash.name
+ if hash.cache then
+ local content=instance.files[cachename]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",cachename)
+ end
+ caches.savecontent(cachename,"files",content)
+ elseif trace_locating then
+ report_resolving("not saving runtime tree %a",cachename)
end
+ end
end
function resolvers.renew(hashname)
- if hashname and hashname~="" then
- local expanded=resolvers.expansion(hashname) or ""
- if expanded~="" then
- if trace_locating then
- report_resolving("identifying tree %a from %a",expanded,hashname)
- end
- hashname=expanded
- else
- if trace_locating then
- report_resolving("identifying tree %a",hashname)
- end
- end
- local realpath=resolveprefix(hashname)
- if isdir(realpath) then
- if trace_locating then
- report_resolving("using path %a",realpath)
- end
- methodhandler('generators',hashname)
- local content=instance.files[hashname]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",hashname)
- end
- caches.savecontent(hashname,"files",content)
- else
- report_resolving("invalid path %a",realpath)
- end
+ if hashname and hashname~="" then
+ local expanded=resolvers.expansion(hashname) or ""
+ if expanded~="" then
+ if trace_locating then
+ report_resolving("identifying tree %a from %a",expanded,hashname)
+ end
+ hashname=expanded
+ else
+ if trace_locating then
+ report_resolving("identifying tree %a",hashname)
+ end
end
+ local realpath=resolveprefix(hashname)
+ if isdir(realpath) then
+ if trace_locating then
+ report_resolving("using path %a",realpath)
+ end
+ methodhandler('generators',hashname)
+ local content=instance.files[hashname]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",hashname)
+ end
+ caches.savecontent(hashname,"files",content)
+ else
+ report_resolving("invalid path %a",realpath)
+ end
+ end
end
local function load_databases()
- locate_file_databases()
- if instance.diskcache and not instance.renewcache then
- load_file_databases()
- if instance.loaderror then
- generate_file_databases()
- save_file_databases()
- end
- else
- generate_file_databases()
- if instance.renewcache then
- save_file_databases()
- end
+ locate_file_databases()
+ if instance.diskcache and not instance.renewcache then
+ load_file_databases()
+ if instance.loaderror then
+ generate_file_databases()
+ save_file_databases()
+ end
+ else
+ generate_file_databases()
+ if instance.renewcache then
+ save_file_databases()
end
+ end
end
function resolvers.appendhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a appended",name)
- end
- insert(instance.hashes,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a appended",name)
end
+ insert(instance.hashes,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.prependhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a prepended",name)
- end
- insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a prepended",name)
end
+ insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.extendtexmfvariable(specification)
- local t=resolvers.splitpath(getenv("TEXMF"))
- insert(t,1,specification)
- local newspec=concat(t,",")
- if instance.environment["TEXMF"] then
- instance.environment["TEXMF"]=newspec
- elseif instance.variables["TEXMF"] then
- instance.variables["TEXMF"]=newspec
- else
- end
- reset_hashes()
+ local t=resolvers.splitpath(getenv("TEXMF"))
+ insert(t,1,specification)
+ local newspec=concat(t,",")
+ if instance.environment["TEXMF"] then
+ instance.environment["TEXMF"]=newspec
+ elseif instance.variables["TEXMF"] then
+ instance.variables["TEXMF"]=newspec
+ else
+ end
+ reset_hashes()
end
function resolvers.splitexpansions()
- local ie=instance.expansions
- for k,v in next,ie do
- local t,tn,h,p={},0,{},splitconfigurationpath(v)
- for kk=1,#p do
- local vv=p[kk]
- if vv~="" and not h[vv] then
- tn=tn+1
- t[tn]=vv
- h[vv]=true
- end
- end
- if #t>1 then
- ie[k]=t
- else
- ie[k]=t[1]
- end
+ local ie=instance.expansions
+ for k,v in next,ie do
+ local t,tn,h,p={},0,{},splitconfigurationpath(v)
+ for kk=1,#p do
+ local vv=p[kk]
+ if vv~="" and not h[vv] then
+ tn=tn+1
+ t[tn]=vv
+ h[vv]=true
+ end
end
+ if #t>1 then
+ ie[k]=t
+ else
+ ie[k]=t[1]
+ end
+ end
end
function resolvers.datastate()
- return caches.contentstate()
+ return caches.contentstate()
end
function resolvers.variable(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.variables[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.variables[name]
+ return result~=nil and result or ""
end
function resolvers.expansion(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.expansions[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.expansions[name]
+ return result~=nil and result or ""
end
function resolvers.unexpandedpathlist(str)
- local pth=resolvers.variable(str)
- local lst=resolvers.splitpath(pth)
- return expandedpathfromlist(lst)
+ local pth=resolvers.variable(str)
+ local lst=resolvers.splitpath(pth)
+ return expandedpathfromlist(lst)
end
function resolvers.unexpandedpath(str)
- return joinpath(resolvers.unexpandedpathlist(str))
+ return joinpath(resolvers.unexpandedpathlist(str))
end
function resolvers.pushpath(name)
- local pathstack=instance.pathstack
- local lastpath=pathstack[#pathstack]
- local pluspath=filedirname(name)
- if lastpath then
- lastpath=collapsepath(filejoin(lastpath,pluspath))
- else
- lastpath=collapsepath(pluspath)
- end
- insert(pathstack,lastpath)
- if trace_paths then
- report_resolving("pushing path %a",lastpath)
- end
+ local pathstack=instance.pathstack
+ local lastpath=pathstack[#pathstack]
+ local pluspath=filedirname(name)
+ if lastpath then
+ lastpath=collapsepath(filejoin(lastpath,pluspath))
+ else
+ lastpath=collapsepath(pluspath)
+ end
+ insert(pathstack,lastpath)
+ if trace_paths then
+ report_resolving("pushing path %a",lastpath)
+ end
end
function resolvers.poppath()
- local pathstack=instance.pathstack
- if trace_paths and #pathstack>0 then
- report_resolving("popping path %a",pathstack[#pathstack])
- end
- remove(pathstack)
+ local pathstack=instance.pathstack
+ if trace_paths and #pathstack>0 then
+ report_resolving("popping path %a",pathstack[#pathstack])
+ end
+ remove(pathstack)
end
function resolvers.stackpath()
- local pathstack=instance.pathstack
- local currentpath=pathstack[#pathstack]
- return currentpath~="" and currentpath or nil
+ local pathstack=instance.pathstack
+ local currentpath=pathstack[#pathstack]
+ return currentpath~="" and currentpath or nil
end
local done={}
function resolvers.resetextrapaths()
- local ep=instance.extra_paths
- if not ep then
- done={}
- instance.extra_paths={}
- elseif #ep>0 then
- done={}
- reset_caches()
- end
+ local ep=instance.extra_paths
+ if not ep then
+ done={}
+ instance.extra_paths={}
+ elseif #ep>0 then
+ done={}
+ reset_caches()
+ end
end
function resolvers.getextrapaths()
- return instance.extra_paths or {}
+ return instance.extra_paths or {}
end
function resolvers.registerextrapath(paths,subpaths)
- if not subpaths or subpaths=="" then
- if not paths or path=="" then
- return
- elseif done[paths] then
- return
- end
- end
- local paths=settings_to_array(paths)
- local subpaths=settings_to_array(subpaths)
- local ep=instance.extra_paths or {}
- local oldn=#ep
- local newn=oldn
- local nofpaths=#paths
- local nofsubpaths=#subpaths
- if nofpaths>0 then
- if nofsubpaths>0 then
- for i=1,nofpaths do
- local p=paths[i]
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=p.."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
- end
- else
- for i=1,nofpaths do
- local p=paths[i]
- if not done[p] then
- newn=newn+1
- ep[newn]=cleanpath(p)
- done[p]=true
- end
- end
+ if not subpaths or subpaths=="" then
+ if not paths or path=="" then
+ return
+ elseif done[paths] then
+ return
+ end
+ end
+ local paths=settings_to_array(paths)
+ local subpaths=settings_to_array(subpaths)
+ local ep=instance.extra_paths or {}
+ local oldn=#ep
+ local newn=oldn
+ local nofpaths=#paths
+ local nofsubpaths=#subpaths
+ if nofpaths>0 then
+ if nofsubpaths>0 then
+ for i=1,nofpaths do
+ local p=paths[i]
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=p.."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
end
- elseif nofsubpaths>0 then
- for i=1,oldn do
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=ep[i].."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
+ end
+ else
+ for i=1,nofpaths do
+ local p=paths[i]
+ if not done[p] then
+ newn=newn+1
+ ep[newn]=cleanpath(p)
+ done[p]=true
end
+ end
end
- if newn>0 then
- instance.extra_paths=ep
- end
- if newn~=oldn then
- reset_caches()
+ elseif nofsubpaths>0 then
+ for i=1,oldn do
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=ep[i].."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
+ end
end
+ end
+ if newn>0 then
+ instance.extra_paths=ep
+ end
+ if newn~=oldn then
+ reset_caches()
+ end
end
function resolvers.pushextrapath(path)
- local paths=settings_to_array(path)
- if instance.extra_stack then
- insert(instance.extra_stack,1,paths)
- else
- instance.extra_stack={ paths }
- end
- reset_caches()
+ local paths=settings_to_array(path)
+ if instance.extra_stack then
+ insert(instance.extra_stack,1,paths)
+ else
+ instance.extra_stack={ paths }
+ end
+ reset_caches()
end
function resolvers.popextrapath()
- if instance.extra_stack then
- reset_caches()
- return remove(instance.extra_stack,1)
- end
+ if instance.extra_stack then
+ reset_caches()
+ return remove(instance.extra_stack,1)
+ end
end
local function made_list(instance,list,extra_too)
- local done={}
- local new={}
- local newn=0
- local function add(p)
- for k=1,#p do
- local v=p[k]
- if not done[v] then
- done[v]=true
- newn=newn+1
- new[newn]=v
- end
- end
+ local done={}
+ local new={}
+ local newn=0
+ local function add(p)
+ for k=1,#p do
+ local v=p[k]
+ if not done[v] then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ end
end
- for k=1,#list do
- local v=list[k]
- if done[v] then
- elseif find(v,"^[%.%/]$") then
- done[v]=true
- newn=newn+1
- new[newn]=v
- else
- break
- end
+ end
+ for k=1,#list do
+ local v=list[k]
+ if done[v] then
+ elseif find(v,"^[%.%/]$") then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ else
+ break
+ end
+ end
+ if extra_too then
+ local es=instance.extra_stack
+ if es and #es>0 then
+ for k=1,#es do
+ add(es[k])
+ end
end
- if extra_too then
- local es=instance.extra_stack
- if es and #es>0 then
- for k=1,#es do
- add(es[k])
- end
- end
- local ep=instance.extra_paths
- if ep and #ep>0 then
- add(ep)
- end
+ local ep=instance.extra_paths
+ if ep and #ep>0 then
+ add(ep)
end
- add(list)
- return new
+ end
+ add(list)
+ return new
end
function resolvers.cleanpathlist(str)
- local t=resolvers.expandedpathlist(str)
- if t then
- for i=1,#t do
- t[i]=collapsepath(cleanpath(t[i]))
- end
+ local t=resolvers.expandedpathlist(str)
+ if t then
+ for i=1,#t do
+ t[i]=collapsepath(cleanpath(t[i]))
end
- return t
+ end
+ return t
end
function resolvers.expandpath(str)
- return joinpath(resolvers.expandedpathlist(str))
+ return joinpath(resolvers.expandedpathlist(str))
end
function resolvers.expandedpathlist(str,extra_too)
- if not str then
- return {}
- elseif instance.savelists then
- str=lpegmatch(dollarstripper,str)
- local lists=instance.lists
- local lst=lists[str]
- if not lst then
- local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
- lst=expandedpathfromlist(l)
- lists[str]=lst
- end
- return lst
- else
- local lst=resolvers.splitpath(resolvers.expansion(str))
- return made_list(instance,expandedpathfromlist(lst),extra_too)
+ if not str then
+ return {}
+ elseif instance.savelists then
+ str=lpegmatch(dollarstripper,str)
+ local lists=instance.lists
+ local lst=lists[str]
+ if not lst then
+ local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
+ lst=expandedpathfromlist(l)
+ lists[str]=lst
end
+ return lst
+ else
+ local lst=resolvers.splitpath(resolvers.expansion(str))
+ return made_list(instance,expandedpathfromlist(lst),extra_too)
+ end
end
function resolvers.expandedpathlistfromvariable(str)
- str=lpegmatch(dollarstripper,str)
- local tmp=resolvers.variableofformatorsuffix(str)
- return resolvers.expandedpathlist(tmp~="" and tmp or str)
+ str=lpegmatch(dollarstripper,str)
+ local tmp=resolvers.variableofformatorsuffix(str)
+ return resolvers.expandedpathlist(tmp~="" and tmp or str)
end
function resolvers.expandpathfromvariable(str)
- return joinpath(resolvers.expandedpathlistfromvariable(str))
+ return joinpath(resolvers.expandedpathlistfromvariable(str))
end
function resolvers.cleanedpathlist(v)
- local t=resolvers.expandedpathlist(v)
- for i=1,#t do
- t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
- end
- return t
+ local t=resolvers.expandedpathlist(v)
+ for i=1,#t do
+ t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
+ end
+ return t
end
function resolvers.expandbraces(str)
- local pth=expandedpathfromlist(resolvers.splitpath(str))
- return joinpath(pth)
+ local pth=expandedpathfromlist(resolvers.splitpath(str))
+ return joinpath(pth)
end
function resolvers.registerfilehash(name,content,someerror)
- if content then
- instance.files[name]=content
- else
- instance.files[name]={}
- if somerror==true then
- instance.loaderror=someerror
- end
+ if content then
+ instance.files[name]=content
+ else
+ instance.files[name]={}
+ if somerror==true then
+ instance.loaderror=someerror
end
+ end
end
function resolvers.getfilehashes()
- return instance and instance.files or {}
+ return instance and instance.files or {}
end
function resolvers.gethashes()
- return instance and instance.hashes or {}
+ return instance and instance.hashes or {}
end
function resolvers.renewcache()
- if instance then
- instance.renewcache=true
- end
+ if instance then
+ instance.renewcache=true
+ end
end
local function isreadable(name)
- local readable=isfile(name)
- if trace_detail then
- if readable then
- report_resolving("file %a is readable",name)
- else
- report_resolving("file %a is not readable",name)
- end
+ local readable=isfile(name)
+ if trace_detail then
+ if readable then
+ report_resolving("file %a is readable",name)
+ else
+ report_resolving("file %a is not readable",name)
end
- return readable
+ end
+ return readable
end
local function collect_files(names)
- local filelist={}
- local noffiles=0
- local function check(hash,root,pathname,path,basename,name)
- if not pathname or find(path,pathname) then
- local variant=hash.type
- local search=filejoin(root,path,name)
- local result=methodhandler('concatinators',variant,root,path,name)
- if trace_detail then
- report_resolving("match: variant %a, search %a, result %a",variant,search,result)
- end
- noffiles=noffiles+1
- filelist[noffiles]={ variant,search,result }
- end
+ local filelist={}
+ local noffiles=0
+ local function check(hash,root,pathname,path,basename,name)
+ if not pathname or find(path,pathname) then
+ local variant=hash.type
+ local search=filejoin(root,path,name)
+ local result=methodhandler('concatinators',variant,root,path,name)
+ if trace_detail then
+ report_resolving("match: variant %a, search %a, result %a",variant,search,result)
+ end
+ noffiles=noffiles+1
+ filelist[noffiles]={ variant,search,result }
end
- for k=1,#names do
- local filename=names[k]
+ end
+ for k=1,#names do
+ local filename=names[k]
+ if trace_detail then
+ report_resolving("checking name %a",filename)
+ end
+ local basename=filebasename(filename)
+ local pathname=filedirname(filename)
+ if pathname=="" or find(pathname,"^%.") then
+ pathname=false
+ else
+ pathname=gsub(pathname,"%*",".*")
+ pathname="/"..pathname.."$"
+ end
+ local hashes=instance.hashes
+ for h=1,#hashes do
+ local hash=hashes[h]
+ local hashname=hash.name
+ local content=hashname and instance.files[hashname]
+ if content then
if trace_detail then
- report_resolving("checking name %a",filename)
+ report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
end
- local basename=filebasename(filename)
- local pathname=filedirname(filename)
- if pathname=="" or find(pathname,"^%.") then
- pathname=false
- else
- pathname=gsub(pathname,"%*",".*")
- pathname="/"..pathname.."$"
- end
- local hashes=instance.hashes
- for h=1,#hashes do
- local hash=hashes[h]
- local hashname=hash.name
- local content=hashname and instance.files[hashname]
- if content then
- if trace_detail then
- report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
- end
- local path,name=lookup(content,basename)
- if path then
- local metadata=content.metadata
- local realroot=metadata and metadata.path or hashname
- if type(path)=="string" then
- check(hash,realroot,pathname,path,basename,name)
- else
- for i=1,#path do
- check(hash,realroot,pathname,path[i],basename,name)
- end
- end
- end
- elseif trace_locating then
- report_resolving("no match in %a (%s)",hashname,basename)
+ local path,name=lookup(content,basename)
+ if path then
+ local metadata=content.metadata
+ local realroot=metadata and metadata.path or hashname
+ if type(path)=="string" then
+ check(hash,realroot,pathname,path,basename,name)
+ else
+ for i=1,#path do
+ check(hash,realroot,pathname,path[i],basename,name)
end
+ end
end
+ elseif trace_locating then
+ report_resolving("no match in %a (%s)",hashname,basename)
+ end
end
- return noffiles>0 and filelist or nil
+ end
+ return noffiles>0 and filelist or nil
end
local fit={}
function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname)
- local foundintrees=instance.foundintrees
- if usedmethod=="direct" and filename==foundname and fit[foundname] then
- else
- local collapsed=collapsepath(foundname,true)
- local t={
- filename=filename,
- format=format~="" and format or nil,
- filetype=filetype~="" and filetype or nil,
- usedmethod=usedmethod,
- foundname=foundname,
- fullname=collapsed,
- }
- fit[foundname]=t
- foundintrees[#foundintrees+1]=t
- end
+ local foundintrees=instance.foundintrees
+ if usedmethod=="direct" and filename==foundname and fit[foundname] then
+ else
+ local collapsed=collapsepath(foundname,true)
+ local t={
+ filename=filename,
+ format=format~="" and format or nil,
+ filetype=filetype~="" and filetype or nil,
+ usedmethod=usedmethod,
+ foundname=foundname,
+ fullname=collapsed,
+ }
+ fit[foundname]=t
+ foundintrees[#foundintrees+1]=t
+ end
end
function resolvers.foundintrees()
- return instance.foundintrees or {}
+ return instance.foundintrees or {}
end
function resolvers.foundintree(fullname)
- local f=fit[fullname]
- return f and f.usedmethod=="database"
+ local f=fit[fullname]
+ return f and f.usedmethod=="database"
end
local function can_be_dir(name)
- local fakepaths=instance.fakepaths
- if not fakepaths[name] then
- if isdir(name) then
- fakepaths[name]=1
- else
- fakepaths[name]=2
- end
+ local fakepaths=instance.fakepaths
+ if not fakepaths[name] then
+ if isdir(name) then
+ fakepaths[name]=1
+ else
+ fakepaths[name]=2
end
- return fakepaths[name]==1
+ end
+ return fakepaths[name]==1
end
local preparetreepattern=Cs((P(".")/"%%."+P("-")/"%%-"+P(1))^0*Cc("$"))
local collect_instance_files
local function find_analyze(filename,askedformat,allresults)
- local filetype=''
- local filesuffix=suffixonly(filename)
- local wantedfiles={}
- wantedfiles[#wantedfiles+1]=filename
- if askedformat=="" then
- if filesuffix=="" or not suffixmap[filesuffix] then
- local defaultsuffixes=resolvers.defaultsuffixes
- local formatofsuffix=resolvers.formatofsuffix
- for i=1,#defaultsuffixes do
- local forcedname=filename..'.'..defaultsuffixes[i]
- wantedfiles[#wantedfiles+1]=forcedname
- filetype=formatofsuffix(forcedname)
- if trace_locating then
- report_resolving("forcing filetype %a",filetype)
- end
- end
- else
- filetype=resolvers.formatofsuffix(filename)
- if trace_locating then
- report_resolving("using suffix based filetype %a",filetype)
- end
+ local filetype=''
+ local filesuffix=suffixonly(filename)
+ local wantedfiles={}
+ wantedfiles[#wantedfiles+1]=filename
+ if askedformat=="" then
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local defaultsuffixes=resolvers.defaultsuffixes
+ local formatofsuffix=resolvers.formatofsuffix
+ for i=1,#defaultsuffixes do
+ local forcedname=filename..'.'..defaultsuffixes[i]
+ wantedfiles[#wantedfiles+1]=forcedname
+ filetype=formatofsuffix(forcedname)
+ if trace_locating then
+ report_resolving("forcing filetype %a",filetype)
end
+ end
else
- if filesuffix=="" or not suffixmap[filesuffix] then
- local format_suffixes=suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
- end
- end
- end
- filetype=askedformat
- if trace_locating then
- report_resolving("using given filetype %a",filetype)
+ filetype=resolvers.formatofsuffix(filename)
+ if trace_locating then
+ report_resolving("using suffix based filetype %a",filetype)
+ end
+ end
+ else
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local format_suffixes=suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
end
+ end
end
- return filetype,wantedfiles
+ filetype=askedformat
+ if trace_locating then
+ report_resolving("using given filetype %a",filetype)
+ end
+ end
+ return filetype,wantedfiles
end
local function find_direct(filename,allresults)
- if not dangerous[askedformat] and isreadable(filename) then
- if trace_detail then
- report_resolving("file %a found directly",filename)
- end
- return "direct",{ filename }
+ if not dangerous[askedformat] and isreadable(filename) then
+ if trace_detail then
+ report_resolving("file %a found directly",filename)
end
+ return "direct",{ filename }
+ end
end
local function find_wildcard(filename,allresults)
- if find(filename,'*',1,true) then
- if trace_locating then
- report_resolving("checking wildcard %a",filename)
- end
- local result=resolvers.findwildcardfiles(filename)
- if result then
- return "wildcard",result
- end
- end
-end
-local function find_qualified(filename,allresults,askedformat,alsostripped)
- if not is_qualified_path(filename) then
- return
- end
+ if find(filename,'*',1,true) then
if trace_locating then
- report_resolving("checking qualified name %a",filename)
+ report_resolving("checking wildcard %a",filename)
end
- if isreadable(filename) then
- if trace_detail then
- report_resolving("qualified file %a found",filename)
- end
- return "qualified",{ filename }
+ local result=resolvers.findwildcardfiles(filename)
+ if result then
+ return "wildcard",result
end
+ end
+end
+local function find_qualified(filename,allresults,askedformat,alsostripped)
+ if not is_qualified_path(filename) then
+ return
+ end
+ if trace_locating then
+ report_resolving("checking qualified name %a",filename)
+ end
+ if isreadable(filename) then
if trace_detail then
- report_resolving("locating qualified file %a",filename)
- end
- local forcedname,suffix="",suffixonly(filename)
- if suffix=="" then
- local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- local s=format_suffixes[i]
- forcedname=filename.."."..s
- if isreadable(forcedname) then
- if trace_locating then
- report_resolving("no suffix, forcing format filetype %a",s)
- end
- return "qualified",{ forcedname }
- end
- end
+ report_resolving("qualified file %a found",filename)
+ end
+ return "qualified",{ filename }
+ end
+ if trace_detail then
+ report_resolving("locating qualified file %a",filename)
+ end
+ local forcedname,suffix="",suffixonly(filename)
+ if suffix=="" then
+ local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ local s=format_suffixes[i]
+ forcedname=filename.."."..s
+ if isreadable(forcedname) then
+ if trace_locating then
+ report_resolving("no suffix, forcing format filetype %a",s)
+ end
+ return "qualified",{ forcedname }
end
+ end
end
- if alsostripped and suffix and suffix~="" then
- local basename=filebasename(filename)
- local pattern=lpegmatch(preparetreepattern,filename)
- local savedformat=askedformat
- local format=savedformat or ""
- if format=="" then
- askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if alsostripped and suffix and suffix~="" then
+ local basename=filebasename(filename)
+ local pattern=lpegmatch(preparetreepattern,filename)
+ local savedformat=askedformat
+ local format=savedformat or ""
+ if format=="" then
+ askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if not format then
+ askedformat="othertextfiles"
+ end
+ if basename~=filename then
+ local resolved=collect_instance_files(basename,askedformat,allresults)
+ if #resolved==0 then
+ local lowered=lower(basename)
+ if filename~=lowered then
+ resolved=collect_instance_files(lowered,askedformat,allresults)
end
- if not format then
- askedformat="othertextfiles"
+ end
+ resolvers.format=savedformat
+ if #resolved>0 then
+ local result={}
+ for r=1,#resolved do
+ local rr=resolved[r]
+ if find(rr,pattern) then
+ result[#result+1]=rr
+ end
end
- if basename~=filename then
- local resolved=collect_instance_files(basename,askedformat,allresults)
- if #resolved==0 then
- local lowered=lower(basename)
- if filename~=lowered then
- resolved=collect_instance_files(lowered,askedformat,allresults)
- end
- end
- resolvers.format=savedformat
- if #resolved>0 then
- local result={}
- for r=1,#resolved do
- local rr=resolved[r]
- if find(rr,pattern) then
- result[#result+1]=rr
- end
- end
- if #result>0 then
- return "qualified",result
- end
- end
+ if #result>0 then
+ return "qualified",result
end
+ end
end
+ end
end
local function check_subpath(fname)
- if isreadable(fname) then
- if trace_detail then
- report_resolving("found %a by deep scanning",fname)
- end
- return fname
+ if isreadable(fname) then
+ if trace_detail then
+ report_resolving("found %a by deep scanning",fname)
end
+ return fname
+ end
end
local function makepathlist(list,filetype)
- local typespec=resolvers.variableofformat(filetype)
- local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
- local entry={}
- if pathlist and #pathlist>0 then
- for k=1,#pathlist do
- local path=pathlist[k]
- local prescanned=find(path,'^!!')
- local resursive=find(path,'//$')
- local pathname=lpegmatch(inhibitstripper,path)
- local expression=makepathexpression(pathname)
- local barename=gsub(pathname,"/+$","")
- barename=resolveprefix(barename)
- local scheme=url.hasscheme(barename)
- local schemename=gsub(barename,"%.%*$",'')
- entry[k]={
- path=path,
- pathname=pathname,
- prescanned=prescanned,
- recursive=recursive,
- expression=expression,
- barename=barename,
- scheme=scheme,
- schemename=schemename,
- }
- end
- entry.typespec=typespec
- list[filetype]=entry
- else
- list[filetype]=false
- end
- return entry
+ local typespec=resolvers.variableofformat(filetype)
+ local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
+ local entry={}
+ if pathlist and #pathlist>0 then
+ for k=1,#pathlist do
+ local path=pathlist[k]
+ local prescanned=find(path,'^!!')
+ local resursive=find(path,'//$')
+ local pathname=lpegmatch(inhibitstripper,path)
+ local expression=makepathexpression(pathname)
+ local barename=gsub(pathname,"/+$","")
+ barename=resolveprefix(barename)
+ local scheme=url.hasscheme(barename)
+ local schemename=gsub(barename,"%.%*$",'')
+ entry[k]={
+ path=path,
+ pathname=pathname,
+ prescanned=prescanned,
+ recursive=recursive,
+ expression=expression,
+ barename=barename,
+ scheme=scheme,
+ schemename=schemename,
+ }
+ end
+ entry.typespec=typespec
+ list[filetype]=entry
+ else
+ list[filetype]=false
+ end
+ return entry
end
local function find_intree(filename,filetype,wantedfiles,allresults)
- local pathlists=instance.pathlists
- if not pathlists then
- pathlists=setmetatableindex({},makepathlist)
- instance.pathlists=pathlists
- end
- local pathlist=pathlists[filetype]
- if pathlist then
- local method="intree"
- local filelist=collect_files(wantedfiles)
- local dirlist={}
- local result={}
- if filelist then
- for i=1,#filelist do
- dirlist[i]=filedirname(filelist[i][3]).."/"
+ local pathlists=instance.pathlists
+ if not pathlists then
+ pathlists=setmetatableindex({},makepathlist)
+ instance.pathlists=pathlists
+ end
+ local pathlist=pathlists[filetype]
+ if pathlist then
+ local method="intree"
+ local filelist=collect_files(wantedfiles)
+ local dirlist={}
+ local result={}
+ if filelist then
+ for i=1,#filelist do
+ dirlist[i]=filedirname(filelist[i][3]).."/"
+ end
+ end
+ if trace_detail then
+ report_resolving("checking filename %a in tree",filename)
+ end
+ for k=1,#pathlist do
+ local entry=pathlist[k]
+ local path=entry.path
+ local pathname=entry.pathname
+ local done=false
+ if filelist then
+ local expression=entry.expression
+ if trace_detail then
+ report_resolving("using pattern %a for path %a",expression,pathname)
+ end
+ for k=1,#filelist do
+ local fl=filelist[k]
+ local f=fl[2]
+ local d=dirlist[k]
+ if find(d,expression) or find(resolveprefix(d),expression) then
+ result[#result+1]=resolveprefix(fl[3])
+ done=true
+ if allresults then
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
+ end
+ else
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
+ end
+ break
end
+ elseif trace_detail then
+ report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ end
end
- if trace_detail then
- report_resolving("checking filename %a in tree",filename)
- end
- for k=1,#pathlist do
- local entry=pathlist[k]
- local path=entry.path
- local pathname=entry.pathname
- local done=false
- if filelist then
- local expression=entry.expression
+ end
+ if done then
+ method="database"
+ else
+ method="filesystem"
+ local scheme=entry.scheme
+ if not scheme or scheme=="file" then
+ local pname=entry.schemename
+ if not find(pname,"*",1,true) then
+ if can_be_dir(pname) then
+ if not done and not entry.prescanned then
if trace_detail then
- report_resolving("using pattern %a for path %a",expression,pathname)
+ report_resolving("quick root scan for %a",pname)
end
- for k=1,#filelist do
- local fl=filelist[k]
- local f=fl[2]
- local d=dirlist[k]
- if find(d,expression) or find(resolveprefix(d),expression) then
- result[#result+1]=resolveprefix(fl[3])
- done=true
- if allresults then
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
- end
- else
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
- end
- break
- end
- elseif trace_detail then
- report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local fname=check_subpath(filejoin(pname,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
- end
- end
- if done then
- method="database"
- else
- method="filesystem"
- local scheme=entry.scheme
- if not scheme or scheme=="file" then
- local pname=entry.schemename
- if not find(pname,"*",1,true) then
- if can_be_dir(pname) then
- if not done and not entry.prescanned then
- if trace_detail then
- report_resolving("quick root scan for %a",pname)
- end
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local fname=check_subpath(filejoin(pname,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- if not done and entry.recursive then
- if trace_detail then
- report_resolving("scanning filesystem for %a",pname)
- end
- local files=resolvers.simplescanfiles(pname,false,true)
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local subpath=files[w]
- if not subpath or subpath=="" then
- elseif type(subpath)=="string" then
- local fname=check_subpath(filejoin(pname,subpath,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- else
- for i=1,#subpath do
- local sp=subpath[i]
- if sp=="" then
- else
- local fname=check_subpath(filejoin(pname,sp,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- end
- if done and not allresults then
- break
- end
- end
- end
- end
- end
+ end
+ end
+ if not done and entry.recursive then
+ if trace_detail then
+ report_resolving("scanning filesystem for %a",pname)
+ end
+ local files=resolvers.simplescanfiles(pname,false,true)
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local subpath=files[w]
+ if not subpath or subpath=="" then
+ elseif type(subpath)=="string" then
+ local fname=check_subpath(filejoin(pname,subpath,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
+ end
else
- end
- else
- for k=1,#wantedfiles do
- local pname=entry.barename
- local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
- if fname then
+ for i=1,#subpath do
+ local sp=subpath[i]
+ if sp=="" then
+ else
+ local fname=check_subpath(filejoin(pname,sp,w))
+ if fname then
result[#result+1]=fname
done=true
if not allresults then
- break
+ break
end
+ end
end
+ end
+ if done and not allresults then
+ break
+ end
end
+ end
end
+ end
end
- if done and not allresults then
+ else
+ end
+ else
+ for k=1,#wantedfiles do
+ local pname=entry.barename
+ local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
break
+ end
end
+ end
end
- if #result>0 then
- return method,result
- end
+ end
+ if done and not allresults then
+ break
+ end
end
+ if #result>0 then
+ return method,result
+ end
+ end
end
local function find_onpath(filename,filetype,wantedfiles,allresults)
- if trace_detail then
- report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
- end
- local result={}
- for k=1,#wantedfiles do
- local fname=wantedfiles[k]
- if fname and isreadable(fname) then
- filename=fname
- result[#result+1]=filejoin('.',fname)
- if not allresults then
- break
- end
- end
- end
- if #result>0 then
- return "onpath",result
+ if trace_detail then
+ report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
+ end
+ local result={}
+ for k=1,#wantedfiles do
+ local fname=wantedfiles[k]
+ if fname and isreadable(fname) then
+ filename=fname
+ result[#result+1]=filejoin('.',fname)
+ if not allresults then
+ break
+ end
end
+ end
+ if #result>0 then
+ return "onpath",result
+ end
end
local function find_otherwise(filename,filetype,wantedfiles,allresults)
- local filelist=collect_files(wantedfiles)
- local fl=filelist and filelist[1]
- if fl then
- return "otherwise",{ resolveprefix(fl[3]) }
- end
+ local filelist=collect_files(wantedfiles)
+ local fl=filelist and filelist[1]
+ if fl then
+ return "otherwise",{ resolveprefix(fl[3]) }
+ end
end
collect_instance_files=function(filename,askedformat,allresults)
- if not filename or filename=="" then
- return {}
- end
- askedformat=askedformat or ""
- filename=collapsepath(filename,".")
- filename=gsub(filename,"^%./",getcurrentdir().."/")
- if allresults then
- local filetype,wantedfiles=find_analyze(filename,askedformat)
- local results={
- { find_direct (filename,true) },
- { find_wildcard (filename,true) },
- { find_qualified(filename,true,askedformat) },
- { find_intree (filename,filetype,wantedfiles,true) },
- { find_onpath (filename,filetype,wantedfiles,true) },
- { find_otherwise(filename,filetype,wantedfiles,true) },
- }
- local result,status,done={},{},{}
- for k,r in next,results do
- local method,list=r[1],r[2]
- if method and list then
- for i=1,#list do
- local c=collapsepath(list[i])
- if not done[c] then
- result[#result+1]=c
- done[c]=true
- end
- status[#status+1]=formatters["%-10s: %s"](method,c)
- end
- end
- end
- if trace_detail then
- report_resolving("lookup status: %s",table.serialize(status,filename))
+ if not filename or filename=="" then
+ return {}
+ end
+ askedformat=askedformat or ""
+ filename=collapsepath(filename,".")
+ filename=gsub(filename,"^%./",getcurrentdir().."/")
+ if allresults then
+ local filetype,wantedfiles=find_analyze(filename,askedformat)
+ local results={
+ { find_direct (filename,true) },
+ { find_wildcard (filename,true) },
+ { find_qualified(filename,true,askedformat) },
+ { find_intree (filename,filetype,wantedfiles,true) },
+ { find_onpath (filename,filetype,wantedfiles,true) },
+ { find_otherwise(filename,filetype,wantedfiles,true) },
+ }
+ local result,status,done={},{},{}
+ for k,r in next,results do
+ local method,list=r[1],r[2]
+ if method and list then
+ for i=1,#list do
+ local c=collapsepath(list[i])
+ if not done[c] then
+ result[#result+1]=c
+ done[c]=true
+ end
+ status[#status+1]=formatters["%-10s: %s"](method,c)
end
- return result,status
- else
- local method,result,stamp,filetype,wantedfiles
- if instance.remember then
- if askedformat=="" then
- stamp=formatters["%s::%s"](suffixonly(filename),filename)
- else
- stamp=formatters["%s::%s"](askedformat,filename)
- end
- result=stamp and instance.found[stamp]
- if result then
- if trace_locating then
- report_resolving("remembered file %a",filename)
- end
- return result
- end
+ end
+ end
+ if trace_detail then
+ report_resolving("lookup status: %s",table.serialize(status,filename))
+ end
+ return result,status
+ else
+ local method,result,stamp,filetype,wantedfiles
+ if instance.remember then
+ if askedformat=="" then
+ stamp=formatters["%s::%s"](suffixonly(filename),filename)
+ else
+ stamp=formatters["%s::%s"](askedformat,filename)
+ end
+ result=stamp and instance.found[stamp]
+ if result then
+ if trace_locating then
+ report_resolving("remembered file %a",filename)
end
- method,result=find_direct(filename)
+ return result
+ end
+ end
+ method,result=find_direct(filename)
+ if not result then
+ method,result=find_wildcard(filename)
+ if not result then
+ method,result=find_qualified(filename,false,askedformat)
if not result then
- method,result=find_wildcard(filename)
- if not result then
- method,result=find_qualified(filename,false,askedformat)
- if not result then
- filetype,wantedfiles=find_analyze(filename,askedformat)
- method,result=find_intree(filename,filetype,wantedfiles)
- if not result then
- method,result=find_onpath(filename,filetype,wantedfiles)
- if resolve_otherwise and not result then
- method,result=find_otherwise(filename,filetype,wantedfiles)
- end
- end
- end
- end
- end
- if result and #result>0 then
- local foundname=collapsepath(result[1])
- resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
- result={ foundname }
- else
- result={}
- end
- if stamp then
- if trace_locating then
- report_resolving("remembering file %a using hash %a",filename,stamp)
+ filetype,wantedfiles=find_analyze(filename,askedformat)
+ method,result=find_intree(filename,filetype,wantedfiles)
+ if not result then
+ method,result=find_onpath(filename,filetype,wantedfiles)
+ if resolve_otherwise and not result then
+ method,result=find_otherwise(filename,filetype,wantedfiles)
end
- instance.found[stamp]=result
+ end
end
- return result
+ end
+ end
+ if result and #result>0 then
+ local foundname=collapsepath(result[1])
+ resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
+ result={ foundname }
+ else
+ result={}
end
+ if stamp then
+ if trace_locating then
+ report_resolving("remembering file %a using hash %a",filename,stamp)
+ end
+ instance.found[stamp]=result
+ end
+ return result
+ end
end
local function findfiles(filename,filetype,allresults)
- if not filename or filename=="" then
- return {}
- end
- local result,status=collect_instance_files(filename,filetype or "",allresults)
- if not result or #result==0 then
- local lowered=lower(filename)
- if filename~=lowered then
- result,status=collect_instance_files(lowered,filetype or "",allresults)
- end
+ if not filename or filename=="" then
+ return {}
+ end
+ local result,status=collect_instance_files(filename,filetype or "",allresults)
+ if not result or #result==0 then
+ local lowered=lower(filename)
+ if filename~=lowered then
+ result,status=collect_instance_files(lowered,filetype or "",allresults)
end
- return result or {},status
+ end
+ return result or {},status
end
function resolvers.findfiles(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,true)
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,true)
+ end
end
function resolvers.findfile(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,false)[1] or ""
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,false)[1] or ""
+ end
end
function resolvers.findpath(filename,filetype)
- return filedirname(findfiles(filename,filetype,false)[1] or "")
+ return filedirname(findfiles(filename,filetype,false)[1] or "")
end
local function findgivenfiles(filename,allresults)
- local base=filebasename(filename)
- local result={}
- local hashes=instance.hashes
- local function okay(hash,path,name)
- local found=methodhandler('concatinators',hash.type,hash.name,path,name)
- if found and found~="" then
- result[#result+1]=resolveprefix(found)
- return not allresults
- end
- end
- for k=1,#hashes do
- local hash=hashes[k]
- local content=instance.files[hash.name]
- if content then
- local path,name=lookup(content,base)
- if not path then
- elseif type(path)=="string" then
- if okay(hash,path,name) then
- return result
- end
- else
- for i=1,#path do
- if okay(hash,path[i],name) then
- return result
- end
- end
- end
+ local base=filebasename(filename)
+ local result={}
+ local hashes=instance.hashes
+ local function okay(hash,path,name)
+ local found=methodhandler('concatinators',hash.type,hash.name,path,name)
+ if found and found~="" then
+ result[#result+1]=resolveprefix(found)
+ return not allresults
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local content=instance.files[hash.name]
+ if content then
+ local path,name=lookup(content,base)
+ if not path then
+ elseif type(path)=="string" then
+ if okay(hash,path,name) then
+ return result
+ end
+ else
+ for i=1,#path do
+ if okay(hash,path[i],name) then
+ return result
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findgivenfiles(filename)
- return findgivenfiles(filename,true)
+ return findgivenfiles(filename,true)
end
function resolvers.findgivenfile(filename)
- return findgivenfiles(filename,false)[1] or ""
+ return findgivenfiles(filename,false)[1] or ""
end
local makewildcard=Cs(
- (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
+ (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
)
function resolvers.wildcardpattern(pattern)
- return lpegmatch(makewildcard,pattern) or pattern
+ return lpegmatch(makewildcard,pattern) or pattern
end
local function findwildcardfiles(filename,allresults,result)
- local result=result or {}
- local base=filebasename(filename)
- local dirn=filedirname(filename)
- local path=lower(lpegmatch(makewildcard,dirn) or dirn)
- local name=lower(lpegmatch(makewildcard,base) or base)
- local files=instance.files
- if find(name,"*",1,true) then
- local hashes=instance.hashes
- local function okay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
- end
+ local result=result or {}
+ local base=filebasename(filename)
+ local dirn=filedirname(filename)
+ local path=lower(lpegmatch(makewildcard,dirn) or dirn)
+ local name=lower(lpegmatch(makewildcard,base) or base)
+ local files=instance.files
+ if find(name,"*",1,true) then
+ local hashes=instance.hashes
+ local function okay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
end
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- for found,base in filtered(files[hashname],name) do
- if type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
- end
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ for found,base in filtered(files[hashname],name) do
+ if type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
end
- end
- else
- local function okayokay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
+ end
end
+ end
end
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- local found,base=lookup(content,base)
- if not found then
- elseif type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
+ end
+ end
+ else
+ local function okayokay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
+ end
+ end
+ end
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ local found,base=lookup(content,base)
+ if not found then
+ elseif type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
+ end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
end
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findwildcardfiles(filename,result)
- return findwildcardfiles(filename,true,result)
+ return findwildcardfiles(filename,true,result)
end
function resolvers.findwildcardfile(filename)
- return findwildcardfiles(filename,false)[1] or ""
+ return findwildcardfiles(filename,false)[1] or ""
end
function resolvers.automount()
end
function resolvers.starttiming()
- statistics.starttiming(instance)
+ statistics.starttiming(instance)
end
function resolvers.stoptiming()
- statistics.stoptiming(instance)
+ statistics.stoptiming(instance)
end
function resolvers.load(option)
- resolvers.starttiming()
- identify_configuration_files()
- load_configuration_files()
- if option~="nofiles" then
- load_databases()
- resolvers.automount()
- end
- resolvers.stoptiming()
- local files=instance.files
- return files and next(files) and true
+ resolvers.starttiming()
+ identify_configuration_files()
+ load_configuration_files()
+ if option~="nofiles" then
+ load_databases()
+ resolvers.automount()
+ end
+ resolvers.stoptiming()
+ local files=instance.files
+ return files and next(files) and true
end
function resolvers.loadtime()
- return statistics.elapsedtime(instance)
+ return statistics.elapsedtime(instance)
end
local function report(str)
- if trace_locating then
- report_resolving(str)
- else
- print(str)
- end
+ if trace_locating then
+ report_resolving(str)
+ else
+ print(str)
+ end
end
function resolvers.dowithfilesandreport(command,files,...)
- if files and #files>0 then
- if trace_locating then
- report('')
- end
- if type(files)=="string" then
- files={ files }
- end
- for f=1,#files do
- local file=files[f]
- local result=command(file,...)
- if type(result)=='string' then
- report(result)
- else
- for i=1,#result do
- report(result[i])
- end
- end
+ if files and #files>0 then
+ if trace_locating then
+ report('')
+ end
+ if type(files)=="string" then
+ files={ files }
+ end
+ for f=1,#files do
+ local file=files[f]
+ local result=command(file,...)
+ if type(result)=='string' then
+ report(result)
+ else
+ for i=1,#result do
+ report(result[i])
end
+ end
end
+ end
end
-function resolvers.showpath(str)
- return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
+function resolvers.showpath(str)
+ return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
end
function resolvers.registerfile(files,name,path)
- if files[name] then
- if type(files[name])=='string' then
- files[name]={ files[name],path }
- else
- files[name]=path
- end
+ if files[name] then
+ if type(files[name])=='string' then
+ files[name]={ files[name],path }
else
- files[name]=path
+ files[name]=path
end
+ else
+ files[name]=path
+ end
end
function resolvers.dowithpath(name,func)
- local pathlist=resolvers.expandedpathlist(name)
- for i=1,#pathlist do
- func("^"..cleanpath(pathlist[i]))
- end
+ local pathlist=resolvers.expandedpathlist(name)
+ for i=1,#pathlist do
+ func("^"..cleanpath(pathlist[i]))
+ end
end
function resolvers.dowithvariable(name,func)
- func(expandedvariable(name))
+ func(expandedvariable(name))
end
function resolvers.locateformat(name)
- local engine=environment.ownmain or "luatex"
- local barename=removesuffix(name)
- local fullname=addsuffix(barename,"fmt")
- local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
- if fmtname=="" then
- fmtname=resolvers.findfile(fullname)
- fmtname=cleanpath(fmtname)
- end
- if fmtname~="" then
- local barename=removesuffix(fmtname)
- local luaname=addsuffix(barename,luasuffixes.lua)
- local lucname=addsuffix(barename,luasuffixes.luc)
- local luiname=addsuffix(barename,luasuffixes.lui)
- if isfile(luiname) then
- return barename,luiname
- elseif isfile(lucname) then
- return barename,lucname
- elseif isfile(luaname) then
- return barename,luaname
- end
- end
- return nil,nil
+ local engine=environment.ownmain or "luatex"
+ local barename=removesuffix(name)
+ local fullname=addsuffix(barename,"fmt")
+ local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
+ if fmtname=="" then
+ fmtname=resolvers.findfile(fullname)
+ fmtname=cleanpath(fmtname)
+ end
+ if fmtname~="" then
+ local barename=removesuffix(fmtname)
+ local luaname=addsuffix(barename,luasuffixes.lua)
+ local lucname=addsuffix(barename,luasuffixes.luc)
+ local luiname=addsuffix(barename,luasuffixes.lui)
+ if isfile(luiname) then
+ return barename,luiname
+ elseif isfile(lucname) then
+ return barename,lucname
+ elseif isfile(luaname) then
+ return barename,luaname
+ end
+ end
+ return nil,nil
end
function resolvers.booleanvariable(str,default)
- local b=resolvers.expansion(str)
- if b=="" then
- return default
- else
- b=toboolean(b)
- return (b==nil and default) or b
- end
+ local b=resolvers.expansion(str)
+ if b=="" then
+ return default
+ else
+ b=toboolean(b)
+ return (b==nil and default) or b
+ end
end
function resolvers.dowithfilesintree(pattern,handle,before,after)
- local hashes=instance.hashes
- for i=1,#hashes do
- local hash=hashes[i]
- local blobtype=hash.type
- local blobpath=hash.name
- if blobtype and blobpath then
- local total=0
- local checked=0
- local done=0
- if before then
- before(blobtype,blobpath,pattern)
- end
- for path,name in filtered(instance.files[blobpath],pattern) do
- if type(path)=="string" then
- checked=checked+1
- if handle(blobtype,blobpath,path,name) then
- done=done+1
- end
- else
- checked=checked+#path
- for i=1,#path do
- if handle(blobtype,blobpath,path[i],name) then
- done=done+1
- end
- end
- end
- end
- if after then
- after(blobtype,blobpath,pattern,checked,done)
+ local hashes=instance.hashes
+ for i=1,#hashes do
+ local hash=hashes[i]
+ local blobtype=hash.type
+ local blobpath=hash.name
+ if blobtype and blobpath then
+ local total=0
+ local checked=0
+ local done=0
+ if before then
+ before(blobtype,blobpath,pattern)
+ end
+ for path,name in filtered(instance.files[blobpath],pattern) do
+ if type(path)=="string" then
+ checked=checked+1
+ if handle(blobtype,blobpath,path,name) then
+ done=done+1
+ end
+ else
+ checked=checked+#path
+ for i=1,#path do
+ if handle(blobtype,blobpath,path[i],name) then
+ done=done+1
end
+ end
end
+ end
+ if after then
+ after(blobtype,blobpath,pattern,checked,done)
+ end
end
+ end
end
local obsolete=resolvers.obsolete or {}
resolvers.obsolete=obsolete
-resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
-resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
+resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
+resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
function resolvers.knownvariables(pattern)
- if instance then
- local environment=instance.environment
- local variables=instance.variables
- local expansions=instance.expansions
- local order=instance.order
- local pattern=upper(pattern or "")
- local result={}
- for i=1,#order do
- for key in next,order[i] do
- if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
- result[key]={
- environment=rawget(environment,key),
- variable=key,
- expansion=expansions[key],
- resolved=resolveprefix(expansions[key]),
- }
- end
- end
+ if instance then
+ local environment=instance.environment
+ local variables=instance.variables
+ local expansions=instance.expansions
+ local order=instance.order
+ local pattern=upper(pattern or "")
+ local result={}
+ for i=1,#order do
+ for key in next,order[i] do
+ if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
+ result[key]={
+ environment=rawget(environment,key),
+ variable=key,
+ expansion=expansions[key],
+ resolved=resolveprefix(expansions[key]),
+ }
end
- return result
- else
- return {}
+ end
end
+ return result
+ else
+ return {}
+ end
end
@@ -22710,14 +22718,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-pre"] = package.loaded["data-pre"] or true
--- original size: 4854, stripped down to: 2993
+-- original size: 4854, stripped down to: 2889
if not modules then modules={} end modules ['data-pre']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local resolvers=resolvers
local prefixes=resolvers.prefixes
@@ -22730,64 +22738,64 @@ local dirname=file.dirname
local joinpath=file.join
local isfile=lfs.isfile
prefixes.environment=function(str)
- return cleanpath(expansion(str))
+ return cleanpath(expansion(str))
end
local function relative(str,n)
- if not isfile(str) then
- local pstr="./"..str
+ if not isfile(str) then
+ local pstr="./"..str
+ if isfile(pstr) then
+ str=pstr
+ else
+ local p="../"
+ for i=1,n or 2 do
+ local pstr=p..str
if isfile(pstr) then
- str=pstr
+ str=pstr
+ break
else
- local p="../"
- for i=1,n or 2 do
- local pstr=p..str
- if isfile(pstr) then
- str=pstr
- break
- else
- p=p.."../"
- end
- end
+ p=p.."../"
end
+ end
end
- return cleanpath(str)
+ end
+ return cleanpath(str)
end
local function locate(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(fullname~="" and fullname or str)
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(fullname~="" and fullname or str)
end
prefixes.relative=relative
prefixes.locate=locate
prefixes.auto=function(str)
- local fullname=relative(str)
- if not isfile(fullname) then
- fullname=locate(str)
- end
- return fullname
+ local fullname=relative(str)
+ if not isfile(fullname) then
+ fullname=locate(str)
+ end
+ return fullname
end
prefixes.filename=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(basename((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(basename((fullname~="" and fullname) or str))
end
prefixes.pathname=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(dirname((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(dirname((fullname~="" and fullname) or str))
end
prefixes.selfautoloc=function(str)
- local pth=getenv('SELFAUTOLOC')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOLOC')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautoparent=function(str)
- local pth=getenv('SELFAUTOPARENT')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOPARENT')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautodir=function(str)
- local pth=getenv('SELFAUTODIR')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTODIR')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.home=function(str)
- local pth=getenv('HOME')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('HOME')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.env=prefixes.environment
prefixes.rel=prefixes.relative
@@ -22797,24 +22805,24 @@ prefixes.full=prefixes.locate
prefixes.file=prefixes.filename
prefixes.path=prefixes.pathname
local function toppath()
- local inputstack=resolvers.inputstack
- if not inputstack then
- return "."
- end
- local pathname=dirname(inputstack[#inputstack] or "")
- if pathname=="" then
- return "."
- else
- return pathname
- end
+ local inputstack=resolvers.inputstack
+ if not inputstack then
+ return "."
+ end
+ local pathname=dirname(inputstack[#inputstack] or "")
+ if pathname=="" then
+ return "."
+ else
+ return pathname
+ end
end
local function jobpath()
- local path=resolvers.stackpath()
- if not path or path=="" then
- return "."
- else
- return path
- end
+ local path=resolvers.stackpath()
+ if not path or path=="" then
+ return "."
+ else
+ return path
+ end
end
resolvers.toppath=toppath
resolvers.jobpath=jobpath
@@ -22830,14 +22838,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-inp"] = package.loaded["data-inp"] or true
--- original size: 910, stripped down to: 823
+-- original size: 910, stripped down to: 818
if not modules then modules={} end modules ['data-inp']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -22860,14 +22868,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-out"] = package.loaded["data-out"] or true
--- original size: 530, stripped down to: 475
+-- original size: 530, stripped down to: 470
if not modules then modules={} end modules ['data-out']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -22883,16 +22891,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-fil"] = package.loaded["data-fil"] or true
--- original size: 3863, stripped down to: 3310
+-- original size: 3863, stripped down to: 3170
if not modules then modules={} end modules ['data-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_files=logs.reporter("resolvers","files")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -22900,88 +22908,88 @@ local finders,openers,loaders,savers=resolvers.finders,resolvers.openers,resolve
local locators,hashers,generators,concatinators=resolvers.locators,resolvers.hashers,resolvers.generators,resolvers.concatinators
local checkgarbage=utilities.garbagecollector and utilities.garbagecollector.check
function locators.file(specification)
- local filename=specification.filename
- local realname=resolveprefix(filename)
- if realname and realname~='' and lfs.isdir(realname) then
- if trace_locating then
- report_files("file locator %a found as %a",filename,realname)
- end
- resolvers.appendhash('file',filename,true)
- elseif trace_locating then
- report_files("file locator %a not found",filename)
+ local filename=specification.filename
+ local realname=resolveprefix(filename)
+ if realname and realname~='' and lfs.isdir(realname) then
+ if trace_locating then
+ report_files("file locator %a found as %a",filename,realname)
end
+ resolvers.appendhash('file',filename,true)
+ elseif trace_locating then
+ report_files("file locator %a not found",filename)
+ end
end
function hashers.file(specification)
- local pathname=specification.filename
- local content=caches.loadcontent(pathname,'files')
- resolvers.registerfilehash(pathname,content,content==nil)
+ local pathname=specification.filename
+ local content=caches.loadcontent(pathname,'files')
+ resolvers.registerfilehash(pathname,content,content==nil)
end
function generators.file(specification)
- local pathname=specification.filename
- local content=resolvers.scanfiles(pathname,false,true)
- resolvers.registerfilehash(pathname,content,true)
+ local pathname=specification.filename
+ local content=resolvers.scanfiles(pathname,false,true)
+ resolvers.registerfilehash(pathname,content,true)
end
concatinators.file=file.join
function finders.file(specification,filetype)
- local filename=specification.filename
- local foundname=resolvers.findfile(filename,filetype)
- if foundname and foundname~="" then
- if trace_locating then
- report_files("file finder: %a found",filename)
- end
- return foundname
- else
- if trace_locating then
- report_files("file finder: %a not found",filename)
- end
- return finders.notfound()
+ local filename=specification.filename
+ local foundname=resolvers.findfile(filename,filetype)
+ if foundname and foundname~="" then
+ if trace_locating then
+ report_files("file finder: %a found",filename)
+ end
+ return foundname
+ else
+ if trace_locating then
+ report_files("file finder: %a not found",filename)
end
+ return finders.notfound()
+ end
end
function openers.helpers.textopener(tag,filename,f)
- return {
- reader=function() return f:read () end,
- close=function() logs.show_close(filename) return f:close() end,
- }
+ return {
+ reader=function() return f:read () end,
+ close=function() logs.show_close(filename) return f:close() end,
+ }
end
function openers.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"r")
- if f then
- if trace_locating then
- report_files("file opener: %a opened",filename)
- end
- return openers.helpers.textopener("file",filename,f)
- end
- end
- if trace_locating then
- report_files("file opener: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"r")
+ if f then
+ if trace_locating then
+ report_files("file opener: %a opened",filename)
+ end
+ return openers.helpers.textopener("file",filename,f)
end
- return openers.notfound()
+ end
+ if trace_locating then
+ report_files("file opener: %a not found",filename)
+ end
+ return openers.notfound()
end
function loaders.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"rb")
- if f then
- logs.show_load(filename)
- if trace_locating then
- report_files("file loader: %a loaded",filename)
- end
- local s=f:read("*a")
- if checkgarbage then
- checkgarbage(#s)
- end
- f:close()
- if s then
- return true,s,#s
- end
- end
- end
- if trace_locating then
- report_files("file loader: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"rb")
+ if f then
+ logs.show_load(filename)
+ if trace_locating then
+ report_files("file loader: %a loaded",filename)
+ end
+ local s=f:read("*a")
+ if checkgarbage then
+ checkgarbage(#s)
+ end
+ f:close()
+ if s then
+ return true,s,#s
+ end
end
- return loaders.notfound()
+ end
+ if trace_locating then
+ report_files("file loader: %a not found",filename)
+ end
+ return loaders.notfound()
end
@@ -22991,116 +22999,116 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-con"] = package.loaded["data-con"] or true
--- original size: 5029, stripped down to: 3607
+-- original size: 5029, stripped down to: 3432
if not modules then modules={} end modules ['data-con']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub=string.format,string.lower,string.gsub
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
-local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
-local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
+local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
containers=containers or {}
local containers=containers
containers.usecache=true
local report_containers=logs.reporter("resolvers","containers")
local allocated={}
local mt={
- __index=function(t,k)
- if k=="writable" then
- local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
- t.writable=writable
- return writable
- elseif k=="readables" then
- local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
- t.readables=readables
- return readables
- end
- end,
- __storage__=true
+ __index=function(t,k)
+ if k=="writable" then
+ local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
+ t.writable=writable
+ return writable
+ elseif k=="readables" then
+ local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
+ t.readables=readables
+ return readables
+ end
+ end,
+ __storage__=true
}
function containers.define(category,subcategory,version,enabled)
- if category and subcategory then
- local c=allocated[category]
- if not c then
- c={}
- allocated[category]=c
- end
- local s=c[subcategory]
- if not s then
- s={
- category=category,
- subcategory=subcategory,
- storage={},
- enabled=enabled,
- version=version or math.pi,
- trace=false,
- }
- setmetatable(s,mt)
- c[subcategory]=s
- end
- return s
+ if category and subcategory then
+ local c=allocated[category]
+ if not c then
+ c={}
+ allocated[category]=c
+ end
+ local s=c[subcategory]
+ if not s then
+ s={
+ category=category,
+ subcategory=subcategory,
+ storage={},
+ enabled=enabled,
+ version=version or math.pi,
+ trace=false,
+ }
+ setmetatable(s,mt)
+ c[subcategory]=s
end
+ return s
+ end
end
function containers.is_usable(container,name)
- return container.enabled and caches and caches.is_writable(container.writable,name)
+ return container.enabled and caches and caches.is_writable(container.writable,name)
end
function containers.is_valid(container,name)
- if name and name~="" then
- local storage=container.storage[name]
- return storage and storage.cache_version==container.version
- else
- return false
- end
+ if name and name~="" then
+ local storage=container.storage[name]
+ return storage and storage.cache_version==container.version
+ else
+ return false
+ end
end
function containers.read(container,name)
- local storage=container.storage
- local stored=storage[name]
- if not stored and container.enabled and caches and containers.usecache then
- stored=caches.loaddata(container.readables,name,container.writable)
- if stored and stored.cache_version==container.version then
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","load",container.subcategory,name)
- end
- else
- stored=nil
- end
- storage[name]=stored
- elseif stored then
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
- end
+ local storage=container.storage
+ local stored=storage[name]
+ if not stored and container.enabled and caches and containers.usecache then
+ stored=caches.loaddata(container.readables,name,container.writable)
+ if stored and stored.cache_version==container.version then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","load",container.subcategory,name)
+ end
+ else
+ stored=nil
end
- return stored
+ storage[name]=stored
+ elseif stored then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
+ end
+ end
+ return stored
end
function containers.write(container,name,data)
- if data then
- data.cache_version=container.version
- if container.enabled and caches then
- local unique,shared=data.unique,data.shared
- data.unique,data.shared=nil,nil
- caches.savedata(container.writable,name,data)
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","save",container.subcategory,name)
- end
- data.unique,data.shared=unique,shared
- end
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","store",container.subcategory,name)
- end
- container.storage[name]=data
+ if data then
+ data.cache_version=container.version
+ if container.enabled and caches then
+ local unique,shared=data.unique,data.shared
+ data.unique,data.shared=nil,nil
+ caches.savedata(container.writable,name,data)
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","save",container.subcategory,name)
+ end
+ data.unique,data.shared=unique,shared
end
- return data
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","store",container.subcategory,name)
+ end
+ container.storage[name]=data
+ end
+ return data
end
function containers.content(container,name)
- return container.storage[name]
+ return container.storage[name]
end
function containers.cleanname(name)
- return (gsub(lower(name),"[^%w\128-\255]+","-"))
+ return (gsub(lower(name),"[^%w\128-\255]+","-"))
end
@@ -23110,97 +23118,97 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-use"] = package.loaded["data-use"] or true
--- original size: 4272, stripped down to: 3289
+-- original size: 4272, stripped down to: 3060
if not modules then modules={} end modules ['data-use']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub,find=string.format,string.lower,string.gsub,string.find
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_mounts=logs.reporter("resolvers","mounts")
local resolvers=resolvers
resolvers.automounted=resolvers.automounted or {}
function resolvers.automount(usecache)
- local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
- if (not mountpaths or #mountpaths==0) and usecache then
- mountpaths=caches.getreadablepaths("mount")
- end
- if mountpaths and #mountpaths>0 then
- resolvers.starttiming()
- for k=1,#mountpaths do
- local root=mountpaths[k]
- local f=io.open(root.."/url.tmi")
- if f then
- for line in f:lines() do
- if line then
- if find(line,"^[%%#%-]") then
- elseif find(line,"^zip://") then
- if trace_locating then
- report_mounts("mounting %a",line)
- end
- table.insert(resolvers.automounted,line)
- resolvers.usezipfile(line)
- end
- end
- end
- f:close()
+ local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
+ if (not mountpaths or #mountpaths==0) and usecache then
+ mountpaths=caches.getreadablepaths("mount")
+ end
+ if mountpaths and #mountpaths>0 then
+ resolvers.starttiming()
+ for k=1,#mountpaths do
+ local root=mountpaths[k]
+ local f=io.open(root.."/url.tmi")
+ if f then
+ for line in f:lines() do
+ if line then
+ if find(line,"^[%%#%-]") then
+ elseif find(line,"^zip://") then
+ if trace_locating then
+ report_mounts("mounting %a",line)
+ end
+ table.insert(resolvers.automounted,line)
+ resolvers.usezipfile(line)
end
+ end
end
- resolvers.stoptiming()
+ f:close()
+ end
end
+ resolvers.stoptiming()
+ end
end
statistics.register("used config file",function() return caches.configfiles() end)
statistics.register("used cache path",function() return caches.usedpaths() end)
function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner)
- local enginebanner=status.banner
- if formatbanner and enginebanner and sourcefile then
- local luvname=file.replacesuffix(texname,"luv")
- local luvdata={
- enginebanner=enginebanner,
- formatbanner=formatbanner,
- sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
- sourcefile=sourcefile,
- luaversion=LUAVERSION,
- }
- io.savedata(luvname,table.serialize(luvdata,true))
- lua.registerfinalizer(function()
- logs.report("format banner","%s",banner)
- logs.newline()
- end)
- end
+ local enginebanner=status.banner
+ if formatbanner and enginebanner and sourcefile then
+ local luvname=file.replacesuffix(texname,"luv")
+ local luvdata={
+ enginebanner=enginebanner,
+ formatbanner=formatbanner,
+ sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
+ sourcefile=sourcefile,
+ luaversion=LUAVERSION,
+ }
+ io.savedata(luvname,table.serialize(luvdata,true))
+ lua.registerfinalizer(function()
+ logs.report("format banner","%s",banner)
+ logs.newline()
+ end)
+ end
end
function statistics.checkfmtstatus(texname)
- local enginebanner=status.banner
- if enginebanner and texname then
- local luvname=file.replacesuffix(texname,"luv")
- if lfs.isfile(luvname) then
- local luv=dofile(luvname)
- if luv and luv.sourcefile then
- local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
- local luvbanner=luv.enginebanner or "?"
- if luvbanner~=enginebanner then
- return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
- end
- local luvhash=luv.sourcehash or "?"
- if luvhash~=sourcehash then
- return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
- end
- local luvluaversion=luv.luaversion or 0
- if luvluaversion~=LUAVERSION then
- return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
- end
- else
- return "invalid status file"
- end
- else
- return "missing status file"
- end
+ local enginebanner=status.banner
+ if enginebanner and texname then
+ local luvname=file.replacesuffix(texname,"luv")
+ if lfs.isfile(luvname) then
+ local luv=dofile(luvname)
+ if luv and luv.sourcefile then
+ local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
+ local luvbanner=luv.enginebanner or "?"
+ if luvbanner~=enginebanner then
+ return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
+ end
+ local luvhash=luv.sourcehash or "?"
+ if luvhash~=sourcehash then
+ return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
+ end
+ local luvluaversion=luv.luaversion or 0
+ if luvluaversion~=LUAVERSION then
+ return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
+ end
+ else
+ return "invalid status file"
+ end
+ else
+ return "missing status file"
end
- return true
+ end
+ return true
end
@@ -23210,17 +23218,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-zip"] = package.loaded["data-zip"] or true
--- original size: 8700, stripped down to: 6781
+-- original size: 8700, stripped down to: 6313
if not modules then modules={} end modules ['data-zip']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,find,match=string.format,string.find,string.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_zip=logs.reporter("resolvers","zip")
local resolvers=resolvers
zip=zip or {}
@@ -23230,213 +23238,213 @@ zip.archives=archives
local registeredfiles=zip.registeredfiles or {}
zip.registeredfiles=registeredfiles
local function validzip(str)
- if not find(str,"^zip://") then
- return "zip:///"..str
- else
- return str
- end
+ if not find(str,"^zip://") then
+ return "zip:///"..str
+ else
+ return str
+ end
end
function zip.openarchive(name)
- if not name or name=="" then
- return nil
- else
- local arch=archives[name]
- if not arch then
- local full=resolvers.findfile(name) or ""
- arch=full~="" and zip.open(full) or false
- archives[name]=arch
- end
- return arch
+ if not name or name=="" then
+ return nil
+ else
+ local arch=archives[name]
+ if not arch then
+ local full=resolvers.findfile(name) or ""
+ arch=full~="" and zip.open(full) or false
+ archives[name]=arch
end
+ return arch
+ end
end
function zip.closearchive(name)
- if not name or (name=="" and archives[name]) then
- zip.close(archives[name])
- archives[name]=nil
- end
+ if not name or (name=="" and archives[name]) then
+ zip.close(archives[name])
+ archives[name]=nil
+ end
end
function resolvers.locators.zip(specification)
- local archive=specification.filename
- local zipfile=archive and archive~="" and zip.openarchive(archive)
- if trace_locating then
- if zipfile then
- report_zip("locator: archive %a found",archive)
- else
- report_zip("locator: archive %a not found",archive)
- end
+ local archive=specification.filename
+ local zipfile=archive and archive~="" and zip.openarchive(archive)
+ if trace_locating then
+ if zipfile then
+ report_zip("locator: archive %a found",archive)
+ else
+ report_zip("locator: archive %a not found",archive)
end
+ end
end
function resolvers.hashers.zip(specification)
- local archive=specification.filename
- if trace_locating then
- report_zip("loading file %a",archive)
- end
- resolvers.usezipfile(specification.original)
+ local archive=specification.filename
+ if trace_locating then
+ report_zip("loading file %a",archive)
+ end
+ resolvers.usezipfile(specification.original)
end
function resolvers.concatinators.zip(zipfile,path,name)
- if not path or path=="" then
- return format('%s?name=%s',zipfile,name)
- else
- return format('%s?name=%s/%s',zipfile,path,name)
- end
+ if not path or path=="" then
+ return format('%s?name=%s',zipfile,name)
+ else
+ return format('%s?name=%s/%s',zipfile,path,name)
+ end
end
function resolvers.finders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("finder: archive %a found",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- dfile:close()
- if trace_locating then
- report_zip("finder: file %a found",queryname)
- end
- return specification.original
- elseif trace_locating then
- report_zip("finder: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("finder: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("finder: archive %a found",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ dfile:close()
+ if trace_locating then
+ report_zip("finder: file %a found",queryname)
+ end
+ return specification.original
+ elseif trace_locating then
+ report_zip("finder: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("finder: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("finder: %a not found",original)
- end
- return resolvers.finders.notfound()
+ end
+ if trace_locating then
+ report_zip("finder: %a not found",original)
+ end
+ return resolvers.finders.notfound()
end
function resolvers.openers.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("opener; archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- if trace_locating then
- report_zip("opener: file %a found",queryname)
- end
- return resolvers.openers.helpers.textopener('zip',original,dfile)
- elseif trace_locating then
- report_zip("opener: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("opener: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("opener; archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ if trace_locating then
+ report_zip("opener: file %a found",queryname)
+ end
+ return resolvers.openers.helpers.textopener('zip',original,dfile)
+ elseif trace_locating then
+ report_zip("opener: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("opener: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("opener: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("opener: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.loaders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("loader: archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- logs.show_load(original)
- if trace_locating then
- report_zip("loader; file %a loaded",original)
- end
- local s=dfile:read("*all")
- dfile:close()
- return true,s,#s
- elseif trace_locating then
- report_zip("loader: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("loader; unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("loader: archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ logs.show_load(original)
+ if trace_locating then
+ report_zip("loader; file %a loaded",original)
+ end
+ local s=dfile:read("*all")
+ dfile:close()
+ return true,s,#s
+ elseif trace_locating then
+ report_zip("loader: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("loader; unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("loader: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("loader: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.usezipfile(archive)
- local specification=resolvers.splitmethod(archive)
- local archive=specification.filename
- if archive and not registeredfiles[archive] then
- local z=zip.openarchive(archive)
- if z then
- local tree=url.query(specification.query).tree or ""
- if trace_locating then
- report_zip("registering: archive %a",archive)
- end
- resolvers.starttiming()
- resolvers.prependhash('zip',archive)
- resolvers.extendtexmfvariable(archive)
- registeredfiles[archive]=z
- resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
- resolvers.stoptiming()
- elseif trace_locating then
- report_zip("registering: unknown archive %a",archive)
- end
+ local specification=resolvers.splitmethod(archive)
+ local archive=specification.filename
+ if archive and not registeredfiles[archive] then
+ local z=zip.openarchive(archive)
+ if z then
+ local tree=url.query(specification.query).tree or ""
+ if trace_locating then
+ report_zip("registering: archive %a",archive)
+ end
+ resolvers.starttiming()
+ resolvers.prependhash('zip',archive)
+ resolvers.extendtexmfvariable(archive)
+ registeredfiles[archive]=z
+ resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
+ resolvers.stoptiming()
elseif trace_locating then
- report_zip("registering: archive %a not found",archive)
+ report_zip("registering: unknown archive %a",archive)
end
+ elseif trace_locating then
+ report_zip("registering: archive %a not found",archive)
+ end
end
function resolvers.registerzipfile(z,tree)
- local names={}
- local files={}
- local remap={}
- local n=0
- local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
- local register=resolvers.registerfile
- if trace_locating then
- report_zip("registering: using filter %a",filter)
- end
- for i in z:files() do
- local filename=i.filename
- local path,name=match(filename,filter)
- if not path then
- n=n+1
- register(names,filename,"")
- local usedname=lower(filename)
- files[usedname]=""
- if usedname~=filename then
- remap[usedname]=filename
- end
- elseif name and name~="" then
- n=n+1
- register(names,name,path)
- local usedname=lower(name)
- files[usedname]=path
- if usedname~=name then
- remap[usedname]=name
- end
- else
- end
+ local names={}
+ local files={}
+ local remap={}
+ local n=0
+ local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
+ local register=resolvers.registerfile
+ if trace_locating then
+ report_zip("registering: using filter %a",filter)
+ end
+ for i in z:files() do
+ local filename=i.filename
+ local path,name=match(filename,filter)
+ if not path then
+ n=n+1
+ register(names,filename,"")
+ local usedname=lower(filename)
+ files[usedname]=""
+ if usedname~=filename then
+ remap[usedname]=filename
+ end
+ elseif name and name~="" then
+ n=n+1
+ register(names,name,path)
+ local usedname=lower(name)
+ files[usedname]=path
+ if usedname~=name then
+ remap[usedname]=name
+ end
+ else
end
- report_zip("registering: %s files registered",n)
- return {
- files=files,
- remap=remap,
- }
+ end
+ report_zip("registering: %s files registered",n)
+ return {
+ files=files,
+ remap=remap,
+ }
end
@@ -23446,20 +23454,20 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tre"] = package.loaded["data-tre"] or true
--- original size: 8478, stripped down to: 5611
+-- original size: 8478, stripped down to: 5223
if not modules then modules={} end modules ['data-tre']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local find,gsub,lower=string.find,string.gsub,string.lower
-local basename,dirname,joinname=file.basename,file.dirname,file .join
+local basename,dirname,joinname=file.basename,file.dirname,file .join
local globdir,isdir,isfile=dir.glob,lfs.isdir,lfs.isfile
local P,lpegmatch=lpeg.P,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_trees=logs.reporter("resolvers","trees")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -23468,167 +23476,167 @@ local lookup=resolvers.get_from_content
local collectors={}
local found={}
function resolvers.finders.tree(specification)
- local spec=specification.filename
- local okay=found[spec]
- if okay==nil then
- if spec~="" then
- local path=dirname(spec)
- local name=basename(spec)
- if path=="" then
- path="."
- end
- local names=collectors[path]
- if not names then
- local pattern=find(path,"/%*+$") and path or (path.."/*")
- names=globdir(pattern)
- collectors[path]=names
- end
- local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
- for i=1,#names do
- local fullname=names[i]
- if find(fullname,pattern) then
- found[spec]=fullname
- return fullname
- end
- end
- local pattern=lower(pattern)
- for i=1,#names do
- local fullname=lower(names[i])
- if find(fullname,pattern) then
- if isfile(fullname) then
- found[spec]=fullname
- return fullname
- else
- break
- end
- end
- end
+ local spec=specification.filename
+ local okay=found[spec]
+ if okay==nil then
+ if spec~="" then
+ local path=dirname(spec)
+ local name=basename(spec)
+ if path=="" then
+ path="."
+ end
+ local names=collectors[path]
+ if not names then
+ local pattern=find(path,"/%*+$") and path or (path.."/*")
+ names=globdir(pattern)
+ collectors[path]=names
+ end
+ local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
+ for i=1,#names do
+ local fullname=names[i]
+ if find(fullname,pattern) then
+ found[spec]=fullname
+ return fullname
+ end
+ end
+ local pattern=lower(pattern)
+ for i=1,#names do
+ local fullname=lower(names[i])
+ if find(fullname,pattern) then
+ if isfile(fullname) then
+ found[spec]=fullname
+ return fullname
+ else
+ break
+ end
end
- okay=notfound()
- found[spec]=okay
+ end
end
- return okay
+ okay=notfound()
+ found[spec]=okay
+ end
+ return okay
end
function resolvers.locators.tree(specification)
- local name=specification.filename
- local realname=resolveprefix(name)
- if realname and realname~='' and isdir(realname) then
- if trace_locating then
- report_trees("locator %a found",realname)
- end
- resolvers.appendhash('tree',name,false)
- elseif trace_locating then
- report_trees("locator %a not found",name)
+ local name=specification.filename
+ local realname=resolveprefix(name)
+ if realname and realname~='' and isdir(realname) then
+ if trace_locating then
+ report_trees("locator %a found",realname)
end
+ resolvers.appendhash('tree',name,false)
+ elseif trace_locating then
+ report_trees("locator %a not found",name)
+ end
end
function resolvers.hashers.tree(specification)
- local name=specification.filename
- if trace_locating then
- report_trees("analyzing %a",name)
- end
- resolvers.methodhandler("hashers",name)
- resolvers.generators.file(specification)
+ local name=specification.filename
+ if trace_locating then
+ report_trees("analyzing %a",name)
+ end
+ resolvers.methodhandler("hashers",name)
+ resolvers.generators.file(specification)
end
local collectors={}
local splitter=lpeg.splitat("/**/")
local stripper=lpeg.replacer { [P("/")*P("*")^1*P(-1)]="" }
table.setmetatableindex(collectors,function(t,k)
- local rootname=lpegmatch(stripper,k)
- local dataname=joinname(rootname,"dirlist")
- local content=caches.loadcontent(dataname,"files",dataname)
- if not content then
- content=resolvers.scanfiles(rootname,nil,nil,false,true)
- caches.savecontent(dataname,"files",content,dataname)
- end
- t[k]=content
- return content
+ local rootname=lpegmatch(stripper,k)
+ local dataname=joinname(rootname,"dirlist")
+ local content=caches.loadcontent(dataname,"files",dataname)
+ if not content then
+ content=resolvers.scanfiles(rootname,nil,nil,false,true)
+ caches.savecontent(dataname,"files",content,dataname)
+ end
+ t[k]=content
+ return content
end)
local function checked(root,p,n)
- if p then
- if type(p)=="table" then
- for i=1,#p do
- local fullname=joinname(root,p[i],n)
- if isfile(fullname) then
- return fullname
- end
- end
- else
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
+ if p then
+ if type(p)=="table" then
+ for i=1,#p do
+ local fullname=joinname(root,p[i],n)
+ if isfile(fullname) then
+ return fullname
end
+ end
+ else
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- return notfound()
+ end
+ return notfound()
end
local function resolve(specification)
- local filename=specification.filename
- if filename~="" then
- local root,rest=lpegmatch(splitter,filename)
- if root and rest then
- local path,name=dirname(rest),basename(rest)
- if name~=rest then
- local content=collectors[root]
- local p,n=lookup(content,name)
- if not p then
- return notfound()
- end
- local pattern=".*/"..path.."$"
- local istable=type(p)=="table"
- if istable then
- for i=1,#p do
- local pi=p[i]
- if pi==path or find(pi,pattern) then
- local fullname=joinname(root,pi,n)
- if isfile(fullname) then
- return fullname
- end
- end
- end
- elseif p==path or find(p,pattern) then
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
- end
- local queries=specification.queries
- if queries and queries.option=="fileonly" then
- return checked(root,p,n)
- else
- return notfound()
- end
+ local filename=specification.filename
+ if filename~="" then
+ local root,rest=lpegmatch(splitter,filename)
+ if root and rest then
+ local path,name=dirname(rest),basename(rest)
+ if name~=rest then
+ local content=collectors[root]
+ local p,n=lookup(content,name)
+ if not p then
+ return notfound()
+ end
+ local pattern=".*/"..path.."$"
+ local istable=type(p)=="table"
+ if istable then
+ for i=1,#p do
+ local pi=p[i]
+ if pi==path or find(pi,pattern) then
+ local fullname=joinname(root,pi,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
+ end
+ elseif p==path or find(p,pattern) then
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- local path,name=dirname(filename),basename(filename)
- local root=lpegmatch(stripper,path)
- local content=collectors[path]
- local p,n=lookup(content,name)
- if p then
- return checked(root,p,n)
+ local queries=specification.queries
+ if queries and queries.option=="fileonly" then
+ return checked(root,p,n)
+ else
+ return notfound()
end
+ end
+ end
+ local path,name=dirname(filename),basename(filename)
+ local root=lpegmatch(stripper,path)
+ local content=collectors[path]
+ local p,n=lookup(content,name)
+ if p then
+ return checked(root,p,n)
end
- return notfound()
+ end
+ return notfound()
end
-resolvers.finders .dirlist=resolve
-resolvers.locators .dirlist=resolvers.locators .tree
-resolvers.hashers .dirlist=resolvers.hashers .tree
+resolvers.finders .dirlist=resolve
+resolvers.locators .dirlist=resolvers.locators .tree
+resolvers.hashers .dirlist=resolvers.hashers .tree
resolvers.generators.dirlist=resolvers.generators.file
-resolvers.openers .dirlist=resolvers.openers .file
-resolvers.loaders .dirlist=resolvers.loaders .file
+resolvers.openers .dirlist=resolvers.openers .file
+resolvers.loaders .dirlist=resolvers.loaders .file
function resolvers.finders.dirfile(specification)
- local queries=specification.queries
- if queries then
- queries.option="fileonly"
- else
- specification.queries={ option="fileonly" }
- end
- return resolve(specification)
-end
-resolvers.locators .dirfile=resolvers.locators .dirlist
-resolvers.hashers .dirfile=resolvers.hashers .dirlist
+ local queries=specification.queries
+ if queries then
+ queries.option="fileonly"
+ else
+ specification.queries={ option="fileonly" }
+ end
+ return resolve(specification)
+end
+resolvers.locators .dirfile=resolvers.locators .dirlist
+resolvers.hashers .dirfile=resolvers.hashers .dirlist
resolvers.generators.dirfile=resolvers.generators.dirlist
-resolvers.openers .dirfile=resolvers.openers .dirlist
-resolvers.loaders .dirfile=resolvers.loaders .dirlist
+resolvers.openers .dirfile=resolvers.openers .dirlist
+resolvers.loaders .dirfile=resolvers.loaders .dirlist
end -- of closure
@@ -23637,19 +23645,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-sch"] = package.loaded["data-sch"] or true
--- original size: 6753, stripped down to: 5511
+-- original size: 6753, stripped down to: 5268
if not modules then modules={} end modules ['data-sch']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local load,tonumber=load,tonumber
local gsub,concat,format=string.gsub,table.concat,string.format
local finders,openers,loaders=resolvers.finders,resolvers.openers,resolvers.loaders
-local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
+local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
local report_schemes=logs.reporter("resolvers","schemes")
local http=require("socket.http")
local ltn12=require("ltn12")
@@ -23662,27 +23670,27 @@ schemes.cleaners=cleaners
local threshold=24*60*60
directives.register("schemes.threshold",function(v) threshold=tonumber(v) or threshold end)
function cleaners.none(specification)
- return specification.original
+ return specification.original
end
function cleaners.strip(specification)
- local path,name=file.splitbase(specification.original)
- if path=="" then
- return (gsub(name,"[^%a%d%.]+","-"))
- else
- return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
- end
+ local path,name=file.splitbase(specification.original)
+ if path=="" then
+ return (gsub(name,"[^%a%d%.]+","-"))
+ else
+ return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
+ end
end
function cleaners.md5(specification)
- return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
+ return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
end
local cleaner=cleaners.strip
directives.register("schemes.cleanmethod",function(v) cleaner=cleaners[v] or cleaners.strip end)
function resolvers.schemes.cleanname(specification)
- local hash=cleaner(specification)
- if trace_schemes then
- report_schemes("hashing %a to %a",specification.original,hash)
- end
- return hash
+ local hash=cleaner(specification)
+ if trace_schemes then
+ report_schemes("hashing %a to %a",specification.original,hash)
+ end
+ return hash
end
local cached={}
local loaded={}
@@ -23690,139 +23698,139 @@ local reused={}
local thresholds={}
local handlers={}
local runner=sandbox.registerrunner {
- name="curl resolver",
- method="execute",
- program="curl",
- template="--silent --insecure --create-dirs --output %cachename% %original%",
- checkers={
- cachename="cache",
- original="url",
- }
+ name="curl resolver",
+ method="execute",
+ program="curl",
+ template="--silent --insecure --create-dirs --output %cachename% %original%",
+ checkers={
+ cachename="cache",
+ original="url",
+ }
}
local function fetch(specification)
- local original=specification.original
- local scheme=specification.scheme
- local cleanname=schemes.cleanname(specification)
- local cachename=caches.setfirstwritablefile(cleanname,"schemes")
- if not cached[original] then
- statistics.starttiming(schemes)
- if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
- cached[original]=cachename
- local handler=handlers[scheme]
- if handler then
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
- end
- logs.flush()
- handler(specification,cachename)
- else
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
- end
- logs.flush()
- runner {
- original=original,
- cachename=cachename,
- }
- end
- end
- if io.exists(cachename) then
- cached[original]=cachename
- if trace_schemes then
- report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
- end
- else
- cached[original]=""
- if trace_schemes then
- report_schemes("using missing %a, protocol %a",original,scheme)
- end
+ local original=specification.original
+ local scheme=specification.scheme
+ local cleanname=schemes.cleanname(specification)
+ local cachename=caches.setfirstwritablefile(cleanname,"schemes")
+ if not cached[original] then
+ statistics.starttiming(schemes)
+ if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
+ cached[original]=cachename
+ local handler=handlers[scheme]
+ if handler then
+ if trace_schemes then
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
end
- loaded[scheme]=loaded[scheme]+1
- statistics.stoptiming(schemes)
- else
+ logs.flush()
+ handler(specification,cachename)
+ else
if trace_schemes then
- report_schemes("reusing %a, protocol %a",original,scheme)
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
end
- reused[scheme]=reused[scheme]+1
+ logs.flush()
+ runner {
+ original=original,
+ cachename=cachename,
+ }
+ end
end
- return cached[original]
+ if io.exists(cachename) then
+ cached[original]=cachename
+ if trace_schemes then
+ report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
+ end
+ else
+ cached[original]=""
+ if trace_schemes then
+ report_schemes("using missing %a, protocol %a",original,scheme)
+ end
+ end
+ loaded[scheme]=loaded[scheme]+1
+ statistics.stoptiming(schemes)
+ else
+ if trace_schemes then
+ report_schemes("reusing %a, protocol %a",original,scheme)
+ end
+ reused[scheme]=reused[scheme]+1
+ end
+ return cached[original]
end
local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
+ return resolvers.methodhandler("finders",fetch(specification),filetype)
end
local opener=openers.file
local loader=loaders.file
local function install(scheme,handler,newthreshold)
- handlers [scheme]=handler
- loaded [scheme]=0
- reused [scheme]=0
- finders [scheme]=finder
- openers [scheme]=opener
- loaders [scheme]=loader
- thresholds[scheme]=newthreshold or threshold
+ handlers [scheme]=handler
+ loaded [scheme]=0
+ reused [scheme]=0
+ finders [scheme]=finder
+ openers [scheme]=opener
+ loaders [scheme]=loader
+ thresholds[scheme]=newthreshold or threshold
end
schemes.install=install
local function http_handler(specification,cachename)
- local tempname=cachename..".tmp"
- local f=io.open(tempname,"wb")
- local status,message=http.request {
- url=specification.original,
- sink=ltn12.sink.file(f)
- }
- if not status then
- os.remove(tempname)
- else
- os.remove(cachename)
- os.rename(tempname,cachename)
- end
- return cachename
+ local tempname=cachename..".tmp"
+ local f=io.open(tempname,"wb")
+ local status,message=http.request {
+ url=specification.original,
+ sink=ltn12.sink.file(f)
+ }
+ if not status then
+ os.remove(tempname)
+ else
+ os.remove(cachename)
+ os.rename(tempname,cachename)
+ end
+ return cachename
end
install('http',http_handler)
install('https')
install('ftp')
statistics.register("scheme handling time",function()
- local l,r,nl,nr={},{},0,0
- for k,v in table.sortedhash(loaded) do
- if v>0 then
- nl=nl+1
- l[nl]=k..":"..v
- end
- end
- for k,v in table.sortedhash(reused) do
- if v>0 then
- nr=nr+1
- r[nr]=k..":"..v
- end
- end
- local n=nl+nr
- if n>0 then
- l=nl>0 and concat(l) or "none"
- r=nr>0 and concat(r) or "none"
- return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
- statistics.elapsedtime(schemes),n,threshold,l,r)
- else
- return nil
- end
+ local l,r,nl,nr={},{},0,0
+ for k,v in table.sortedhash(loaded) do
+ if v>0 then
+ nl=nl+1
+ l[nl]=k..":"..v
+ end
+ end
+ for k,v in table.sortedhash(reused) do
+ if v>0 then
+ nr=nr+1
+ r[nr]=k..":"..v
+ end
+ end
+ local n=nl+nr
+ if n>0 then
+ l=nl>0 and concat(l) or "none"
+ r=nr>0 and concat(r) or "none"
+ return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
+ statistics.elapsedtime(schemes),n,threshold,l,r)
+ else
+ return nil
+ end
end)
local httprequest=http.request
local toquery=url.toquery
local function fetchstring(url,data)
- local q=data and toquery(data)
- if q then
- url=url.."?"..q
- end
- local reply=httprequest(url)
- return reply
+ local q=data and toquery(data)
+ if q then
+ url=url.."?"..q
+ end
+ local reply=httprequest(url)
+ return reply
end
schemes.fetchstring=fetchstring
function schemes.fetchtable(url,data)
- local reply=fetchstring(url,data)
- if reply then
- local s=load("return "..reply)
- if s then
- return s()
- end
+ local reply=fetchstring(url,data)
+ if reply then
+ local s=load("return "..reply)
+ if s then
+ return s()
end
+ end
end
@@ -23832,14 +23840,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lua"] = package.loaded["data-lua"] or true
--- original size: 4207, stripped down to: 3137
+-- original size: 4207, stripped down to: 3041
if not modules then modules={} end modules ['data-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local package,lpeg=package,lpeg
local gsub=string.gsub
@@ -23858,20 +23866,20 @@ helpers.report=logs.reporter("resolvers","libraries")
trackers.register("resolvers.libraries",function(v) helpers.trace=v end)
trackers.register("resolvers.locating",function(v) helpers.trace=v end)
helpers.sequence={
- "already loaded",
- "preload table",
- "lua variable format",
- "lib variable format",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
+ "already loaded",
+ "preload table",
+ "lua variable format",
+ "lib variable format",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
}
local pattern=Cs(P("!")^0/""*(P("/")*P(-1)/"/"+P("/")^1/"/"+1)^0)
function helpers.cleanpath(path)
- return resolveprefix(lpegmatch(pattern,path))
+ return resolveprefix(lpegmatch(pattern,path))
end
local loadedaslib=helpers.loadedaslib
local registerpath=helpers.registerpath
@@ -23879,56 +23887,56 @@ local lualibfile=helpers.lualibfile
local luaformatpaths
local libformatpaths
local function getluaformatpaths()
- if not luaformatpaths then
- luaformatpaths={}
- for i=1,#luaformats do
- registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
- end
+ if not luaformatpaths then
+ luaformatpaths={}
+ for i=1,#luaformats do
+ registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
end
- return luaformatpaths
+ end
+ return luaformatpaths
end
local function getlibformatpaths()
- if not libformatpaths then
- libformatpaths={}
- for i=1,#libformats do
- registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
- end
+ if not libformatpaths then
+ libformatpaths={}
+ for i=1,#libformats do
+ registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
end
- return libformatpaths
+ end
+ return libformatpaths
end
local function loadedbyformat(name,rawname,suffixes,islib,what)
- local trace=helpers.trace
- local report=helpers.report
- for i=1,#suffixes do
- local format=suffixes[i]
- local resolved=resolvers.findfile(name,format) or ""
- if trace then
- report("%s format, identifying %a using format %a",what,name,format)
- end
- if resolved~="" then
- if trace then
- report("%s format, %a found on %a",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ local report=helpers.report
+ for i=1,#suffixes do
+ local format=suffixes[i]
+ local resolved=resolvers.findfile(name,format) or ""
+ if trace then
+ report("%s format, identifying %a using format %a",what,name,format)
end
+ if resolved~="" then
+ if trace then
+ report("%s format, %a found on %a",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
+ end
+ end
end
helpers.loadedbyformat=loadedbyformat
methods["lua variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
end
methods["lib variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
end
resolvers.loadlualib=require
@@ -23939,64 +23947,64 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-aux"] = package.loaded["data-aux"] or true
--- original size: 2438, stripped down to: 2003
+-- original size: 2438, stripped down to: 1863
if not modules then modules={} end modules ['data-aux']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local find=string.find
local type,next=type,next
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local resolvers=resolvers
local report_scripts=logs.reporter("resolvers","scripts")
function resolvers.updatescript(oldname,newname)
- local scriptpath="context/lua"
- newname=file.addsuffix(newname,"lua")
- local oldscript=resolvers.cleanpath(oldname)
+ local scriptpath="context/lua"
+ newname=file.addsuffix(newname,"lua")
+ local oldscript=resolvers.cleanpath(oldname)
+ if trace_locating then
+ report_scripts("to be replaced old script %a",oldscript)
+ end
+ local newscripts=resolvers.findfiles(newname) or {}
+ if #newscripts==0 then
if trace_locating then
- report_scripts("to be replaced old script %a",oldscript)
+ report_scripts("unable to locate new script")
end
- local newscripts=resolvers.findfiles(newname) or {}
- if #newscripts==0 then
+ else
+ for i=1,#newscripts do
+ local newscript=resolvers.cleanpath(newscripts[i])
+ if trace_locating then
+ report_scripts("checking new script %a",newscript)
+ end
+ if oldscript==newscript then
if trace_locating then
- report_scripts("unable to locate new script")
+ report_scripts("old and new script are the same")
end
- else
- for i=1,#newscripts do
- local newscript=resolvers.cleanpath(newscripts[i])
- if trace_locating then
- report_scripts("checking new script %a",newscript)
- end
- if oldscript==newscript then
- if trace_locating then
- report_scripts("old and new script are the same")
- end
- elseif not find(newscript,scriptpath,1,true) then
- if trace_locating then
- report_scripts("new script should come from %a",scriptpath)
- end
- elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
- if trace_locating then
- report_scripts("invalid new script name")
- end
- else
- local newdata=io.loaddata(newscript)
- if newdata then
- if trace_locating then
- report_scripts("old script content replaced by new content")
- end
- io.savedata(oldscript,newdata)
- break
- elseif trace_locating then
- report_scripts("unable to load new script")
- end
- end
+ elseif not find(newscript,scriptpath,1,true) then
+ if trace_locating then
+ report_scripts("new script should come from %a",scriptpath)
+ end
+ elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
+ if trace_locating then
+ report_scripts("invalid new script name")
end
+ else
+ local newdata=io.loaddata(newscript)
+ if newdata then
+ if trace_locating then
+ report_scripts("old script content replaced by new content")
+ end
+ io.savedata(oldscript,newdata)
+ break
+ elseif trace_locating then
+ report_scripts("unable to load new script")
+ end
+ end
end
+ end
end
@@ -24006,53 +24014,53 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmf"] = package.loaded["data-tmf"] or true
--- original size: 2601, stripped down to: 1627
+-- original size: 2601, stripped down to: 1549
if not modules then modules={} end modules ['data-tmf']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local resolvers=resolvers
local report_tds=logs.reporter("resolvers","tds")
function resolvers.load_tree(tree,resolve)
- if type(tree)=="string" and tree~="" then
- local getenv,setenv=resolvers.getenv,resolvers.setenv
- local texos="texmf-"..os.platform
- local oldroot=environment.texroot
- local newroot=file.collapsepath(tree)
- local newtree=file.join(newroot,texos)
- local newpath=file.join(newtree,"bin")
- if not lfs.isdir(newtree) then
- report_tds("no %a under tree %a",texos,tree)
- os.exit()
- end
- if not lfs.isdir(newpath) then
- report_tds("no '%s/bin' under tree %a",texos,tree)
- os.exit()
- end
- local texmfos=newtree
- environment.texroot=newroot
- environment.texos=texos
- environment.texmfos=texmfos
- if resolve then
- resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
- end
- setenv('SELFAUTOPARENT',newroot)
- setenv('SELFAUTODIR',newtree)
- setenv('SELFAUTOLOC',newpath)
- setenv('TEXROOT',newroot)
- setenv('TEXOS',texos)
- setenv('TEXMFOS',texmfos)
- setenv('TEXMFCNF',resolvers.luacnfspec,true)
- setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
- report_tds("changing from root %a to %a",oldroot,newroot)
- report_tds("prepending %a to PATH",newpath)
- report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
- report_tds()
- end
+ if type(tree)=="string" and tree~="" then
+ local getenv,setenv=resolvers.getenv,resolvers.setenv
+ local texos="texmf-"..os.platform
+ local oldroot=environment.texroot
+ local newroot=file.collapsepath(tree)
+ local newtree=file.join(newroot,texos)
+ local newpath=file.join(newtree,"bin")
+ if not lfs.isdir(newtree) then
+ report_tds("no %a under tree %a",texos,tree)
+ os.exit()
+ end
+ if not lfs.isdir(newpath) then
+ report_tds("no '%s/bin' under tree %a",texos,tree)
+ os.exit()
+ end
+ local texmfos=newtree
+ environment.texroot=newroot
+ environment.texos=texos
+ environment.texmfos=texmfos
+ if resolve then
+ resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
+ end
+ setenv('SELFAUTOPARENT',newroot)
+ setenv('SELFAUTODIR',newtree)
+ setenv('SELFAUTOLOC',newpath)
+ setenv('TEXROOT',newroot)
+ setenv('TEXOS',texos)
+ setenv('TEXMFOS',texmfos)
+ setenv('TEXMFCNF',resolvers.luacnfspec,true)
+ setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
+ report_tds("changing from root %a to %a",oldroot,newroot)
+ report_tds("prepending %a to PATH",newpath)
+ report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
+ report_tds()
+ end
end
@@ -24062,14 +24070,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lst"] = package.loaded["data-lst"] or true
--- original size: 1823, stripped down to: 1591
+-- original size: 1823, stripped down to: 1542
if not modules then modules={} end modules ['data-lst']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type=type
local concat,sortedhash=table.concat,table.sortedhash
@@ -24080,37 +24088,37 @@ local resolveprefix=resolvers.resolve
local report_lists=logs.reporter("resolvers","lists")
local report_resolved=logs.reporter("system","resolved")
local function tabstr(str)
- if type(str)=='table' then
- return concat(str," | ")
- else
- return str
- end
+ if type(str)=='table' then
+ return concat(str," | ")
+ else
+ return str
+ end
end
function listers.variables(pattern)
- local result=resolvers.knownvariables(pattern)
- for key,value in sortedhash(result) do
- report_lists(key)
- report_lists(" env: %s",tabstr(value.environment or "unset"))
- report_lists(" var: %s",tabstr(value.variable or "unset"))
- report_lists(" exp: %s",tabstr(value.expansion or "unset"))
- report_lists(" res: %s",tabstr(value.resolved or "unset"))
- end
+ local result=resolvers.knownvariables(pattern)
+ for key,value in sortedhash(result) do
+ report_lists(key)
+ report_lists(" env: %s",tabstr(value.environment or "unset"))
+ report_lists(" var: %s",tabstr(value.variable or "unset"))
+ report_lists(" exp: %s",tabstr(value.expansion or "unset"))
+ report_lists(" res: %s",tabstr(value.resolved or "unset"))
+ end
end
function listers.configurations()
- local configurations=resolvers.configurationfiles()
- for i=1,#configurations do
- report_resolved("file : %s",resolveprefix(configurations[i]))
- end
- report_resolved("")
- local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
- for i=1,#list do
- local li=resolveprefix(list[i])
- if lfs.isdir(li) then
- report_resolved("path - %s",li)
- else
- report_resolved("path + %s",li)
- end
+ local configurations=resolvers.configurationfiles()
+ for i=1,#configurations do
+ report_resolved("file : %s",resolveprefix(configurations[i]))
+ end
+ report_resolved("")
+ local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
+ for i=1,#list do
+ local li=resolveprefix(list[i])
+ if lfs.isdir(li) then
+ report_resolved("path - %s",li)
+ else
+ report_resolved("path + %s",li)
end
+ end
end
@@ -24120,14 +24128,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lib"] = package.loaded["util-lib"] or true
--- original size: 16094, stripped down to: 9206
+-- original size: 16094, stripped down to: 8443
if not modules then modules={} end modules ['util-lib']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local type=type
local next=next
@@ -24147,291 +24155,291 @@ local qualifiedpath=file.is_qualified_path
local isfile=lfs.isfile
local done=false
local function locate(required,version,trace,report,action)
- if type(required)~="string" then
- report("provide a proper library name")
- return
- end
- if trace then
- report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/")
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
- if isfile(addsuffix(required,os.libsuffix)) then
- if trace then
- report("qualified name %a found",required)
- end
- found_library=required
- else
- if trace then
- report("qualified name %a not found",required)
- end
- end
+ if type(required)~="string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library=nil
+ local required_full=gsub(required,"%.","/")
+ local required_path=pathpart(required_full)
+ local required_base=nameonly(required_full)
+ if qualifiedpath(required) then
+ if isfile(addsuffix(required,os.libsuffix)) then
+ if trace then
+ report("qualified name %a found",required)
+ end
+ found_library=required
else
- local required_name=required_base.."."..os.libsuffix
- local version=type(version)=="string" and version~="" and version or false
- local engine="luatex"
- if trace and not done then
- local list=expandpaths("lib")
- for i=1,#list do
- report("tds path %i: %s",i,list[i])
- end
+ if trace then
+ report("qualified name %a not found",required)
+ end
+ end
+ else
+ local required_name=required_base.."."..os.libsuffix
+ local version=type(version)=="string" and version~="" and version or false
+ local engine="luatex"
+ if trace and not done then
+ local list=expandpaths("lib")
+ for i=1,#list do
+ report("tds path %i: %s",i,list[i])
+ end
+ end
+ local function found(locate,asked_library,how,...)
+ if trace then
+ report("checking %s: %a",how,asked_library)
+ end
+ return locate(asked_library,...)
+ end
+ local function check(locate,...)
+ local found=nil
+ if version then
+ local asked_library=joinfile(required_path,version,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function found(locate,asked_library,how,...)
- if trace then
- report("checking %s: %a",how,asked_library)
- end
- return locate(asked_library,...)
- end
- local function check(locate,...)
- local found=nil
- if version then
- local asked_library=joinfile(required_path,version,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- if not found or found=="" then
- local asked_library=joinfile(required_path,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- return found and found~="" and found or false
+ found=locate(asked_library,...)
+ end
+ if not found or found=="" then
+ local asked_library=joinfile(required_path,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function attempt(checkpattern)
- if trace then
- report("checking tds lib paths strictly")
- end
- local found=findfile and check(findfile,"lib")
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- if trace then
- report("checking tds lib paths with wildcard")
- end
- local asked_library=joinfile(required_path,".*",required_name)
- if trace then
- report("checking %s: %a","latest version",asked_library)
- end
- local list=findfiles(asked_library,"lib",true)
- if list and #list>0 then
- sort(list)
- local found=list[#list]
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- if trace then
- report("checking lib paths")
- end
- package.extralibpath(environment.ownpath)
- local paths=package.libpaths()
- local pattern="/[^/]+%."..os.libsuffix.."$"
- for i=1,#paths do
- required_path=gsub(paths[i],pattern,"")
- local found=check(lfs.isfound)
- if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- return false
+ found=locate(asked_library,...)
+ end
+ return found and found~="" and found or false
+ end
+ local function attempt(checkpattern)
+ if trace then
+ report("checking tds lib paths strictly")
+ end
+ local found=findfile and check(findfile,"lib")
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
+ end
+ if trace then
+ report("checking tds lib paths with wildcard")
+ end
+ local asked_library=joinfile(required_path,".*",required_name)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
+ end
+ local list=findfiles(asked_library,"lib",true)
+ if list and #list>0 then
+ sort(list)
+ local found=list[#list]
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
end
- if engine then
- if trace then
- report("attemp 1, engine %a",engine)
- end
- found_library=attempt("/"..engine.."/")
- if not found_library then
- if trace then
- report("attemp 2, no engine",asked_library)
- end
- found_library=attempt()
- end
- else
- found_library=attempt()
+ end
+ if trace then
+ report("checking lib paths")
+ end
+ package.extralibpath(environment.ownpath)
+ local paths=package.libpaths()
+ local pattern="/[^/]+%."..os.libsuffix.."$"
+ for i=1,#paths do
+ required_path=gsub(paths[i],pattern,"")
+ local found=check(lfs.isfound)
+ if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
+ return found
end
+ end
+ return false
end
- if not found_library then
+ if engine then
+ if trace then
+ report("attemp 1, engine %a",engine)
+ end
+ found_library=attempt("/"..engine.."/")
+ if not found_library then
if trace then
- report("not found: %a",required)
+ report("attemp 2, no engine",asked_library)
end
- library=false
+ found_library=attempt()
+ end
else
- if trace then
- report("found: %a",found_library)
- end
- local result,message=action(found_library,required_base)
- if result then
- library=result
- else
- library=false
- report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
- end
+ found_library=attempt()
end
+ end
+ if not found_library then
if trace then
- if not library then
- report("unknown library: %a",required)
- else
- report("stored library: %a",required)
- end
+ report("not found: %a",required)
+ end
+ library=false
+ else
+ if trace then
+ report("found: %a",found_library)
+ end
+ local result,message=action(found_library,required_base)
+ if result then
+ library=result
+ else
+ library=false
+ report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
end
- return library or nil
+ end
+ if trace then
+ if not library then
+ report("unknown library: %a",required)
+ else
+ report("stored library: %a",required)
+ end
+ end
+ return library or nil
end
do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
- local library=loadedlibs[library]
- if library==nil then
- local trace_swiglib=trace_swiglib or package.helpers.trace
- library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
- pushdir(pathpart(name))
- local opener="luaopen_"..base
- if trace_swiglib then
- report_swiglib("opening: %a with %a",name,opener)
- end
- local library,message=loadlib(name,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
- else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
- end
- popdir()
- return library
- end)
- loadedlibs[required]=library or false
- end
- return library
- end
- function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
+ local report_swiglib=logs.reporter("swiglib")
+ local trace_swiglib=false
+ local savedrequire=require
+ local loadedlibs={}
+ local loadlib=package.loadlib
+ local pushdir=dir.push
+ local popdir=dir.pop
+ trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+ function requireswiglib(required,version)
+ local library=loadedlibs[library]
+ if library==nil then
+ local trace_swiglib=trace_swiglib or package.helpers.trace
+ library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ pushdir(pathpart(name))
+ local opener="luaopen_"..base
+ if trace_swiglib then
+ report_swiglib("opening: %a with %a",name,opener)
+ end
+ local library,message=loadlib(name,opener)
+ local libtype=type(library)
+ if libtype=="function" then
+ library=library()
else
- return savedrequire(name)
- end
- end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
- else
- fullname="swiglib."..name
- end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library=false
end
+ popdir()
return library
+ end)
+ loadedlibs[required]=library or false
+ end
+ return library
+ end
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
+ else
+ return savedrequire(name)
+ end
+ end
+ local swiglibs={}
+ local initializer="core"
+ function swiglib(name,version)
+ local library=swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
+ if trace_swiglib then
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%."..initializer.."$") then
+ fullname="swiglib."..name.."."..initializer
+ else
+ fullname="swiglib."..name
+ end
+ library=requireswiglib(fullname,version)
+ swiglibs[name]=library
+ statistics.stoptiming(swiglibs)
end
- statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
- end)
+ return library
+ end
+ statistics.register("used swiglibs",function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
+ end
+ end)
end
if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
- name=removesuffix(name)
- local l=loaded[name]
- if l==nil then
- local state,library=pcall(savedffiload,name)
- if type(library)=="userdata" then
- l=library
- elseif type(state)=="userdata" then
- l=state
- else
- l=false
- end
- loaded[name]=l
- elseif trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
+ local report_ffilib=logs.reporter("ffilib")
+ local trace_ffilib=false
+ local savedffiload=ffi.load
+ trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+ local loaded={}
+ local function locateindeed(name)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l==nil then
+ local state,library=pcall(savedffiload,name)
+ if type(library)=="userdata" then
+ l=library
+ elseif type(state)=="userdata" then
+ l=state
+ else
+ l=false
+ end
+ loaded[name]=l
+ elseif trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
end
- local function getlist(required)
- local list=directives.value("system.librarynames" )
- if type(list)=="table" then
- list=list[required]
- if type(list)=="table" then
- if trace then
- report("using lookup list for library %a: % | t",required,list)
- end
- return list
- end
+ return l
+ end
+ local function getlist(required)
+ local list=directives.value("system.librarynames" )
+ if type(list)=="table" then
+ list=list[required]
+ if type(list)=="table" then
+ if trace then
+ report("using lookup list for library %a: % | t",required,list)
end
- return { required }
+ return list
+ end
end
- function ffilib(name,version)
- name=removesuffix(name)
- local l=loaded[name]
- if l~=nil then
- if trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- end
- local list=getlist(name)
- if version=="system" then
- for i=1,#list do
- local library=locateindeed(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- else
- for i=1,#list do
- local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
- if type(library)=="userdata" then
- return library
- end
- end
- end
+ return { required }
+ end
+ function ffilib(name,version)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l~=nil then
+ if trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
+ end
+ return l
end
- function ffi.load(name)
- local list=getlist(name)
- for i=1,#list do
- local library=ffilib(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- if trace_ffilib then
- report_ffilib("trying to load %a using normal loader",name)
+ local list=getlist(name)
+ if version=="system" then
+ for i=1,#list do
+ local library=locateindeed(list[i])
+ if type(library)=="userdata" then
+ return library
end
- for i=1,#list do
- local state,library=pcall(savedffiload,list[i])
- if type(library)=="userdata" then
- return library
- elseif type(state)=="userdata" then
- return library
- end
+ end
+ else
+ for i=1,#list do
+ local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
+ if type(library)=="userdata" then
+ return library
end
+ end
+ end
+ end
+ function ffi.load(name)
+ local list=getlist(name)
+ for i=1,#list do
+ local library=ffilib(list[i])
+ if type(library)=="userdata" then
+ return library
+ end
+ end
+ if trace_ffilib then
+ report_ffilib("trying to load %a using normal loader",name)
+ end
+ for i=1,#list do
+ local state,library=pcall(savedffiload,list[i])
+ if type(library)=="userdata" then
+ return library
+ elseif type(state)=="userdata" then
+ return library
+ end
end
+ end
end
@@ -24441,13 +24449,13 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-sta"] = package.loaded["luat-sta"] or true
--- original size: 5703, stripped down to: 2507
+-- original size: 5703, stripped down to: 2321
if not modules then modules={} end modules ['luat-sta']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local gmatch,match=string.gmatch,string.match
local type=type
@@ -24460,81 +24468,81 @@ local hash=states.hash
states.tag=states.tag or ""
states.filename=states.filename or ""
function states.save(filename,tag)
- tag=tag or states.tag
- filename=file.addsuffix(filename or states.filename,'lus')
- io.savedata(filename,
- "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
- )
+ tag=tag or states.tag
+ filename=file.addsuffix(filename or states.filename,'lus')
+ io.savedata(filename,
+ "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
+ )
end
function states.load(filename,tag)
- states.filename=filename
- states.tag=tag or "whatever"
- states.filename=file.addsuffix(states.filename,'lus')
- data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
+ states.filename=filename
+ states.tag=tag or "whatever"
+ states.filename=file.addsuffix(states.filename,'lus')
+ data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
end
local function set_by_tag(tag,key,value,default,persistent)
- local d,h=data[tag],hash[tag]
- if d then
- if type(d)=="table" then
- local dkey,hkey=key,key
- local pre,post=match(key,"(.+)%.([^%.]+)$")
- if pre and post then
- for k in gmatch(pre,"[^%.]+") do
- local dk=d[k]
- if not dk then
- dk={}
- d[k]=dk
- elseif type(dk)=="string" then
- break
- end
- d=dk
- end
- dkey,hkey=post,key
- end
- if value==nil then
- value=default
- elseif value==false then
- elseif persistent then
- value=value or d[dkey] or default
- else
- value=value or default
- end
- d[dkey],h[hkey]=value,value
- elseif type(d)=="string" then
- data[tag],hash[tag]=value,value
+ local d,h=data[tag],hash[tag]
+ if d then
+ if type(d)=="table" then
+ local dkey,hkey=key,key
+ local pre,post=match(key,"(.+)%.([^%.]+)$")
+ if pre and post then
+ for k in gmatch(pre,"[^%.]+") do
+ local dk=d[k]
+ if not dk then
+ dk={}
+ d[k]=dk
+ elseif type(dk)=="string" then
+ break
+ end
+ d=dk
end
+ dkey,hkey=post,key
+ end
+ if value==nil then
+ value=default
+ elseif value==false then
+ elseif persistent then
+ value=value or d[dkey] or default
+ else
+ value=value or default
+ end
+ d[dkey],h[hkey]=value,value
+ elseif type(d)=="string" then
+ data[tag],hash[tag]=value,value
end
+ end
end
local function get_by_tag(tag,key,default)
- local h=hash[tag]
- if h and h[key] then
- return h[key]
- else
- local d=data[tag]
- if d then
- for k in gmatch(key,"[^%.]+") do
- local dk=d[k]
- if dk~=nil then
- d=dk
- else
- return default
- end
- end
- if d==false then
- return false
- else
- return d or default
- end
+ local h=hash[tag]
+ if h and h[key] then
+ return h[key]
+ else
+ local d=data[tag]
+ if d then
+ for k in gmatch(key,"[^%.]+") do
+ local dk=d[k]
+ if dk~=nil then
+ d=dk
+ else
+ return default
end
+ end
+ if d==false then
+ return false
+ else
+ return d or default
+ end
end
+ end
end
states.set_by_tag=set_by_tag
states.get_by_tag=get_by_tag
function states.set(key,value,default,persistent)
- set_by_tag(states.tag,key,value,default,persistent)
+ set_by_tag(states.tag,key,value,default,persistent)
end
function states.get(key,default)
- return get_by_tag(states.tag,key,default)
+ return get_by_tag(states.tag,key,default)
end
@@ -24544,14 +24552,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
--- original size: 9346, stripped down to: 7465
+-- original size: 9346, stripped down to: 7085
if not modules then modules={} end modules ['luat-fmt']={
- version=1.001,
- comment="companion to mtxrun",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to mtxrun",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format=string.format
local concat=table.concat
@@ -24559,223 +24567,223 @@ local quoted=string.quoted
local luasuffixes=utilities.lua.suffixes
local report_format=logs.reporter("resolvers","formats")
local function primaryflags()
- local arguments=environment.arguments
- local flags={}
- if arguments.silent then
- flags[#flags+1]="--interaction=batchmode"
- end
- if arguments.jit then
- flags[#flags+1]="--jiton"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local flags={}
+ if arguments.silent then
+ flags[#flags+1]="--interaction=batchmode"
+ end
+ if arguments.jit then
+ flags[#flags+1]="--jiton"
+ end
+ return concat(flags," ")
end
local function secondaryflags()
- local arguments=environment.arguments
- local trackers=arguments.trackers
- local directives=arguments.directives
- local flags={}
- if trackers and trackers~="" then
- flags[#flags+1]="--c:trackers="..quoted(trackers)
- end
- if directives and directives~="" then
- flags[#flags+1]="--c:directives="..quoted(directives)
- end
- if arguments.silent then
- flags[#flags+1]="--c:silent"
- end
- if arguments.errors then
- flags[#flags+1]="--c:errors"
- end
- if arguments.jit then
- flags[#flags+1]="--c:jiton"
- end
- if arguments.ansi then
- flags[#flags+1]="--c:ansi"
- end
- if arguments.strip then
- flags[#flags+1]="--c:strip"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local trackers=arguments.trackers
+ local directives=arguments.directives
+ local flags={}
+ if trackers and trackers~="" then
+ flags[#flags+1]="--c:trackers="..quoted(trackers)
+ end
+ if directives and directives~="" then
+ flags[#flags+1]="--c:directives="..quoted(directives)
+ end
+ if arguments.silent then
+ flags[#flags+1]="--c:silent"
+ end
+ if arguments.errors then
+ flags[#flags+1]="--c:errors"
+ end
+ if arguments.jit then
+ flags[#flags+1]="--c:jiton"
+ end
+ if arguments.ansi then
+ flags[#flags+1]="--c:ansi"
+ end
+ if arguments.strip then
+ flags[#flags+1]="--c:strip"
+ end
+ return concat(flags," ")
end
local template=[[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]]
local checkers={
- primaryflags="string",
- secondaryflags="string",
- luafile="readable",
- texfile="readable",
- redirect="string",
- dump="string",
+ primaryflags="string",
+ secondaryflags="string",
+ luafile="readable",
+ texfile="readable",
+ redirect="string",
+ dump="string",
}
local runners={
- luatex=sandbox.registerrunner {
- name="make luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="make luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="make luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="make luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.make_format(name,arguments)
- local engine=environment.ownmain or "luatex"
- local silent=environment.arguments.silent
- local errors=environment.arguments.errors
- local olddir=dir.current()
- local path=caches.getwritablepath("formats",engine) or ""
- if path~="" then
- lfs.chdir(path)
- end
- report_format("using format path %a",dir.current())
- local texsourcename=file.addsuffix(name,"mkiv")
- local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- if fulltexsourcename=="" then
- texsourcename=file.addsuffix(name,"tex")
- fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- end
- if fulltexsourcename=="" then
- report_format("no tex source file with name %a (mkiv or tex)",name)
- lfs.chdir(olddir)
- return
- else
- report_format("using tex source file %a",fulltexsourcename)
- end
- local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
- local specificationname=file.replacesuffix(fulltexsourcename,"lus")
- local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- if fullspecificationname=="" then
- specificationname=file.join(texsourcepath,"context.lus")
- fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- end
- if fullspecificationname=="" then
- report_format("unknown stub specification %a",specificationname)
- lfs.chdir(olddir)
- return
- end
- local specificationpath=file.dirname(fullspecificationname)
- local usedluastub=nil
- local usedlualibs=dofile(fullspecificationname)
- if type(usedlualibs)=="string" then
- usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
- elseif type(usedlualibs)=="table" then
- report_format("using stub specification %a",fullspecificationname)
- local texbasename=file.basename(name)
- local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
- local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
- report_format("creating initialization file %a",luastubname)
- utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
- if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
- report_format("using compiled initialization file %a",lucstubname)
- usedluastub=lucstubname
- else
- report_format("using uncompiled initialization file %a",luastubname)
- usedluastub=luastubname
- end
- else
- report_format("invalid stub specification %a",fullspecificationname)
- lfs.chdir(olddir)
- return
- end
- local specification={
- primaryflags=primaryflags(),
- secondaryflags=secondaryflags(),
- luafile=quoted(usedluastub),
- texfile=quoted(fulltexsourcename),
- dump=os.platform=="unix" and "\\\\dump" or "\\dump",
- }
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
- elseif silent then
- statistics.starttiming()
- specification.redirect="> temp.log"
- local result=runner(specification)
- local runtime=statistics.stoptiming()
- if result~=0 then
- print(format("%s silent make > fatal error when making format %q",engine,name))
- else
- print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
- end
- os.remove("temp.log")
- else
- runner(specification)
- end
- local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
- local mp=dir.glob(pattern)
- if mp then
- for i=1,#mp do
- local name=mp[i]
- report_format("removing related mplib format %a",file.basename(name))
- os.remove(name)
- end
- end
+ local engine=environment.ownmain or "luatex"
+ local silent=environment.arguments.silent
+ local errors=environment.arguments.errors
+ local olddir=dir.current()
+ local path=caches.getwritablepath("formats",engine) or ""
+ if path~="" then
+ lfs.chdir(path)
+ end
+ report_format("using format path %a",dir.current())
+ local texsourcename=file.addsuffix(name,"mkiv")
+ local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ if fulltexsourcename=="" then
+ texsourcename=file.addsuffix(name,"tex")
+ fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ end
+ if fulltexsourcename=="" then
+ report_format("no tex source file with name %a (mkiv or tex)",name)
lfs.chdir(olddir)
+ return
+ else
+ report_format("using tex source file %a",fulltexsourcename)
+ end
+ local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
+ local specificationname=file.replacesuffix(fulltexsourcename,"lus")
+ local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ if fullspecificationname=="" then
+ specificationname=file.join(texsourcepath,"context.lus")
+ fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ end
+ if fullspecificationname=="" then
+ report_format("unknown stub specification %a",specificationname)
+ lfs.chdir(olddir)
+ return
+ end
+ local specificationpath=file.dirname(fullspecificationname)
+ local usedluastub=nil
+ local usedlualibs=dofile(fullspecificationname)
+ if type(usedlualibs)=="string" then
+ usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
+ elseif type(usedlualibs)=="table" then
+ report_format("using stub specification %a",fullspecificationname)
+ local texbasename=file.basename(name)
+ local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
+ local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
+ report_format("creating initialization file %a",luastubname)
+ utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
+ if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
+ report_format("using compiled initialization file %a",lucstubname)
+ usedluastub=lucstubname
+ else
+ report_format("using uncompiled initialization file %a",luastubname)
+ usedluastub=luastubname
+ end
+ else
+ report_format("invalid stub specification %a",fullspecificationname)
+ lfs.chdir(olddir)
+ return
+ end
+ local specification={
+ primaryflags=primaryflags(),
+ secondaryflags=secondaryflags(),
+ luafile=quoted(usedluastub),
+ texfile=quoted(fulltexsourcename),
+ dump=os.platform=="unix" and "\\\\dump" or "\\dump",
+ }
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
+ elseif silent then
+ statistics.starttiming()
+ specification.redirect="> temp.log"
+ local result=runner(specification)
+ local runtime=statistics.stoptiming()
+ if result~=0 then
+ print(format("%s silent make > fatal error when making format %q",engine,name))
+ else
+ print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
+ end
+ os.remove("temp.log")
+ else
+ runner(specification)
+ end
+ local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
+ local mp=dir.glob(pattern)
+ if mp then
+ for i=1,#mp do
+ local name=mp[i]
+ report_format("removing related mplib format %a",file.basename(name))
+ os.remove(name)
+ end
+ end
+ lfs.chdir(olddir)
end
local template=[[%flags% --fmt=%fmtfile% --lua=%luafile% %texfile% %more%]]
local checkers={
- flags="string",
- more="string",
- fmtfile="readable",
- luafile="readable",
- texfile="readable",
+ flags="string",
+ more="string",
+ fmtfile="readable",
+ luafile="readable",
+ texfile="readable",
}
local runners={
- luatex=sandbox.registerrunner {
- name="run luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="run luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="run luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="run luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.run_format(name,data,more)
- if name and name~="" then
- local engine=environment.ownmain or "luatex"
- local barename=file.removesuffix(name)
- local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
- if fmtname=="" then
- fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
- end
- fmtname=resolvers.cleanpath(fmtname)
- if fmtname=="" then
- report_format("no format with name %a",name)
+ if name and name~="" then
+ local engine=environment.ownmain or "luatex"
+ local barename=file.removesuffix(name)
+ local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
+ if fmtname=="" then
+ fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
+ end
+ fmtname=resolvers.cleanpath(fmtname)
+ if fmtname=="" then
+ report_format("no format with name %a",name)
+ else
+ local barename=file.removesuffix(name)
+ local luaname=file.addsuffix(barename,"luc")
+ if not lfs.isfile(luaname) then
+ luaname=file.addsuffix(barename,"lua")
+ end
+ if not lfs.isfile(luaname) then
+ report_format("using format name %a",fmtname)
+ report_format("no luc/lua file with name %a",barename)
+ else
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be run, no runner available for engine %a",name,engine)
else
- local barename=file.removesuffix(name)
- local luaname=file.addsuffix(barename,"luc")
- if not lfs.isfile(luaname) then
- luaname=file.addsuffix(barename,"lua")
- end
- if not lfs.isfile(luaname) then
- report_format("using format name %a",fmtname)
- report_format("no luc/lua file with name %a",barename)
- else
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be run, no runner available for engine %a",name,engine)
- else
- runner {
- flags=primaryflags(),
- fmtfile=quoted(barename),
- luafile=quoted(luaname),
- texfile=quoted(data),
- more=more,
- }
- end
- end
+ runner {
+ flags=primaryflags(),
+ fmtfile=quoted(barename),
+ luafile=quoted(luaname),
+ texfile=quoted(data),
+ more=more,
+ }
end
+ end
end
+ end
end
@@ -24783,8 +24791,8 @@ end -- of closure
-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 988986
--- stripped bytes : 349358
+-- original bytes : 989364
+-- stripped bytes : 391967
-- end library merge
@@ -25707,7 +25715,7 @@ function runners.timedrun(filename) -- just for me
end
function runners.timed(action)
- statistics.timed(action)
+ statistics.timed(action,true)
end
function runners.associate(filename)
diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua
index 2763cbc04..168f204c7 100644
--- a/scripts/context/stubs/win64/mtxrun.lua
+++ b/scripts/context/stubs/win64/mtxrun.lua
@@ -63,14 +63,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lua"] = package.loaded["l-lua"] or true
--- original size: 6266, stripped down to: 3009
+-- original size: 6266, stripped down to: 2875
if not modules then modules={} end modules ['l-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,tonumber=next,type,tonumber
LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
@@ -78,111 +78,111 @@ LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
LUAVERSION=LUAMAJORVERSION+LUAMINORVERSION/10
if LUAVERSION<5.2 and jit then
- MINORVERSION=2
- LUAVERSION=5.2
+ MINORVERSION=2
+ LUAVERSION=5.2
end
_LUAVERSION=LUAVERSION
if not lpeg then
- lpeg=require("lpeg")
+ lpeg=require("lpeg")
end
if loadstring then
- local loadnormal=load
- function load(first,...)
- if type(first)=="string" then
- return loadstring(first,...)
- else
- return loadnormal(first,...)
- end
+ local loadnormal=load
+ function load(first,...)
+ if type(first)=="string" then
+ return loadstring(first,...)
+ else
+ return loadnormal(first,...)
end
+ end
else
- loadstring=load
+ loadstring=load
end
if not ipairs then
- local function iterate(a,i)
- i=i+1
- local v=a[i]
- if v~=nil then
- return i,v
- end
- end
- function ipairs(a)
- return iterate,a,0
+ local function iterate(a,i)
+ i=i+1
+ local v=a[i]
+ if v~=nil then
+ return i,v
end
+ end
+ function ipairs(a)
+ return iterate,a,0
+ end
end
if not pairs then
- function pairs(t)
- return next,t
- end
+ function pairs(t)
+ return next,t
+ end
end
if not table.unpack then
- table.unpack=_G.unpack
+ table.unpack=_G.unpack
elseif not unpack then
- _G.unpack=table.unpack
+ _G.unpack=table.unpack
end
if not package.loaders then
- package.loaders=package.searchers
+ package.loaders=package.searchers
end
local print,select,tostring=print,select,tostring
local inspectors={}
function setinspector(kind,inspector)
- inspectors[kind]=inspector
+ inspectors[kind]=inspector
end
function inspect(...)
- for s=1,select("#",...) do
- local value=select(s,...)
- if value==nil then
- print("nil")
- else
- local done=false
- local kind=type(value)
- local inspector=inspectors[kind]
- if inspector then
- done=inspector(value)
- if done then
- break
- end
- end
- for kind,inspector in next,inspectors do
- done=inspector(value)
- if done then
- break
- end
- end
- if not done then
- print(tostring(value))
- end
+ for s=1,select("#",...) do
+ local value=select(s,...)
+ if value==nil then
+ print("nil")
+ else
+ local done=false
+ local kind=type(value)
+ local inspector=inspectors[kind]
+ if inspector then
+ done=inspector(value)
+ if done then
+ break
+ end
+ end
+ for kind,inspector in next,inspectors do
+ done=inspector(value)
+ if done then
+ break
end
+ end
+ if not done then
+ print(tostring(value))
+ end
end
+ end
end
local dummy=function() end
function optionalrequire(...)
- local ok,result=xpcall(require,dummy,...)
- if ok then
- return result
- end
+ local ok,result=xpcall(require,dummy,...)
+ if ok then
+ return result
+ end
end
if lua then
- lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
+ lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
end
local flush=io.flush
if flush then
- local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
- local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
- local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
- local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
+ local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
+ local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
+ local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
+ local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
end
FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
if not FFISUPPORTED then
- local okay;okay,ffi=pcall(require,"ffi")
- FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
+ local okay;okay,ffi=pcall(require,"ffi")
+ FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
end
if not FFISUPPORTED then
- ffi=nil
+ ffi=nil
elseif not ffi.number then
- ffi.number=tonumber
+ ffi.number=tonumber
end
if not bit32 then
- bit32=require("l-bit32")
+ bit32=require("l-bit32")
end
@@ -192,14 +192,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-macro"] = package.loaded["l-macro"] or true
--- original size: 10131, stripped down to: 6337
+-- original size: 10131, stripped down to: 5991
if not modules then modules={} end modules ['l-macros']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local S,P,R,V,C,Cs,Cc,Ct,Carg=lpeg.S,lpeg.P,lpeg.R,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg
local lpegmatch=lpeg.match
@@ -229,214 +229,214 @@ local definitions={}
local resolve
local subparser
local report_lua=function(...)
- if logs and logs.reporter then
- report_lua=logs.reporter("system","lua")
- report_lua(...)
- else
- print(format(...))
- end
+ if logs and logs.reporter then
+ report_lua=logs.reporter("system","lua")
+ report_lua(...)
+ else
+ print(format(...))
+ end
end
local safeguard=P("local")*whitespace^1*name*(whitespace+P("="))
resolve=safeguard+C(C(name)*(arguments^-1))/function(raw,s,a)
- local d=definitions[s]
- if d then
- if a then
- local n=#a
- local p=patterns[s][n]
- if p then
- local d=d[n]
- for i=1,n do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return lpegmatch(p,d,1,a) or d
- else
- return raw
- end
- else
- return d[0] or raw
- end
- elseif a then
- for i=1,#a do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
+ local d=definitions[s]
+ if d then
+ if a then
+ local n=#a
+ local p=patterns[s][n]
+ if p then
+ local d=d[n]
+ for i=1,n do
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
end
- return s.."("..concat(a,",")..")"
- else
+ return lpegmatch(p,d,1,a) or d
+ else
return raw
+ end
+ else
+ return d[0] or raw
end
+ elseif a then
+ for i=1,#a do
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
+ end
+ return s.."("..concat(a,",")..")"
+ else
+ return raw
+ end
end
subparser=Cs((resolve+P(1))^1)
local enddefine=P("#enddefine")/""
local beginregister=(C(name)*(arguments+Cc(false))*C((1-enddefine)^1)*enddefine)/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
+ definitions[k]=d
+ end
+ d[n]=lpegmatch(subparser,v) or v
+ return ""
end
local register=(Cs(name)*(arguments+Cc(false))*spaces^0*Cs(body))/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ d={ a=a,[0]=false,false,false,false,false,false,false,false,false }
+ definitions[k]=d
+ end
+ d[n]=lpegmatch(subparser,v) or v
+ return ""
end
local unregister=(C(name)*spaces^0*(arguments+Cc(false)))/function(k,a)
- local n=0
- if a then
- n=#a
- local p=patterns[k]
- if p then
- p[n]=false
- end
- end
- local d=definitions[k]
- if d then
- d[n]=false
+ local n=0
+ if a then
+ n=#a
+ local p=patterns[k]
+ if p then
+ p[n]=false
end
- return ""
+ end
+ local d=definitions[k]
+ if d then
+ d[n]=false
+ end
+ return ""
end
local begindefine=(P("begindefine")*spaces^0/"")*beginregister
-local define=(P("define" )*spaces^0/"")*register
-local undefine=(P("undefine" )*spaces^0/"")*unregister
+local define=(P("define" )*spaces^0/"")*register
+local undefine=(P("undefine" )*spaces^0/"")*unregister
local parser=Cs((((P("#")/"")*(define+begindefine+undefine)*(newline^0/"") )+resolve+P(1) )^0 )
function macros.reset()
- definitions={}
- patterns={}
+ definitions={}
+ patterns={}
end
function macros.showdefinitions()
- for name,list in table.sortedhash(definitions) do
- local arguments=list.a
- if arguments then
- arguments="("..concat(arguments,",")..")"
- else
- arguments=""
- end
- print("macro: "..name..arguments)
- for i=0,#list do
- local l=list[i]
- if l then
- print(" "..l)
- end
- end
+ for name,list in table.sortedhash(definitions) do
+ local arguments=list.a
+ if arguments then
+ arguments="("..concat(arguments,",")..")"
+ else
+ arguments=""
+ end
+ print("macro: "..name..arguments)
+ for i=0,#list do
+ local l=list[i]
+ if l then
+ print(" "..l)
+ end
end
+ end
end
function macros.resolvestring(str)
- return lpegmatch(parser,str) or str
+ return lpegmatch(parser,str) or str
end
function macros.resolving()
- return next(patterns)
+ return next(patterns)
end
local function reload(path,name,data)
- local only=match(name,".-([^/]+)%.lua")
+ local only=match(name,".-([^/]+)%.lua")
+ if only and only~="" then
+ local name=path.."/"..only
+ local f=io.open(name,"wb")
+ f:write(data)
+ f:close()
+ local f=loadfile(name)
+ os.remove(name)
+ return f
+ end
+end
+local function reload(path,name,data)
+ if path and path~="" then
+ local only=string.match(name,".-([^/]+)%.lua")
if only and only~="" then
- local name=path.."/"..only
- local f=io.open(name,"wb")
+ local name=path.."/"..only.."-macro.lua"
+ local f=io.open(name,"wb")
+ if f then
f:write(data)
f:close()
- local f=loadfile(name)
+ local l=loadfile(name)
os.remove(name)
- return f
- end
-end
-local function reload(path,name,data)
- if path and path~="" then
- local only=string.match(name,".-([^/]+)%.lua")
- if only and only~="" then
- local name=path.."/"..only.."-macro.lua"
- local f=io.open(name,"wb")
- if f then
- f:write(data)
- f:close()
- local l=loadfile(name)
- os.remove(name)
- return l
- end
- end
+ return l
+ end
end
- return load(data,name)
+ end
+ return load(data,name)
end
local function loaded(name,trace,detail)
- local f=io.open(name,"rb")
- if not f then
- return false,format("file '%s' not found",name)
- end
- local c=f:read("*a")
- if not c then
- return false,format("file '%s' is invalid",name)
- end
- f:close()
- local n=lpegmatch(parser,c)
- if trace then
- if #n~=#c then
- report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
- if detail then
- report_lua()
- report_lua(n)
- report_lua()
- end
- elseif detail then
- report_lua("no macros expanded in '%s'",name)
- end
+ local f=io.open(name,"rb")
+ if not f then
+ return false,format("file '%s' not found",name)
+ end
+ local c=f:read("*a")
+ if not c then
+ return false,format("file '%s' is invalid",name)
+ end
+ f:close()
+ local n=lpegmatch(parser,c)
+ if trace then
+ if #n~=#c then
+ report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
+ if detail then
+ report_lua()
+ report_lua(n)
+ report_lua()
+ end
+ elseif detail then
+ report_lua("no macros expanded in '%s'",name)
end
- return reload(lfs and lfs.currentdir(),name,n)
+ end
+ return reload(lfs and lfs.currentdir(),name,n)
end
macros.loaded=loaded
function required(name,trace)
- local filename=file.addsuffix(name,"lua")
- local fullname=resolvers and resolvers.find_file(filename) or filename
- if not fullname or fullname=="" then
- return false
- end
- local codeblob=package.loaded[fullname]
- if codeblob then
- return codeblob
- end
- local code,message=loaded(fullname,macros,trace,trace)
- if type(code)=="function" then
- code=code()
- else
- report_lua("error when loading '%s'",fullname)
- return false,message
- end
- if code==nil then
- code=false
- end
- package.loaded[fullname]=code
- return code
+ local filename=file.addsuffix(name,"lua")
+ local fullname=resolvers and resolvers.find_file(filename) or filename
+ if not fullname or fullname=="" then
+ return false
+ end
+ local codeblob=package.loaded[fullname]
+ if codeblob then
+ return codeblob
+ end
+ local code,message=loaded(fullname,macros,trace,trace)
+ if type(code)=="function" then
+ code=code()
+ else
+ report_lua("error when loading '%s'",fullname)
+ return false,message
+ end
+ if code==nil then
+ code=false
+ end
+ package.loaded[fullname]=code
+ return code
end
macros.required=required
@@ -447,14 +447,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true
--- original size: 9747, stripped down to: 6739
+-- original size: 9747, stripped down to: 6313
if not modules then modules={} end modules ['l-sandbox']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local global=_G
local next=next
@@ -480,234 +480,234 @@ local trace=false
local logger=false
local blocked={}
local function report(...)
- tprint("sandbox ! "..format(...))
+ tprint("sandbox ! "..format(...))
end
sandbox.report=report
function sandbox.setreporter(r)
- report=r
- sandbox.report=r
+ report=r
+ sandbox.report=r
end
function sandbox.settrace(v)
- trace=v
+ trace=v
end
function sandbox.setlogger(l)
- logger=type(l)=="function" and l or false
+ logger=type(l)=="function" and l or false
end
local function register(func,overload,comment)
- if type(func)=="function" then
- if type(overload)=="string" then
- comment=overload
- overload=nil
- end
- local function f(...)
- if sandboxed then
- local overload=overloads[f]
- if overload then
- if logger then
- local result={ overload(func,...) }
- logger {
- comment=comments[f] or tostring(f),
- arguments={... },
- result=result[1] and true or false,
- }
- return unpack(result)
- else
- return overload(func,...)
- end
- else
- end
- else
- return func(...)
- end
- end
- if comment then
- comments[f]=comment
- if trace then
- report("registering function: %s",comment)
- end
+ if type(func)=="function" then
+ if type(overload)=="string" then
+ comment=overload
+ overload=nil
+ end
+ local function f(...)
+ if sandboxed then
+ local overload=overloads[f]
+ if overload then
+ if logger then
+ local result={ overload(func,...) }
+ logger {
+ comment=comments[f] or tostring(f),
+ arguments={... },
+ result=result[1] and true or false,
+ }
+ return unpack(result)
+ else
+ return overload(func,...)
+ end
+ else
end
- overloads[f]=overload or false
- originals[f]=func
- return f
+ else
+ return func(...)
+ end
end
+ if comment then
+ comments[f]=comment
+ if trace then
+ report("registering function: %s",comment)
+ end
+ end
+ overloads[f]=overload or false
+ originals[f]=func
+ return f
+ end
end
local function redefine(func,comment)
- if type(func)=="function" then
- skiploads[func]=comment or comments[func] or "unknown"
- if overloads[func]==false then
- overloads[func]=nil
- end
+ if type(func)=="function" then
+ skiploads[func]=comment or comments[func] or "unknown"
+ if overloads[func]==false then
+ overloads[func]=nil
end
+ end
end
sandbox.register=register
sandbox.redefine=redefine
function sandbox.original(func)
- return originals and originals[func] or func
+ return originals and originals[func] or func
end
function sandbox.overload(func,overload,comment)
- comment=comment or comments[func] or "?"
- if type(func)~="function" then
- if trace then
- report("overloading unknown function: %s",comment)
- end
- elseif type(overload)~="function" then
- if trace then
- report("overloading function with bad overload: %s",comment)
- end
- elseif overloads[func]==nil then
- if trace then
- report("function is not registered: %s",comment)
- end
- elseif skiploads[func] then
- if trace then
- report("function is not skipped: %s",comment)
- end
- else
- if trace then
- report("overloading function: %s",comment)
- end
- overloads[func]=overload
+ comment=comment or comments[func] or "?"
+ if type(func)~="function" then
+ if trace then
+ report("overloading unknown function: %s",comment)
+ end
+ elseif type(overload)~="function" then
+ if trace then
+ report("overloading function with bad overload: %s",comment)
+ end
+ elseif overloads[func]==nil then
+ if trace then
+ report("function is not registered: %s",comment)
+ end
+ elseif skiploads[func] then
+ if trace then
+ report("function is not skipped: %s",comment)
+ end
+ else
+ if trace then
+ report("overloading function: %s",comment)
end
- return func
+ overloads[func]=overload
+ end
+ return func
end
local function whatever(specification,what,target)
- if type(specification)~="table" then
- report("%s needs a specification",what)
- elseif type(specification.category)~="string" or type(specification.action)~="function" then
- report("%s needs a category and action",what)
- elseif not sandboxed then
- target[#target+1]=specification
- elseif trace then
- report("already enabled, discarding %s",what)
- end
+ if type(specification)~="table" then
+ report("%s needs a specification",what)
+ elseif type(specification.category)~="string" or type(specification.action)~="function" then
+ report("%s needs a category and action",what)
+ elseif not sandboxed then
+ target[#target+1]=specification
+ elseif trace then
+ report("already enabled, discarding %s",what)
+ end
end
function sandbox.initializer(specification)
- whatever(specification,"initializer",initializers)
+ whatever(specification,"initializer",initializers)
end
function sandbox.finalizer(specification)
- whatever(specification,"finalizer",finalizers)
+ whatever(specification,"finalizer",finalizers)
end
function require(name)
- local n=gsub(name,"^.*[\\/]","")
- local n=gsub(n,"[%.].*$","")
- local b=blocked[n]
- if b==false then
- return nil
- elseif b then
- if trace then
- report("using blocked: %s",n)
- end
- return b
- else
- if trace then
- report("requiring: %s",name)
- end
- return requiem(name)
+ local n=gsub(name,"^.*[\\/]","")
+ local n=gsub(n,"[%.].*$","")
+ local b=blocked[n]
+ if b==false then
+ return nil
+ elseif b then
+ if trace then
+ report("using blocked: %s",n)
end
-end
-function blockrequire(name,lib)
+ return b
+ else
if trace then
- report("preventing reload of: %s",name)
+ report("requiring: %s",name)
end
- blocked[name]=lib or _G[name] or false
+ return requiem(name)
+ end
+end
+function blockrequire(name,lib)
+ if trace then
+ report("preventing reload of: %s",name)
+ end
+ blocked[name]=lib or _G[name] or false
end
function sandbox.enable()
- if not sandboxed then
- debug={
- traceback=debug.traceback,
- }
- for i=1,#initializers do
- initializers[i].action()
- end
- for i=1,#finalizers do
- finalizers[i].action()
- end
- local nnot=0
- local nyes=0
- local cnot={}
- local cyes={}
- local skip={}
- for k,v in next,overloads do
- local c=comments[k]
- if v then
- if c then
- cyes[#cyes+1]=c
- else
- nyes=nyes+1
- end
- else
- if c then
- cnot[#cnot+1]=c
- else
- nnot=nnot+1
- end
- end
- end
- for k,v in next,skiploads do
- skip[#skip+1]=v
- end
- if #cyes>0 then
- sort(cyes)
- report("overloaded known: %s",concat(cyes," | "))
- end
- if nyes>0 then
- report("overloaded unknown: %s",nyes)
- end
- if #cnot>0 then
- sort(cnot)
- report("not overloaded known: %s",concat(cnot," | "))
- end
- if nnot>0 then
- report("not overloaded unknown: %s",nnot)
+ if not sandboxed then
+ debug={
+ traceback=debug.traceback,
+ }
+ for i=1,#initializers do
+ initializers[i].action()
+ end
+ for i=1,#finalizers do
+ finalizers[i].action()
+ end
+ local nnot=0
+ local nyes=0
+ local cnot={}
+ local cyes={}
+ local skip={}
+ for k,v in next,overloads do
+ local c=comments[k]
+ if v then
+ if c then
+ cyes[#cyes+1]=c
+ else
+ nyes=nyes+1
end
- if #skip>0 then
- sort(skip)
- report("not overloaded redefined: %s",concat(skip," | "))
+ else
+ if c then
+ cnot[#cnot+1]=c
+ else
+ nnot=nnot+1
end
- initializers=nil
- finalizers=nil
- originals=nil
- sandboxed=true
+ end
+ end
+ for k,v in next,skiploads do
+ skip[#skip+1]=v
+ end
+ if #cyes>0 then
+ sort(cyes)
+ report("overloaded known: %s",concat(cyes," | "))
+ end
+ if nyes>0 then
+ report("overloaded unknown: %s",nyes)
+ end
+ if #cnot>0 then
+ sort(cnot)
+ report("not overloaded known: %s",concat(cnot," | "))
+ end
+ if nnot>0 then
+ report("not overloaded unknown: %s",nnot)
end
+ if #skip>0 then
+ sort(skip)
+ report("not overloaded redefined: %s",concat(skip," | "))
+ end
+ initializers=nil
+ finalizers=nil
+ originals=nil
+ sandboxed=true
+ end
end
blockrequire("lfs",lfs)
blockrequire("io",io)
blockrequire("os",os)
blockrequire("ffi",ffi)
local function supported(library)
- local l=_G[library]
- return l
+ local l=_G[library]
+ return l
end
loadfile=register(loadfile,"loadfile")
if supported("io") then
- io.open=register(io.open,"io.open")
- io.popen=register(io.popen,"io.popen")
- io.lines=register(io.lines,"io.lines")
- io.output=register(io.output,"io.output")
- io.input=register(io.input,"io.input")
+ io.open=register(io.open,"io.open")
+ io.popen=register(io.popen,"io.popen")
+ io.lines=register(io.lines,"io.lines")
+ io.output=register(io.output,"io.output")
+ io.input=register(io.input,"io.input")
end
if supported("os") then
- os.execute=register(os.execute,"os.execute")
- os.spawn=register(os.spawn,"os.spawn")
- os.exec=register(os.exec,"os.exec")
- os.rename=register(os.rename,"os.rename")
- os.remove=register(os.remove,"os.remove")
+ os.execute=register(os.execute,"os.execute")
+ os.spawn=register(os.spawn,"os.spawn")
+ os.exec=register(os.exec,"os.exec")
+ os.rename=register(os.rename,"os.rename")
+ os.remove=register(os.remove,"os.remove")
end
if supported("lfs") then
- lfs.chdir=register(lfs.chdir,"lfs.chdir")
- lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
- lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
- lfs.isfile=register(lfs.isfile,"lfs.isfile")
- lfs.isdir=register(lfs.isdir,"lfs.isdir")
- lfs.attributes=register(lfs.attributes,"lfs.attributes")
- lfs.dir=register(lfs.dir,"lfs.dir")
- lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
- lfs.touch=register(lfs.touch,"lfs.touch")
- lfs.link=register(lfs.link,"lfs.link")
- lfs.setmode=register(lfs.setmode,"lfs.setmode")
- lfs.readlink=register(lfs.readlink,"lfs.readlink")
- lfs.shortname=register(lfs.shortname,"lfs.shortname")
- lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
+ lfs.chdir=register(lfs.chdir,"lfs.chdir")
+ lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
+ lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
+ lfs.isfile=register(lfs.isfile,"lfs.isfile")
+ lfs.isdir=register(lfs.isdir,"lfs.isdir")
+ lfs.attributes=register(lfs.attributes,"lfs.attributes")
+ lfs.dir=register(lfs.dir,"lfs.dir")
+ lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
+ lfs.touch=register(lfs.touch,"lfs.touch")
+ lfs.link=register(lfs.link,"lfs.link")
+ lfs.setmode=register(lfs.setmode,"lfs.setmode")
+ lfs.readlink=register(lfs.readlink,"lfs.readlink")
+ lfs.shortname=register(lfs.shortname,"lfs.shortname")
+ lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
end
@@ -717,14 +717,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-package"] = package.loaded["l-package"] or true
--- original size: 11605, stripped down to: 8663
+-- original size: 11605, stripped down to: 8299
if not modules then modules={} end modules ['l-package']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type=type
local gsub,format,find=string.gsub,string.format,string.find
@@ -732,40 +732,40 @@ local insert,remove=table.insert,table.remove
local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
local package=package
local searchers=package.searchers or package.loaders
-local filejoin=file and file.join or function(path,name) return path.."/"..name end
-local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
-local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
+local filejoin=file and file.join or function(path,name) return path.."/"..name end
+local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
+local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
local function cleanpath(path)
- return path
+ return path
end
local pattern=Cs((((1-S("\\/"))^0*(S("\\/")^1/"/"))^0*(P(".")^1/"/"+P(1))^1)*-1)
local function lualibfile(name)
- return lpegmatch(pattern,name) or name
+ return lpegmatch(pattern,name) or name
end
local offset=luarocks and 1 or 0
local helpers=package.helpers or {
- cleanpath=cleanpath,
- lualibfile=lualibfile,
- trace=false,
- report=function(...) print(format(...)) end,
- builtin={
- ["preload table"]=searchers[1+offset],
- ["path specification"]=searchers[2+offset],
- ["cpath specification"]=searchers[3+offset],
- ["all in one fallback"]=searchers[4+offset],
- },
- methods={},
- sequence={
- "already loaded",
- "preload table",
- "qualified path",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
- }
+ cleanpath=cleanpath,
+ lualibfile=lualibfile,
+ trace=false,
+ report=function(...) print(format(...)) end,
+ builtin={
+ ["preload table"]=searchers[1+offset],
+ ["path specification"]=searchers[2+offset],
+ ["cpath specification"]=searchers[3+offset],
+ ["all in one fallback"]=searchers[4+offset],
+ },
+ methods={},
+ sequence={
+ "already loaded",
+ "preload table",
+ "qualified path",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
+ }
}
package.helpers=helpers
local methods=helpers.methods
@@ -781,255 +781,255 @@ local nofextralib=-1
local nofpathlua=-1
local nofpathlib=-1
local function listpaths(what,paths)
- local nofpaths=#paths
- if nofpaths>0 then
- for i=1,nofpaths do
- helpers.report("using %s path %i: %s",what,i,paths[i])
- end
- else
- helpers.report("no %s paths defined",what)
+ local nofpaths=#paths
+ if nofpaths>0 then
+ for i=1,nofpaths do
+ helpers.report("using %s path %i: %s",what,i,paths[i])
end
- return nofpaths
+ else
+ helpers.report("no %s paths defined",what)
+ end
+ return nofpaths
end
local function getextraluapaths()
- if helpers.trace and #extraluapaths~=nofextralua then
- nofextralua=listpaths("extra lua",extraluapaths)
- end
- return extraluapaths
+ if helpers.trace and #extraluapaths~=nofextralua then
+ nofextralua=listpaths("extra lua",extraluapaths)
+ end
+ return extraluapaths
end
local function getextralibpaths()
- if helpers.trace and #extralibpaths~=nofextralib then
- nofextralib=listpaths("extra lib",extralibpaths)
- end
- return extralibpaths
+ if helpers.trace and #extralibpaths~=nofextralib then
+ nofextralib=listpaths("extra lib",extralibpaths)
+ end
+ return extralibpaths
end
local function getluapaths()
- local luapath=package.path or ""
- if oldluapath~=luapath then
- luapaths=file.splitpath(luapath,";")
- oldluapath=luapath
- nofpathlua=-1
- end
- if helpers.trace and #luapaths~=nofpathlua then
- nofpathlua=listpaths("builtin lua",luapaths)
- end
- return luapaths
+ local luapath=package.path or ""
+ if oldluapath~=luapath then
+ luapaths=file.splitpath(luapath,";")
+ oldluapath=luapath
+ nofpathlua=-1
+ end
+ if helpers.trace and #luapaths~=nofpathlua then
+ nofpathlua=listpaths("builtin lua",luapaths)
+ end
+ return luapaths
end
local function getlibpaths()
- local libpath=package.cpath or ""
- if oldlibpath~=libpath then
- libpaths=file.splitpath(libpath,";")
- oldlibpath=libpath
- nofpathlib=-1
- end
- if helpers.trace and #libpaths~=nofpathlib then
- nofpathlib=listpaths("builtin lib",libpaths)
- end
- return libpaths
+ local libpath=package.cpath or ""
+ if oldlibpath~=libpath then
+ libpaths=file.splitpath(libpath,";")
+ oldlibpath=libpath
+ nofpathlib=-1
+ end
+ if helpers.trace and #libpaths~=nofpathlib then
+ nofpathlib=listpaths("builtin lib",libpaths)
+ end
+ return libpaths
end
package.luapaths=getluapaths
package.libpaths=getlibpaths
package.extraluapaths=getextraluapaths
package.extralibpaths=getextralibpaths
local hashes={
- lua={},
- lib={},
+ lua={},
+ lib={},
}
local function registerpath(tag,what,target,...)
- local pathlist={... }
- local cleanpath=helpers.cleanpath
- local trace=helpers.trace
- local report=helpers.report
- local hash=hashes[what]
- local function add(path)
- local path=cleanpath(path)
- if not hash[path] then
- target[#target+1]=path
- hash[path]=true
- if trace then
- report("registered %s path %s: %s",tag,#target,path)
- end
- else
- if trace then
- report("duplicate %s path: %s",tag,path)
- end
- end
+ local pathlist={... }
+ local cleanpath=helpers.cleanpath
+ local trace=helpers.trace
+ local report=helpers.report
+ local hash=hashes[what]
+ local function add(path)
+ local path=cleanpath(path)
+ if not hash[path] then
+ target[#target+1]=path
+ hash[path]=true
+ if trace then
+ report("registered %s path %s: %s",tag,#target,path)
+ end
+ else
+ if trace then
+ report("duplicate %s path: %s",tag,path)
+ end
end
- for p=1,#pathlist do
- local path=pathlist[p]
- if type(path)=="table" then
- for i=1,#path do
- add(path[i])
- end
- else
- add(path)
- end
+ end
+ for p=1,#pathlist do
+ local path=pathlist[p]
+ if type(path)=="table" then
+ for i=1,#path do
+ add(path[i])
+ end
+ else
+ add(path)
end
+ end
end
local function pushpath(tag,what,target,path)
- local path=helpers.cleanpath(path)
- insert(target,1,path)
- if helpers.trace then
- helpers.report("pushing %s path in front: %s",tag,path)
- end
+ local path=helpers.cleanpath(path)
+ insert(target,1,path)
+ if helpers.trace then
+ helpers.report("pushing %s path in front: %s",tag,path)
+ end
end
local function poppath(tag,what,target)
- local path=remove(target,1)
- if helpers.trace then
- if path then
- helpers.report("popping %s path from front: %s",tag,path)
- else
- helpers.report("no %s path to pop",tag)
- end
+ local path=remove(target,1)
+ if helpers.trace then
+ if path then
+ helpers.report("popping %s path from front: %s",tag,path)
+ else
+ helpers.report("no %s path to pop",tag)
end
+ end
end
helpers.registerpath=registerpath
function package.extraluapath(...)
- registerpath("extra lua","lua",extraluapaths,...)
+ registerpath("extra lua","lua",extraluapaths,...)
end
function package.pushluapath(path)
- pushpath("extra lua","lua",extraluapaths,path)
+ pushpath("extra lua","lua",extraluapaths,path)
end
function package.popluapath()
- poppath("extra lua","lua",extraluapaths)
+ poppath("extra lua","lua",extraluapaths)
end
function package.extralibpath(...)
- registerpath("extra lib","lib",extralibpaths,...)
+ registerpath("extra lib","lib",extralibpaths,...)
end
function package.pushlibpath(path)
- pushpath("extra lib","lib",extralibpaths,path)
+ pushpath("extra lib","lib",extralibpaths,path)
end
function package.poplibpath()
- poppath("extra lib","lua",extralibpaths)
+ poppath("extra lib","lua",extralibpaths)
end
local function loadedaslib(resolved,rawname)
- local base=gsub(rawname,"%.","_")
- local init="luaopen_"..gsub(base,"%.","_")
- if helpers.trace then
- helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
- end
- return package.loadlib(resolved,init)
+ local base=gsub(rawname,"%.","_")
+ local init="luaopen_"..gsub(base,"%.","_")
+ if helpers.trace then
+ helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+ end
+ return package.loadlib(resolved,init)
end
helpers.loadedaslib=loadedaslib
local function loadedbypath(name,rawname,paths,islib,what)
- local trace=helpers.trace
- for p=1,#paths do
- local path=paths[p]
- local resolved=filejoin(path,name)
- if trace then
- helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
- end
- if isreadable(resolved) then
- if trace then
- helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ for p=1,#paths do
+ local path=paths[p]
+ local resolved=filejoin(path,name)
+ if trace then
+ helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
+ end
+ if isreadable(resolved) then
+ if trace then
+ helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
end
+ end
end
helpers.loadedbypath=loadedbypath
local function loadedbyname(name,rawname)
- if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
- local trace=helpers.trace
- if trace then
- helpers.report("qualified name, identifying '%s'",what,name)
- end
- if isreadable(name) then
- if trace then
- helpers.report("qualified name, '%s' found",what,name)
- end
- return loadfile(name)
- end
+ if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
+ local trace=helpers.trace
+ if trace then
+ helpers.report("qualified name, identifying '%s'",what,name)
end
+ if isreadable(name) then
+ if trace then
+ helpers.report("qualified name, '%s' found",what,name)
+ end
+ return loadfile(name)
+ end
+ end
end
helpers.loadedbyname=loadedbyname
methods["already loaded"]=function(name)
- return package.loaded[name]
+ return package.loaded[name]
end
methods["preload table"]=function(name)
- return builtin["preload table"](name)
+ return builtin["preload table"](name)
end
methods["qualified path"]=function(name)
- return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
+ return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
end
methods["lua extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
+ return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
end
methods["lib extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
+ return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
end
methods["path specification"]=function(name)
- getluapaths()
- return builtin["path specification"](name)
+ getluapaths()
+ return builtin["path specification"](name)
end
methods["cpath specification"]=function(name)
- getlibpaths()
- return builtin["cpath specification"](name)
+ getlibpaths()
+ return builtin["cpath specification"](name)
end
methods["all in one fallback"]=function(name)
- return builtin["all in one fallback"](name)
+ return builtin["all in one fallback"](name)
end
methods["not loaded"]=function(name)
- if helpers.trace then
- helpers.report("unable to locate '%s'",name or "?")
- end
- return nil
+ if helpers.trace then
+ helpers.report("unable to locate '%s'",name or "?")
+ end
+ return nil
end
local level=0
local used={}
helpers.traceused=false
function helpers.loaded(name)
- local sequence=helpers.sequence
- level=level+1
- for i=1,#sequence do
- local method=sequence[i]
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
- end
- local result,rest=methods[method](name)
- if type(result)=="function" then
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
- end
- if helpers.traceused then
- used[#used+1]={ level=level,name=name }
- end
- level=level-1
- return result,rest
- end
+ local sequence=helpers.sequence
+ level=level+1
+ for i=1,#sequence do
+ local method=sequence[i]
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
end
- level=level-1
- return nil
+ local result,rest=methods[method](name)
+ if type(result)=="function" then
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
+ end
+ if helpers.traceused then
+ used[#used+1]={ level=level,name=name }
+ end
+ level=level-1
+ return result,rest
+ end
+ end
+ level=level-1
+ return nil
end
function helpers.showused()
- local n=#used
- if n>0 then
- helpers.report("%s libraries loaded:",n)
- helpers.report()
- for i=1,n do
- local u=used[i]
- helpers.report("%i %a",u.level,u.name)
- end
- helpers.report()
- end
+ local n=#used
+ if n>0 then
+ helpers.report("%s libraries loaded:",n)
+ helpers.report()
+ for i=1,n do
+ local u=used[i]
+ helpers.report("%i %a",u.level,u.name)
+ end
+ helpers.report()
+ end
end
function helpers.unload(name)
- if helpers.trace then
- if package.loaded[name] then
- helpers.report("unloading, name '%s', %s",name,"done")
- else
- helpers.report("unloading, name '%s', %s",name,"not loaded")
- end
+ if helpers.trace then
+ if package.loaded[name] then
+ helpers.report("unloading, name '%s', %s",name,"done")
+ else
+ helpers.report("unloading, name '%s', %s",name,"not loaded")
end
- package.loaded[name]=nil
+ end
+ package.loaded[name]=nil
end
table.insert(searchers,1,helpers.loaded)
if context then
- package.path=""
+ package.path=""
end
@@ -1039,14 +1039,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
--- original size: 38434, stripped down to: 20344
+-- original size: 38434, stripped down to: 19310
if not modules then modules={} end modules ['l-lpeg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
lpeg=require("lpeg")
local lpeg=lpeg
@@ -1057,7 +1057,7 @@ local floor=math.floor
local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt
local lpegtype,lpegmatch,lpegprint=lpeg.type,lpeg.match,lpeg.print
if setinspector then
- setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
+ setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
end
lpeg.patterns=lpeg.patterns or {}
local patterns=lpeg.patterns
@@ -1080,7 +1080,7 @@ local underscore=P("_")
local hexdigit=digit+lowercase+uppercase
local hexdigits=hexdigit^1
local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
-local newline=P("\r")*(P("\n")+P(true))+P("\n")
+local newline=P("\r")*(P("\n")+P(true))+P("\n")
local escaped=P("\\")*anything
local squote=P("'")
local dquote=P('"')
@@ -1089,9 +1089,9 @@ local period=P(".")
local comma=P(",")
local utfbom_32_be=P('\000\000\254\255')
local utfbom_32_le=P('\255\254\000\000')
-local utfbom_16_be=P('\254\255')
-local utfbom_16_le=P('\255\254')
-local utfbom_8=P('\239\187\191')
+local utfbom_16_be=P('\254\255')
+local utfbom_16_le=P('\255\254')
+local utfbom_8=P('\239\187\191')
local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8
local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8")
local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")
@@ -1123,7 +1123,7 @@ patterns.utf8character=utf8character
patterns.validutf8=validutf8char
patterns.validutf8char=validutf8char
local eol=S("\n\r")
-local spacer=S(" \t\f\v")
+local spacer=S(" \t\f\v")
local whitespace=eol+spacer
local nonspacer=1-spacer
local nonwhitespace=1-whitespace
@@ -1132,7 +1132,7 @@ patterns.spacer=spacer
patterns.whitespace=whitespace
patterns.nonspacer=nonspacer
patterns.nonwhitespace=nonwhitespace
-local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
+local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0)
local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0)
@@ -1209,82 +1209,82 @@ patterns.somecontent=(anything-newline-space)^1
patterns.beginline=#(1-newline)
patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0))
function anywhere(pattern)
- return (1-P(pattern))^0*P(pattern)
+ return (1-P(pattern))^0*P(pattern)
end
lpeg.anywhere=anywhere
function lpeg.instringchecker(p)
- p=anywhere(p)
- return function(str)
- return lpegmatch(p,str) and true or false
- end
+ p=anywhere(p)
+ return function(str)
+ return lpegmatch(p,str) and true or false
+ end
end
function lpeg.splitter(pattern,action)
- if action then
- return (((1-P(pattern))^1)/action+1)^0
- else
- return (Cs((1-P(pattern))^1)+1)^0
- end
+ if action then
+ return (((1-P(pattern))^1)/action+1)^0
+ else
+ return (Cs((1-P(pattern))^1)+1)^0
+ end
end
function lpeg.tsplitter(pattern,action)
- if action then
- return Ct((((1-P(pattern))^1)/action+1)^0)
- else
- return Ct((Cs((1-P(pattern))^1)+1)^0)
- end
+ if action then
+ return Ct((((1-P(pattern))^1)/action+1)^0)
+ else
+ return Ct((Cs((1-P(pattern))^1)+1)^0)
+ end
end
local splitters_s,splitters_m,splitters_t={},{},{}
local function splitat(separator,single)
- local splitter=(single and splitters_s[separator]) or splitters_m[separator]
- if not splitter then
- separator=P(separator)
- local other=C((1-separator)^0)
- if single then
- local any=anything
- splitter=other*(separator*C(any^0)+"")
- splitters_s[separator]=splitter
- else
- splitter=other*(separator*other)^0
- splitters_m[separator]=splitter
- end
+ local splitter=(single and splitters_s[separator]) or splitters_m[separator]
+ if not splitter then
+ separator=P(separator)
+ local other=C((1-separator)^0)
+ if single then
+ local any=anything
+ splitter=other*(separator*C(any^0)+"")
+ splitters_s[separator]=splitter
+ else
+ splitter=other*(separator*other)^0
+ splitters_m[separator]=splitter
end
- return splitter
+ end
+ return splitter
end
local function tsplitat(separator)
- local splitter=splitters_t[separator]
- if not splitter then
- splitter=Ct(splitat(separator))
- splitters_t[separator]=splitter
- end
- return splitter
+ local splitter=splitters_t[separator]
+ if not splitter then
+ splitter=Ct(splitat(separator))
+ splitters_t[separator]=splitter
+ end
+ return splitter
end
lpeg.splitat=splitat
lpeg.tsplitat=tsplitat
function string.splitup(str,separator)
- if not separator then
- separator=","
- end
- return lpegmatch(splitters_m[separator] or splitat(separator),str)
+ if not separator then
+ separator=","
+ end
+ return lpegmatch(splitters_m[separator] or splitat(separator),str)
end
local cache={}
function lpeg.split(separator,str)
+ local c=cache[separator]
+ if not c then
+ c=tsplitat(separator)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+function string.split(str,separator)
+ if separator then
local c=cache[separator]
if not c then
- c=tsplitat(separator)
- cache[separator]=c
+ c=tsplitat(separator)
+ cache[separator]=c
end
return lpegmatch(c,str)
-end
-function string.split(str,separator)
- if separator then
- local c=cache[separator]
- if not c then
- c=tsplitat(separator)
- cache[separator]=c
- end
- return lpegmatch(c,str)
- else
- return { str }
- end
+ else
+ return { str }
+ end
end
local spacing=patterns.spacer^0*newline
local empty=spacing*Cc("")
@@ -1294,463 +1294,463 @@ patterns.textline=content
local linesplitter=tsplitat(newline)
patterns.linesplitter=linesplitter
function string.splitlines(str)
- return lpegmatch(linesplitter,str)
+ return lpegmatch(linesplitter,str)
end
local cache={}
function lpeg.checkedsplit(separator,str)
- local c=cache[separator]
- if not c then
- separator=P(separator)
- local other=C((1-separator)^1)
- c=Ct(separator^0*other*(separator^1*other)^0)
- cache[separator]=c
- end
- return lpegmatch(c,str)
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
end
function string.checkedsplit(str,separator)
- local c=cache[separator]
- if not c then
- separator=P(separator)
- local other=C((1-separator)^1)
- c=Ct(separator^0*other*(separator^1*other)^0)
- cache[separator]=c
- end
- return lpegmatch(c,str)
-end
-local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
-local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
+local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
local function f4(s) local c1,c2,c3,c4=byte(s,1,4) return ((c1*64+c2)*64+c3)*64+c4-63447168 end
local utf8byte=patterns.utf8one/byte+patterns.utf8two/f2+patterns.utf8three/f3+patterns.utf8four/f4
patterns.utf8byte=utf8byte
local cache={}
function lpeg.stripper(str)
- if type(str)=="string" then
- local s=cache[str]
- if not s then
- s=Cs(((S(str)^1)/""+1)^0)
- cache[str]=s
- end
- return s
- else
- return Cs(((str^1)/""+1)^0)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs(((S(str)^1)/""+1)^0)
+ cache[str]=s
end
+ return s
+ else
+ return Cs(((str^1)/""+1)^0)
+ end
end
local cache={}
function lpeg.keeper(str)
- if type(str)=="string" then
- local s=cache[str]
- if not s then
- s=Cs((((1-S(str))^1)/""+1)^0)
- cache[str]=s
- end
- return s
- else
- return Cs((((1-str)^1)/""+1)^0)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs((((1-S(str))^1)/""+1)^0)
+ cache[str]=s
end
+ return s
+ else
+ return Cs((((1-str)^1)/""+1)^0)
+ end
end
function lpeg.frontstripper(str)
- return (P(str)+P(true))*Cs(anything^0)
+ return (P(str)+P(true))*Cs(anything^0)
end
function lpeg.endstripper(str)
- return Cs((1-P(str)*endofstring)^0)
+ return Cs((1-P(str)*endofstring)^0)
end
function lpeg.replacer(one,two,makefunction,isutf)
- local pattern
- local u=isutf and utf8char or 1
- if type(one)=="table" then
- local no=#one
- local p=P(false)
- if no==0 then
- for k,v in next,one do
- p=p+P(k)/v
- end
- pattern=Cs((p+u)^0)
- elseif no==1 then
- local o=one[1]
- one,two=P(o[1]),o[2]
- pattern=Cs((one/two+u)^0)
- else
- for i=1,no do
- local o=one[i]
- p=p+P(o[1])/o[2]
- end
- pattern=Cs((p+u)^0)
- end
- else
- pattern=Cs((P(one)/(two or "")+u)^0)
+ local pattern
+ local u=isutf and utf8char or 1
+ if type(one)=="table" then
+ local no=#one
+ local p=P(false)
+ if no==0 then
+ for k,v in next,one do
+ p=p+P(k)/v
+ end
+ pattern=Cs((p+u)^0)
+ elseif no==1 then
+ local o=one[1]
+ one,two=P(o[1]),o[2]
+ pattern=Cs((one/two+u)^0)
+ else
+ for i=1,no do
+ local o=one[i]
+ p=p+P(o[1])/o[2]
+ end
+ pattern=Cs((p+u)^0)
end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ else
+ pattern=Cs((P(one)/(two or "")+u)^0)
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
end
+ else
+ return pattern
+ end
end
function lpeg.finder(lst,makefunction,isutf)
- local pattern
- if type(lst)=="table" then
- pattern=P(false)
- if #lst==0 then
- for k,v in next,lst do
- pattern=pattern+P(k)
- end
- else
- for i=1,#lst do
- pattern=pattern+P(lst[i])
- end
- end
- else
- pattern=P(lst)
- end
- if isutf then
- pattern=((utf8char or 1)-pattern)^0*pattern
+ local pattern
+ if type(lst)=="table" then
+ pattern=P(false)
+ if #lst==0 then
+ for k,v in next,lst do
+ pattern=pattern+P(k)
+ end
else
- pattern=(1-pattern)^0*pattern
+ for i=1,#lst do
+ pattern=pattern+P(lst[i])
+ end
end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ else
+ pattern=P(lst)
+ end
+ if isutf then
+ pattern=((utf8char or 1)-pattern)^0*pattern
+ else
+ pattern=(1-pattern)^0*pattern
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
end
+ else
+ return pattern
+ end
end
local splitters_f,splitters_s={},{}
function lpeg.firstofsplit(separator)
- local splitter=splitters_f[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)
- splitters_f[separator]=splitter
- end
- return splitter
+ local splitter=splitters_f[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)
+ splitters_f[separator]=splitter
+ end
+ return splitter
end
function lpeg.secondofsplit(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=(1-pattern)^0*pattern*C(anything^0)
- splitters_s[separator]=splitter
- end
- return splitter
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=(1-pattern)^0*pattern*C(anything^0)
+ splitters_s[separator]=splitter
+ end
+ return splitter
end
local splitters_s,splitters_p={},{}
function lpeg.beforesuffix(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)*pattern*endofstring
- splitters_s[separator]=splitter
- end
- return splitter
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)*pattern*endofstring
+ splitters_s[separator]=splitter
+ end
+ return splitter
end
function lpeg.afterprefix(separator)
- local splitter=splitters_p[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=pattern*C(anything^0)
- splitters_p[separator]=splitter
- end
- return splitter
+ local splitter=splitters_p[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=pattern*C(anything^0)
+ splitters_p[separator]=splitter
+ end
+ return splitter
end
function lpeg.balancer(left,right)
- left,right=P(left),P(right)
- return P { left*((1-left-right)+V(1))^0*right }
+ left,right=P(left),P(right)
+ return P { left*((1-left-right)+V(1))^0*right }
end
function lpeg.counter(pattern,action)
- local n=0
- local pattern=(P(pattern)/function() n=n+1 end+anything)^0
- if action then
- return function(str) n=0;lpegmatch(pattern,str);action(n) end
- else
- return function(str) n=0;lpegmatch(pattern,str);return n end
- end
+ local n=0
+ local pattern=(P(pattern)/function() n=n+1 end+anything)^0
+ if action then
+ return function(str) n=0;lpegmatch(pattern,str);action(n) end
+ else
+ return function(str) n=0;lpegmatch(pattern,str);return n end
+ end
end
function lpeg.is_lpeg(p)
- return p and lpegtype(p)=="pattern"
+ return p and lpegtype(p)=="pattern"
end
function lpeg.oneof(list,...)
- if type(list)~="table" then
- list={ list,... }
- end
- local p=P(list[1])
- for l=2,#list do
- p=p+P(list[l])
- end
- return p
+ if type(list)~="table" then
+ list={ list,... }
+ end
+ local p=P(list[1])
+ for l=2,#list do
+ p=p+P(list[l])
+ end
+ return p
end
local sort=table.sort
local function copyindexed(old)
- local new={}
- for i=1,#old do
- new[i]=old
- end
- return new
+ local new={}
+ for i=1,#old do
+ new[i]=old
+ end
+ return new
end
local function sortedkeys(tab)
- local keys,s={},0
- for key,_ in next,tab do
- s=s+1
- keys[s]=key
- end
- sort(keys)
- return keys
+ local keys,s={},0
+ for key,_ in next,tab do
+ s=s+1
+ keys[s]=key
+ end
+ sort(keys)
+ return keys
end
function lpeg.append(list,pp,delayed,checked)
- local p=pp
- if #list>0 then
- local keys=copyindexed(list)
- sort(keys)
- for i=#keys,1,-1 do
- local k=keys[i]
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- elseif delayed then
- local keys=sortedkeys(list)
+ local p=pp
+ if #list>0 then
+ local keys=copyindexed(list)
+ sort(keys)
+ for i=#keys,1,-1 do
+ local k=keys[i]
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
+ end
+ elseif delayed then
+ local keys=sortedkeys(list)
+ if p then
+ for i=1,#keys,1 do
+ local k=keys[i]
+ local v=list[k]
+ p=P(k)/list+p
+ end
+ else
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
if p then
- for i=1,#keys,1 do
- local k=keys[i]
- local v=list[k]
- p=P(k)/list+p
- end
+ p=P(k)+p
else
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- if p then
- p=p/list
- end
+ p=P(k)
end
- elseif checked then
- local keys=sortedkeys(list)
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- if k==v then
- p=P(k)+p
- else
- p=P(k)/v+p
- end
- else
- if k==v then
- p=P(k)
- else
- p=P(k)/v
- end
- end
+ end
+ if p then
+ p=p/list
+ end
+ end
+ elseif checked then
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ if k==v then
+ p=P(k)+p
+ else
+ p=P(k)/v+p
end
- else
- local keys=sortedkeys(list)
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- p=P(k)/v+p
- else
- p=P(k)/v
- end
+ else
+ if k==v then
+ p=P(k)
+ else
+ p=P(k)/v
end
+ end
end
- return p
+ else
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ p=P(k)/v+p
+ else
+ p=P(k)/v
+ end
+ end
+ end
+ return p
end
local p_false=P(false)
local p_true=P(true)
local lower=utf and utf.lower or string.lower
local upper=utf and utf.upper or string.upper
function lpeg.setutfcasers(l,u)
- lower=l or lower
- upper=u or upper
+ lower=l or lower
+ upper=u or upper
end
local function make1(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
- local k=keys[i]
- if k~="" then
- local v=t[k]
- if v==true then
- p=p+P(k)*p_true
- elseif v==false then
- else
- p=p+P(k)*make1(v,v[""])
- end
- end
- end
- if rest then
- p=p+p_true
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+P(k)*p_true
+ elseif v==false then
+ else
+ p=p+P(k)*make1(v,v[""])
+ end
end
- return p
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
end
local function make2(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
- local k=keys[i]
- if k~="" then
- local v=t[k]
- if v==true then
- p=p+(P(lower(k))+P(upper(k)))*p_true
- elseif v==false then
- else
- p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
- end
- end
- end
- if rest then
- p=p+p_true
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+(P(lower(k))+P(upper(k)))*p_true
+ elseif v==false then
+ else
+ p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
+ end
end
- return p
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
end
local function utfchartabletopattern(list,insensitive)
- local tree={}
- local n=#list
- if n==0 then
- for s in next,list do
- local t=tree
- local p,pk
- for c in gmatch(s,".") do
- if t==true then
- t={ [c]=true,[""]=true }
- p[pk]=t
- p=t
- t=false
- elseif t==false then
- t={ [c]=false }
- p[pk]=t
- p=t
- t=false
- else
- local tc=t[c]
- if not tc then
- tc=false
- t[c]=false
- end
- p=t
- t=tc
- end
- pk=c
- end
- if t==false then
- p[pk]=true
- elseif t==true then
- else
- t[""]=true
- end
+ local tree={}
+ local n=#list
+ if n==0 then
+ for s in next,list do
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
end
- else
- for i=1,n do
- local s=list[i]
- local t=tree
- local p,pk
- for c in gmatch(s,".") do
- if t==true then
- t={ [c]=true,[""]=true }
- p[pk]=t
- p=t
- t=false
- elseif t==false then
- t={ [c]=false }
- p[pk]=t
- p=t
- t=false
- else
- local tc=t[c]
- if not tc then
- tc=false
- t[c]=false
- end
- p=t
- t=tc
- end
- pk=c
- end
- if t==false then
- p[pk]=true
- elseif t==true then
- else
- t[""]=true
- end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
+ end
+ else
+ for i=1,n do
+ local s=list[i]
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
end
- return (insensitive and make2 or make1)(tree)
+ end
+ return (insensitive and make2 or make1)(tree)
end
lpeg.utfchartabletopattern=utfchartabletopattern
function lpeg.utfreplacer(list,insensitive)
- local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
- return function(str)
- return lpegmatch(pattern,str) or str
- end
+ local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
+ return function(str)
+ return lpegmatch(pattern,str) or str
+ end
end
patterns.containseol=lpeg.finder(eol)
local function nextstep(n,step,result)
- local m=n%step
- local d=floor(n/step)
- if d>0 then
- local v=V(tostring(step))
- local s=result.start
- for i=1,d do
- if s then
- s=v*s
- else
- s=v
- end
- end
- result.start=s
- end
- if step>1 and result.start then
- local v=V(tostring(step/2))
- result[tostring(step)]=v*v
- end
- if step>0 then
- return nextstep(m,step/2,result)
- else
- return result
+ local m=n%step
+ local d=floor(n/step)
+ if d>0 then
+ local v=V(tostring(step))
+ local s=result.start
+ for i=1,d do
+ if s then
+ s=v*s
+ else
+ s=v
+ end
end
+ result.start=s
+ end
+ if step>1 and result.start then
+ local v=V(tostring(step/2))
+ result[tostring(step)]=v*v
+ end
+ if step>0 then
+ return nextstep(m,step/2,result)
+ else
+ return result
+ end
end
function lpeg.times(pattern,n)
- return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
+ return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
end
do
- local trailingzeros=zero^0*-digit
- local stripper=Cs((
- digits*(
- period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
- )+1
- )^0)
- lpeg.patterns.stripzeros=stripper
- local nonzero=digit-zero
- local trailingzeros=zero^1*endofstring
- local stripper=Cs((1-period)^0*(
- period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
- ))
- lpeg.patterns.stripzero=stripper
+ local trailingzeros=zero^0*-digit
+ local stripper=Cs((
+ digits*(
+ period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
+ )+1
+ )^0)
+ lpeg.patterns.stripzeros=stripper
+ local nonzero=digit-zero
+ local trailingzeros=zero^1*endofstring
+ local stripper=Cs((1-period)^0*(
+ period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
+ ))
+ lpeg.patterns.stripzero=stripper
end
local byte_to_HEX={}
local byte_to_hex={}
local byte_to_dec={}
local hex_to_byte={}
for i=0,255 do
- local H=format("%02X",i)
- local h=format("%02x",i)
- local d=format("%03i",i)
- local c=char(i)
- byte_to_HEX[c]=H
- byte_to_hex[c]=h
- byte_to_dec[c]=d
- hex_to_byte[h]=c
- hex_to_byte[H]=c
+ local H=format("%02X",i)
+ local h=format("%02x",i)
+ local d=format("%03i",i)
+ local c=char(i)
+ byte_to_HEX[c]=H
+ byte_to_hex[c]=h
+ byte_to_dec[c]=d
+ hex_to_byte[h]=c
+ hex_to_byte[H]=c
end
local hextobyte=P(2)/hex_to_byte
local bytetoHEX=P(1)/byte_to_HEX
@@ -1769,47 +1769,47 @@ patterns.bytestoHEX=bytestoHEX
patterns.bytestohex=bytestohex
patterns.bytestodec=bytestodec
function string.toHEX(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestoHEX,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestoHEX,s)
+ end
end
function string.tohex(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestohex,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestohex,s)
+ end
end
function string.todec(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestodec,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestodec,s)
+ end
end
function string.tobytes(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(hextobytes,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(hextobytes,s)
+ end
end
local patterns={}
local function containsws(what)
- local p=patterns[what]
- if not p then
- local p1=P(what)*(whitespace+endofstring)*Cc(true)
- local p2=whitespace*P(p1)
- p=P(p1)+P(1-p2)^0*p2+Cc(false)
- patterns[what]=p
- end
- return p
+ local p=patterns[what]
+ if not p then
+ local p1=P(what)*(whitespace+endofstring)*Cc(true)
+ local p2=whitespace*P(p1)
+ p=P(p1)+P(1-p2)^0*p2+Cc(false)
+ patterns[what]=p
+ end
+ return p
end
lpeg.containsws=containsws
function string.containsws(str,what)
- return lpegmatch(patterns[what] or containsws(what),str)
+ return lpegmatch(patterns[what] or containsws(what),str)
end
@@ -1819,14 +1819,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-function"] = package.loaded["l-function"] or true
--- original size: 361, stripped down to: 322
+-- original size: 361, stripped down to: 317
if not modules then modules={} end modules ['l-functions']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
functions=functions or {}
function functions.dummy() end
@@ -1838,14 +1838,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-string"] = package.loaded["l-string"] or true
--- original size: 6461, stripped down to: 3341
+-- original size: 6461, stripped down to: 3255
if not modules then modules={} end modules ['l-string']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local string=string
local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower
@@ -1853,25 +1853,25 @@ local lpegmatch,patterns=lpeg.match,lpeg.patterns
local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs
local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote
function string.unquoted(str)
- return lpegmatch(unquoted,str) or str
+ return lpegmatch(unquoted,str) or str
end
function string.quoted(str)
- return format("%q",str)
+ return format("%q",str)
end
function string.count(str,pattern)
- local n=0
- for _ in gmatch(str,pattern) do
- n=n+1
- end
- return n
+ local n=0
+ for _ in gmatch(str,pattern) do
+ n=n+1
+ end
+ return n
end
function string.limit(str,n,sentinel)
- if #str>n then
- sentinel=sentinel or "..."
- return sub(str,1,(n-#sentinel))..sentinel
- else
- return str
- end
+ if #str>n then
+ sentinel=sentinel or "..."
+ return sub(str,1,(n-#sentinel))..sentinel
+ else
+ return str
+ end
end
local stripper=patterns.stripper
local fullstripper=patterns.fullstripper
@@ -1879,81 +1879,81 @@ local collapser=patterns.collapser
local nospacer=patterns.nospacer
local longtostring=patterns.longtostring
function string.strip(str)
- return str and lpegmatch(stripper,str) or ""
+ return str and lpegmatch(stripper,str) or ""
end
function string.fullstrip(str)
- return str and lpegmatch(fullstripper,str) or ""
+ return str and lpegmatch(fullstripper,str) or ""
end
function string.collapsespaces(str)
- return str and lpegmatch(collapser,str) or ""
+ return str and lpegmatch(collapser,str) or ""
end
function string.nospaces(str)
- return str and lpegmatch(nospacer,str) or ""
+ return str and lpegmatch(nospacer,str) or ""
end
function string.longtostring(str)
- return str and lpegmatch(longtostring,str) or ""
+ return str and lpegmatch(longtostring,str) or ""
end
local pattern=P(" ")^0*P(-1)
function string.is_empty(str)
- if not str or str=="" then
- return true
- else
- return lpegmatch(pattern,str) and true or false
- end
+ if not str or str=="" then
+ return true
+ else
+ return lpegmatch(pattern,str) and true or false
+ end
end
local anything=patterns.anything
local allescapes=Cc("%")*S(".-+%?()[]*")
-local someescapes=Cc("%")*S(".-+%()[]")
-local matchescapes=Cc(".")*S("*?")
+local someescapes=Cc("%")*S(".-+%()[]")
+local matchescapes=Cc(".")*S("*?")
local pattern_a=Cs ((allescapes+anything )^0 )
local pattern_b=Cs ((someescapes+matchescapes+anything )^0 )
local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") )
function string.escapedpattern(str,simple)
- return lpegmatch(simple and pattern_b or pattern_a,str)
+ return lpegmatch(simple and pattern_b or pattern_a,str)
end
function string.topattern(str,lowercase,strict)
- if str=="" or type(str)~="string" then
- return ".*"
- elseif strict then
- str=lpegmatch(pattern_c,str)
- else
- str=lpegmatch(pattern_b,str)
- end
- if lowercase then
- return lower(str)
- else
- return str
- end
+ if str=="" or type(str)~="string" then
+ return ".*"
+ elseif strict then
+ str=lpegmatch(pattern_c,str)
+ else
+ str=lpegmatch(pattern_b,str)
+ end
+ if lowercase then
+ return lower(str)
+ else
+ return str
+ end
end
function string.valid(str,default)
- return (type(str)=="string" and str~="" and str) or default or nil
+ return (type(str)=="string" and str~="" and str) or default or nil
end
string.itself=function(s) return s end
local pattern_c=Ct(C(1)^0)
local pattern_b=Ct((C(1)/byte)^0)
function string.totable(str,bytes)
- return lpegmatch(bytes and pattern_b or pattern_c,str)
+ return lpegmatch(bytes and pattern_b or pattern_c,str)
end
local replacer=lpeg.replacer("@","%%")
function string.tformat(fmt,...)
- return format(lpegmatch(replacer,fmt),...)
+ return format(lpegmatch(replacer,fmt),...)
end
string.quote=string.quoted
string.unquote=string.unquoted
if not string.bytetable then
- local limit=5000
- function string.bytetable(str)
- local n=#str
- if n>limit then
- local t={ byte(str,1,limit) }
- for i=limit+1,n do
- t[i]=byte(str,i)
- end
- return t
- else
- return { byte(str,1,n) }
- end
+ local limit=5000
+ function string.bytetable(str)
+ local n=#str
+ if n>limit then
+ local t={ byte(str,1,limit) }
+ for i=limit+1,n do
+ t[i]=byte(str,i)
+ end
+ return t
+ else
+ return { byte(str,1,n) }
end
+ end
end
@@ -1963,14 +1963,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 40960, stripped down to: 24090
+-- original size: 40960, stripped down to: 21348
if not modules then modules={} end modules ['l-table']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber,select=type,next,tostring,tonumber,select
local table,string=table,string
@@ -1981,147 +1981,147 @@ local lpegmatch,patterns=lpeg.match,lpeg.patterns
local floor=math.floor
local stripper=patterns.stripper
function table.getn(t)
- return t and #t
+ return t and #t
end
function table.strip(tab)
- local lst,l={},0
- for i=1,#tab do
- local s=lpegmatch(stripper,tab[i]) or ""
- if s=="" then
- else
- l=l+1
- lst[l]=s
- end
+ local lst,l={},0
+ for i=1,#tab do
+ local s=lpegmatch(stripper,tab[i]) or ""
+ if s=="" then
+ else
+ l=l+1
+ lst[l]=s
end
- return lst
+ end
+ return lst
end
function table.keys(t)
- if t then
- local keys,k={},0
- for key in next,t do
- k=k+1
- keys[k]=key
- end
- return keys
- else
- return {}
+ if t then
+ local keys,k={},0
+ for key in next,t do
+ k=k+1
+ keys[k]=key
end
+ return keys
+ else
+ return {}
+ end
end
local function compare(a,b)
- local ta=type(a)
- if ta=="number" then
- local tb=type(b)
- if ta==tb then
- return a<b
- elseif tb=="string" then
- return tostring(a)<b
- end
- elseif ta=="string" then
- local tb=type(b)
- if ta==tb then
- return a<b
- else
- return a<tostring(b)
- end
+ local ta=type(a)
+ if ta=="number" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ elseif tb=="string" then
+ return tostring(a)<b
+ end
+ elseif ta=="string" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ else
+ return a<tostring(b)
end
- return tostring(a)<tostring(b)
+ end
+ return tostring(a)<tostring(b)
end
local function sortedkeys(tab)
- if tab then
- local srt,category,s={},0,0
- for key in next,tab do
- s=s+1
- srt[s]=key
- if category==3 then
- elseif category==1 then
- if type(key)~="string" then
- category=3
- end
- elseif category==2 then
- if type(key)~="number" then
- category=3
- end
- else
- local tkey=type(key)
- if tkey=="string" then
- category=1
- elseif tkey=="number" then
- category=2
- else
- category=3
- end
- end
- end
- if s<2 then
- elseif category==3 then
- sort(srt,compare)
+ if tab then
+ local srt,category,s={},0,0
+ for key in next,tab do
+ s=s+1
+ srt[s]=key
+ if category==3 then
+ elseif category==1 then
+ if type(key)~="string" then
+ category=3
+ end
+ elseif category==2 then
+ if type(key)~="number" then
+ category=3
+ end
+ else
+ local tkey=type(key)
+ if tkey=="string" then
+ category=1
+ elseif tkey=="number" then
+ category=2
else
- sort(srt)
+ category=3
end
- return srt
+ end
+ end
+ if s<2 then
+ elseif category==3 then
+ sort(srt,compare)
else
- return {}
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="string" then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if type(key)=="string" then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedindexonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="number" then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if type(key)=="number" then
+ s=s+1
+ srt[s]=key
+ end
end
+ if s>1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashkeys(tab,cmp)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if key then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt,cmp)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if key then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt,cmp)
end
+ return srt
+ else
+ return {}
+ end
end
function table.allkeys(t)
- local keys={}
- for k,v in next,t do
- for k in next,v do
- keys[k]=true
- end
+ local keys={}
+ for k,v in next,t do
+ for k in next,v do
+ keys[k]=true
end
- return sortedkeys(keys)
+ end
+ return sortedkeys(keys)
end
table.sortedkeys=sortedkeys
table.sortedhashonly=sortedhashonly
@@ -2129,927 +2129,927 @@ table.sortedindexonly=sortedindexonly
table.sortedhashkeys=sortedhashkeys
local function nothing() end
local function sortedhash(t,cmp)
- if t then
- local s
- if cmp then
- s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
- else
- s=sortedkeys(t)
- end
- local m=#s
- if m==1 then
- return next,t
- elseif m>0 then
- local n=0
- return function()
- if n<m then
- n=n+1
- local k=s[n]
- return k,t[k]
- end
- end
+ if t then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local m=#s
+ if m==1 then
+ return next,t
+ elseif m>0 then
+ local n=0
+ return function()
+ if n<m then
+ n=n+1
+ local k=s[n]
+ return k,t[k]
end
+ end
end
- return nothing
+ end
+ return nothing
end
table.sortedhash=sortedhash
table.sortedpairs=sortedhash
function table.append(t,list)
- local n=#t
- for i=1,#list do
- n=n+1
- t[n]=list[i]
- end
- return t
+ local n=#t
+ for i=1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ return t
end
function table.prepend(t,list)
- local nl=#list
- local nt=nl+#t
- for i=#t,1,-1 do
- t[nt]=t[i]
- nt=nt-1
- end
- for i=1,#list do
- t[i]=list[i]
- end
- return t
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+ t[nt]=t[i]
+ nt=nt-1
+ end
+ for i=1,#list do
+ t[i]=list[i]
+ end
+ return t
end
function table.merge(t,...)
- t=t or {}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ t=t or {}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.merged(...)
- local t={}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ local t={}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.imerge(t,...)
- local nt=#t
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- nt=nt+1
- t[nt]=nst[j]
- end
+ local nt=#t
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ nt=nt+1
+ t[nt]=nst[j]
end
- return t
+ end
+ return t
end
function table.imerged(...)
- local tmp,ntmp={},0
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- ntmp=ntmp+1
- tmp[ntmp]=nst[j]
- end
+ local tmp,ntmp={},0
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ ntmp=ntmp+1
+ tmp[ntmp]=nst[j]
end
- return tmp
+ end
+ return tmp
end
local function fastcopy(old,metatabletoo)
- if old then
- local new={}
- for k,v in next,old do
- if type(v)=="table" then
- new[k]=fastcopy(v,metatabletoo)
- else
- new[k]=v
- end
- end
- if metatabletoo then
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ if type(v)=="table" then
+ new[k]=fastcopy(v,metatabletoo)
+ else
+ new[k]=v
+ end
end
+ if metatabletoo then
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ end
+ return new
+ else
+ return {}
+ end
end
local function copy(t,tables)
- tables=tables or {}
- local tcopy={}
- if not tables[t] then
- tables[t]=tcopy
- end
- for i,v in next,t do
- if type(i)=="table" then
- if tables[i] then
- i=tables[i]
- else
- i=copy(i,tables)
- end
- end
- if type(v)~="table" then
- tcopy[i]=v
- elseif tables[v] then
- tcopy[i]=tables[v]
- else
- tcopy[i]=copy(v,tables)
- end
+ tables=tables or {}
+ local tcopy={}
+ if not tables[t] then
+ tables[t]=tcopy
+ end
+ for i,v in next,t do
+ if type(i)=="table" then
+ if tables[i] then
+ i=tables[i]
+ else
+ i=copy(i,tables)
+ end
end
- local mt=getmetatable(t)
- if mt then
- setmetatable(tcopy,mt)
+ if type(v)~="table" then
+ tcopy[i]=v
+ elseif tables[v] then
+ tcopy[i]=tables[v]
+ else
+ tcopy[i]=copy(v,tables)
end
- return tcopy
+ end
+ local mt=getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
end
table.fastcopy=fastcopy
table.copy=copy
function table.derive(parent)
- local child={}
- if parent then
- setmetatable(child,{ __index=parent })
- end
- return child
+ local child={}
+ if parent then
+ setmetatable(child,{ __index=parent })
+ end
+ return child
end
function table.tohash(t,value)
- local h={}
- if t then
- if value==nil then value=true end
- for _,v in next,t do
- h[v]=value
- end
+ local h={}
+ if t then
+ if value==nil then value=true end
+ for _,v in next,t do
+ h[v]=value
end
- return h
+ end
+ return h
end
function table.fromhash(t)
- local hsh,h={},0
- for k,v in next,t do
- if v then
- h=h+1
- hsh[h]=k
- end
+ local hsh,h={},0
+ for k,v in next,t do
+ if v then
+ h=h+1
+ hsh[h]=k
end
- return hsh
+ end
+ return hsh
end
local noquotes,hexify,handle,compact,inline,functions,metacheck
local reserved=table.tohash {
- 'and','break','do','else','elseif','end','false','for','function','if',
- 'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
}
local function is_simple_table(t,hexify)
- local nt=#t
- if nt>0 then
- local n=0
- for _,v in next,t do
- n=n+1
- if type(v)=="table" then
- return nil
- end
+ local nt=#t
+ if nt>0 then
+ local n=0
+ for _,v in next,t do
+ n=n+1
+ if type(v)=="table" then
+ return nil
+ end
+ end
+ local haszero=rawget(t,0)
+ if n==nt then
+ local tt={}
+ for i=1,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i]=format("0x%X",v)
+ else
+ tt[i]=v
+ end
+ elseif tv=="string" then
+ tt[i]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i]=v and "true" or "false"
+ else
+ return nil
end
- local haszero=rawget(t,0)
- if n==nt then
- local tt={}
- for i=1,nt do
- local v=t[i]
- local tv=type(v)
- if tv=="number" then
- if hexify then
- tt[i]=format("0x%X",v)
- else
- tt[i]=v
- end
- elseif tv=="string" then
- tt[i]=format("%q",v)
- elseif tv=="boolean" then
- tt[i]=v and "true" or "false"
- else
- return nil
- end
- end
- return tt
- elseif haszero and (n==nt+1) then
- local tt={}
- for i=0,nt do
- local v=t[i]
- local tv=type(v)
- if tv=="number" then
- if hexify then
- tt[i+1]=format("0x%X",v)
- else
- tt[i+1]=v
- end
- elseif tv=="string" then
- tt[i+1]=format("%q",v)
- elseif tv=="boolean" then
- tt[i+1]=v and "true" or "false"
- else
- return nil
- end
- end
- tt[1]="[0] = "..tt[1]
- return tt
+ end
+ return tt
+ elseif haszero and (n==nt+1) then
+ local tt={}
+ for i=0,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i+1]=format("0x%X",v)
+ else
+ tt[i+1]=v
+ end
+ elseif tv=="string" then
+ tt[i+1]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i+1]=v and "true" or "false"
+ else
+ return nil
end
+ end
+ tt[1]="[0] = "..tt[1]
+ return tt
end
- return nil
+ end
+ return nil
end
table.is_simple_table=is_simple_table
local propername=patterns.propername
local function dummy() end
local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- depth=depth.." "
- if indexed then
- handle(format("%s{",depth))
+ if level>0 then
+ depth=depth.." "
+ if indexed then
+ handle(format("%s{",depth))
+ else
+ local tn=type(name)
+ if tn=="number" then
+ if hexify then
+ handle(format("%s[0x%X]={",depth,name))
else
- local tn=type(name)
- if tn=="number" then
- if hexify then
- handle(format("%s[0x%X]={",depth,name))
- else
- handle(format("%s[%s]={",depth,name))
- end
- elseif tn=="string" then
- if noquotes and not reserved[name] and lpegmatch(propername,name) then
- handle(format("%s%s={",depth,name))
- else
- handle(format("%s[%q]={",depth,name))
- end
- elseif tn=="boolean" then
- handle(format("%s[%s]={",depth,name and "true" or "false"))
- else
- handle(format("%s{",depth))
- end
+ handle(format("%s[%s]={",depth,name))
end
+ elseif tn=="string" then
+ if noquotes and not reserved[name] and lpegmatch(propername,name) then
+ handle(format("%s%s={",depth,name))
+ else
+ handle(format("%s[%q]={",depth,name))
+ end
+ elseif tn=="boolean" then
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
+ else
+ handle(format("%s{",depth))
+ end
end
- if root and next(root)~=nil then
- local first,last=nil,0
- if compact then
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
- end
- if last>0 then
- first=1
- end
+ end
+ if root and next(root)~=nil then
+ local first,last=nil,0
+ if compact then
+ last=#root
+ for k=1,last do
+ if rawget(root,k)==nil then
+ last=k-1
+ break
end
- local sk=sortedkeys(root)
- for i=1,#sk do
- local k=sk[i]
- local v=root[k]
- local tv=type(v)
- local tk=type(k)
- if compact and first and tk=="number" and k>=first and k<=last then
- if tv=="number" then
- if hexify then
- handle(format("%s 0x%X,",depth,v))
- else
- handle(format("%s %s,",depth,v))
- end
- elseif tv=="string" then
- handle(format("%s %q,",depth,v))
- elseif tv=="table" then
- if next(v)==nil then
- handle(format("%s {},",depth))
- elseif inline then
- local st=is_simple_table(v,hexify)
- if st then
- handle(format("%s { %s },",depth,concat(st,", ")))
- else
- do_serialize(v,k,depth,level+1,true)
- end
- else
- do_serialize(v,k,depth,level+1,true)
- end
- elseif tv=="boolean" then
- handle(format("%s %s,",depth,v and "true" or "false"))
- elseif tv=="function" then
- if functions then
- handle(format('%s load(%q),',depth,dump(v)))
- else
- handle(format('%s "function",',depth))
- end
- else
- handle(format("%s %q,",depth,tostring(v)))
- end
- elseif k=="__p__" then
- if false then
- handle(format("%s __p__=nil,",depth))
- end
- elseif tv=="number" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=0x%X,",depth,k,v))
- else
- handle(format("%s [%s]=%s,",depth,k,v))
- end
- elseif tk=="boolean" then
- if hexify then
- handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
- else
- handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
- end
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- if hexify then
- handle(format("%s %s=0x%X,",depth,k,v))
- else
- handle(format("%s %s=%s,",depth,k,v))
- end
- else
- if hexify then
- handle(format("%s [%q]=0x%X,",depth,k,v))
- else
- handle(format("%s [%q]=%s,",depth,k,v))
- end
- end
- elseif tv=="string" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%q,",depth,k,v))
- else
- handle(format("%s [%s]=%q,",depth,k,v))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%q,",depth,k,v))
- else
- handle(format("%s [%q]=%q,",depth,k,v))
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]={},",depth,k))
- else
- handle(format("%s [%s]={},",depth,k))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]={},",depth,k and "true" or "false"))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s={},",depth,k))
- else
- handle(format("%s [%q]={},",depth,k))
- end
- elseif inline then
- local st=is_simple_table(v,hexify)
- if st then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
- else
- handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
- else
- handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
- end
- else
- do_serialize(v,k,depth,level+1)
- end
- else
- do_serialize(v,k,depth,level+1)
- end
- elseif tv=="boolean" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
- else
- handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
- else
- handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
- end
- elseif tv=="function" then
- if functions then
- local getinfo=debug and debug.getinfo
- if getinfo then
- local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=load(%q),",depth,k,f))
- else
- handle(format("%s [%s]=load(%q),",depth,k,f))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=load(%q),",depth,k,f))
- else
- handle(format("%s [%q]=load(%q),",depth,k,f))
- end
- end
- end
+ end
+ if last>0 then
+ first=1
+ end
+ end
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if compact and first and tk=="number" and k>=first and k<=last then
+ if tv=="number" then
+ if hexify then
+ handle(format("%s 0x%X,",depth,v))
+ else
+ handle(format("%s %s,",depth,v))
+ end
+ elseif tv=="string" then
+ handle(format("%s %q,",depth,v))
+ elseif tv=="table" then
+ if next(v)==nil then
+ handle(format("%s {},",depth))
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ handle(format("%s { %s },",depth,concat(st,", ")))
else
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
- else
- handle(format("%s [%s]=%q,",depth,k,tostring(v)))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%q,",depth,k,tostring(v)))
- else
- handle(format("%s [%q]=%q,",depth,k,tostring(v)))
- end
+ do_serialize(v,k,depth,level+1,true)
end
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ elseif tv=="boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv=="function" then
+ if functions then
+ handle(format('%s load(%q),',depth,dump(v)))
+ else
+ handle(format('%s "function",',depth))
+ end
+ else
+ handle(format("%s %q,",depth,tostring(v)))
end
- end
- if level>0 then
- handle(format("%s},",depth))
- end
-end
-local function serialize(_handle,root,name,specification)
- local tname=type(name)
- if type(specification)=="table" then
- noquotes=specification.noquotes
- hexify=specification.hexify
- handle=_handle or specification.handle or print
- functions=specification.functions
- compact=specification.compact
- inline=specification.inline and compact
- metacheck=specification.metacheck
- if functions==nil then
- functions=true
- end
- if compact==nil then
- compact=true
- end
- if inline==nil then
- inline=compact
- end
- if metacheck==nil then
- metacheck=true
+ elseif k=="__p__" then
+ if false then
+ handle(format("%s __p__=nil,",depth))
end
- else
- noquotes=false
- hexify=false
- handle=_handle or print
- compact=true
- inline=true
- functions=true
- metacheck=true
- end
- if tname=="string" then
- if name=="return" then
- handle("return {")
+ elseif tv=="number" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ if hexify then
+ handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ else
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
+ end
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ if hexify then
+ handle(format("%s %s=0x%X,",depth,k,v))
+ else
+ handle(format("%s %s=%s,",depth,k,v))
+ end
else
- handle(name.."={")
+ if hexify then
+ handle(format("%s [%q]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v))
+ end
end
- elseif tname=="number" then
- if hexify then
- handle(format("[0x%X]={",name))
+ elseif tv=="string" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,v))
+ else
+ handle(format("%s [%s]=%q,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,v))
else
- handle("["..name.."]={")
+ handle(format("%s [%q]=%q,",depth,k,v))
end
- elseif tname=="boolean" then
- if name then
- handle("return {")
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={},",depth,k))
+ else
+ handle(format("%s [%s]={},",depth,k))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={},",depth,k))
+ else
+ handle(format("%s [%q]={},",depth,k))
+ end
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
+ end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
else
- handle("{")
+ do_serialize(v,k,depth,level+1)
end
- else
- handle("t={")
- end
- if root then
- if metacheck and getmetatable(root) then
- local dummy=root._w_h_a_t_e_v_e_r_
- root._w_h_a_t_e_v_e_r_=nil
+ elseif tv=="boolean" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
end
- if next(root)~=nil then
- do_serialize(root,name,"",0)
+ elseif tv=="function" then
+ if functions then
+ local getinfo=debug and debug.getinfo
+ if getinfo then
+ local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%s]=load(%q),",depth,k,f))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%q]=load(%q),",depth,k,f))
+ end
+ end
+ end
+ else
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
end
+ end
end
- handle("}")
+ end
+ if level>0 then
+ handle(format("%s},",depth))
+ end
end
-function table.serialize(root,name,specification)
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
+local function serialize(_handle,root,name,specification)
+ local tname=type(name)
+ if type(specification)=="table" then
+ noquotes=specification.noquotes
+ hexify=specification.hexify
+ handle=_handle or specification.handle or print
+ functions=specification.functions
+ compact=specification.compact
+ inline=specification.inline and compact
+ metacheck=specification.metacheck
+ if functions==nil then
+ functions=true
+ end
+ if compact==nil then
+ compact=true
+ end
+ if inline==nil then
+ inline=compact
+ end
+ if metacheck==nil then
+ metacheck=true
+ end
+ else
+ noquotes=false
+ hexify=false
+ handle=_handle or print
+ compact=true
+ inline=true
+ functions=true
+ metacheck=true
+ end
+ if tname=="string" then
+ if name=="return" then
+ handle("return {")
+ else
+ handle(name.."={")
+ end
+ elseif tname=="number" then
+ if hexify then
+ handle(format("[0x%X]={",name))
+ else
+ handle("["..name.."]={")
+ end
+ elseif tname=="boolean" then
+ if name then
+ handle("return {")
+ else
+ handle("{")
+ end
+ else
+ handle("t={")
+ end
+ if root then
+ if metacheck and getmetatable(root) then
+ local dummy=root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_=nil
+ end
+ if next(root)~=nil then
+ do_serialize(root,name,"",0)
end
- serialize(flush,root,name,specification)
- return concat(t,"\n")
+ end
+ handle("}")
+end
+function table.serialize(root,name,specification)
+ local t,n={},0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ end
+ serialize(flush,root,name,specification)
+ return concat(t,"\n")
end
table.tohandle=serialize
local maxtab=2*1024
function table.tofile(filename,root,name,specification)
- local f=io.open(filename,'w')
- if f then
- if maxtab>1 then
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
- if n>maxtab then
- f:write(concat(t,"\n"),"\n")
- t,n={},0
- end
- end
- serialize(flush,root,name,specification)
- f:write(concat(t,"\n"),"\n")
- else
- local function flush(s)
- f:write(s,"\n")
- end
- serialize(flush,root,name,specification)
+ local f=io.open(filename,'w')
+ if f then
+ if maxtab>1 then
+ local t,n={},0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ if n>maxtab then
+ f:write(concat(t,"\n"),"\n")
+ t,n={},0
end
- f:close()
- io.flush()
+ end
+ serialize(flush,root,name,specification)
+ f:write(concat(t,"\n"),"\n")
+ else
+ local function flush(s)
+ f:write(s,"\n")
+ end
+ serialize(flush,root,name,specification)
end
+ f:close()
+ io.flush()
+ end
end
local function flattened(t,f,depth)
- if f==nil then
- f={}
- depth=0xFFFF
- elseif tonumber(f) then
- depth=f
- f={}
- elseif not depth then
- depth=0xFFFF
- end
- for k,v in next,t do
- if type(k)~="number" then
- if depth>0 and type(v)=="table" then
- flattened(v,f,depth-1)
- else
- f[#f+1]=v
- end
- end
+ if f==nil then
+ f={}
+ depth=0xFFFF
+ elseif tonumber(f) then
+ depth=f
+ f={}
+ elseif not depth then
+ depth=0xFFFF
+ end
+ for k,v in next,t do
+ if type(k)~="number" then
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
+ end
end
- for k=1,#t do
- local v=t[k]
- if depth>0 and type(v)=="table" then
- flattened(v,f,depth-1)
- else
- f[#f+1]=v
- end
+ end
+ for k=1,#t do
+ local v=t[k]
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
end
- return f
+ end
+ return f
end
table.flattened=flattened
local function collapsed(t,f,h)
- if f==nil then
- f={}
- h={}
- end
- for k=1,#t do
- local v=t[k]
- if type(v)=="table" then
- collapsed(v,f,h)
- elseif not h[v] then
- f[#f+1]=v
- h[v]=true
- end
+ if f==nil then
+ f={}
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsed(v,f,h)
+ elseif not h[v] then
+ f[#f+1]=v
+ h[v]=true
end
- return f
+ end
+ return f
end
local function collapsedhash(t,h)
- if h==nil then
- h={}
- end
- for k=1,#t do
- local v=t[k]
- if type(v)=="table" then
- collapsedhash(v,h)
- else
- h[v]=true
- end
+ if h==nil then
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsedhash(v,h)
+ else
+ h[v]=true
end
- return h
+ end
+ return h
end
-table.collapsed=collapsed
+table.collapsed=collapsed
table.collapsedhash=collapsedhash
local function unnest(t,f)
- if not f then
- f={}
- end
- for i=1,#t do
- local v=t[i]
- if type(v)=="table" then
- if type(v[1])=="table" then
- unnest(v,f)
- else
- f[#f+1]=v
- end
- else
- f[#f+1]=v
- end
+ if not f then
+ f={}
+ end
+ for i=1,#t do
+ local v=t[i]
+ if type(v)=="table" then
+ if type(v[1])=="table" then
+ unnest(v,f)
+ else
+ f[#f+1]=v
+ end
+ else
+ f[#f+1]=v
end
- return f
+ end
+ return f
end
function table.unnest(t)
- return unnest(t)
+ return unnest(t)
end
local function are_equal(a,b,n,m)
- if a==b then
- return true
- elseif a and b and #a==#b then
- n=n or 1
- m=m or #a
- for i=n,m do
- local ai,bi=a[i],b[i]
- if ai==bi then
- elseif type(ai)=="table" and type(bi)=="table" then
- if not are_equal(ai,bi) then
- return false
- end
- else
- return false
- end
- end
- return true
- else
+ if a==b then
+ return true
+ elseif a and b and #a==#b then
+ n=n or 1
+ m=m or #a
+ for i=n,m do
+ local ai,bi=a[i],b[i]
+ if ai==bi then
+ elseif type(ai)=="table" and type(bi)=="table" then
+ if not are_equal(ai,bi) then
+ return false
+ end
+ else
return false
+ end
end
+ return true
+ else
+ return false
+ end
end
local function identical(a,b)
- if a~=b then
- for ka,va in next,a do
- local vb=b[ka]
- if va==vb then
- elseif type(va)=="table" and type(vb)=="table" then
- if not identical(va,vb) then
- return false
- end
- else
- return false
- end
- end
+ if a~=b then
+ for ka,va in next,a do
+ local vb=b[ka]
+ if va==vb then
+ elseif type(va)=="table" and type(vb)=="table" then
+ if not identical(va,vb) then
+ return false
+ end
+ else
+ return false
+ end
end
- return true
+ end
+ return true
end
table.identical=identical
table.are_equal=are_equal
local function sparse(old,nest,keeptables)
- local new={}
- for k,v in next,old do
- if not (v=="" or v==false) then
- if nest and type(v)=="table" then
- v=sparse(v,nest)
- if keeptables or next(v)~=nil then
- new[k]=v
- end
- else
- new[k]=v
- end
- end
+ local new={}
+ for k,v in next,old do
+ if not (v=="" or v==false) then
+ if nest and type(v)=="table" then
+ v=sparse(v,nest)
+ if keeptables or next(v)~=nil then
+ new[k]=v
+ end
+ else
+ new[k]=v
+ end
end
- return new
+ end
+ return new
end
table.sparse=sparse
function table.compact(t)
- return sparse(t,true,true)
+ return sparse(t,true,true)
end
function table.contains(t,v)
- if t then
- for i=1,#t do
- if t[i]==v then
- return i
- end
- end
+ if t then
+ for i=1,#t do
+ if t[i]==v then
+ return i
+ end
end
- return false
+ end
+ return false
end
function table.count(t)
- local n=0
- for k,v in next,t do
- n=n+1
- end
- return n
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ end
+ return n
end
function table.swapped(t,s)
- local n={}
- if s then
- for k,v in next,s do
- n[k]=v
- end
+ local n={}
+ if s then
+ for k,v in next,s do
+ n[k]=v
end
- for k,v in next,t do
- n[v]=k
- end
- return n
+ end
+ for k,v in next,t do
+ n[v]=k
+ end
+ return n
end
function table.hashed(t)
- for i=1,#t do
- t[t[i]]=i
- end
- return t
+ for i=1,#t do
+ t[t[i]]=i
+ end
+ return t
end
function table.mirrored(t)
- local n={}
- for k,v in next,t do
- n[v]=k
- n[k]=v
- end
- return n
+ local n={}
+ for k,v in next,t do
+ n[v]=k
+ n[k]=v
+ end
+ return n
end
function table.reversed(t)
- if t then
- local tt,tn={},#t
- if tn>0 then
- local ttn=0
- for i=tn,1,-1 do
- ttn=ttn+1
- tt[ttn]=t[i]
- end
- end
- return tt
+ if t then
+ local tt,tn={},#t
+ if tn>0 then
+ local ttn=0
+ for i=tn,1,-1 do
+ ttn=ttn+1
+ tt[ttn]=t[i]
+ end
end
+ return tt
+ end
end
function table.reverse(t)
- if t then
- local n=#t
- local m=n+1
- for i=1,floor(n/2) do
- local j=m-i
- t[i],t[j]=t[j],t[i]
- end
- return t
+ if t then
+ local n=#t
+ local m=n+1
+ for i=1,floor(n/2) do
+ local j=m-i
+ t[i],t[j]=t[j],t[i]
end
+ return t
+ end
end
local function sequenced(t,sep,simple)
- if not t then
- return ""
- elseif type(t)=="string" then
- return t
+ if not t then
+ return ""
+ elseif type(t)=="string" then
+ return t
+ end
+ local n=#t
+ local s={}
+ if n>0 then
+ for i=1,n do
+ local v=t[i]
+ if type(v)=="table" then
+ s[i]="{"..sequenced(v,sep,simple).."}"
+ else
+ s[i]=tostring(t[i])
+ end
end
- local n=#t
- local s={}
- if n>0 then
- for i=1,n do
- local v=t[i]
- if type(v)=="table" then
- s[i]="{"..sequenced(v,sep,simple).."}"
- else
- s[i]=tostring(t[i])
- end
+ else
+ n=0
+ for k,v in sortedhash(t) do
+ if simple then
+ if v==true then
+ n=n+1
+ s[n]=k
+ elseif v and v~="" then
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
+ end
end
- else
- n=0
- for k,v in sortedhash(t) do
- if simple then
- if v==true then
- n=n+1
- s[n]=k
- elseif v and v~="" then
- n=n+1
- if type(v)=="table" then
- s[n]=k.."={"..sequenced(v,sep,simple).."}"
- else
- s[n]=k.."="..tostring(v)
- end
- end
- else
- n=n+1
- if type(v)=="table" then
- s[n]=k.."={"..sequenced(v,sep,simple).."}"
- else
- s[n]=k.."="..tostring(v)
- end
- end
+ else
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
end
+ end
end
- return concat(s,sep or " | ")
+ end
+ return concat(s,sep or " | ")
end
table.sequenced=sequenced
function table.print(t,...)
- if type(t)~="table" then
- print(tostring(t))
- else
- serialize(print,t,...)
- end
+ if type(t)~="table" then
+ print(tostring(t))
+ else
+ serialize(print,t,...)
+ end
end
if setinspector then
- setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
+ setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
end
function table.sub(t,i,j)
- return { unpack(t,i,j) }
+ return { unpack(t,i,j) }
end
function table.is_empty(t)
- return not t or next(t)==nil
+ return not t or next(t)==nil
end
function table.has_one_entry(t)
- return t and next(t,next(t))==nil
+ return t and next(t,next(t))==nil
end
function table.loweredkeys(t)
- local l={}
- for k,v in next,t do
- l[lower(k)]=v
- end
- return l
+ local l={}
+ for k,v in next,t do
+ l[lower(k)]=v
+ end
+ return l
end
function table.unique(old)
- local hash={}
- local new={}
- local n=0
- for i=1,#old do
- local oi=old[i]
- if not hash[oi] then
- n=n+1
- new[n]=oi
- hash[oi]=true
- end
- end
- return new
+ local hash={}
+ local new={}
+ local n=0
+ for i=1,#old do
+ local oi=old[i]
+ if not hash[oi] then
+ n=n+1
+ new[n]=oi
+ hash[oi]=true
+ end
+ end
+ return new
end
function table.sorted(t,...)
- sort(t,...)
- return t
+ sort(t,...)
+ return t
end
function table.values(t,s)
- if t then
- local values,keys,v={},{},0
- for key,value in next,t do
- if not keys[value] then
- v=v+1
- values[v]=value
- keys[k]=key
- end
- end
- if s then
- sort(values)
- end
- return values
- else
- return {}
+ if t then
+ local values,keys,v={},{},0
+ for key,value in next,t do
+ if not keys[value] then
+ v=v+1
+ values[v]=value
+ keys[k]=key
+ end
end
+ if s then
+ sort(values)
+ end
+ return values
+ else
+ return {}
+ end
end
function table.filtered(t,pattern,sort,cmp)
- if t and type(pattern)=="string" then
- if sort then
- local s
- if cmp then
- s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
- else
- s=sortedkeys(t)
- end
- local n=0
- local m=#s
- local function kv(s)
- while n<m do
- n=n+1
- local k=s[n]
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return kv,s
- else
- local n=next(t)
- local function iterator()
- while n~=nil do
- local k=n
- n=next(t,k)
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return iterator,t
+ if t and type(pattern)=="string" then
+ if sort then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local n=0
+ local m=#s
+ local function kv(s)
+ while n<m do
+ n=n+1
+ local k=s[n]
+ if find(k,pattern) then
+ return k,t[k]
+ end
end
- else
- return nothing
+ end
+ return kv,s
+ else
+ local n=next(t)
+ local function iterator()
+ while n~=nil do
+ local k=n
+ n=next(t,k)
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return iterator,t
end
+ else
+ return nothing
+ end
end
if not table.move then
- function table.move(a1,f,e,t,a2)
- if a2 and a1~=a2 then
- for i=f,e do
- a2[t]=a1[i]
- t=t+1
- end
- return a2
- else
- t=t+e-f
- for i=e,f,-1 do
- a1[t]=a1[i]
- t=t-1
- end
- return a1
- end
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1~=a2 then
+ for i=f,e do
+ a2[t]=a1[i]
+ t=t+1
+ end
+ return a2
+ else
+ t=t+e-f
+ for i=e,f,-1 do
+ a1[t]=a1[i]
+ t=t-1
+ end
+ return a1
end
+ end
end
@@ -3059,14 +3059,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-io"] = package.loaded["l-io"] or true
--- original size: 11823, stripped down to: 6945
+-- original size: 11823, stripped down to: 6325
if not modules then modules={} end modules ['l-io']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local io=io
local open,flush,write,read=io.open,io.flush,io.write,io.read
@@ -3074,334 +3074,334 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
local concat=table.concat
local type=type
if string.find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator="\\",";"
+ io.fileseparator,io.pathseparator="\\",";"
else
- io.fileseparator,io.pathseparator="/",":"
+ io.fileseparator,io.pathseparator="/",":"
end
local large=0x01000000
local medium=0x00100000
local small=0x00020000
local function readall(f)
- local size=f:seek("end")
- if size>0 then
- f:seek("set",0)
- return f:read(size)
- else
- return ""
- end
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ return f:read(size)
+ else
+ return ""
+ end
end
io.readall=readall
function io.loaddata(filename,textmode)
- local f=open(filename,(textmode and 'r') or 'rb')
- if f then
- local size=f:seek("end")
- local data=nil
- if size>0 then
- f:seek("set",0)
- data=f:read(size)
- end
- f:close()
- return data
+ local f=open(filename,(textmode and 'r') or 'rb')
+ if f then
+ local size=f:seek("end")
+ local data=nil
+ if size>0 then
+ f:seek("set",0)
+ data=f:read(size)
end
+ f:close()
+ return data
+ end
end
function io.copydata(source,target,action)
- local f=open(source,"rb")
- if f then
- local g=open(target,"wb")
- if g then
- local size=f:seek("end")
- if size>0 then
- f:seek("set",0)
- local data=f:read(size)
- if action then
- data=action(data)
- end
- if data then
- g:write(data)
- end
- end
- g:close()
+ local f=open(source,"rb")
+ if f then
+ local g=open(target,"wb")
+ if g then
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ local data=f:read(size)
+ if action then
+ data=action(data)
end
- f:close()
- flush()
+ if data then
+ g:write(data)
+ end
+ end
+ g:close()
end
+ f:close()
+ flush()
+ end
end
function io.savedata(filename,data,joiner)
- local f=open(filename,"wb")
- if f then
- if type(data)=="table" then
- f:write(concat(data,joiner or ""))
- elseif type(data)=="function" then
- data(f)
- else
- f:write(data or "")
- end
- f:close()
- flush()
- return true
+ local f=open(filename,"wb")
+ if f then
+ if type(data)=="table" then
+ f:write(concat(data,joiner or ""))
+ elseif type(data)=="function" then
+ data(f)
else
- return false
+ f:write(data or "")
end
+ f:close()
+ flush()
+ return true
+ else
+ return false
+ end
end
if fio and fio.readline then
- local readline=fio.readline
- function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=readline(f)
- if line then
- lines[i]=line
- else
- break
- end
- end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
+ local readline=fio.readline
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=readline(f)
+ if line then
+ lines[i]=line
else
- local line=readline(f)
- f:close()
- if line and #line>0 then
- return line
- end
+ break
end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=readline(f)
+ f:close()
+ if line and #line>0 then
+ return line
+ end
end
+ end
else
- function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=f:read("*lines")
- if line then
- lines[i]=line
- else
- break
- end
- end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=f:read("*lines")
+ if line then
+ lines[i]=line
else
- local line=f:read("*line") or ""
- f:close()
- if #line>0 then
- return line
- end
+ break
end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=f:read("*line") or ""
+ f:close()
+ if #line>0 then
+ return line
+ end
end
+ end
end
function io.loadchunk(filename,n)
- local f=open(filename,'rb')
- if f then
- local data=f:read(n or 1024)
- f:close()
- if #data>0 then
- return data
- end
+ local f=open(filename,'rb')
+ if f then
+ local data=f:read(n or 1024)
+ f:close()
+ if #data>0 then
+ return data
end
+ end
end
function io.exists(filename)
- local f=open(filename)
- if f==nil then
- return false
- else
- f:close()
- return true
- end
+ local f=open(filename)
+ if f==nil then
+ return false
+ else
+ f:close()
+ return true
+ end
end
function io.size(filename)
- local f=open(filename)
- if f==nil then
- return 0
- else
- local s=f:seek("end")
- f:close()
- return s
- end
+ local f=open(filename)
+ if f==nil then
+ return 0
+ else
+ local s=f:seek("end")
+ f:close()
+ return s
+ end
end
local function noflines(f)
- if type(f)=="string" then
- local f=open(filename)
- if f then
- local n=f and noflines(f) or 0
- f:close()
- return n
- else
- return 0
- end
+ if type(f)=="string" then
+ local f=open(filename)
+ if f then
+ local n=f and noflines(f) or 0
+ f:close()
+ return n
else
- local n=0
- for _ in f:lines() do
- n=n+1
- end
- f:seek('set',0)
- return n
+ return 0
+ end
+ else
+ local n=0
+ for _ in f:lines() do
+ n=n+1
end
+ f:seek('set',0)
+ return n
+ end
end
io.noflines=noflines
local nextchar={
- [ 4]=function(f)
- return f:read(1,1,1,1)
- end,
- [ 2]=function(f)
- return f:read(1,1)
- end,
- [ 1]=function(f)
- return f:read(1)
- end,
- [-2]=function(f)
- local a,b=f:read(1,1)
- return b,a
- end,
- [-4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- return d,c,b,a
- end
+ [ 4]=function(f)
+ return f:read(1,1,1,1)
+ end,
+ [ 2]=function(f)
+ return f:read(1,1)
+ end,
+ [ 1]=function(f)
+ return f:read(1)
+ end,
+ [-2]=function(f)
+ local a,b=f:read(1,1)
+ return b,a
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ return d,c,b,a
+ end
}
function io.characters(f,n)
- if f then
- return nextchar[n or 1],f
- end
+ if f then
+ return nextchar[n or 1],f
+ end
end
local nextbyte={
- [4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- if d then
- return byte(a),byte(b),byte(c),byte(d)
- end
- end,
- [3]=function(f)
- local a,b,c=f:read(1,1,1)
- if b then
- return byte(a),byte(b),byte(c)
- end
- end,
- [2]=function(f)
- local a,b=f:read(1,1)
- if b then
- return byte(a),byte(b)
- end
- end,
- [1]=function (f)
- local a=f:read(1)
- if a then
- return byte(a)
- end
- end,
- [-2]=function (f)
- local a,b=f:read(1,1)
- if b then
- return byte(b),byte(a)
- end
- end,
- [-3]=function(f)
- local a,b,c=f:read(1,1,1)
- if b then
- return byte(c),byte(b),byte(a)
- end
- end,
- [-4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- if d then
- return byte(d),byte(c),byte(b),byte(a)
- end
+ [4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(a),byte(b),byte(c),byte(d)
+ end
+ end,
+ [3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(a),byte(b),byte(c)
+ end
+ end,
+ [2]=function(f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(a),byte(b)
+ end
+ end,
+ [1]=function (f)
+ local a=f:read(1)
+ if a then
+ return byte(a)
+ end
+ end,
+ [-2]=function (f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(b),byte(a)
+ end
+ end,
+ [-3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(c),byte(b),byte(a)
+ end
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(d),byte(c),byte(b),byte(a)
end
+ end
}
function io.bytes(f,n)
- if f then
- return nextbyte[n or 1],f
- else
- return nil,nil
- end
+ if f then
+ return nextbyte[n or 1],f
+ else
+ return nil,nil
+ end
end
function io.ask(question,default,options)
- while true do
- write(question)
- if options then
- write(format(" [%s]",concat(options,"|")))
- end
- if default then
- write(format(" [%s]",default))
- end
- write(format(" "))
- flush()
- local answer=read()
- answer=gsub(answer,"^%s*(.*)%s*$","%1")
- if answer=="" and default then
- return default
- elseif not options then
- return answer
- else
- for k=1,#options do
- if options[k]==answer then
- return answer
- end
- end
- local pattern="^"..answer
- for k=1,#options do
- local v=options[k]
- if find(v,pattern) then
- return v
- end
- end
+ while true do
+ write(question)
+ if options then
+ write(format(" [%s]",concat(options,"|")))
+ end
+ if default then
+ write(format(" [%s]",default))
+ end
+ write(format(" "))
+ flush()
+ local answer=read()
+ answer=gsub(answer,"^%s*(.*)%s*$","%1")
+ if answer=="" and default then
+ return default
+ elseif not options then
+ return answer
+ else
+ for k=1,#options do
+ if options[k]==answer then
+ return answer
end
+ end
+ local pattern="^"..answer
+ for k=1,#options do
+ local v=options[k]
+ if find(v,pattern) then
+ return v
+ end
+ end
end
+ end
end
local function readnumber(f,n,m)
- if m then
- f:seek("set",n)
- n=m
- end
- if n==1 then
- return byte(f:read(1))
- elseif n==2 then
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
- elseif n==3 then
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
- elseif n==4 then
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==8 then
- local a,b=readnumber(f,4),readnumber(f,4)
- return 0x100*a+b
- elseif n==12 then
- local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
- return 0x10000*a+0x100*b+c
- elseif n==-2 then
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
- elseif n==-3 then
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
- elseif n==-4 then
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==-8 then
- local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
- return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
- else
- return 0
- end
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ if n==1 then
+ return byte(f:read(1))
+ elseif n==2 then
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==3 then
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==4 then
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==8 then
+ local a,b=readnumber(f,4),readnumber(f,4)
+ return 0x100*a+b
+ elseif n==12 then
+ local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
+ return 0x10000*a+0x100*b+c
+ elseif n==-2 then
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==-3 then
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==-4 then
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==-8 then
+ local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
+ return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+ else
+ return 0
+ end
end
io.readnumber=readnumber
function io.readstring(f,n,m)
- if m then
- f:seek("set",n)
- n=m
- end
- local str=gsub(f:read(n),"\000","")
- return str
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ local str=gsub(f:read(n),"\000","")
+ return str
end
@@ -3411,14 +3411,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-number"] = package.loaded["l-number"] or true
--- original size: 5720, stripped down to: 2392
+-- original size: 5720, stripped down to: 2176
if not modules then modules={} end modules ['l-number']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tostring,tonumber=tostring,tonumber
local format,floor,match,rep=string.format,math.floor,string.match,string.rep
@@ -3428,107 +3428,107 @@ local floor=math.floor
number=number or {}
local number=number
if bit32 then
- local bextract=bit32.extract
- local t={
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- }
- function number.tobitstring(b,m,w)
- if not w then
- w=32
- end
- local n=w
- for i=0,w-1 do
- local v=bextract(b,i)
- local k=w-i
- if v==1 then
- n=k
- t[k]="1"
- else
- t[k]="0"
- end
- end
- if w then
- return concat(t,"",1,w)
- elseif m then
- m=33-m*8
- if m<1 then
- m=1
- end
- return concat(t,"",1,m)
- elseif n<8 then
- return concat(t)
- elseif n<16 then
- return concat(t,"",9)
- elseif n<24 then
- return concat(t,"",17)
- else
- return concat(t,"",25)
- end
+ local bextract=bit32.extract
+ local t={
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ }
+ function number.tobitstring(b,m,w)
+ if not w then
+ w=32
+ end
+ local n=w
+ for i=0,w-1 do
+ local v=bextract(b,i)
+ local k=w-i
+ if v==1 then
+ n=k
+ t[k]="1"
+ else
+ t[k]="0"
+ end
+ end
+ if w then
+ return concat(t,"",1,w)
+ elseif m then
+ m=33-m*8
+ if m<1 then
+ m=1
+ end
+ return concat(t,"",1,m)
+ elseif n<8 then
+ return concat(t)
+ elseif n<16 then
+ return concat(t,"",9)
+ elseif n<24 then
+ return concat(t,"",17)
+ else
+ return concat(t,"",25)
end
+ end
else
- function number.tobitstring(n,m)
- if n>0 then
- local t={}
- while n>0 do
- insert(t,1,n%2>0 and 1 or 0)
- n=floor(n/2)
- end
- local nn=8-#t%8
- if nn>0 and nn<8 then
- for i=1,nn do
- insert(t,1,0)
- end
- end
- if m then
- m=m*8-#t
- if m>0 then
- insert(t,1,rep("0",m))
- end
- end
- return concat(t)
- elseif m then
- rep("00000000",m)
- else
- return "00000000"
+ function number.tobitstring(n,m)
+ if n>0 then
+ local t={}
+ while n>0 do
+ insert(t,1,n%2>0 and 1 or 0)
+ n=floor(n/2)
+ end
+ local nn=8-#t%8
+ if nn>0 and nn<8 then
+ for i=1,nn do
+ insert(t,1,0)
+ end
+ end
+ if m then
+ m=m*8-#t
+ if m>0 then
+ insert(t,1,rep("0",m))
end
+ end
+ return concat(t)
+ elseif m then
+ rep("00000000",m)
+ else
+ return "00000000"
end
+ end
end
function number.valid(str,default)
- return tonumber(str) or default or nil
+ return tonumber(str) or default or nil
end
function number.toevenhex(n)
- local s=format("%X",n)
- if #s%2==0 then
- return s
- else
- return "0"..s
- end
+ local s=format("%X",n)
+ if #s%2==0 then
+ return s
+ else
+ return "0"..s
+ end
end
function number.bytetodecimal(b)
- local d=floor(b*100/255+0.5)
- if d>100 then
- return 100
- elseif d<-100 then
- return -100
- else
- return d
- end
+ local d=floor(b*100/255+0.5)
+ if d>100 then
+ return 100
+ elseif d<-100 then
+ return -100
+ else
+ return d
+ end
end
function number.decimaltobyte(d)
- local b=floor(d*255/100+0.5)
- if b>255 then
- return 255
- elseif b<-255 then
- return -255
- else
- return b
- end
+ local b=floor(d*255/100+0.5)
+ if b>255 then
+ return 255
+ elseif b<-255 then
+ return -255
+ else
+ return b
+ end
end
function number.idiv(i,d)
- return floor(i/d)
+ return floor(i/d)
end
@@ -3538,14 +3538,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-set"] = package.loaded["l-set"] or true
--- original size: 1923, stripped down to: 1133
+-- original size: 1923, stripped down to: 1044
if not modules then modules={} end modules ['l-set']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
set=set or {}
local nums={}
@@ -3554,54 +3554,54 @@ local concat=table.concat
local next,type=next,type
set.create=table.tohash
function set.tonumber(t)
- if next(t) then
- local s=""
- for k,v in next,t do
- if v then
- s=s.." "..k
- end
- end
- local n=nums[s]
- if not n then
- n=#tabs+1
- tabs[n]=t
- nums[s]=n
- end
- return n
- else
- return 0
+ if next(t) then
+ local s=""
+ for k,v in next,t do
+ if v then
+ s=s.." "..k
+ end
+ end
+ local n=nums[s]
+ if not n then
+ n=#tabs+1
+ tabs[n]=t
+ nums[s]=n
end
+ return n
+ else
+ return 0
+ end
end
function set.totable(n)
- if n==0 then
- return {}
- else
- return tabs[n] or {}
- end
+ if n==0 then
+ return {}
+ else
+ return tabs[n] or {}
+ end
end
function set.tolist(n)
- if n==0 or not tabs[n] then
- return ""
- else
- local t,n={},0
- for k,v in next,tabs[n] do
- if v then
- n=n+1
- t[n]=k
- end
- end
- return concat(t," ")
+ if n==0 or not tabs[n] then
+ return ""
+ else
+ local t,n={},0
+ for k,v in next,tabs[n] do
+ if v then
+ n=n+1
+ t[n]=k
+ end
end
+ return concat(t," ")
+ end
end
function set.contains(n,s)
- if type(n)=="table" then
- return n[s]
- elseif n==0 then
- return false
- else
- local t=tabs[n]
- return t and t[s]
- end
+ if type(n)=="table" then
+ return n[s]
+ elseif n==0 then
+ return false
+ else
+ local t=tabs[n]
+ return t and t[s]
+ end
end
@@ -3611,14 +3611,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-os"] = package.loaded["l-os"] or true
--- original size: 19347, stripped down to: 11016
+-- original size: 19347, stripped down to: 10258
if not modules then modules={} end modules ['l-os']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local os=os
local date,time=os.date,os.time
@@ -3627,433 +3627,433 @@ local concat=table.concat
local random,ceil,randomseed=math.random,math.ceil,math.randomseed
local rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring=rawget,rawset,type,getmetatable,setmetatable,tonumber,tostring
do
- local selfdir=os.selfdir
- if selfdir=="" then
- selfdir=nil
+ local selfdir=os.selfdir
+ if selfdir=="" then
+ selfdir=nil
+ end
+ if not selfdir then
+ if arg then
+ for i=1,#arg do
+ local a=arg[i]
+ if find(a,"^%-%-[c:]*texmfbinpath=") then
+ selfdir=gsub(a,"^.-=","")
+ break
+ end
+ end
end
if not selfdir then
- if arg then
- for i=1,#arg do
- local a=arg[i]
- if find(a,"^%-%-[c:]*texmfbinpath=") then
- selfdir=gsub(a,"^.-=","")
- break
- end
+ selfdir=os.selfbin or "luatex"
+ if find(selfdir,"[/\\]") then
+ selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
+ elseif os.getenv then
+ local path=os.getenv("PATH")
+ local name=gsub(selfdir,"^.*[/\\][^/\\]","")
+ local patt="[^:]+"
+ if os.type=="windows" then
+ patt="[^;]+"
+ name=name..".exe"
+ end
+ local isfile
+ if lfs then
+ local attributes=lfs.attributes
+ isfile=function(name)
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
+ end
+ else
+ local open=io.open
+ isfile=function(name)
+ local f=open(name)
+ if f then
+ f:close()
+ return true
end
+ end
end
- if not selfdir then
- selfdir=os.selfbin or "luatex"
- if find(selfdir,"[/\\]") then
- selfdir=gsub(selfdir,"[/\\][^/\\]*$","")
- elseif os.getenv then
- local path=os.getenv("PATH")
- local name=gsub(selfdir,"^.*[/\\][^/\\]","")
- local patt="[^:]+"
- if os.type=="windows" then
- patt="[^;]+"
- name=name..".exe"
- end
- local isfile
- if lfs then
- local attributes=lfs.attributes
- isfile=function(name)
- local a=attributes(name,"mode")
- return a=="file" or a=="link" or nil
- end
- else
- local open=io.open
- isfile=function(name)
- local f=open(name)
- if f then
- f:close()
- return true
- end
- end
- end
- for p in gmatch(path,patt) do
- if isfile(p.."/"..name) then
- selfdir=p
- break
- end
- end
- end
+ for p in gmatch(path,patt) do
+ if isfile(p.."/"..name) then
+ selfdir=p
+ break
+ end
end
- os.selfdir=selfdir or "."
+ end
end
+ os.selfdir=selfdir or "."
+ end
end
math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
randomseed(math.initialseed)
if not os.__getenv__ then
- os.__getenv__=os.getenv
- os.__setenv__=os.setenv
- if os.env then
- local osgetenv=os.getenv
- local ossetenv=os.setenv
- local osenv=os.env local _=osenv.PATH
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- if type(v)=="table" then
- v=concat(v,";")
- end
- ossetenv(K,v)
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
- end
- else
- local ossetenv=os.setenv
- local osgetenv=os.getenv
- local osenv={}
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
- end
- local function __index(t,k)
- return os.getenv(k)
- end
- local function __newindex(t,k,v)
- os.setenv(k,v)
- end
- os.env={}
- setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ os.__getenv__=os.getenv
+ os.__setenv__=os.setenv
+ if os.env then
+ local osgetenv=os.getenv
+ local ossetenv=os.setenv
+ local osenv=os.env local _=osenv.PATH
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ if type(v)=="table" then
+ v=concat(v,";")
+ end
+ ossetenv(K,v)
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ else
+ local ossetenv=os.setenv
+ local osgetenv=os.getenv
+ local osenv={}
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ local function __index(t,k)
+ return os.getenv(k)
+ end
+ local function __newindex(t,k,v)
+ os.setenv(k,v)
+ end
+ os.env={}
+ setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
end
local execute=os.execute
local iopopen=io.popen
local function resultof(command)
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- else
- return ""
- end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ else
+ return ""
+ end
end
os.resultof=resultof
function os.pipeto(command)
- return iopopen(command,"w")
+ return iopopen(command,"w")
end
if not io.fileseparator then
- if find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
- else
- io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
- end
+ if find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
+ else
+ io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
+ end
end
os.type=os.type or (io.pathseparator==";" and "windows") or "unix"
-os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
+os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
if os.type=="windows" then
- os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
else
- os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
end
local launchers={
- windows="start %s",
- macosx="open %s",
- unix="xdg-open %s &> /dev/null &",
+ windows="start %s",
+ macosx="open %s",
+ unix="xdg-open %s &> /dev/null &",
}
function os.launch(str)
- execute(format(launchers[os.name] or launchers.unix,str))
+ execute(format(launchers[os.name] or launchers.unix,str))
end
if not os.times then
- function os.times()
- return {
- utime=os.gettimeofday(),
- stime=0,
- cutime=0,
- cstime=0,
- }
- end
+ function os.times()
+ return {
+ utime=os.gettimeofday(),
+ stime=0,
+ cutime=0,
+ cstime=0,
+ }
+ end
end
local gettimeofday=os.gettimeofday or os.clock
os.gettimeofday=gettimeofday
local startuptime=gettimeofday()
function os.runtime()
- return gettimeofday()-startuptime
+ return gettimeofday()-startuptime
end
local resolvers=os.resolvers or {}
os.resolvers=resolvers
setmetatable(os,{ __index=function(t,k)
- local r=resolvers[k]
- return r and r(t,k) or nil
+ local r=resolvers[k]
+ return r and r(t,k) or nil
end })
local name,platform=os.name or "linux",os.getenv("MTX_PLATFORM") or ""
if platform~="" then
- os.platform=platform
+ os.platform=platform
elseif os.type=="windows" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
- local platform=""
- if find(architecture,"AMD64",1,true) then
- platform="win64"
- else
- platform="mswin"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
+ local platform=""
+ if find(architecture,"AMD64",1,true) then
+ platform="win64"
+ else
+ platform="mswin"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="linux" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- local platform=os.getenv("MTX_PLATFORM") or ""
- local musl=find(os.selfdir or "","linuxmusl")
- if platform~="" then
- elseif find(architecture,"x86_64",1,true) then
- platform=musl and "linuxmusl" or "linux-64"
- elseif find(architecture,"ppc",1,true) then
- platform="linux-ppc"
- else
- platform=musl and "linuxmusl" or "linux"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=os.getenv("MTX_PLATFORM") or ""
+ local musl=find(os.selfdir or "","linuxmusl")
+ if platform~="" then
+ elseif find(architecture,"x86_64",1,true) then
+ platform=musl and "linuxmusl" or "linux-64"
+ elseif find(architecture,"ppc",1,true) then
+ platform="linux-ppc"
+ else
+ platform=musl and "linuxmusl" or "linux"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="macosx" then
- function resolvers.platform(t,k)
- local architecture=resultof("echo $HOSTTYPE") or ""
- local platform=""
- if architecture=="" then
- platform="osx-intel"
- elseif find(architecture,"i386",1,true) then
- platform="osx-intel"
- elseif find(architecture,"x86_64",1,true) then
- platform="osx-64"
- else
- platform="osx-ppc"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local architecture=resultof("echo $HOSTTYPE") or ""
+ local platform=""
+ if architecture=="" then
+ platform="osx-intel"
+ elseif find(architecture,"i386",1,true) then
+ platform="osx-intel"
+ elseif find(architecture,"x86_64",1,true) then
+ platform="osx-64"
+ else
+ platform="osx-ppc"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="sunos" then
- function resolvers.platform(t,k)
- local architecture=resultof("uname -m") or ""
- local platform=""
- if find(architecture,"sparc",1,true) then
- platform="solaris-sparc"
- else
- platform="solaris-intel"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"sparc",1,true) then
+ platform="solaris-sparc"
+ else
+ platform="solaris-intel"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="freebsd" then
- function resolvers.platform(t,k)
- local architecture=resultof("uname -m") or ""
- local platform=""
- if find(architecture,"amd64",1,true) then
- platform="freebsd-amd64"
- else
- platform="freebsd"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"amd64",1,true) then
+ platform="freebsd-amd64"
+ else
+ platform="freebsd"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="kfreebsd" then
- function resolvers.platform(t,k)
- local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- local platform=""
- if find(architecture,"x86_64",1,true) then
- platform="kfreebsd-amd64"
- else
- platform="kfreebsd-i386"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"x86_64",1,true) then
+ platform="kfreebsd-amd64"
+ else
+ platform="kfreebsd-i386"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
else
- function resolvers.platform(t,k)
- local platform="linux"
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local platform="linux"
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
end
os.newline=name=="windows" and "\013\010" or "\010"
function resolvers.bits(t,k)
- local bits=find(os.platform,"64",1,true) and 64 or 32
- os.bits=bits
- return bits
+ local bits=find(os.platform,"64",1,true) and 64 or 32
+ os.bits=bits
+ return bits
end
local t={ 8,9,"a","b" }
function os.uuid()
- return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
- random(0xFFFF),random(0xFFFF),
- random(0x0FFF),
- t[ceil(random(4))] or 8,random(0x0FFF),
- random(0xFFFF),
- random(0xFFFF),random(0xFFFF),random(0xFFFF)
- )
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
end
local d
function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
- if delta then
- if d>0 then
- return format("+%02i:00",d)
- else
- return format("-%02i:00",-d)
- end
+ d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ if delta then
+ if d>0 then
+ return format("+%02i:00",d)
else
- return 1
+ return format("-%02i:00",-d)
end
+ else
+ return 1
+ end
end
local timeformat=format("%%s%s",os.timezone(true))
local dateformat="!%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.fulltime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=format(timeformat,date(dateformat))
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=format(timeformat,date(dateformat))
+ end
+ return lastdate
end
local dateformat="%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.localtime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=date(dateformat,t)
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=date(dateformat,t)
+ end
+ return lastdate
end
function os.converttime(t,default)
- local t=tonumber(t)
- if t and t>0 then
- return date(dateformat,t)
- else
- return default or "-"
- end
+ local t=tonumber(t)
+ if t and t>0 then
+ return date(dateformat,t)
+ else
+ return default or "-"
+ end
end
local memory={}
local function which(filename)
- local fullname=memory[filename]
- if fullname==nil then
- local suffix=file.suffix(filename)
- local suffixes=suffix=="" and os.binsuffixes or { suffix }
- for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
- local df=file.join(directory,filename)
- for i=1,#suffixes do
- local dfs=file.addsuffix(df,suffixes[i])
- if io.exists(dfs) then
- fullname=dfs
- break
- end
- end
- end
- if not fullname then
- fullname=false
+ local fullname=memory[filename]
+ if fullname==nil then
+ local suffix=file.suffix(filename)
+ local suffixes=suffix=="" and os.binsuffixes or { suffix }
+ for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local df=file.join(directory,filename)
+ for i=1,#suffixes do
+ local dfs=file.addsuffix(df,suffixes[i])
+ if io.exists(dfs) then
+ fullname=dfs
+ break
end
- memory[filename]=fullname
+ end
end
- return fullname
+ if not fullname then
+ fullname=false
+ end
+ memory[filename]=fullname
+ end
+ return fullname
end
os.which=which
os.where=which
function os.today()
- return date("!*t")
+ return date("!*t")
end
function os.now()
- return date("!%Y-%m-%d %H:%M:%S")
+ return date("!%Y-%m-%d %H:%M:%S")
end
if not os.sleep then
- local socket=socket
- function os.sleep(n)
- if not socket then
- socket=require("socket")
- end
- socket.sleep(n)
+ local socket=socket
+ function os.sleep(n)
+ if not socket then
+ socket=require("socket")
end
+ socket.sleep(n)
+ end
end
local function isleapyear(year)
- return (year%4==0) and (year%100~=0 or year%400==0)
+ return (year%4==0) and (year%100~=0 or year%400==0)
end
os.isleapyear=isleapyear
local days={ 31,28,31,30,31,30,31,31,30,31,30,31 }
local function nofdays(year,month)
- if not month then
- return isleapyear(year) and 365 or 364
- else
- return month==2 and isleapyear(year) and 29 or days[month]
- end
+ if not month then
+ return isleapyear(year) and 365 or 364
+ else
+ return month==2 and isleapyear(year) and 29 or days[month]
+ end
end
os.nofdays=nofdays
function os.weekday(day,month,year)
- return date("%w",time { year=year,month=month,day=day })+1
+ return date("%w",time { year=year,month=month,day=day })+1
end
function os.validdate(year,month,day)
- if month<1 then
- month=1
- elseif month>12 then
- month=12
- end
- if day<1 then
- day=1
- else
- local max=nofdays(year,month)
- if day>max then
- day=max
- end
- end
- return year,month,day
+ if month<1 then
+ month=1
+ elseif month>12 then
+ month=12
+ end
+ if day<1 then
+ day=1
+ else
+ local max=nofdays(year,month)
+ if day>max then
+ day=max
+ end
+ end
+ return year,month,day
end
local osexit=os.exit
local exitcode=nil
function os.setexitcode(code)
- exitcode=code
+ exitcode=code
end
function os.exit(c)
- if exitcode~=nil then
- return osexit(exitcode)
- end
- if c~=nil then
- return osexit(c)
- end
- return osexit()
+ if exitcode~=nil then
+ return osexit(exitcode)
+ end
+ if c~=nil then
+ return osexit(c)
+ end
+ return osexit()
end
@@ -4063,19 +4063,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-file"] = package.loaded["l-file"] or true
--- original size: 21804, stripped down to: 10461
+-- original size: 21804, stripped down to: 9980
if not modules then modules={} end modules ['l-file']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
file=file or {}
local file=file
if not lfs then
- lfs=optionalrequire("lfs")
+ lfs=optionalrequire("lfs")
end
local insert,concat=table.insert,table.concat
local match,find,gmatch=string.match,string.find,string.gmatch
@@ -4085,20 +4085,20 @@ local checkedsplit=string.checkedsplit
local P,R,S,C,Cs,Cp,Cc,Ct=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cp,lpeg.Cc,lpeg.Ct
local attributes=lfs.attributes
function lfs.isdir(name)
- return attributes(name,"mode")=="directory"
+ return attributes(name,"mode")=="directory"
end
function lfs.isfile(name)
- local a=attributes(name,"mode")
- return a=="file" or a=="link" or nil
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
end
function lfs.isfound(name)
- local a=attributes(name,"mode")
- return (a=="file" or a=="link") and name or nil
+ local a=attributes(name,"mode")
+ return (a=="file" or a=="link") and name or nil
end
if sandbox then
- sandbox.redefine(lfs.isfile,"lfs.isfile")
- sandbox.redefine(lfs.isdir,"lfs.isdir")
- sandbox.redefine(lfs.isfound,"lfs.isfound")
+ sandbox.redefine(lfs.isfile,"lfs.isfile")
+ sandbox.redefine(lfs.isdir,"lfs.isdir")
+ sandbox.redefine(lfs.isfound,"lfs.isfound")
end
local colon=P(":")
local period=P(".")
@@ -4112,27 +4112,27 @@ local name=noperiod^1
local suffix=period/""*(1-period-slashes)^1*-1
local pattern=C((1-(slashes^1*noslashes^1*-1))^1)*P(1)
local function pathpart(name,default)
- return name and lpegmatch(pattern,name) or default or ""
+ return name and lpegmatch(pattern,name) or default or ""
end
local pattern=(noslashes^0*slashes)^1*C(noslashes^1)*-1
local function basename(name)
- return name and lpegmatch(pattern,name) or name
+ return name and lpegmatch(pattern,name) or name
end
local pattern=(noslashes^0*slashes^1)^0*Cs((1-suffix)^1)*suffix^0
local function nameonly(name)
- return name and lpegmatch(pattern,name) or name
+ return name and lpegmatch(pattern,name) or name
end
local pattern=(noslashes^0*slashes)^0*(noperiod^1*period)^1*C(noperiod^1)*-1
local function suffixonly(name)
- return name and lpegmatch(pattern,name) or ""
+ return name and lpegmatch(pattern,name) or ""
end
local pattern=(noslashes^0*slashes)^0*noperiod^1*((period*C(noperiod^1))^1)*-1+Cc("")
local function suffixesonly(name)
- if name then
- return lpegmatch(pattern,name)
- else
- return ""
- end
+ if name then
+ return lpegmatch(pattern,name)
+ else
+ return ""
+ end
end
file.pathpart=pathpart
file.basename=basename
@@ -4141,7 +4141,7 @@ file.suffixonly=suffixonly
file.suffix=suffixonly
file.suffixesonly=suffixesonly
file.suffixes=suffixesonly
-file.dirname=pathpart
+file.dirname=pathpart
file.extname=suffixonly
local drive=C(R("az","AZ"))*colon
local path=C((noslashes^0*slashes)^0)
@@ -4157,142 +4157,142 @@ local pattern_b=path*base*suffix
local pattern_c=C(drive*path)*C(base*suffix)
local pattern_d=path*rest
function file.splitname(str,splitdrive)
- if not str then
- elseif splitdrive then
- return lpegmatch(pattern_a,str)
- else
- return lpegmatch(pattern_b,str)
- end
+ if not str then
+ elseif splitdrive then
+ return lpegmatch(pattern_a,str)
+ else
+ return lpegmatch(pattern_b,str)
+ end
end
function file.splitbase(str)
- if str then
- return lpegmatch(pattern_d,str)
- else
- return "",str
- end
+ if str then
+ return lpegmatch(pattern_d,str)
+ else
+ return "",str
+ end
end
function file.nametotable(str,splitdrive)
- if str then
- local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
- if splitdrive then
- return {
- path=path,
- drive=drive,
- subpath=subpath,
- name=name,
- base=base,
- suffix=suffix,
- }
- else
- return {
- path=path,
- name=name,
- base=base,
- suffix=suffix,
- }
- end
+ if str then
+ local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
+ if splitdrive then
+ return {
+ path=path,
+ drive=drive,
+ subpath=subpath,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
+ else
+ return {
+ path=path,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
end
+ end
end
local pattern=Cs(((period*(1-period-slashes)^1*-1)/""+1)^1)
function file.removesuffix(name)
- return name and lpegmatch(pattern,name)
+ return name and lpegmatch(pattern,name)
end
local suffix=period/""*(1-period-slashes)^1*-1
local pattern=Cs((noslashes^0*slashes^1)^0*((1-suffix)^1))*Cs(suffix)
function file.addsuffix(filename,suffix,criterium)
- if not filename or not suffix or suffix=="" then
- return filename
- elseif criterium==true then
- return filename.."."..suffix
- elseif not criterium then
- local n,s=lpegmatch(pattern,filename)
- if not s or s=="" then
- return filename.."."..suffix
- else
+ if not filename or not suffix or suffix=="" then
+ return filename
+ elseif criterium==true then
+ return filename.."."..suffix
+ elseif not criterium then
+ local n,s=lpegmatch(pattern,filename)
+ if not s or s=="" then
+ return filename.."."..suffix
+ else
+ return filename
+ end
+ else
+ local n,s=lpegmatch(pattern,filename)
+ if s and s~="" then
+ local t=type(criterium)
+ if t=="table" then
+ for i=1,#criterium do
+ if s==criterium[i] then
return filename
+ end
end
- else
- local n,s=lpegmatch(pattern,filename)
- if s and s~="" then
- local t=type(criterium)
- if t=="table" then
- for i=1,#criterium do
- if s==criterium[i] then
- return filename
- end
- end
- elseif t=="string" then
- if s==criterium then
- return filename
- end
- end
+ elseif t=="string" then
+ if s==criterium then
+ return filename
end
- return (n or filename).."."..suffix
+ end
end
+ return (n or filename).."."..suffix
+ end
end
local suffix=period*(1-period-slashes)^1*-1
local pattern=Cs((1-suffix)^0)
function file.replacesuffix(name,suffix)
- if name and suffix and suffix~="" then
- return lpegmatch(pattern,name).."."..suffix
- else
- return name
- end
+ if name and suffix and suffix~="" then
+ return lpegmatch(pattern,name).."."..suffix
+ else
+ return name
+ end
end
local reslasher=lpeg.replacer(P("\\"),"/")
function file.reslash(str)
- return str and lpegmatch(reslasher,str)
+ return str and lpegmatch(reslasher,str)
end
function file.is_writable(name)
- if not name then
- elseif lfs.isdir(name) then
- name=name.."/m_t_x_t_e_s_t.tmp"
- local f=io.open(name,"wb")
- if f then
- f:close()
- os.remove(name)
- return true
- end
- elseif lfs.isfile(name) then
- local f=io.open(name,"ab")
- if f then
- f:close()
- return true
- end
- else
- local f=io.open(name,"ab")
- if f then
- f:close()
- os.remove(name)
- return true
- end
+ if not name then
+ elseif lfs.isdir(name) then
+ name=name.."/m_t_x_t_e_s_t.tmp"
+ local f=io.open(name,"wb")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
end
- return false
+ elseif lfs.isfile(name) then
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ return true
+ end
+ else
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ end
+ return false
end
local readable=P("r")*Cc(true)
function file.is_readable(name)
- if name then
- local a=attributes(name)
- return a and lpegmatch(readable,a.permissions) or false
- else
- return false
- end
+ if name then
+ local a=attributes(name)
+ return a and lpegmatch(readable,a.permissions) or false
+ else
+ return false
+ end
end
file.isreadable=file.is_readable
file.iswritable=file.is_writable
function file.size(name)
- if name then
- local a=attributes(name)
- return a and a.size or 0
- else
- return 0
- end
+ if name then
+ local a=attributes(name)
+ return a and a.size or 0
+ else
+ return 0
+ end
end
function file.splitpath(str,separator)
- return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
+ return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
end
function file.joinpath(tab,separator)
- return tab and concat(tab,separator or io.pathseparator)
+ return tab and concat(tab,separator or io.pathseparator)
end
local someslash=S("\\/")
local stripper=Cs(P(fwslash)^0/""*reslasher)
@@ -4302,30 +4302,30 @@ local hasroot=fwslash^1
local reslasher=lpeg.replacer(S("\\/"),"/")
local deslasher=lpeg.replacer(S("\\/")^1,"/")
function file.join(one,two,three,...)
- if not two then
- return one=="" and one or lpegmatch(reslasher,one)
- end
- if one=="" then
- return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
- end
- if lpegmatch(isnetwork,one) then
- local one=lpegmatch(reslasher,one)
- local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
- if lpegmatch(hasroot,two) then
- return one..two
- else
- return one.."/"..two
- end
- elseif lpegmatch(isroot,one) then
- local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
- if lpegmatch(hasroot,two) then
- return two
- else
- return "/"..two
- end
- else
- return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
- end
+ if not two then
+ return one=="" and one or lpegmatch(reslasher,one)
+ end
+ if one=="" then
+ return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
+ end
+ if lpegmatch(isnetwork,one) then
+ local one=lpegmatch(reslasher,one)
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return one..two
+ else
+ return one.."/"..two
+ end
+ elseif lpegmatch(isroot,one) then
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return two
+ else
+ return "/"..two
+ end
+ else
+ return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+ end
end
local drivespec=R("az","AZ")^1*colon
local anchors=fwslash+drivespec
@@ -4335,56 +4335,56 @@ local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//")
local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
local absolute=fwslash
function file.collapsepath(str,anchor)
- if not str then
- return
- end
- if anchor==true and not lpegmatch(anchors,str) then
- str=getcurrentdir().."/"..str
- end
- if str=="" or str=="." then
- return "."
- elseif lpegmatch(untouched,str) then
- return lpegmatch(reslasher,str)
- end
- local starter,oldelements=lpegmatch(splitstarter,str)
- local newelements={}
- local i=#oldelements
- while i>0 do
- local element=oldelements[i]
- if element=='.' then
- elseif element=='..' then
- local n=i-1
- while n>0 do
- local element=oldelements[n]
- if element~='..' and element~='.' then
- oldelements[n]='.'
- break
- else
- n=n-1
- end
- end
- if n<1 then
- insert(newelements,1,'..')
- end
- elseif element~="" then
- insert(newelements,1,element)
- end
- i=i-1
- end
- if #newelements==0 then
- return starter or "."
- elseif starter then
- return starter..concat(newelements,'/')
- elseif lpegmatch(absolute,str) then
- return "/"..concat(newelements,'/')
- else
- newelements=concat(newelements,'/')
- if anchor=="." and find(str,"^%./") then
- return "./"..newelements
+ if not str then
+ return
+ end
+ if anchor==true and not lpegmatch(anchors,str) then
+ str=getcurrentdir().."/"..str
+ end
+ if str=="" or str=="." then
+ return "."
+ elseif lpegmatch(untouched,str) then
+ return lpegmatch(reslasher,str)
+ end
+ local starter,oldelements=lpegmatch(splitstarter,str)
+ local newelements={}
+ local i=#oldelements
+ while i>0 do
+ local element=oldelements[i]
+ if element=='.' then
+ elseif element=='..' then
+ local n=i-1
+ while n>0 do
+ local element=oldelements[n]
+ if element~='..' and element~='.' then
+ oldelements[n]='.'
+ break
else
- return newelements
+ n=n-1
end
- end
+ end
+ if n<1 then
+ insert(newelements,1,'..')
+ end
+ elseif element~="" then
+ insert(newelements,1,element)
+ end
+ i=i-1
+ end
+ if #newelements==0 then
+ return starter or "."
+ elseif starter then
+ return starter..concat(newelements,'/')
+ elseif lpegmatch(absolute,str) then
+ return "/"..concat(newelements,'/')
+ else
+ newelements=concat(newelements,'/')
+ if anchor=="." and find(str,"^%./") then
+ return "./"..newelements
+ else
+ return newelements
+ end
+ end
end
local validchars=R("az","09","AZ","--","..")
local pattern_a=lpeg.replacer(1-validchars)
@@ -4392,26 +4392,26 @@ local pattern_a=Cs((validchars+P(1)/"-")^1)
local whatever=P("-")^0/""
local pattern_b=Cs(whatever*(1-whatever*-1)^1)
function file.robustname(str,strict)
- if str then
- str=lpegmatch(pattern_a,str) or str
- if strict then
- return lpegmatch(pattern_b,str) or str
- else
- return str
- end
+ if str then
+ str=lpegmatch(pattern_a,str) or str
+ if strict then
+ return lpegmatch(pattern_b,str) or str
+ else
+ return str
end
+ end
end
local loaddata=io.loaddata
local savedata=io.savedata
file.readdata=loaddata
file.savedata=savedata
function file.copy(oldname,newname)
- if oldname and newname then
- local data=loaddata(oldname)
- if data and data~="" then
- savedata(newname,data)
- end
+ if oldname and newname then
+ local data=loaddata(oldname)
+ if data and data~="" then
+ savedata(newname,data)
end
+ end
end
local letter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -4420,44 +4420,44 @@ local rootbased=fwslash+letter*colon
lpeg.patterns.qualified=qualified
lpeg.patterns.rootbased=rootbased
function file.is_qualified_path(filename)
- return filename and lpegmatch(qualified,filename)~=nil
+ return filename and lpegmatch(qualified,filename)~=nil
end
function file.is_rootbased_path(filename)
- return filename and lpegmatch(rootbased,filename)~=nil
+ return filename and lpegmatch(rootbased,filename)~=nil
end
function file.strip(name,dir)
- if name then
- local b,a=match(name,"^(.-)"..dir.."(.*)$")
- return a~="" and a or name
- end
+ if name then
+ local b,a=match(name,"^(.-)"..dir.."(.*)$")
+ return a~="" and a or name
+ end
end
function lfs.mkdirs(path)
- local full=""
- for sub in gmatch(path,"(/*[^\\/]+)") do
- full=full..sub
- lfs.mkdir(full)
- end
+ local full=""
+ for sub in gmatch(path,"(/*[^\\/]+)") do
+ full=full..sub
+ lfs.mkdir(full)
+ end
end
function file.withinbase(path)
- local l=0
- if not find(path,"^/") then
- path="/"..path
- end
- for dir in gmatch(path,"/([^/]+)") do
- if dir==".." then
- l=l-1
- elseif dir~="." then
- l=l+1
- end
- if l<0 then
- return false
- end
- end
- return true
+ local l=0
+ if not find(path,"^/") then
+ path="/"..path
+ end
+ for dir in gmatch(path,"/([^/]+)") do
+ if dir==".." then
+ l=l-1
+ elseif dir~="." then
+ l=l+1
+ end
+ if l<0 then
+ return false
+ end
+ end
+ return true
end
local symlinkattributes=lfs.symlinkattributes
function lfs.readlink(name)
- return symlinkattributes(name,"target") or nil
+ return symlinkattributes(name,"target") or nil
end
@@ -4467,51 +4467,51 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-gzip"] = package.loaded["l-gzip"] or true
--- original size: 1211, stripped down to: 1002
+-- original size: 1211, stripped down to: 951
if not modules then modules={} end modules ['l-gzip']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not gzip then
- return
+ return
end
local suffix,suffixes=file.suffix,file.suffixes
function gzip.load(filename)
- local f=io.open(filename,"rb")
- if not f then
- elseif suffix(filename)=="gz" then
- f:close()
- local g=gzip.open(filename,"rb")
- if g then
- local str=g:read("*all")
- g:close()
- return str
- end
- else
- local str=f:read("*all")
- f:close()
- return str
- end
+ local f=io.open(filename,"rb")
+ if not f then
+ elseif suffix(filename)=="gz" then
+ f:close()
+ local g=gzip.open(filename,"rb")
+ if g then
+ local str=g:read("*all")
+ g:close()
+ return str
+ end
+ else
+ local str=f:read("*all")
+ f:close()
+ return str
+ end
end
function gzip.save(filename,data)
- if suffix(filename)~="gz" then
- filename=filename..".gz"
- end
- local f=io.open(filename,"wb")
- if f then
- local s=zlib.compress(data or "",9,nil,15+16)
- f:write(s)
- f:close()
- return #s
- end
+ if suffix(filename)~="gz" then
+ filename=filename..".gz"
+ end
+ local f=io.open(filename,"wb")
+ if f then
+ local s=zlib.compress(data or "",9,nil,15+16)
+ f:write(s)
+ f:close()
+ return #s
+ end
end
function gzip.suffix(filename)
- local suffix,extra=suffixes(filename)
- local gzipped=extra=="gz"
- return suffix,gzipped
+ local suffix,extra=suffixes(filename)
+ local gzipped=extra=="gz"
+ return suffix,gzipped
end
@@ -4521,87 +4521,87 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-md5"] = package.loaded["l-md5"] or true
--- original size: 3309, stripped down to: 2314
+-- original size: 3309, stripped down to: 2218
if not modules then modules={} end modules ['l-md5']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not md5 then
- md5=optionalrequire("md5")
+ md5=optionalrequire("md5")
end
if not md5 then
- md5={
- sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
- sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
- }
+ md5={
+ sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
+ sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
+ }
end
local md5,file=md5,file
local gsub=string.gsub
do
- local patterns=lpeg and lpeg.patterns
- if patterns then
- local bytestoHEX=patterns.bytestoHEX
- local bytestohex=patterns.bytestohex
- local bytestodec=patterns.bytestodec
- local lpegmatch=lpeg.match
- local md5sum=md5.sum
- if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
- if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
- if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
- md5.sumhexa=md5.hex
- md5.sumHEXA=md5.HEX
- end
+ local patterns=lpeg and lpeg.patterns
+ if patterns then
+ local bytestoHEX=patterns.bytestoHEX
+ local bytestohex=patterns.bytestohex
+ local bytestodec=patterns.bytestodec
+ local lpegmatch=lpeg.match
+ local md5sum=md5.sum
+ if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
+ if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
+ if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
+ md5.sumhexa=md5.hex
+ md5.sumHEXA=md5.HEX
+ end
end
function file.needsupdating(oldname,newname,threshold)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime then
- local newtime=lfs.attributes(newname,"modification")
- if not newtime then
- return true
- elseif newtime>=oldtime then
- return false
- elseif oldtime-newtime<(threshold or 1) then
- return false
- else
- return true
- end
- else
- return false
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime then
+ local newtime=lfs.attributes(newname,"modification")
+ if not newtime then
+ return true
+ elseif newtime>=oldtime then
+ return false
+ elseif oldtime-newtime<(threshold or 1) then
+ return false
+ else
+ return true
+ end
+ else
+ return false
+ end
end
file.needs_updating=file.needsupdating
function file.syncmtimes(oldname,newname)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime and lfs.isfile(newname) then
- lfs.touch(newname,oldtime,oldtime)
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime and lfs.isfile(newname) then
+ lfs.touch(newname,oldtime,oldtime)
+ end
end
function file.checksum(name)
- if md5 then
- local data=io.loaddata(name)
- if data then
- return md5.HEX(data)
- end
+ if md5 then
+ local data=io.loaddata(name)
+ if data then
+ return md5.HEX(data)
end
- return nil
+ end
+ return nil
end
function file.loadchecksum(name)
- if md5 then
- local data=io.loaddata(name..".md5")
- return data and (gsub(data,"%s",""))
- end
- return nil
+ if md5 then
+ local data=io.loaddata(name..".md5")
+ return data and (gsub(data,"%s",""))
+ end
+ return nil
end
function file.savechecksum(name,checksum)
- if not checksum then checksum=file.checksum(name) end
- if checksum then
- io.savedata(name..".md5",checksum)
- return checksum
- end
- return nil
+ if not checksum then checksum=file.checksum(name) end
+ if checksum then
+ io.savedata(name..".md5",checksum)
+ return checksum
+ end
+ return nil
end
@@ -4611,29 +4611,29 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-sha"] = package.loaded["l-sha"] or true
--- original size: 1085, stripped down to: 987
+-- original size: 1085, stripped down to: 969
if not modules then modules={} end modules ['l-sha']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if sha2 then
- local lpegmatch=lpeg.match
- local lpegpatterns=lpeg.patterns
- local bytestohex=lpegpatterns.bytestohex
- local bytestoHEX=lpegpatterns.bytestoHEX
- local digest256=sha2.digest256
- local digest384=sha2.digest384
- local digest512=sha2.digest512
- sha2.hash256=function(str) return lpegmatch(bytestohex,digest256(str)) end
- sha2.hash384=function(str) return lpegmatch(bytestohex,digest384(str)) end
- sha2.hash512=function(str) return lpegmatch(bytestohex,digest512(str)) end
- sha2.HASH256=function(str) return lpegmatch(bytestoHEX,digest256(str)) end
- sha2.HASH384=function(str) return lpegmatch(bytestoHEX,digest384(str)) end
- sha2.HASH512=function(str) return lpegmatch(bytestoHEX,digest512(str)) end
+ local lpegmatch=lpeg.match
+ local lpegpatterns=lpeg.patterns
+ local bytestohex=lpegpatterns.bytestohex
+ local bytestoHEX=lpegpatterns.bytestoHEX
+ local digest256=sha2.digest256
+ local digest384=sha2.digest384
+ local digest512=sha2.digest512
+ sha2.hash256=function(str) return lpegmatch(bytestohex,digest256(str)) end
+ sha2.hash384=function(str) return lpegmatch(bytestohex,digest384(str)) end
+ sha2.hash512=function(str) return lpegmatch(bytestohex,digest512(str)) end
+ sha2.HASH256=function(str) return lpegmatch(bytestoHEX,digest256(str)) end
+ sha2.HASH384=function(str) return lpegmatch(bytestoHEX,digest384(str)) end
+ sha2.HASH512=function(str) return lpegmatch(bytestoHEX,digest512(str)) end
end
@@ -4643,14 +4643,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-url"] = package.loaded["l-url"] or true
--- original size: 14755, stripped down to: 7236
+-- original size: 14755, stripped down to: 6981
if not modules then modules={} end modules ['l-url']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local char,format,byte=string.char,string.format,string.byte
local concat=table.concat
@@ -4663,14 +4663,14 @@ local url=url
local unescapes={}
local escapes={}
setmetatable(unescapes,{ __index=function(t,k)
- local v=char(tonumber(k,16))
- t[k]=v
- return v
+ local v=char(tonumber(k,16))
+ t[k]=v
+ return v
end })
setmetatable(escapes,{ __index=function(t,k)
- local v=format("%%%02X",byte(k))
- t[k]=v
- return v
+ local v=format("%%%02X",byte(k))
+ t[k]=v
+ return v
end })
local colon=P(":")
local qmark=P("?")
@@ -4689,21 +4689,21 @@ local escaped=(plus/" ")+escapedchar
local noslash=P("/")/""
local plustospace=P("+")/" "
local decoder=Cs((
- plustospace+escapedchar+P("\r\n")/"\n"+P(1)
- )^0 )
+ plustospace+escapedchar+P("\r\n")/"\n"+P(1)
+ )^0 )
local encoder=Cs((
- R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
- )^0 )
+ R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
+ )^0 )
lpegpatterns.urldecoder=decoder
lpegpatterns.urlencoder=encoder
-function url.decode (str) return str and lpegmatch(decoder,str) or str end
-function url.encode (str) return str and lpegmatch(encoder,str) or str end
+function url.decode (str) return str and lpegmatch(decoder,str) or str end
+function url.encode (str) return str and lpegmatch(encoder,str) or str end
function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2)
local authoritystr=Cs((escaped+(1- slash-qmark-hash))^0)
-local pathstr=Cs((escaped+(1- qmark-hash))^0)
-local querystr=Cs(((1- hash))^0)
-local fragmentstr=Cs((escaped+(1- endofstring))^0)
+local pathstr=Cs((escaped+(1- qmark-hash))^0)
+local querystr=Cs(((1- hash))^0)
+local fragmentstr=Cs((escaped+(1- endofstring))^0)
local scheme=schemestr*colon+nothing
local authority=slash*slash*authoritystr+nothing
local path=slash*pathstr+nothing
@@ -4721,19 +4721,19 @@ lpegpatterns.urlescaper=escaper
lpegpatterns.urlunescaper=unescaper
lpegpatterns.urlgetcleaner=getcleaner
function url.unescapeget(str)
- return lpegmatch(getcleaner,str)
+ return lpegmatch(getcleaner,str)
end
local function split(str)
- return (type(str)=="string" and lpegmatch(parser,str)) or str
+ return (type(str)=="string" and lpegmatch(parser,str)) or str
end
local isscheme=schemestr*colon*slash*slash
local function hasscheme(str)
- if str then
- local scheme=lpegmatch(isscheme,str)
- return scheme~="" and scheme or false
- else
- return false
- end
+ if str then
+ local scheme=lpegmatch(isscheme,str)
+ return scheme~="" and scheme or false
+ else
+ return false
+ end
end
local rootletter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -4743,161 +4743,161 @@ local barswapper=replacer("|",":")
local backslashswapper=replacer("\\","/")
local equal=P("=")
local amp=P("&")
-local key=Cs(((plustospace+escapedchar+1)-equal )^0)
+local key=Cs(((plustospace+escapedchar+1)-equal )^0)
local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0)
local splitquery=Cf (Ct("")*P { "sequence",
- sequence=V("pair")*(amp*V("pair"))^0,
- pair=Cg(key*equal*value),
+ sequence=V("pair")*(amp*V("pair"))^0,
+ pair=Cg(key*equal*value),
},rawset)
local userpart=(1-atsign-colon)^1
local serverpart=(1-colon)^1
local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil))
local function hashed(str)
- if not str or str=="" then
- return {
- scheme="invalid",
- original=str,
- }
- end
- local detailed=split(str)
- local rawscheme=""
- local rawquery=""
- local somescheme=false
- local somequery=false
- if detailed then
- rawscheme=detailed[1]
- rawquery=detailed[4]
- somescheme=rawscheme~=""
- somequery=rawquery~=""
- end
- if not somescheme and not somequery then
- return {
- scheme="file",
- authority="",
- path=str,
- query="",
- fragment="",
- original=str,
- noscheme=true,
- filename=str,
- }
- end
- local authority=detailed[2]
- local path=detailed[3]
- local filename
- local username
- local password
- local host
- local port
- if authority~="" then
- username,password,host,port=lpegmatch(splitauthority,authority)
- end
- if authority=="" then
- filename=path
- elseif path=="" then
- filename=""
- else
- filename=authority.."/"..path
- end
+ if not str or str=="" then
return {
- scheme=rawscheme,
- authority=authority,
- path=path,
- query=lpegmatch(unescaper,rawquery),
- queries=lpegmatch(splitquery,rawquery),
- fragment=detailed[5],
- original=str,
- noscheme=false,
- filename=filename,
- host=host,
- port=port,
+ scheme="invalid",
+ original=str,
+ }
+ end
+ local detailed=split(str)
+ local rawscheme=""
+ local rawquery=""
+ local somescheme=false
+ local somequery=false
+ if detailed then
+ rawscheme=detailed[1]
+ rawquery=detailed[4]
+ somescheme=rawscheme~=""
+ somequery=rawquery~=""
+ end
+ if not somescheme and not somequery then
+ return {
+ scheme="file",
+ authority="",
+ path=str,
+ query="",
+ fragment="",
+ original=str,
+ noscheme=true,
+ filename=str,
}
+ end
+ local authority=detailed[2]
+ local path=detailed[3]
+ local filename
+ local username
+ local password
+ local host
+ local port
+ if authority~="" then
+ username,password,host,port=lpegmatch(splitauthority,authority)
+ end
+ if authority=="" then
+ filename=path
+ elseif path=="" then
+ filename=""
+ else
+ filename=authority.."/"..path
+ end
+ return {
+ scheme=rawscheme,
+ authority=authority,
+ path=path,
+ query=lpegmatch(unescaper,rawquery),
+ queries=lpegmatch(splitquery,rawquery),
+ fragment=detailed[5],
+ original=str,
+ noscheme=false,
+ filename=filename,
+ host=host,
+ port=port,
+ }
end
url.split=split
url.hasscheme=hasscheme
url.hashed=hashed
function url.addscheme(str,scheme)
- if hasscheme(str) then
- return str
- elseif not scheme then
- return "file:///"..str
- else
- return scheme..":///"..str
- end
+ if hasscheme(str) then
+ return str
+ elseif not scheme then
+ return "file:///"..str
+ else
+ return scheme..":///"..str
+ end
end
function url.construct(hash)
- local result,r={},0
- local scheme=hash.scheme
- local authority=hash.authority
- local path=hash.path
- local queries=hash.queries
- local fragment=hash.fragment
- if scheme and scheme~="" then
- r=r+1;result[r]=lpegmatch(escaper,scheme)
- r=r+1;result[r]="://"
- end
- if authority and authority~="" then
- r=r+1;result[r]=lpegmatch(escaper,authority)
- end
- if path and path~="" then
- r=r+1;result[r]="/"
- r=r+1;result[r]=lpegmatch(escaper,path)
- end
- if queries then
- local done=false
- for k,v in sortedhash(queries) do
- r=r+1;result[r]=done and "&" or "?"
- r=r+1;result[r]=lpegmatch(escaper,k)
- r=r+1;result[r]="="
- r=r+1;result[r]=lpegmatch(escaper,v)
- done=true
- end
- end
- if fragment and fragment~="" then
- r=r+1;result[r]="#"
- r=r+1;result[r]=lpegmatch(escaper,fragment)
- end
- return concat(result)
+ local result,r={},0
+ local scheme=hash.scheme
+ local authority=hash.authority
+ local path=hash.path
+ local queries=hash.queries
+ local fragment=hash.fragment
+ if scheme and scheme~="" then
+ r=r+1;result[r]=lpegmatch(escaper,scheme)
+ r=r+1;result[r]="://"
+ end
+ if authority and authority~="" then
+ r=r+1;result[r]=lpegmatch(escaper,authority)
+ end
+ if path and path~="" then
+ r=r+1;result[r]="/"
+ r=r+1;result[r]=lpegmatch(escaper,path)
+ end
+ if queries then
+ local done=false
+ for k,v in sortedhash(queries) do
+ r=r+1;result[r]=done and "&" or "?"
+ r=r+1;result[r]=lpegmatch(escaper,k)
+ r=r+1;result[r]="="
+ r=r+1;result[r]=lpegmatch(escaper,v)
+ done=true
+ end
+ end
+ if fragment and fragment~="" then
+ r=r+1;result[r]="#"
+ r=r+1;result[r]=lpegmatch(escaper,fragment)
+ end
+ return concat(result)
end
local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0)
function url.filename(filename)
- local spec=hashed(filename)
- local path=spec.path
- return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
+ local spec=hashed(filename)
+ local path=spec.path
+ return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
end
local function escapestring(str)
- return lpegmatch(escaper,str)
+ return lpegmatch(escaper,str)
end
url.escape=escapestring
function url.query(str)
- if type(str)=="string" then
- return lpegmatch(splitquery,str) or ""
- else
- return str
- end
+ if type(str)=="string" then
+ return lpegmatch(splitquery,str) or ""
+ else
+ return str
+ end
end
function url.toquery(data)
- local td=type(data)
- if td=="string" then
- return #str and escape(data) or nil
- elseif td=="table" then
- if next(data) then
- local t={}
- for k,v in next,data do
- t[#t+1]=format("%s=%s",k,escapestring(v))
- end
- return concat(t,"&")
- end
- else
+ local td=type(data)
+ if td=="string" then
+ return #str and escape(data) or nil
+ elseif td=="table" then
+ if next(data) then
+ local t={}
+ for k,v in next,data do
+ t[#t+1]=format("%s=%s",k,escapestring(v))
+ end
+ return concat(t,"&")
end
+ else
+ end
end
local pattern=Cs(noslash^0*(1-noslash*P(-1))^0)
function url.barepath(path)
- if not path or path=="" then
- return ""
- else
- return lpegmatch(pattern,path)
- end
+ if not path or path=="" then
+ return ""
+ else
+ return lpegmatch(pattern,path)
+ end
end
@@ -4907,14 +4907,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-dir"] = package.loaded["l-dir"] or true
--- original size: 18002, stripped down to: 11863
+-- original size: 18002, stripped down to: 10681
if not modules then modules={} end modules ['l-dir']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,select=type,select
local find,gmatch,match,gsub,sub=string.find,string.gmatch,string.match,string.gsub,string.sub
@@ -4926,478 +4926,478 @@ local dir=dir
local lfs=lfs
local attributes=lfs.attributes
local walkdir=lfs.dir
-local isdir=lfs.isdir
+local isdir=lfs.isdir
local isfile=lfs.isfile
local currentdir=lfs.currentdir
local chdir=lfs.chdir
local mkdir=lfs.mkdir
local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true)
if onwindows then
- local tricky=S("/\\")*P(-1)
- isdir=function(name)
- if lpegmatch(tricky,name) then
- return attributes(name,"mode")=="directory"
- else
- return attributes(name.."/.","mode")=="directory"
- end
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ local tricky=S("/\\")*P(-1)
+ isdir=function(name)
+ if lpegmatch(tricky,name) then
+ return attributes(name,"mode")=="directory"
+ else
+ return attributes(name.."/.","mode")=="directory"
+ end
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
else
- isdir=function(name)
- return attributes(name,"mode")=="directory"
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ isdir=function(name)
+ return attributes(name,"mode")=="directory"
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
end
function dir.current()
- return (gsub(currentdir(),"\\","/"))
+ return (gsub(currentdir(),"\\","/"))
end
local function glob_pattern_function(path,patt,recurse,action)
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- local nofdirs=0
- for name in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- action(full)
- end
- elseif recurse and mode=="directory" then
- if dirs then
- nofdirs=nofdirs+1
- dirs[nofdirs]=full
- else
- nofdirs=1
- dirs={ full }
- end
- end
- end
- end
- if dirs then
- for i=1,nofdirs do
- glob_pattern_function(dirs[i],patt,recurse,action)
- end
- end
- end
-end
-local function glob_pattern_table(path,patt,recurse,result)
- if not result then
- result={}
- end
+ if isdir(path) then
local usedpath
if path=="/" then
- usedpath="/."
+ usedpath="/."
elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
+ usedpath=path.."/."
+ path=path.."/"
else
- usedpath=path
+ usedpath=path
end
local dirs
local nofdirs=0
- local noffiles=#result
- for name,a in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- noffiles=noffiles+1
- result[noffiles]=full
- end
- elseif recurse and mode=="directory" then
- if dirs then
- nofdirs=nofdirs+1
- dirs[nofdirs]=full
- else
- nofdirs=1
- dirs={ full }
- end
- end
+ for name in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ action(full)
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
end
+ end
end
if dirs then
- for i=1,nofdirs do
- glob_pattern_table(dirs[i],patt,recurse,result)
- end
+ for i=1,nofdirs do
+ glob_pattern_function(dirs[i],patt,recurse,action)
+ end
end
- return result
+ end
end
-local function globpattern(path,patt,recurse,method)
- local kind=type(method)
- if patt and sub(patt,1,-3)==path then
- patt=false
+local function glob_pattern_table(path,patt,recurse,result)
+ if not result then
+ result={}
+ end
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ local noffiles=#result
+ for name,a in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ noffiles=noffiles+1
+ result[noffiles]=full
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
+ end
end
- local okay=isdir(path)
- if kind=="function" then
- return okay and glob_pattern_function(path,patt,recurse,method) or {}
- elseif kind=="table" then
- return okay and glob_pattern_table(path,patt,recurse,method) or method
- else
- return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_table(dirs[i],patt,recurse,result)
end
+ end
+ return result
+end
+local function globpattern(path,patt,recurse,method)
+ local kind=type(method)
+ if patt and sub(patt,1,-3)==path then
+ patt=false
+ end
+ local okay=isdir(path)
+ if kind=="function" then
+ return okay and glob_pattern_function(path,patt,recurse,method) or {}
+ elseif kind=="table" then
+ return okay and glob_pattern_table(path,patt,recurse,method) or method
+ else
+ return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
end
dir.globpattern=globpattern
local function collectpattern(path,patt,recurse,result)
- local ok,scanner
- result=result or {}
- if path=="/" then
- ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
- else
- ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
- end
- if ok and type(scanner)=="function" then
- if not find(path,"/$") then
- path=path..'/'
- end
- for name in scanner,first do
- if name=="." then
- elseif name==".." then
- else
- local full=path..name
- local attr=attributes(full)
- local mode=attr.mode
- if mode=='file' then
- if find(full,patt) then
- result[name]=attr
- end
- elseif recurse and mode=="directory" then
- attr.list=collectpattern(full,patt,recurse)
- result[name]=attr
- end
- end
+ local ok,scanner
+ result=result or {}
+ if path=="/" then
+ ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
+ else
+ ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
+ end
+ if ok and type(scanner)=="function" then
+ if not find(path,"/$") then
+ path=path..'/'
+ end
+ for name in scanner,first do
+ if name=="." then
+ elseif name==".." then
+ else
+ local full=path..name
+ local attr=attributes(full)
+ local mode=attr.mode
+ if mode=='file' then
+ if find(full,patt) then
+ result[name]=attr
+ end
+ elseif recurse and mode=="directory" then
+ attr.list=collectpattern(full,patt,recurse)
+ result[name]=attr
end
+ end
end
- return result
+ end
+ return result
end
dir.collectpattern=collectpattern
local separator,pattern
if onwindows then
- local slash=S("/\\")/"/"
- pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
- }
+ local slash=S("/\\")/"/"
+ pattern={
+ [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
+ [3]=Cs(P(1)^0)
+ }
else
- pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
- }
+ pattern={
+ [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ [2]=C(((1-S("*?/"))^0*P("/"))^0),
+ [3]=C(P(1)^0)
+ }
end
local filter=Cs ((
- P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
+ P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
)^0 )
local function glob(str,t)
- if type(t)=="function" then
- if type(str)=="table" then
- for s=1,#str do
- glob(str[s],t)
- end
- elseif isfile(str) then
- t(str)
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- globpattern(start,result,recurse,t)
- end
- end
+ if type(t)=="function" then
+ if type(str)=="table" then
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ elseif isfile(str) then
+ t(str)
+ else
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ globpattern(start,result,recurse,t)
+ end
+ end
+ else
+ if type(str)=="table" then
+ local t=t or {}
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ return t
+ elseif isfile(str) then
+ if t then
+ t[#t+1]=str
+ return t
+ else
+ return { str }
+ end
else
- if type(str)=="table" then
- local t=t or {}
- for s=1,#str do
- glob(str[s],t)
- end
- return t
- elseif isfile(str) then
- if t then
- t[#t+1]=str
- return t
- else
- return { str }
- end
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- return globpattern(start,result,recurse,t)
- else
- return {}
- end
- end
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ return globpattern(start,result,recurse,t)
+ else
+ return {}
+ end
end
+ end
end
dir.glob=glob
local function globfiles(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if recurse then
- globfiles(path.."/"..name,recurse,func,files)
- end
- elseif mode=="file" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if recurse then
+ globfiles(path.."/"..name,recurse,func,files)
+ end
+ elseif mode=="file" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
end
+ end
end
- return files
+ end
+ return files
end
dir.globfiles=globfiles
local function globdirs(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- if recurse then
- globdirs(path.."/"..name,recurse,func,files)
- end
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
+ if recurse then
+ globdirs(path.."/"..name,recurse,func,files)
+ end
end
+ end
end
- return files
+ end
+ return files
end
dir.globdirs=globdirs
function dir.ls(pattern)
- return concat(glob(pattern),"\n")
+ return concat(glob(pattern),"\n")
end
local make_indeed=true
if onwindows then
- function dir.mkdirs(...)
- local n=select("#",...)
- local str
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s=="" then
+ elseif str=="" then
+ str=s
else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s=="" then
- elseif str=="" then
- str=s
- else
- str=str.."/"..s
- end
- end
+ str=str.."/"..s
end
- local pth=""
- local drive=false
- local first,middle,last=match(str,"^(//)(//*)(.*)$")
- if first then
+ end
+ end
+ local pth=""
+ local drive=false
+ local first,middle,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ else
+ first,last=match(str,"^(//)/*(.-)$")
+ if first then
+ middle,last=match(str,"([^/]+)/+(.-)$")
+ if middle then
+ pth="//"..middle
else
- first,last=match(str,"^(//)/*(.-)$")
- if first then
- middle,last=match(str,"([^/]+)/+(.-)$")
- if middle then
- pth="//"..middle
- else
- pth="//"..last
- last=""
- end
- else
- first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
- if first then
- pth,drive=first..middle,true
- else
- middle,last=match(str,"^(/*)(.-)$")
- if not middle then
- last=str
- end
- end
- end
+ pth="//"..last
+ last=""
end
- for s in gmatch(last,"[^/]+") do
- if pth=="" then
- pth=s
- elseif drive then
- pth,drive=pth..s,false
- else
- pth=pth.."/"..s
- end
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
+ else
+ first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
+ if first then
+ pth,drive=first..middle,true
+ else
+ middle,last=match(str,"^(/*)(.-)$")
+ if not middle then
+ last=str
+ end
end
- return pth,(isdir(pth)==true)
+ end
end
+ for s in gmatch(last,"[^/]+") do
+ if pth=="" then
+ pth=s
+ elseif drive then
+ pth,drive=pth..s,false
+ else
+ pth=pth.."/"..s
+ end
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ return pth,(isdir(pth)==true)
+ end
else
- function dir.mkdirs(...)
- local n=select("#",...)
- local str,pth
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
- else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s and s~="" then
- if str~="" then
- str=str.."/"..s
- else
- str=s
- end
- end
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str,pth
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s and s~="" then
+ if str~="" then
+ str=str.."/"..s
+ else
+ str=s
+ end
end
- str=gsub(str,"/+","/")
- if find(str,"^/") then
- pth="/"
- for s in gmatch(str,"[^/]+") do
- local first=(pth=="/")
- if first then
- pth=pth..s
- else
- pth=pth.."/"..s
- end
- if make_indeed and not first and not isdir(pth) then
- mkdir(pth)
- end
- end
+ end
+ end
+ str=gsub(str,"/+","/")
+ if find(str,"^/") then
+ pth="/"
+ for s in gmatch(str,"[^/]+") do
+ local first=(pth=="/")
+ if first then
+ pth=pth..s
else
- pth="."
- for s in gmatch(str,"[^/]+") do
- pth=pth.."/"..s
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
- end
+ pth=pth.."/"..s
+ end
+ if make_indeed and not first and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ else
+ pth="."
+ for s in gmatch(str,"[^/]+") do
+ pth=pth.."/"..s
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
end
- return pth,(isdir(pth)==true)
+ end
end
+ return pth,(isdir(pth)==true)
+ end
end
dir.makedirs=dir.mkdirs
do
- local chdir=sandbox and sandbox.original(chdir) or chdir
- if onwindows then
- local xcurrentdir=dir.current
- function dir.expandname(str)
- local first,nothing,last=match(str,"^(//)(//*)(.*)$")
- if first then
- first=xcurrentdir().."/"
- end
- if not first then
- first,last=match(str,"^(//)/*(.*)$")
- end
- if not first then
- first,last=match(str,"^([a-zA-Z]:)(.*)$")
- if first and not find(last,"^/") then
- local d=currentdir()
- if chdir(first) then
- first=xcurrentdir()
- end
- chdir(d)
- end
- end
- if not first then
- first,last=xcurrentdir(),str
- end
- last=gsub(last,"//","/")
- last=gsub(last,"/%./","/")
- last=gsub(last,"^/*","")
- first=gsub(first,"/*$","")
- if last=="" or last=="." then
- return first
- else
- return first.."/"..last
- end
- end
- else
- function dir.expandname(str)
- if not find(str,"^/") then
- str=currentdir().."/"..str
- end
- str=gsub(str,"//","/")
- str=gsub(str,"/%./","/")
- str=gsub(str,"(.)/%.$","%1")
- return str
+ local chdir=sandbox and sandbox.original(chdir) or chdir
+ if onwindows then
+ local xcurrentdir=dir.current
+ function dir.expandname(str)
+ local first,nothing,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ first=xcurrentdir().."/"
+ end
+ if not first then
+ first,last=match(str,"^(//)/*(.*)$")
+ end
+ if not first then
+ first,last=match(str,"^([a-zA-Z]:)(.*)$")
+ if first and not find(last,"^/") then
+ local d=currentdir()
+ if chdir(first) then
+ first=xcurrentdir()
+ end
+ chdir(d)
end
+ end
+ if not first then
+ first,last=xcurrentdir(),str
+ end
+ last=gsub(last,"//","/")
+ last=gsub(last,"/%./","/")
+ last=gsub(last,"^/*","")
+ first=gsub(first,"/*$","")
+ if last=="" or last=="." then
+ return first
+ else
+ return first.."/"..last
+ end
+ end
+ else
+ function dir.expandname(str)
+ if not find(str,"^/") then
+ str=currentdir().."/"..str
+ end
+ str=gsub(str,"//","/")
+ str=gsub(str,"/%./","/")
+ str=gsub(str,"(.)/%.$","%1")
+ return str
end
+ end
end
file.expandname=dir.expandname
local stack={}
function dir.push(newdir)
- local curdir=currentdir()
- insert(stack,curdir)
- if newdir and newdir~="" then
- chdir(newdir)
- return newdir
- else
- return curdir
- end
+ local curdir=currentdir()
+ insert(stack,curdir)
+ if newdir and newdir~="" then
+ chdir(newdir)
+ return newdir
+ else
+ return curdir
+ end
end
function dir.pop()
- local d=remove(stack)
- if d then
- chdir(d)
- end
- return d
+ local d=remove(stack)
+ if d then
+ chdir(d)
+ end
+ return d
end
local function found(...)
- for i=1,select("#",...) do
- local path=select(i,...)
- local kind=type(path)
- if kind=="string" then
- if isdir(path) then
- return path
- end
- elseif kind=="table" then
- local path=found(unpack(path))
- if path then
- return path
- end
- end
+ for i=1,select("#",...) do
+ local path=select(i,...)
+ local kind=type(path)
+ if kind=="string" then
+ if isdir(path) then
+ return path
+ end
+ elseif kind=="table" then
+ local path=found(unpack(path))
+ if path then
+ return path
+ end
end
+ end
end
dir.found=found
@@ -5408,69 +5408,69 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-boolean"] = package.loaded["l-boolean"] or true
--- original size: 1850, stripped down to: 1568
+-- original size: 1850, stripped down to: 1498
if not modules then modules={} end modules ['l-boolean']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber=type,tonumber
boolean=boolean or {}
local boolean=boolean
function boolean.tonumber(b)
- if b then return 1 else return 0 end
+ if b then return 1 else return 0 end
end
function toboolean(str,tolerant)
- if str==nil then
- return false
- elseif str==false then
- return false
- elseif str==true then
- return true
- elseif str=="true" then
- return true
- elseif str=="false" then
- return false
- elseif not tolerant then
- return false
- elseif str==0 then
- return false
- elseif (tonumber(str) or 0)>0 then
- return true
- else
- return str=="yes" or str=="on" or str=="t"
- end
+ if str==nil then
+ return false
+ elseif str==false then
+ return false
+ elseif str==true then
+ return true
+ elseif str=="true" then
+ return true
+ elseif str=="false" then
+ return false
+ elseif not tolerant then
+ return false
+ elseif str==0 then
+ return false
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
end
string.toboolean=toboolean
function string.booleanstring(str)
- if str=="0" then
- return false
- elseif str=="1" then
- return true
- elseif str=="" then
- return false
- elseif str=="false" then
- return false
- elseif str=="true" then
- return true
- elseif (tonumber(str) or 0)>0 then
- return true
- else
- return str=="yes" or str=="on" or str=="t"
- end
+ if str=="0" then
+ return false
+ elseif str=="1" then
+ return true
+ elseif str=="" then
+ return false
+ elseif str=="false" then
+ return false
+ elseif str=="true" then
+ return true
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
end
function string.is_boolean(str,default,strict)
- if type(str)=="string" then
- if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
- return true
- elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
- return false
- end
+ if type(str)=="string" then
+ if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
+ return true
+ elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
+ return false
end
- return default
+ end
+ return default
end
@@ -5480,22 +5480,22 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 41047, stripped down to: 18594
+-- original size: 41047, stripped down to: 17171
if not modules then modules={} end modules ['l-unicode']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utf=utf or {}
unicode=nil
if not string.utfcharacters then
- local gmatch=string.gmatch
- function string.characters(str)
- return gmatch(str,".[\128-\191]*")
- end
+ local gmatch=string.gmatch
+ function string.characters(str)
+ return gmatch(str,".[\128-\191]*")
+ end
end
utf.characters=string.utfcharacters
local type=type
@@ -5518,304 +5518,304 @@ local p_utfbom=patterns.utfbom
local p_newline=patterns.newline
local p_whitespace=patterns.whitespace
if not utf.char then
- utf.char=string.utfcharacter or (utf8 and utf8.char)
- if not utf.char then
- local char=string.char
- if bit32 then
- local rshift=bit32.rshift
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+rshift(n,6),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+rshift(n,12),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+rshift(n,18),
- 0x80+(rshift(n,12)%0x40),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
+ utf.char=string.utfcharacter or (utf8 and utf8.char)
+ if not utf.char then
+ local char=string.char
+ if bit32 then
+ local rshift=bit32.rshift
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+rshift(n,6),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+rshift(n,12),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+rshift(n,18),
+ 0x80+(rshift(n,12)%0x40),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
else
- local floor=math.floor
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+floor(n/0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+floor(n/0x1000),
- 0x80+(floor(n/0x40)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+floor(n/0x40000),
- 0x80+(floor(n/0x1000)%0x40),
- 0x80+(floor(n/0x40)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
+ return ""
+ end
+ end
+ else
+ local floor=math.floor
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+floor(n/0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+floor(n/0x1000),
+ 0x80+(floor(n/0x40)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+floor(n/0x40000),
+ 0x80+(floor(n/0x1000)%0x40),
+ 0x80+(floor(n/0x40)%0x40),
+ 0x80+(n%0x40)
+ )
+ else
+ return ""
end
+ end
end
+ end
end
if not utf.byte then
- utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
- if not utf.byte then
- function utf.byte(c)
- return lpegmatch(p_utf8byte,c)
- end
+ utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
+ if not utf.byte then
+ function utf.byte(c)
+ return lpegmatch(p_utf8byte,c)
end
+ end
end
local utfchar,utfbyte=utf.char,utf.byte
function utf.filetype(data)
- return data and lpegmatch(p_utftype,data) or "unknown"
+ return data and lpegmatch(p_utftype,data) or "unknown"
end
local toentities=Cs (
- (
- patterns.utf8one+(
- patterns.utf8two+patterns.utf8three+patterns.utf8four
- )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
- )^0
+ (
+ patterns.utf8one+(
+ patterns.utf8two+patterns.utf8three+patterns.utf8four
+ )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
+ )^0
)
patterns.toentities=toentities
function utf.toentities(str)
- return lpegmatch(toentities,str)
+ return lpegmatch(toentities,str)
end
local one=P(1)
local two=C(1)*C(1)
local four=C(R(utfchar(0xD8),utfchar(0xFF)))*C(1)*C(1)*C(1)
local pattern=P("\254\255")*Cs((
- four/function(a,b,c,d)
- local ab=0xFF*byte(a)+byte(b)
- local cd=0xFF*byte(c)+byte(d)
- return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
- end+two/function(a,b)
- return utfchar(byte(a)*256+byte(b))
- end+one
- )^1 )+P("\255\254")*Cs((
- four/function(b,a,d,c)
- local ab=0xFF*byte(a)+byte(b)
- local cd=0xFF*byte(c)+byte(d)
- return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
- end+two/function(b,a)
- return utfchar(byte(a)*256+byte(b))
- end+one
- )^1 )
+ four/function(a,b,c,d)
+ local ab=0xFF*byte(a)+byte(b)
+ local cd=0xFF*byte(c)+byte(d)
+ return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+ end+two/function(a,b)
+ return utfchar(byte(a)*256+byte(b))
+ end+one
+ )^1 )+P("\255\254")*Cs((
+ four/function(b,a,d,c)
+ local ab=0xFF*byte(a)+byte(b)
+ local cd=0xFF*byte(c)+byte(d)
+ return utfchar((ab-0xD800)*0x400+(cd-0xDC00)+0x10000)
+ end+two/function(b,a)
+ return utfchar(byte(a)*256+byte(b))
+ end+one
+ )^1 )
function string.toutf(s)
- return lpegmatch(pattern,s) or s
+ return lpegmatch(pattern,s) or s
end
local validatedutf=Cs (
- (
- patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
- )^0
+ (
+ patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
+ )^0
)
patterns.validatedutf=validatedutf
function utf.is_valid(str)
- return type(str)=="string" and lpegmatch(validatedutf,str) or false
+ return type(str)=="string" and lpegmatch(validatedutf,str) or false
end
if not utf.len then
- utf.len=string.utflength or (utf8 and utf8.len)
- if not utf.len then
- local n,f=0,1
- local utfcharcounter=patterns.utfbom^-1*Cmt (
- Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
- function(_,t,d)
- n=n+(t-f)/d
- f=t
- return true
- end
- )^0
- function utf.len(str)
- n,f=0,1
- lpegmatch(utfcharcounter,str or "")
- return n
- end
+ utf.len=string.utflength or (utf8 and utf8.len)
+ if not utf.len then
+ local n,f=0,1
+ local utfcharcounter=patterns.utfbom^-1*Cmt (
+ Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1,
+ function(_,t,d)
+ n=n+(t-f)/d
+ f=t
+ return true
+ end
+ )^0
+ function utf.len(str)
+ n,f=0,1
+ lpegmatch(utfcharcounter,str or "")
+ return n
end
+ end
end
utf.length=utf.len
if not utf.sub then
- local utflength=utf.length
- local b,e,n,first,last=0,0,0,0,0
- local function slide_zero(s,p)
- n=n+1
- if n>=last then
- e=p-1
- else
- return p
- end
+ local utflength=utf.length
+ local b,e,n,first,last=0,0,0,0,0
+ local function slide_zero(s,p)
+ n=n+1
+ if n>=last then
+ e=p-1
+ else
+ return p
end
- local function slide_one(s,p)
- n=n+1
- if n==first then
- b=p
- end
- if n>=last then
- e=p-1
- else
- return p
- end
+ end
+ local function slide_one(s,p)
+ n=n+1
+ if n==first then
+ b=p
end
- local function slide_two(s,p)
- n=n+1
- if n==first then
- b=p
- else
- return true
- end
+ if n>=last then
+ e=p-1
+ else
+ return p
end
- local pattern_zero=Cmt(p_utf8character,slide_zero)^0
- local pattern_one=Cmt(p_utf8character,slide_one )^0
- local pattern_two=Cmt(p_utf8character,slide_two )^0
- local pattern_first=C(p_utf8character)
- function utf.sub(str,start,stop)
- if not start then
- return str
- end
- if start==0 then
- start=1
- end
- if not stop then
- if start<0 then
- local l=utflength(str)
- start=l+start
- else
- start=start-1
- end
- b,n,first=0,0,start
- lpegmatch(pattern_two,str)
- if n>=first then
- return sub(str,b)
- else
- return ""
- end
- end
- if start<0 or stop<0 then
- local l=utf.length(str)
- if start<0 then
- start=l+start
- if start<=0 then
- start=1
- else
- start=start+1
- end
- end
- if stop<0 then
- stop=l+stop
- if stop==0 then
- stop=1
- else
- stop=stop+1
- end
- end
+ end
+ local function slide_two(s,p)
+ n=n+1
+ if n==first then
+ b=p
+ else
+ return true
+ end
+ end
+ local pattern_zero=Cmt(p_utf8character,slide_zero)^0
+ local pattern_one=Cmt(p_utf8character,slide_one )^0
+ local pattern_two=Cmt(p_utf8character,slide_two )^0
+ local pattern_first=C(p_utf8character)
+ function utf.sub(str,start,stop)
+ if not start then
+ return str
+ end
+ if start==0 then
+ start=1
+ end
+ if not stop then
+ if start<0 then
+ local l=utflength(str)
+ start=l+start
+ else
+ start=start-1
+ end
+ b,n,first=0,0,start
+ lpegmatch(pattern_two,str)
+ if n>=first then
+ return sub(str,b)
+ else
+ return ""
+ end
+ end
+ if start<0 or stop<0 then
+ local l=utf.length(str)
+ if start<0 then
+ start=l+start
+ if start<=0 then
+ start=1
+ else
+ start=start+1
end
- if start==1 and stop==1 then
- return lpegmatch(pattern_first,str) or ""
- elseif start>stop then
- return ""
- elseif start>1 then
- b,e,n,first,last=0,0,0,start-1,stop
- lpegmatch(pattern_one,str)
- if n>=first and e==0 then
- e=#str
- end
- return sub(str,b,e)
+ end
+ if stop<0 then
+ stop=l+stop
+ if stop==0 then
+ stop=1
else
- b,e,n,last=1,0,0,stop
- lpegmatch(pattern_zero,str)
- if e==0 then
- e=#str
- end
- return sub(str,b,e)
+ stop=stop+1
end
+ end
end
+ if start==1 and stop==1 then
+ return lpegmatch(pattern_first,str) or ""
+ elseif start>stop then
+ return ""
+ elseif start>1 then
+ b,e,n,first,last=0,0,0,start-1,stop
+ lpegmatch(pattern_one,str)
+ if n>=first and e==0 then
+ e=#str
+ end
+ return sub(str,b,e)
+ else
+ b,e,n,last=1,0,0,stop
+ lpegmatch(pattern_zero,str)
+ if e==0 then
+ e=#str
+ end
+ return sub(str,b,e)
+ end
+ end
end
function utf.remapper(mapping,option,action)
- local variant=type(mapping)
- if variant=="table" then
- action=action or mapping
- if option=="dynamic" then
- local pattern=false
- table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
- return function(str)
- if not str or str=="" then
- return ""
- else
- if not pattern then
- pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
- end
- return lpegmatch(pattern,str)
- end
- end
- elseif option=="pattern" then
- return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ local variant=type(mapping)
+ if variant=="table" then
+ action=action or mapping
+ if option=="dynamic" then
+ local pattern=false
+ table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end)
+ return function(str)
+ if not str or str=="" then
+ return ""
else
- local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
- return function(str)
- if not str or str=="" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end,pattern
+ if not pattern then
+ pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ end
+ return lpegmatch(pattern,str)
end
- elseif variant=="function" then
- if option=="pattern" then
- return Cs((p_utf8character/mapping+p_utf8character)^0)
+ end
+ elseif option=="pattern" then
+ return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ else
+ local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
else
- local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
- return function(str)
- if not str or str=="" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end,pattern
+ return lpegmatch(pattern,str)
end
+ end,pattern
+ end
+ elseif variant=="function" then
+ if option=="pattern" then
+ return Cs((p_utf8character/mapping+p_utf8character)^0)
else
- return function(str)
- return str or ""
+ local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
end
+ end,pattern
end
-end
-function utf.replacer(t)
- local r=replacer(t,false,false,true)
+ else
return function(str)
- return lpegmatch(r,str)
+ return str or ""
end
+ end
+end
+function utf.replacer(t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ return lpegmatch(r,str)
+ end
end
function utf.subtituter(t)
- local f=finder (t)
- local r=replacer(t,false,false,true)
- return function(str)
- local i=lpegmatch(f,str)
- if not i then
- return str
- elseif i>#str then
- return str
- else
- return lpegmatch(r,str)
- end
+ local f=finder (t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ local i=lpegmatch(f,str)
+ if not i then
+ return str
+ elseif i>#str then
+ return str
+ else
+ return lpegmatch(r,str)
end
+ end
end
local utflinesplitter=p_utfbom^-1*lpeg.tsplitat(p_newline)
local utfcharsplitter_ows=p_utfbom^-1*Ct(C(p_utf8character)^0)
@@ -5823,25 +5823,25 @@ local utfcharsplitter_iws=p_utfbom^-1*Ct((p_whitespace^1+C(p_utf8character))^0)
local utfcharsplitter_raw=Ct(C(p_utf8character)^0)
patterns.utflinesplitter=utflinesplitter
function utf.splitlines(str)
- return lpegmatch(utflinesplitter,str or "")
+ return lpegmatch(utflinesplitter,str or "")
end
function utf.split(str,ignorewhitespace)
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
+ if ignorewhitespace then
+ return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+ return lpegmatch(utfcharsplitter_ows,str or "")
+ end
end
function utf.totable(str)
- return lpegmatch(utfcharsplitter_raw,str)
+ return lpegmatch(utfcharsplitter_raw,str)
end
function utf.magic(f)
- local str=f:read(4) or ""
- local off=lpegmatch(p_utfoffset,str)
- if off<4 then
- f:seek('set',off)
- end
- return lpegmatch(p_utftype,str)
+ local str=f:read(4) or ""
+ local off=lpegmatch(p_utfoffset,str)
+ if off<4 then
+ f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
end
local utf16_to_utf8_be,utf16_to_utf8_le
local utf32_to_utf8_be,utf32_to_utf8_le
@@ -5855,36 +5855,36 @@ local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_n
local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
local more=0
local p_utf16_to_utf8_be=C(1)*C(1)/function(left,right)
- local now=256*byte(left)+byte(right)
- if more>0 then
- now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ return ""
+ else
+ return utfchar(now)
+ end
end
local p_utf16_to_utf8_le=C(1)*C(1)/function(right,left)
- local now=256*byte(left)+byte(right)
- if more>0 then
- now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
+ local now=256*byte(left)+byte(right)
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ return utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ return ""
+ else
+ return utfchar(now)
+ end
end
local p_utf32_to_utf8_be=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
- return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
+ return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
end
local p_utf32_to_utf8_le=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d)
- return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
+ return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
end
p_utf16_to_utf8_be=P(true)/function() more=0 end*utf_16_be_getbom*Cs(p_utf16_to_utf8_be^0)
p_utf16_to_utf8_le=P(true)/function() more=0 end*utf_16_le_getbom*Cs(p_utf16_to_utf8_le^0)
@@ -5895,88 +5895,88 @@ patterns.utf16_to_utf8_le=p_utf16_to_utf8_le
patterns.utf32_to_utf8_be=p_utf32_to_utf8_be
patterns.utf32_to_utf8_le=p_utf32_to_utf8_le
utf16_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_be,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+ return s
+ end
end
local utf16_to_utf8_be_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_16_be_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf16_to_utf8_be,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_16_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf16_to_utf8_be,s)
end
- return t
+ end
+ return t
end
utf16_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+ return s
+ end
end
local utf16_to_utf8_le_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_16_le_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf16_to_utf8_le,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_16_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf16_to_utf8_le,s)
end
- return t
+ end
+ return t
end
utf32_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_be,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+ return s
+ end
end
local utf32_to_utf8_be_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_32_be_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf32_to_utf8_be,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_32_be_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf32_to_utf8_be,s)
end
- return t
+ end
+ return t
end
utf32_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+ return s
+ end
end
local utf32_to_utf8_le_t=function(t)
- if not t then
- return nil
- elseif type(t)=="string" then
- t=lpegmatch(utf_32_le_linesplitter,t)
- end
- for i=1,#t do
- local s=t[i]
- if s~="" then
- t[i]=lpegmatch(p_utf32_to_utf8_le,s)
- end
+ if not t then
+ return nil
+ elseif type(t)=="string" then
+ t=lpegmatch(utf_32_le_linesplitter,t)
+ end
+ for i=1,#t do
+ local s=t[i]
+ if s~="" then
+ t[i]=lpegmatch(p_utf32_to_utf8_le,s)
end
- return t
+ end
+ return t
end
utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
@@ -5987,225 +5987,225 @@ utf.utf16_to_utf8_be=utf16_to_utf8_be
utf.utf32_to_utf8_le=utf32_to_utf8_le
utf.utf32_to_utf8_be=utf32_to_utf8_be
function utf.utf8_to_utf8_t(t)
- return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
+ return type(t)=="string" and lpegmatch(utflinesplitter,t) or t
end
function utf.utf16_to_utf8_t(t,endian)
- return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
+ return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t
end
function utf.utf32_to_utf8_t(t,endian)
- return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
+ return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t
end
local function little(b)
- if b<0x10000 then
- return char(b%256,rshift(b,8))
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
- end
+ if b<0x10000 then
+ return char(b%256,rshift(b,8))
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8))
+ end
end
local function big(b)
- if b<0x10000 then
- return char(rshift(b,8),b%256)
- else
- b=b-0x10000
- local b1=rshift(b,10)+0xD800
- local b2=b%1024+0xDC00
- return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
- end
+ if b<0x10000 then
+ return char(rshift(b,8),b%256)
+ else
+ b=b-0x10000
+ local b1=rshift(b,10)+0xD800
+ local b2=b%1024+0xDC00
+ return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256)
+ end
end
local l_remap=Cs((p_utf8byte/little+P(1)/"")^0)
local b_remap=Cs((p_utf8byte/big+P(1)/"")^0)
local function utf8_to_utf16_be(str,nobom)
- if nobom then
- return lpegmatch(b_remap,str)
- else
- return char(254,255)..lpegmatch(b_remap,str)
- end
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
end
local function utf8_to_utf16_le(str,nobom)
- if nobom then
- return lpegmatch(l_remap,str)
- else
- return char(255,254)..lpegmatch(l_remap,str)
- end
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
end
utf.utf8_to_utf16_be=utf8_to_utf16_be
utf.utf8_to_utf16_le=utf8_to_utf16_le
function utf.utf8_to_utf16(str,littleendian,nobom)
- if littleendian then
- return utf8_to_utf16_le(str,nobom)
- else
- return utf8_to_utf16_be(str,nobom)
- end
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
end
local pattern=Cs (
- (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
+ (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0
)
function utf.tocodes(str,separator)
- return lpegmatch(pattern,str,1,separator or " ")
+ return lpegmatch(pattern,str,1,separator or " ")
end
function utf.ustring(s)
- return format("U+%05X",type(s)=="number" and s or utfbyte(s))
+ return format("U+%05X",type(s)=="number" and s or utfbyte(s))
end
function utf.xstring(s)
- return format("0x%05X",type(s)=="number" and s or utfbyte(s))
+ return format("0x%05X",type(s)=="number" and s or utfbyte(s))
end
function utf.toeight(str)
- if not str or str=="" then
- return nil
- end
- local utftype=lpegmatch(p_utfstricttype,str)
- if utftype=="utf-8" then
- return sub(str,4)
- elseif utftype=="utf-16-be" then
- return utf16_to_utf8_be(str)
- elseif utftype=="utf-16-le" then
- return utf16_to_utf8_le(str)
- else
- return str
- end
+ if not str or str=="" then
+ return nil
+ end
+ local utftype=lpegmatch(p_utfstricttype,str)
+ if utftype=="utf-8" then
+ return sub(str,4)
+ elseif utftype=="utf-16-be" then
+ return utf16_to_utf8_be(str)
+ elseif utftype=="utf-16-le" then
+ return utf16_to_utf8_le(str)
+ else
+ return str
+ end
end
do
- local p_nany=p_utf8character/""
- local cache={}
- function utf.count(str,what)
- if type(what)=="string" then
- local p=cache[what]
- if not p then
- p=Cs((P(what)/" "+p_nany)^0)
- cache[p]=p
- end
- return #lpegmatch(p,str)
- else
- return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
- end
+ local p_nany=p_utf8character/""
+ local cache={}
+ function utf.count(str,what)
+ if type(what)=="string" then
+ local p=cache[what]
+ if not p then
+ p=Cs((P(what)/" "+p_nany)^0)
+ cache[p]=p
+ end
+ return #lpegmatch(p,str)
+ else
+ return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str)
end
+ end
end
if not string.utfvalues then
- local find=string.find
- local dummy=function()
- end
- function string.utfvalues(str)
- local n=#str
- if n==0 then
- return dummy
- elseif n==1 then
- return function() return utfbyte(str) end
- else
- local p=1
- return function()
- local b,e=find(str,".[\128-\191]*",p)
- if b then
- p=e+1
- return utfbyte(sub(str,b,e))
- end
- end
- end
+ local find=string.find
+ local dummy=function()
+ end
+ function string.utfvalues(str)
+ local n=#str
+ if n==0 then
+ return dummy
+ elseif n==1 then
+ return function() return utfbyte(str) end
+ else
+ local p=1
+ return function()
+ local b,e=find(str,".[\128-\191]*",p)
+ if b then
+ p=e+1
+ return utfbyte(sub(str,b,e))
+ end
+ end
end
+ end
end
utf.values=string.utfvalues
function utf.chrlen(u)
- return
- (u<0x80 and 1) or
- (u<0xE0 and 2) or
- (u<0xF0 and 3) or
- (u<0xF8 and 4) or
- (u<0xFC and 5) or
- (u<0xFE and 6) or 0
+ return
+ (u<0x80 and 1) or
+ (u<0xE0 and 2) or
+ (u<0xF0 and 3) or
+ (u<0xF8 and 4) or
+ (u<0xFC and 5) or
+ (u<0xFE and 6) or 0
end
if bit32 then
- local extract=bit32.extract
- local char=string.char
- function utf.toutf32string(n)
- if n<=0xFF then
- return
- char(n).."\000\000\000"
- elseif n<=0xFFFF then
- return
- char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
- elseif n<=0xFFFFFF then
- return
- char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
- else
- return
- char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
- end
- end
+ local extract=bit32.extract
+ local char=string.char
+ function utf.toutf32string(n)
+ if n<=0xFF then
+ return
+ char(n).."\000\000\000"
+ elseif n<=0xFFFF then
+ return
+ char(extract(n,0,8))..char(extract(n,8,8)).."\000\000"
+ elseif n<=0xFFFFFF then
+ return
+ char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000"
+ else
+ return
+ char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8))
+ end
+ end
end
local len=utf.len
local rep=rep
function string.utfpadd(s,n)
- if n and n~=0 then
- local l=len(s)
- if n>0 then
- local d=n-l
- if d>0 then
- return rep(c or " ",d)..s
- end
- else
- local d=- n-l
- if d>0 then
- return s..rep(c or " ",d)
- end
- end
+ if n and n~=0 then
+ local l=len(s)
+ if n>0 then
+ local d=n-l
+ if d>0 then
+ return rep(c or " ",d)..s
+ end
+ else
+ local d=- n-l
+ if d>0 then
+ return s..rep(c or " ",d)
+ end
end
- return s
+ end
+ return s
end
do
- local utfcharacters=utf.characters or string.utfcharacters
- local utfchar=utf.char or string.utfcharacter
- lpeg.UP=P
- if utfcharacters then
- function lpeg.US(str)
- local p=P(false)
- for uc in utfcharacters(str) do
- p=p+P(uc)
- end
- return p
- end
- else
- function lpeg.US(str)
- local p=P(false)
- local f=function(uc)
- p=p+P(uc)
- end
- lpegmatch((p_utf8char/f)^0,str)
- return p
- end
+ local utfcharacters=utf.characters or string.utfcharacters
+ local utfchar=utf.char or string.utfcharacter
+ lpeg.UP=P
+ if utfcharacters then
+ function lpeg.US(str)
+ local p=P(false)
+ for uc in utfcharacters(str) do
+ p=p+P(uc)
+ end
+ return p
end
- local range=p_utf8byte*p_utf8byte+Cc(false)
- function lpeg.UR(str,more)
- local first,last
- if type(str)=="number" then
- first=str
- last=more or first
- else
- first,last=lpegmatch(range,str)
- if not last then
- return P(str)
- end
- end
- if first==last then
- return P(str)
- end
- if not utfchar then
- utfchar=utf.char
- end
- if utfchar and (last-first<8) then
- local p=P(false)
- for i=first,last do
- p=p+P(utfchar(i))
- end
- return p
- else
- local f=function(b)
- return b>=first and b<=last
- end
- return p_utf8byte/f
- end
+ else
+ function lpeg.US(str)
+ local p=P(false)
+ local f=function(uc)
+ p=p+P(uc)
+ end
+ lpegmatch((p_utf8char/f)^0,str)
+ return p
+ end
+ end
+ local range=p_utf8byte*p_utf8byte+Cc(false)
+ function lpeg.UR(str,more)
+ local first,last
+ if type(str)=="number" then
+ first=str
+ last=more or first
+ else
+ first,last=lpegmatch(range,str)
+ if not last then
+ return P(str)
+ end
+ end
+ if first==last then
+ return P(str)
+ end
+ if not utfchar then
+ utfchar=utf.char
+ end
+ if utfchar and (last-first<8) then
+ local p=P(false)
+ for i=first,last do
+ p=p+P(utfchar(i))
+ end
+ return p
+ else
+ local f=function(b)
+ return b>=first and b<=last
+ end
+ return p_utf8byte/f
end
+ end
end
@@ -6215,93 +6215,93 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-math"] = package.loaded["l-math"] or true
--- original size: 2555, stripped down to: 1900
+-- original size: 2555, stripped down to: 1831
if not modules then modules={} end modules ['l-math']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not math.ceiling then
- math.ceiling=math.ceil
+ math.ceiling=math.ceil
end
if not math.round then
- local floor=math.floor
- function math.round(x) return floor(x+0.5) end
+ local floor=math.floor
+ function math.round(x) return floor(x+0.5) end
end
if not math.div then
- local floor=math.floor
- function math.div(n,m) return floor(n/m) end
+ local floor=math.floor
+ function math.div(n,m) return floor(n/m) end
end
if not math.mod then
- function math.mod(n,m) return n%m end
+ function math.mod(n,m) return n%m end
end
if not math.sind then
- local sin,cos,tan=math.sin,math.cos,math.tan
- local pipi=2*math.pi/360
- function math.sind(d) return sin(d*pipi) end
- function math.cosd(d) return cos(d*pipi) end
- function math.tand(d) return tan(d*pipi) end
+ local sin,cos,tan=math.sin,math.cos,math.tan
+ local pipi=2*math.pi/360
+ function math.sind(d) return sin(d*pipi) end
+ function math.cosd(d) return cos(d*pipi) end
+ function math.tand(d) return tan(d*pipi) end
end
if not math.odd then
- function math.odd (n) return n%2~=0 end
- function math.even(n) return n%2==0 end
+ function math.odd (n) return n%2~=0 end
+ function math.even(n) return n%2==0 end
end
if not math.cosh then
- local exp=math.exp
- function math.cosh(x)
- local xx=exp(x)
- return (xx+1/xx)/2
- end
- function math.sinh(x)
- local xx=exp(x)
- return (xx-1/xx)/2
- end
- function math.tanh(x)
- local xx=exp(x)
- return (xx-1/xx)/(xx+1/xx)
- end
+ local exp=math.exp
+ function math.cosh(x)
+ local xx=exp(x)
+ return (xx+1/xx)/2
+ end
+ function math.sinh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/2
+ end
+ function math.tanh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/(xx+1/xx)
+ end
end
if not math.pow then
- function math.pow(x,y)
- return x^y
- end
+ function math.pow(x,y)
+ return x^y
+ end
end
if not math.atan2 then
- math.atan2=math.atan
+ math.atan2=math.atan
end
if not math.ldexp then
- function math.ldexp(x,e)
- return x*2.0^e
- end
+ function math.ldexp(x,e)
+ return x*2.0^e
+ end
end
if not math.log10 then
- local log=math.log
- function math.log10(x)
- return log(x,10)
- end
+ local log=math.log
+ function math.log10(x)
+ return log(x,10)
+ end
end
if not math.type then
- function math.type()
- return "float"
- end
+ function math.type()
+ return "float"
+ end
end
if not math.tointeger then
- math.mininteger=-0x4FFFFFFFFFFF
- math.maxinteger=0x4FFFFFFFFFFF
- local floor=math.floor
- function math.tointeger(n)
- local f=floor(n)
- return f==n and f or nil
- end
+ math.mininteger=-0x4FFFFFFFFFFF
+ math.maxinteger=0x4FFFFFFFFFFF
+ local floor=math.floor
+ function math.tointeger(n)
+ local f=floor(n)
+ return f==n and f or nil
+ end
end
if not math.ult then
- local floor=math.floor
- function math.tointeger(m,n)
- return floor(m)<floor(n)
- end
+ local floor=math.floor
+ function math.tointeger(m,n)
+ return floor(m)<floor(n)
+ end
end
@@ -6311,14 +6311,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 43481, stripped down to: 23845
+-- original size: 43481, stripped down to: 23049
if not modules then modules={} end modules ['util-str']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.strings=utilities.strings or {}
@@ -6334,17 +6334,17 @@ local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
local loadstripped=nil
local oldfashioned=LUAVERSION<5.2
if oldfashioned then
- loadstripped=function(str,shortcuts)
- return load(str)
- end
+ loadstripped=function(str,shortcuts)
+ return load(str)
+ end
else
- loadstripped=function(str,shortcuts)
- if shortcuts then
- return load(dump(load(str),true),nil,nil,shortcuts)
- else
- return load(dump(load(str),true))
- end
+ loadstripped=function(str,shortcuts)
+ if shortcuts then
+ return load(dump(load(str),true),nil,nil,shortcuts)
+ else
+ return load(dump(load(str),true))
end
+ end
end
if not number then number={} end
local stripzero=patterns.stripzero
@@ -6362,32 +6362,32 @@ local period=patterns.period
local ptf=1/65536
local bpf=(7200/7227)/65536
local function points(n)
- if n==0 then
- return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
- return "0pt"
- end
- n=n*ptf
- if n%1==0 then
- return format("%ipt",n)
- end
- return lpegmatch(stripzeros,format("%.5fpt",n))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*ptf
+ if n%1==0 then
+ return format("%ipt",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fpt",n))
end
local function basepoints(n)
- if n==0 then
- return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
- return "0pt"
- end
- n=n*bpf
- if n%1==0 then
- return format("%ibp",n)
- end
- return lpegmatch(stripzeros,format("%.5fbp",n))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*bpf
+ if n%1==0 then
+ return format("%ibp",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fbp",n))
end
number.points=points
number.basepoints=basepoints
@@ -6399,65 +6399,65 @@ local trailing=(anyrubish^1*endofstring)/""
local redundant=rubish^3/"\n"
local pattern=Cs(leading*(trailing+redundant+stripped+anything)^0)
function strings.collapsecrlf(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local repeaters={}
function strings.newrepeater(str,offset)
- offset=offset or 0
- local s=repeaters[str]
- if not s then
- s={}
- repeaters[str]=s
- end
- local t=s[offset]
- if t then
- return t
- end
- t={}
- setmetatable(t,{ __index=function(t,k)
- if not k then
- return ""
- end
- local n=k+offset
- local s=n>0 and rep(str,n) or ""
- t[k]=s
- return s
- end })
- s[offset]=t
+ offset=offset or 0
+ local s=repeaters[str]
+ if not s then
+ s={}
+ repeaters[str]=s
+ end
+ local t=s[offset]
+ if t then
return t
+ end
+ t={}
+ setmetatable(t,{ __index=function(t,k)
+ if not k then
+ return ""
+ end
+ local n=k+offset
+ local s=n>0 and rep(str,n) or ""
+ t[k]=s
+ return s
+ end })
+ s[offset]=t
+ return t
end
local extra,tab,start=0,0,4,0
local nspaces=strings.newrepeater(" ")
string.nspaces=nspaces
local pattern=Carg(1)/function(t)
- extra,tab,start=0,t or 7,1
- end*Cs((
+ extra,tab,start=0,t or 7,1
+ end*Cs((
Cp()*patterns.tab/function(position)
- local current=(position-start+1)+extra
- local spaces=tab-(current-1)%tab
- if spaces>0 then
- extra=extra+spaces-1
- return nspaces[spaces]
- else
- return ""
- end
+ local current=(position-start+1)+extra
+ local spaces=tab-(current-1)%tab
+ if spaces>0 then
+ extra=extra+spaces-1
+ return nspaces[spaces]
+ else
+ return ""
+ end
end+newline*Cp()/function(position)
- extra,start=0,position
+ extra,start=0,position
end+anything
- )^1)
+ )^1)
function strings.tabtospace(str,tab)
- return lpegmatch(pattern,str,1,tab or 7)
+ return lpegmatch(pattern,str,1,tab or 7)
end
function string.utfpadding(s,n)
- if not n or n==0 then
- return ""
- end
- local l=utflen(s)
- if n>0 then
- return nspaces[n-l]
- else
- return nspaces[-n-l]
- end
+ if not n or n==0 then
+ return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
end
local optionalspace=spacer^0
local nospace=optionalspace/""
@@ -6475,130 +6475,130 @@ local notrailing=noleading*endofstring
local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 )
local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 )
local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 )
-local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
+local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
local p_retain_normal=Cs ((normalline+normalempty )^0 )
local p_retain_collapse=Cs ((normalline+doubleempty )^0 )
local p_retain_noempty=Cs ((normalline+singleempty )^0 )
local striplinepatterns={
- ["prune"]=p_prune_normal,
- ["prune and collapse"]=p_prune_collapse,
- ["prune and no empty"]=p_prune_noempty,
- ["prune and to space"]=p_prune_intospace,
- ["retain"]=p_retain_normal,
- ["retain and collapse"]=p_retain_collapse,
- ["retain and no empty"]=p_retain_noempty,
- ["collapse"]=patterns.collapser,
+ ["prune"]=p_prune_normal,
+ ["prune and collapse"]=p_prune_collapse,
+ ["prune and no empty"]=p_prune_noempty,
+ ["prune and to space"]=p_prune_intospace,
+ ["retain"]=p_retain_normal,
+ ["retain and collapse"]=p_retain_collapse,
+ ["retain and no empty"]=p_retain_noempty,
+ ["collapse"]=patterns.collapser,
}
setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end })
strings.striplinepatterns=striplinepatterns
function strings.striplines(str,how)
- return str and lpegmatch(striplinepatterns[how],str) or str
+ return str and lpegmatch(striplinepatterns[how],str) or str
end
function strings.collapse(str)
- return str and lpegmatch(p_prune_intospace,str) or str
+ return str and lpegmatch(p_prune_intospace,str) or str
end
strings.striplong=strings.striplines
function strings.nice(str)
- str=gsub(str,"[:%-+_]+"," ")
- return str
+ str=gsub(str,"[:%-+_]+"," ")
+ return str
end
local n=0
local sequenced=table.sequenced
function string.autodouble(s,sep)
- if s==nil then
- return '""'
- end
- local t=type(s)
- if t=="number" then
- return tostring(s)
- end
- if t=="table" then
- return ('"'..sequenced(s,sep or ",")..'"')
- end
- return ('"'..tostring(s)..'"')
+ if s==nil then
+ return '""'
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ('"'..sequenced(s,sep or ",")..'"')
+ end
+ return ('"'..tostring(s)..'"')
end
function string.autosingle(s,sep)
- if s==nil then
- return "''"
- end
- local t=type(s)
- if t=="number" then
- return tostring(s)
- end
- if t=="table" then
- return ("'"..sequenced(s,sep or ",").."'")
- end
- return ("'"..tostring(s).."'")
+ if s==nil then
+ return "''"
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ("'"..sequenced(s,sep or ",").."'")
+ end
+ return ("'"..tostring(s).."'")
end
local tracedchars={ [0]=
- "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
- "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
- "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
- "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
- "[space]",
+ "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
+ "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
+ "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
+ "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
+ "[space]",
}
string.tracedchars=tracedchars
strings.tracers=tracedchars
function string.tracedchar(b)
- if type(b)=="number" then
- return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
- else
- local c=utfbyte(b)
- return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
- end
+ if type(b)=="number" then
+ return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
+ else
+ local c=utfbyte(b)
+ return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
+ end
end
function number.signed(i)
- if i>0 then
- return "+",i
- else
- return "-",-i
- end
+ if i>0 then
+ return "+",i
+ else
+ return "-",-i
+ end
end
local two=digit*digit
local three=two*digit
local prefix=(Carg(1)*three)^1
local splitter=Cs (
- (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
+ (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
)
local splitter3=Cs (
- three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
+ three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
)
patterns.formattednumber=splitter
function number.formatted(n,sep1,sep2)
- if sep1==false then
- if type(n)=="number" then
- n=tostring(n)
- end
- return lpegmatch(splitter3,n,1,sep2 or ".")
+ if sep1==false then
+ if type(n)=="number" then
+ n=tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n)=="number" then
+ n=format("%0.2f",n)
+ end
+ if sep1==true then
+ return lpegmatch(splitter,n,1,".",",")
+ elseif sep1=="." then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
+ elseif sep1=="," then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
else
- if type(n)=="number" then
- n=format("%0.2f",n)
- end
- if sep1==true then
- return lpegmatch(splitter,n,1,".",",")
- elseif sep1=="." then
- return lpegmatch(splitter,n,1,sep1,sep2 or ",")
- elseif sep1=="," then
- return lpegmatch(splitter,n,1,sep1,sep2 or ".")
- else
- return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
- end
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
end
+ end
end
local p=Cs(
- P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
- )
+ P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
+ )
function number.compactfloat(n,fmt)
- if n==0 then
- return "0"
- elseif n==1 then
- return "1"
- end
- n=lpegmatch(p,format(fmt or "%0.3f",n))
- if n=="." or n=="" or n=="-" then
- return "0"
- end
- return n
+ if n==0 then
+ return "0"
+ elseif n==1 then
+ return "1"
+ end
+ n=lpegmatch(p,format(fmt or "%0.3f",n))
+ if n=="." or n=="" or n=="-" then
+ return "0"
+ end
+ return n
end
local zero=P("0")^1/""
local plus=P("+")/""
@@ -6609,41 +6609,41 @@ local exponent=(S("eE")*(plus+Cs((minus*zero^0*endofstring)/"")+minus)*zero^0*(e
local pattern_a=Cs(minus^0*digit^1*(separator/""*trailing+separator*(trailing+digit)^0)*exponent)
local pattern_b=Cs((exponent+anything)^0)
function number.sparseexponent(f,n)
- if not n then
- n=f
- f="%e"
- end
- local tn=type(n)
- if tn=="string" then
- local m=tonumber(n)
- if m then
- return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
- end
- elseif tn=="number" then
- return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ if not n then
+ n=f
+ f="%e"
+ end
+ local tn=type(n)
+ if tn=="string" then
+ local m=tonumber(n)
+ if m then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
end
- return tostring(n)
+ elseif tn=="number" then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ end
+ return tostring(n)
end
local hf={}
local hs={}
setmetatable(hf,{ __index=function(t,k)
- local v="%."..k.."f"
- t[k]=v
- return v
+ local v="%."..k.."f"
+ t[k]=v
+ return v
end } )
setmetatable(hs,{ __index=function(t,k)
- local v="%"..k.."s"
- t[k]=v
- return v
+ local v="%"..k.."s"
+ t[k]=v
+ return v
end } )
function number.formattedfloat(n,b,a)
- local s=format(hf[a],n)
- local l=(b or 0)+(a or 0)+1
- if #s<l then
- return format(hs[l],s)
- else
- return s
- end
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
end
local template=[[
%s
@@ -6652,7 +6652,7 @@ return function(%s) return %s end
]]
local preamble,environment="",{}
if oldfashioned then
- preamble=[[
+ preamble=[[
local lpeg=lpeg
local type=type
local tostring=tostring
@@ -6678,339 +6678,339 @@ local stripzero=lpeg.patterns.stripzero
local stripzeros=lpeg.patterns.stripzeros
]]
else
- environment={
- global=global or _G,
- lpeg=lpeg,
- type=type,
- tostring=tostring,
- tonumber=tonumber,
- format=string.format,
- concat=table.concat,
- signed=number.signed,
- points=number.points,
- basepoints=number.basepoints,
- utfchar=utf.char,
- utfbyte=utf.byte,
- lpegmatch=lpeg.match,
- nspaces=string.nspaces,
- utfpadding=string.utfpadding,
- tracedchar=string.tracedchar,
- autosingle=string.autosingle,
- autodouble=string.autodouble,
- sequenced=table.sequenced,
- formattednumber=number.formatted,
- sparseexponent=number.sparseexponent,
- formattedfloat=number.formattedfloat,
- stripzero=lpeg.patterns.stripzero,
- stripzeros=lpeg.patterns.stripzeros,
- }
+ environment={
+ global=global or _G,
+ lpeg=lpeg,
+ type=type,
+ tostring=tostring,
+ tonumber=tonumber,
+ format=string.format,
+ concat=table.concat,
+ signed=number.signed,
+ points=number.points,
+ basepoints=number.basepoints,
+ utfchar=utf.char,
+ utfbyte=utf.byte,
+ lpegmatch=lpeg.match,
+ nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
+ tracedchar=string.tracedchar,
+ autosingle=string.autosingle,
+ autodouble=string.autodouble,
+ sequenced=table.sequenced,
+ formattednumber=number.formatted,
+ sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat,
+ stripzero=lpeg.patterns.stripzero,
+ stripzeros=lpeg.patterns.stripzeros,
+ }
end
local arguments={ "a1" }
setmetatable(arguments,{ __index=function(t,k)
- local v=t[k-1]..",a"..k
- t[k]=v
- return v
- end
+ local v=t[k-1]..",a"..k
+ t[k]=v
+ return v
+ end
})
local prefix_any=C((sign+space+period+digit)^0)
local prefix_sub=(C((sign+digit)^0)+Cc(0))*period*(C((sign+digit)^0)+Cc(0))
local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
local format_s=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',a%s)",f,n)
- else
- return format("(a%s or '')",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("(a%s or '')",n)
+ end
end
local format_S=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',tostring(a%s))",f,n)
- else
- return format("tostring(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',tostring(a%s))",f,n)
+ else
+ return format("tostring(a%s)",n)
+ end
end
local format_right=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
- return format("(a%s or '')",n)
- elseif f>0 then
- return format("utfpadding(a%s,%i)..a%s",n,f,n)
- else
- return format("a%s..utfpadding(a%s,%i)",n,n,f)
- end
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ elseif f>0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
end
local format_left=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
- return format("(a%s or '')",n)
- end
- if f<0 then
- return format("utfpadding(a%s,%i)..a%s",n,-f,n)
- else
- return format("a%s..utfpadding(a%s,%i)",n,n,-f)
- end
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ end
+ if f<0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
end
local format_q=function()
- n=n+1
- return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
end
local format_Q=function()
- n=n+1
- return format("format('%%q',tostring(a%s))",n)
+ n=n+1
+ return format("format('%%q',tostring(a%s))",n)
end
local format_i=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%si',a%s)",f,n)
- else
- return format("format('%%i',a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%si',a%s)",f,n)
+ else
+ return format("format('%%i',a%s)",n)
+ end
end
local format_d=format_i
local format_I=function(f)
- n=n+1
- return format("format('%%s%%%si',signed(a%s))",f,n)
+ n=n+1
+ return format("format('%%s%%%si',signed(a%s))",f,n)
end
local format_f=function(f)
- n=n+1
- return format("format('%%%sf',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sf',a%s)",f,n)
end
local format_F=function(f)
- n=n+1
- if not f or f=="" then
- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
- else
- return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
- end
+ n=n+1
+ if not f or f=="" then
+ return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
+ else
+ return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
+ end
end
local format_k=function(b,a)
- n=n+1
- return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
+ n=n+1
+ return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
end
local format_g=function(f)
- n=n+1
- return format("format('%%%sg',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sg',a%s)",f,n)
end
local format_G=function(f)
- n=n+1
- return format("format('%%%sG',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sG',a%s)",f,n)
end
local format_e=function(f)
- n=n+1
- return format("format('%%%se',a%s)",f,n)
+ n=n+1
+ return format("format('%%%se',a%s)",f,n)
end
local format_E=function(f)
- n=n+1
- return format("format('%%%sE',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sE',a%s)",f,n)
end
local format_j=function(f)
- n=n+1
- return format("sparseexponent('%%%se',a%s)",f,n)
+ n=n+1
+ return format("sparseexponent('%%%se',a%s)",f,n)
end
local format_J=function(f)
- n=n+1
- return format("sparseexponent('%%%sE',a%s)",f,n)
+ n=n+1
+ return format("sparseexponent('%%%sE',a%s)",f,n)
end
local format_x=function(f)
- n=n+1
- return format("format('%%%sx',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sx',a%s)",f,n)
end
local format_X=function(f)
- n=n+1
- return format("format('%%%sX',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sX',a%s)",f,n)
end
local format_o=function(f)
- n=n+1
- return format("format('%%%so',a%s)",f,n)
+ n=n+1
+ return format("format('%%%so',a%s)",f,n)
end
local format_c=function()
- n=n+1
- return format("utfchar(a%s)",n)
+ n=n+1
+ return format("utfchar(a%s)",n)
end
local format_C=function()
- n=n+1
- return format("tracedchar(a%s)",n)
+ n=n+1
+ return format("tracedchar(a%s)",n)
end
local format_r=function(f)
- n=n+1
- return format("format('%%%s.0f',a%s)",f,n)
+ n=n+1
+ return format("format('%%%s.0f',a%s)",f,n)
end
local format_h=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_H=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_u=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_U=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_p=function()
- n=n+1
- return format("points(a%s)",n)
+ n=n+1
+ return format("points(a%s)",n)
end
local format_b=function()
- n=n+1
- return format("basepoints(a%s)",n)
+ n=n+1
+ return format("basepoints(a%s)",n)
end
local format_t=function(f)
- n=n+1
- if f and f~="" then
- return format("concat(a%s,%q)",n,f)
- else
- return format("concat(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("concat(a%s,%q)",n,f)
+ else
+ return format("concat(a%s)",n)
+ end
end
local format_T=function(f)
- n=n+1
- if f and f~="" then
- return format("sequenced(a%s,%q)",n,f)
- else
- return format("sequenced(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("sequenced(a%s,%q)",n,f)
+ else
+ return format("sequenced(a%s)",n)
+ end
end
local format_l=function()
- n=n+1
- return format("(a%s and 'true' or 'false')",n)
+ n=n+1
+ return format("(a%s and 'true' or 'false')",n)
end
local format_L=function()
- n=n+1
- return format("(a%s and 'TRUE' or 'FALSE')",n)
+ n=n+1
+ return format("(a%s and 'TRUE' or 'FALSE')",n)
end
local format_n=function()
- n=n+1
- return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+ n=n+1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
end
local format_N=function(f)
- n=n+1
- if not f or f=="" then
- f=".9"
- end
- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+ n=n+1
+ if not f or f=="" then
+ f=".9"
+ end
+ return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
end
local format_a=function(f)
- n=n+1
- if f and f~="" then
- return format("autosingle(a%s,%q)",n,f)
- else
- return format("autosingle(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("autosingle(a%s,%q)",n,f)
+ else
+ return format("autosingle(a%s)",n)
+ end
end
local format_A=function(f)
- n=n+1
- if f and f~="" then
- return format("autodouble(a%s,%q)",n,f)
- else
- return format("autodouble(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("autodouble(a%s,%q)",n,f)
+ else
+ return format("autodouble(a%s)",n)
+ end
end
local format_w=function(f)
- n=n+1
- f=tonumber(f)
- if f then
- return format("nspaces[%s+a%s]",f,n)
- else
- return format("nspaces[a%s]",n)
- end
+ n=n+1
+ f=tonumber(f)
+ if f then
+ return format("nspaces[%s+a%s]",f,n)
+ else
+ return format("nspaces[a%s]",n)
+ end
end
local format_W=function(f)
- return format("nspaces[%s]",tonumber(f) or 0)
+ return format("nspaces[%s]",tonumber(f) or 0)
end
local format_m=function(f)
- n=n+1
- if not f or f=="" then
- f=","
- end
- if f=="0" then
- return format([[formattednumber(a%s,false)]],n)
- else
- return format([[formattednumber(a%s,%q,".")]],n,f)
- end
+ n=n+1
+ if not f or f=="" then
+ f=","
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,".")]],n,f)
+ end
end
local format_M=function(f)
- n=n+1
- if not f or f=="" then
- f="."
- end
- if f=="0" then
- return format([[formattednumber(a%s,false)]],n)
- else
- return format([[formattednumber(a%s,%q,",")]],n,f)
- end
+ n=n+1
+ if not f or f=="" then
+ f="."
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,",")]],n,f)
+ end
end
local format_z=function(f)
- n=n+(tonumber(f) or 1)
- return "''"
+ n=n+(tonumber(f) or 1)
+ return "''"
end
local format_rest=function(s)
- return format("%q",s)
+ return format("%q",s)
end
local format_extension=function(extensions,f,name)
- local extension=extensions[name] or "tostring(%s)"
- local f=tonumber(f) or 1
- local w=find(extension,"%.%.%.")
- if f==0 then
- if w then
- extension=gsub(extension,"%.%.%.","")
- end
- return extension
- elseif f==1 then
- if w then
- extension=gsub(extension,"%.%.%.","%%s")
- end
- n=n+1
- local a="a"..n
- return format(extension,a,a)
- elseif f<0 then
- local a="a"..(n+f+1)
- return format(extension,a,a)
- else
- if w then
- extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
- end
- local t={}
- for i=1,f do
- n=n+1
- t[i]="a"..n
- end
- return format(extension,unpack(t))
+ local extension=extensions[name] or "tostring(%s)"
+ local f=tonumber(f) or 1
+ local w=find(extension,"%.%.%.")
+ if f==0 then
+ if w then
+ extension=gsub(extension,"%.%.%.","")
+ end
+ return extension
+ elseif f==1 then
+ if w then
+ extension=gsub(extension,"%.%.%.","%%s")
+ end
+ n=n+1
+ local a="a"..n
+ return format(extension,a,a)
+ elseif f<0 then
+ local a="a"..(n+f+1)
+ return format(extension,a,a)
+ else
+ if w then
+ extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
end
+ local t={}
+ for i=1,f do
+ n=n+1
+ t[i]="a"..n
+ end
+ return format(extension,unpack(t))
+ end
end
local builder=Cs { "start",
- start=(
- (
- P("%")/""*(
- V("!")
+ start=(
+ (
+ P("%")/""*(
+ V("!")
+V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
+V("c")+V("C")+V("S")
+V("Q")
@@ -7026,119 +7026,119 @@ local builder=Cs { "start",
+V("z")
+V(">")
+V("<")
- )+V("*")
- )*(endofstring+Carg(1))
- )^0,
- ["s"]=(prefix_any*P("s"))/format_s,
- ["q"]=(prefix_any*P("q"))/format_q,
- ["i"]=(prefix_any*P("i"))/format_i,
- ["d"]=(prefix_any*P("d"))/format_d,
- ["f"]=(prefix_any*P("f"))/format_f,
- ["F"]=(prefix_any*P("F"))/format_F,
- ["g"]=(prefix_any*P("g"))/format_g,
- ["G"]=(prefix_any*P("G"))/format_G,
- ["e"]=(prefix_any*P("e"))/format_e,
- ["E"]=(prefix_any*P("E"))/format_E,
- ["x"]=(prefix_any*P("x"))/format_x,
- ["X"]=(prefix_any*P("X"))/format_X,
- ["o"]=(prefix_any*P("o"))/format_o,
- ["S"]=(prefix_any*P("S"))/format_S,
- ["Q"]=(prefix_any*P("Q"))/format_Q,
- ["n"]=(prefix_any*P("n"))/format_n,
- ["N"]=(prefix_any*P("N"))/format_N,
- ["k"]=(prefix_sub*P("k"))/format_k,
- ["c"]=(prefix_any*P("c"))/format_c,
- ["C"]=(prefix_any*P("C"))/format_C,
- ["r"]=(prefix_any*P("r"))/format_r,
- ["h"]=(prefix_any*P("h"))/format_h,
- ["H"]=(prefix_any*P("H"))/format_H,
- ["u"]=(prefix_any*P("u"))/format_u,
- ["U"]=(prefix_any*P("U"))/format_U,
- ["p"]=(prefix_any*P("p"))/format_p,
- ["b"]=(prefix_any*P("b"))/format_b,
- ["t"]=(prefix_tab*P("t"))/format_t,
- ["T"]=(prefix_tab*P("T"))/format_T,
- ["l"]=(prefix_any*P("l"))/format_l,
- ["L"]=(prefix_any*P("L"))/format_L,
- ["I"]=(prefix_any*P("I"))/format_I,
- ["w"]=(prefix_any*P("w"))/format_w,
- ["W"]=(prefix_any*P("W"))/format_W,
- ["j"]=(prefix_any*P("j"))/format_j,
- ["J"]=(prefix_any*P("J"))/format_J,
- ["m"]=(prefix_any*P("m"))/format_m,
- ["M"]=(prefix_any*P("M"))/format_M,
- ["z"]=(prefix_any*P("z"))/format_z,
- ["a"]=(prefix_any*P("a"))/format_a,
- ["A"]=(prefix_any*P("A"))/format_A,
- ["<"]=(prefix_any*P("<"))/format_left,
- [">"]=(prefix_any*P(">"))/format_right,
- ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
- ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
- ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
+ )+V("*")
+ )*(endofstring+Carg(1))
+ )^0,
+ ["s"]=(prefix_any*P("s"))/format_s,
+ ["q"]=(prefix_any*P("q"))/format_q,
+ ["i"]=(prefix_any*P("i"))/format_i,
+ ["d"]=(prefix_any*P("d"))/format_d,
+ ["f"]=(prefix_any*P("f"))/format_f,
+ ["F"]=(prefix_any*P("F"))/format_F,
+ ["g"]=(prefix_any*P("g"))/format_g,
+ ["G"]=(prefix_any*P("G"))/format_G,
+ ["e"]=(prefix_any*P("e"))/format_e,
+ ["E"]=(prefix_any*P("E"))/format_E,
+ ["x"]=(prefix_any*P("x"))/format_x,
+ ["X"]=(prefix_any*P("X"))/format_X,
+ ["o"]=(prefix_any*P("o"))/format_o,
+ ["S"]=(prefix_any*P("S"))/format_S,
+ ["Q"]=(prefix_any*P("Q"))/format_Q,
+ ["n"]=(prefix_any*P("n"))/format_n,
+ ["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
+ ["c"]=(prefix_any*P("c"))/format_c,
+ ["C"]=(prefix_any*P("C"))/format_C,
+ ["r"]=(prefix_any*P("r"))/format_r,
+ ["h"]=(prefix_any*P("h"))/format_h,
+ ["H"]=(prefix_any*P("H"))/format_H,
+ ["u"]=(prefix_any*P("u"))/format_u,
+ ["U"]=(prefix_any*P("U"))/format_U,
+ ["p"]=(prefix_any*P("p"))/format_p,
+ ["b"]=(prefix_any*P("b"))/format_b,
+ ["t"]=(prefix_tab*P("t"))/format_t,
+ ["T"]=(prefix_tab*P("T"))/format_T,
+ ["l"]=(prefix_any*P("l"))/format_l,
+ ["L"]=(prefix_any*P("L"))/format_L,
+ ["I"]=(prefix_any*P("I"))/format_I,
+ ["w"]=(prefix_any*P("w"))/format_w,
+ ["W"]=(prefix_any*P("W"))/format_W,
+ ["j"]=(prefix_any*P("j"))/format_j,
+ ["J"]=(prefix_any*P("J"))/format_J,
+ ["m"]=(prefix_any*P("m"))/format_m,
+ ["M"]=(prefix_any*P("M"))/format_M,
+ ["z"]=(prefix_any*P("z"))/format_z,
+ ["a"]=(prefix_any*P("a"))/format_a,
+ ["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
+ ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
+ ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
+ ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
}
local xx=setmetatable({},{ __index=function(t,k) local v=format("%02x",k) t[k]=v return v end })
local XX=setmetatable({},{ __index=function(t,k) local v=format("%02X",k) t[k]=v return v end })
local preset={
- ["%02x"]=function(n) return xx[n] end,
- ["%02X"]=function(n) return XX[n] end,
+ ["%02x"]=function(n) return xx[n] end,
+ ["%02X"]=function(n) return XX[n] end,
}
local direct=P("%")*(sign+space+period+digit)^0*S("sqidfgGeExXo")*endofstring/[[local format = string.format return function(str) return format("%0",str) end]]
local function make(t,str)
- local f=preset[str]
- if f then
- return f
- end
- local p=lpegmatch(direct,str)
- if p then
- f=loadstripped(p)()
+ local f=preset[str]
+ if f then
+ return f
+ end
+ local p=lpegmatch(direct,str)
+ if p then
+ f=loadstripped(p)()
+ else
+ n=0
+ p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
+ if n>0 then
+ p=format(template,preamble,t._preamble_,arguments[n],p)
+ f=loadstripped(p,t._environment_)()
else
- n=0
- p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
- if n>0 then
- p=format(template,preamble,t._preamble_,arguments[n],p)
- f=loadstripped(p,t._environment_)()
- else
- f=function() return str end
- end
+ f=function() return str end
end
- t[str]=f
- return f
+ end
+ t[str]=f
+ return f
end
local function use(t,fmt,...)
- return t[fmt](...)
+ return t[fmt](...)
end
strings.formatters={}
if oldfashioned then
- function strings.formatters.new(noconcat)
- local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} }
- setmetatable(t,{ __index=make,__call=use })
- return t
- end
+ function strings.formatters.new(noconcat)
+ local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
+ end
else
- function strings.formatters.new(noconcat)
- local e={}
- for k,v in next,environment do
- e[k]=v
- end
- local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e }
- setmetatable(t,{ __index=make,__call=use })
- return t
+ function strings.formatters.new(noconcat)
+ local e={}
+ for k,v in next,environment do
+ e[k]=v
end
+ local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
+ end
end
local formatters=strings.formatters.new()
string.formatters=formatters
string.formatter=function(str,...) return formatters[str](...) end
local function add(t,name,template,preamble)
- if type(t)=="table" and t._type_=="formatter" then
- t._extensions_[name]=template or "%s"
- if type(preamble)=="string" then
- t._preamble_=preamble.."\n"..t._preamble_
- elseif type(preamble)=="table" then
- for k,v in next,preamble do
- t._environment_[k]=v
- end
- end
+ if type(t)=="table" and t._type_=="formatter" then
+ t._extensions_[name]=template or "%s"
+ if type(preamble)=="string" then
+ t._preamble_=preamble.."\n"..t._preamble_
+ elseif type(preamble)=="table" then
+ for k,v in next,preamble do
+ t._environment_[k]=v
+ end
end
+ end
end
strings.formatters.add=add
patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+anything)^0)
@@ -7146,44 +7146,44 @@ patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+anything)^0)
patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0)
patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"'))
if oldfashioned then
- add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
- add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
- add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
+ add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
+ add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
+ add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
else
- add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape })
- add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
- add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
+ add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape })
+ add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
+ add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
end
local dquote=patterns.dquote
local equote=patterns.escaped+dquote/'\\"'+1
local cquote=Cc('"')
-local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
+local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
+Cs(cquote*(equote-space)^0*space*equote^0*cquote)
function string.optionalquoted(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local pattern=Cs((newline/(os.newline or "\r")+1)^0)
function string.replacenewlines(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function strings.newcollector()
- local result,r={},0
- return
- function(fmt,str,...)
- r=r+1
- result[r]=str==nil and fmt or formatters[fmt](str,...)
- end,
- function(connector)
- if result then
- local str=concat(result,connector)
- result,r={},0
- return str
- end
- end
+ local result,r={},0
+ return
+ function(fmt,str,...)
+ r=r+1
+ result[r]=str==nil and fmt or formatters[fmt](str,...)
+ end,
+ function(connector)
+ if result then
+ local str=concat(result,connector)
+ result,r={},0
+ return str
+ end
+ end
end
local f_16_16=formatters["%0.5N"]
function number.to16dot16(n)
- return f_16_16(n/65536.0)
+ return f_16_16(n/65536.0)
end
@@ -7193,14 +7193,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 28756, stripped down to: 17693
+-- original size: 28756, stripped down to: 16104
if not modules then modules={} end modules ['util-tab']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.tables=utilities.tables or {}
@@ -7215,219 +7215,219 @@ local formatters=string.formatters
local utftoeight=utf.toeight
local splitter=lpeg.tsplitat(".")
function utilities.tables.definetable(target,nofirst,nolast)
- local composed,t=nil,{}
- local snippets=lpegmatch(splitter,target)
- for i=1,#snippets-(nolast and 1 or 0) do
- local name=snippets[i]
- if composed then
- composed=composed.."."..name
- t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
- else
- composed=name
- if not nofirst then
- t[#t+1]=formatters["%s = %s or { }"](composed,composed)
- end
- end
- end
+ local composed,t=nil,{}
+ local snippets=lpegmatch(splitter,target)
+ for i=1,#snippets-(nolast and 1 or 0) do
+ local name=snippets[i]
if composed then
- if nolast then
- composed=composed.."."..snippets[#snippets]
- end
- return concat(t,"\n"),composed
+ composed=composed.."."..name
+ t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
else
- return "",target
+ composed=name
+ if not nofirst then
+ t[#t+1]=formatters["%s = %s or { }"](composed,composed)
+ end
end
+ end
+ if composed then
+ if nolast then
+ composed=composed.."."..snippets[#snippets]
+ end
+ return concat(t,"\n"),composed
+ else
+ return "",target
+ end
end
function tables.definedtable(...)
- local t=_G
- for i=1,select("#",...) do
- local li=select(i,...)
- local tl=t[li]
- if not tl then
- tl={}
- t[li]=tl
- end
- t=tl
- end
- return t
+ local t=_G
+ for i=1,select("#",...) do
+ local li=select(i,...)
+ local tl=t[li]
+ if not tl then
+ tl={}
+ t[li]=tl
+ end
+ t=tl
+ end
+ return t
end
function tables.accesstable(target,root)
- local t=root or _G
- for name in gmatch(target,"([^%.]+)") do
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ for name in gmatch(target,"([^%.]+)") do
+ t=t[name]
+ if not t then
+ return
end
- return t
+ end
+ return t
end
function tables.migratetable(target,v,root)
- local t=root or _G
- local names=lpegmatch(splitter,target)
- for i=1,#names-1 do
- local name=names[i]
- t[name]=t[name] or {}
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ local names=lpegmatch(splitter,target)
+ for i=1,#names-1 do
+ local name=names[i]
+ t[name]=t[name] or {}
+ t=t[name]
+ if not t then
+ return
end
- t[names[#names]]=v
+ end
+ t[names[#names]]=v
end
function tables.removevalue(t,value)
- if value then
- for i=1,#t do
- if t[i]==value then
- remove(t,i)
- end
- end
+ if value then
+ for i=1,#t do
+ if t[i]==value then
+ remove(t,i)
+ end
end
+ end
end
function tables.replacevalue(t,oldvalue,newvalue)
- if oldvalue and newvalue then
- for i=1,#t do
- if t[i]==oldvalue then
- t[i]=newvalue
- end
- end
+ if oldvalue and newvalue then
+ for i=1,#t do
+ if t[i]==oldvalue then
+ t[i]=newvalue
+ end
end
+ end
end
function tables.insertbeforevalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i,extra)
+ return
end
- insert(t,1,extra)
+ end
+ insert(t,1,extra)
end
function tables.insertaftervalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i+1,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i+1,extra)
+ return
end
- insert(t,#t+1,extra)
+ end
+ insert(t,#t+1,extra)
end
local escape=Cs(Cc('"')*((P('"')/'""'+P(1))^0)*Cc('"'))
function table.tocsv(t,specification)
- if t and #t>0 then
- local result={}
- local r={}
- specification=specification or {}
- local fields=specification.fields
- if type(fields)~="string" then
- fields=sortedkeys(t[1])
- end
- local separator=specification.separator or ","
- local noffields=#fields
- if specification.preamble==true then
- for f=1,noffields do
- r[f]=lpegmatch(escape,tostring(fields[f]))
- end
- result[1]=concat(r,separator)
- end
- for i=1,#t do
- local ti=t[i]
- for f=1,noffields do
- local field=ti[fields[f]]
- if type(field)=="string" then
- r[f]=lpegmatch(escape,field)
- else
- r[f]=tostring(field)
- end
- end
- result[i+1]=concat(r,separator)
+ if t and #t>0 then
+ local result={}
+ local r={}
+ specification=specification or {}
+ local fields=specification.fields
+ if type(fields)~="string" then
+ fields=sortedkeys(t[1])
+ end
+ local separator=specification.separator or ","
+ local noffields=#fields
+ if specification.preamble==true then
+ for f=1,noffields do
+ r[f]=lpegmatch(escape,tostring(fields[f]))
+ end
+ result[1]=concat(r,separator)
+ end
+ for i=1,#t do
+ local ti=t[i]
+ for f=1,noffields do
+ local field=ti[fields[f]]
+ if type(field)=="string" then
+ r[f]=lpegmatch(escape,field)
+ else
+ r[f]=tostring(field)
end
- return concat(result,"\n")
- else
- return ""
+ end
+ result[i+1]=concat(r,separator)
end
+ return concat(result,"\n")
+ else
+ return ""
+ end
end
local nspaces=utilities.strings.newrepeater(" ")
local function toxml(t,d,result,step)
- local r=#result
- for k,v in sortedpairs(t) do
- local s=nspaces[d]
- local tk=type(k)
- local tv=type(v)
- if tv=="table" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</entry>"](s,k)
- else
- r=r+1 result[r]=formatters["%s<%s>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</%s>"](s,k)
- end
- elseif tv=="string" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
- end
- elseif tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
- end
+ local r=#result
+ for k,v in sortedpairs(t) do
+ local s=nspaces[d]
+ local tk=type(k)
+ local tv=type(v)
+ if tv=="table" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</entry>"](s,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</%s>"](s,k)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
+ end
+ elseif tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
end
+ end
end
function table.toxml(t,specification)
- specification=specification or {}
- local name=specification.name
- local noroot=name==false
- local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
- local indent=specification.indent or 0
- local spaces=specification.spaces or 1
- if noroot then
- toxml(t,indent,result,spaces)
- else
- toxml({ [name or "data"]=t },indent,result,spaces)
- end
- return concat(result,"\n")
+ specification=specification or {}
+ local name=specification.name
+ local noroot=name==false
+ local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
+ local indent=specification.indent or 0
+ local spaces=specification.spaces or 1
+ if noroot then
+ toxml(t,indent,result,spaces)
+ else
+ toxml({ [name or "data"]=t },indent,result,spaces)
+ end
+ return concat(result,"\n")
end
function tables.encapsulate(core,capsule,protect)
- if type(capsule)~="table" then
- protect=true
- capsule={}
- end
+ if type(capsule)~="table" then
+ protect=true
+ capsule={}
+ end
+ for key,value in next,core do
+ if capsule[key] then
+ print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
+ os.exit()
+ else
+ capsule[key]=value
+ end
+ end
+ if protect then
for key,value in next,core do
+ core[key]=nil
+ end
+ setmetatable(core,{
+ __index=capsule,
+ __newindex=function(t,key,value)
if capsule[key] then
- print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
- os.exit()
+ print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
+ os.exit()
else
- capsule[key]=value
+ rawset(t,key,value)
end
- end
- if protect then
- for key,value in next,core do
- core[key]=nil
- end
- setmetatable(core,{
- __index=capsule,
- __newindex=function(t,key,value)
- if capsule[key] then
- print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
- os.exit()
- else
- rawset(t,key,value)
- end
- end
- } )
- end
+ end
+ } )
+ end
end
local f_hashed_string=formatters["[%q]=%q,"]
local f_hashed_number=formatters["[%q]=%s,"]
@@ -7441,157 +7441,157 @@ local f_ordered_string=formatters["%q,"]
local f_ordered_number=formatters["%s,"]
local f_ordered_boolean=formatters["%l,"]
function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- for i=0,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
- end
- end
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ for i=0,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
- end
- end
- else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
- end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ else
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_hashed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_hashed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_hashed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
- return r
+ end
end
- return concat(fastserialize(t,true))
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
+ end
+ return concat(fastserialize(t,true))
end
function table.deserialize(str)
- if not str or str=="" then
- return
- end
- local code=load(str)
- if not code then
- return
- end
- code=code()
- if not code then
- return
- end
- return code
+ if not str or str=="" then
+ return
+ end
+ local code=load(str)
+ if not code then
+ return
+ end
+ code=code()
+ if not code then
+ return
+ end
+ return code
end
function table.load(filename,loader)
- if filename then
- local t=(loader or io.loaddata)(filename)
- if t and t~="" then
- local t=utftoeight(t)
- t=load(t)
- if type(t)=="function" then
- t=t()
- if type(t)=="table" then
- return t
- end
- end
+ if filename then
+ local t=(loader or io.loaddata)(filename)
+ if t and t~="" then
+ local t=utftoeight(t)
+ t=load(t)
+ if type(t)=="function" then
+ t=t()
+ if type(t)=="table" then
+ return t
end
+ end
end
+ end
end
function table.save(filename,t,n,...)
- io.savedata(filename,table.serialize(t,n==nil and true or n,...))
+ io.savedata(filename,table.serialize(t,n==nil and true or n,...))
end
local f_key_value=formatters["%s=%q"]
local f_add_table=formatters[" {%t},\n"]
local f_return_table=formatters["return {\n%t}"]
local function slowdrop(t)
- local r={}
- local l={}
- for i=1,#t do
- local ti=t[i]
- local j=0
- for k,v in next,ti do
- j=j+1
- l[j]=f_key_value(k,v)
- end
- r[i]=f_add_table(l)
- end
- return f_return_table(r)
+ local r={}
+ local l={}
+ for i=1,#t do
+ local ti=t[i]
+ local j=0
+ for k,v in next,ti do
+ j=j+1
+ l[j]=f_key_value(k,v)
+ end
+ r[i]=f_add_table(l)
+ end
+ return f_return_table(r)
end
local function fastdrop(t)
- local r={ "return {\n" }
- local m=1
- for i=1,#t do
- local ti=t[i]
- m=m+1 r[m]=" {"
- for k,v in next,ti do
- m=m+1 r[m]=f_key_value(k,v)
- end
- m=m+1 r[m]="},\n"
- end
- m=m+1
- r[m]="}"
- return concat(r)
+ local r={ "return {\n" }
+ local m=1
+ for i=1,#t do
+ local ti=t[i]
+ m=m+1 r[m]=" {"
+ for k,v in next,ti do
+ m=m+1 r[m]=f_key_value(k,v)
+ end
+ m=m+1 r[m]="},\n"
+ end
+ m=m+1
+ r[m]="}"
+ return concat(r)
end
function table.drop(t,slow)
- if #t==0 then
- return "return { }"
- elseif slow==true then
- return slowdrop(t)
- else
- return fastdrop(t)
- end
+ if #t==0 then
+ return "return { }"
+ elseif slow==true then
+ return slowdrop(t)
+ else
+ return fastdrop(t)
+ end
end
local selfmapper={ __index=function(t,k) t[k]=k return k end }
-function table.twowaymapper(t)
- if not t then
- t={}
- else
- local zero=rawget(t,0)
- for i=zero and 0 or 1,#t do
- local ti=t[i]
- if ti then
- local i=tostring(i)
- t[i]=ti
- t[ti]=i
- end
- end
+function table.twowaymapper(t)
+ if not t then
+ t={}
+ else
+ local zero=rawget(t,0)
+ for i=zero and 0 or 1,#t do
+ local ti=t[i]
+ if ti then
+ local i=tostring(i)
+ t[i]=ti
+ t[ti]=i
+ end
end
- setmetatable(t,selfmapper)
- return t
+ end
+ setmetatable(t,selfmapper)
+ return t
end
local f_start_key_idx=formatters["%w{"]
local f_start_key_num=formatters["%w[%s]={"]
@@ -7629,223 +7629,223 @@ local spaces=utilities.strings.newrepeater(" ")
local original_serialize=table.serialize
local is_simple_table=table.is_simple_table
local function serialize(root,name,specification)
- if type(specification)=="table" then
- return original_serialize(root,name,specification)
- end
- local t
- local n=1
- local unknown=false
- local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- n=n+1
- if indexed then
- t[n]=f_start_key_idx(depth)
+ if type(specification)=="table" then
+ return original_serialize(root,name,specification)
+ end
+ local t
+ local n=1
+ local unknown=false
+ local function do_serialize(root,name,depth,level,indexed)
+ if level>0 then
+ n=n+1
+ if indexed then
+ t[n]=f_start_key_idx(depth)
+ else
+ local tn=type(name)
+ if tn=="number" then
+ t[n]=f_start_key_num(depth,name)
+ elseif tn=="string" then
+ t[n]=f_start_key_str(depth,name)
+ elseif tn=="boolean" then
+ t[n]=f_start_key_boo(depth,name)
+ else
+ t[n]=f_start_key_nop(depth)
+ end
+ end
+ depth=depth+1
+ end
+ if root and next(root)~=nil then
+ local first=nil
+ local last=0
+ last=#root
+ for k=1,last do
+ if rawget(root,k)==nil then
+ last=k-1
+ break
+ end
+ end
+ if last>0 then
+ first=1
+ end
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if first and tk=="number" and k<=last and k>=first then
+ if tv=="number" then
+ n=n+1 t[n]=f_val_num(depth,v)
+ elseif tv=="string" then
+ n=n+1 t[n]=f_val_str(depth,v)
+ elseif tv=="table" then
+ if next(v)==nil then
+ n=n+1 t[n]=f_val_not(depth)
else
- local tn=type(name)
- if tn=="number" then
- t[n]=f_start_key_num(depth,name)
- elseif tn=="string" then
- t[n]=f_start_key_str(depth,name)
- elseif tn=="boolean" then
- t[n]=f_start_key_boo(depth,name)
- else
- t[n]=f_start_key_nop(depth)
- end
- end
- depth=depth+1
- end
- if root and next(root)~=nil then
- local first=nil
- local last=0
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
+ local st=is_simple_table(v)
+ if st then
+ n=n+1 t[n]=f_val_seq(depth,st)
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
end
- if last>0 then
- first=1
+ elseif tv=="boolean" then
+ n=n+1 t[n]=f_val_boo(depth,v)
+ elseif unknown then
+ n=n+1 t[n]=f_val_str(depth,tostring(v))
+ end
+ elseif tv=="number" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_num(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_num(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
+ end
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_not(depth,k)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_not(depth,k)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_not(depth,k)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
end
- local sk=sortedkeys(root)
- for i=1,#sk do
- local k=sk[i]
- local v=root[k]
- local tv=type(v)
- local tk=type(k)
- if first and tk=="number" and k<=last and k>=first then
- if tv=="number" then
- n=n+1 t[n]=f_val_num(depth,v)
- elseif tv=="string" then
- n=n+1 t[n]=f_val_str(depth,v)
- elseif tv=="table" then
- if next(v)==nil then
- n=n+1 t[n]=f_val_not(depth)
- else
- local st=is_simple_table(v)
- if st then
- n=n+1 t[n]=f_val_seq(depth,st)
- else
- do_serialize(v,k,depth,level+1,true)
- end
- end
- elseif tv=="boolean" then
- n=n+1 t[n]=f_val_boo(depth,v)
- elseif unknown then
- n=n+1 t[n]=f_val_str(depth,tostring(v))
- end
- elseif tv=="number" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_num(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_num(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
- end
- elseif tv=="string" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_not(depth,k)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_not(depth,k)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_not(depth,k)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
- end
- else
- local st=is_simple_table(v)
- if not st then
- do_serialize(v,k,depth,level+1)
- elseif tk=="number" then
- n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
- end
- end
- elseif tv=="boolean" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
- end
- else
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
- end
- end
+ else
+ local st=is_simple_table(v)
+ if not st then
+ do_serialize(v,k,depth,level+1)
+ elseif tk=="number" then
+ n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
end
- end
- if level>0 then
- n=n+1 t[n]=f_stop(depth-1)
- end
- end
- local tname=type(name)
- if tname=="string" then
- if name=="return" then
- t={ f_table_return() }
- else
- t={ f_table_name(name) }
- end
- elseif tname=="number" then
- t={ f_table_entry(name) }
- elseif tname=="boolean" then
- if name then
- t={ f_table_return() }
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
+ end
else
- t={ f_table_direct() }
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
+ end
end
+ end
+ end
+ if level>0 then
+ n=n+1 t[n]=f_stop(depth-1)
+ end
+ end
+ local tname=type(name)
+ if tname=="string" then
+ if name=="return" then
+ t={ f_table_return() }
else
- t={ f_table_name("t") }
+ t={ f_table_name(name) }
end
- if root then
- if getmetatable(root) then
- local dummy=root._w_h_a_t_e_v_e_r_
- root._w_h_a_t_e_v_e_r_=nil
- end
- if next(root)~=nil then
- local st=is_simple_table(root)
- if st then
- return t[1]..f_fin_seq(st)
- else
- do_serialize(root,name,1,0)
- end
- end
+ elseif tname=="number" then
+ t={ f_table_entry(name) }
+ elseif tname=="boolean" then
+ if name then
+ t={ f_table_return() }
+ else
+ t={ f_table_direct() }
+ end
+ else
+ t={ f_table_name("t") }
+ end
+ if root then
+ if getmetatable(root) then
+ local dummy=root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_=nil
+ end
+ if next(root)~=nil then
+ local st=is_simple_table(root)
+ if st then
+ return t[1]..f_fin_seq(st)
+ else
+ do_serialize(root,name,1,0)
+ end
end
- n=n+1
- t[n]=f_table_finish()
- return concat(t,"\n")
+ end
+ n=n+1
+ t[n]=f_table_finish()
+ return concat(t,"\n")
end
table.serialize=serialize
if setinspector then
- setinspector("table",function(v)
- if type(v)=="table" then
- print(serialize(v,"table",{ metacheck=false }))
- return true
- end
- end)
+ setinspector("table",function(v)
+ if type(v)=="table" then
+ print(serialize(v,"table",{ metacheck=false }))
+ return true
+ end
+ end)
end
local mt={
- __newindex=function(t,k,v)
- local n=t.last+1
- t.last=n
- t.list[n]=k
- t.hash[k]=v
- end,
- __index=function(t,k)
- return t.hash[k]
- end,
- __len=function(t)
- return t.last
- end,
+ __newindex=function(t,k,v)
+ local n=t.last+1
+ t.last=n
+ t.list[n]=k
+ t.hash[k]=v
+ end,
+ __index=function(t,k)
+ return t.hash[k]
+ end,
+ __len=function(t)
+ return t.last
+ end,
}
function table.orderedhash()
- return setmetatable({ list={},hash={},last=0 },mt)
+ return setmetatable({ list={},hash={},last=0 },mt)
end
function table.ordered(t)
- local n=t.last
- if n>0 then
- local l=t.list
- local i=1
- local h=t.hash
- local f=function()
- if i<=n then
- local k=i
- local v=h[l[k]]
- i=i+1
- return k,v
- end
- end
- return f,1,h[l[1]]
- else
- return function() end
+ local n=t.last
+ if n>0 then
+ local l=t.list
+ local i=1
+ local h=t.hash
+ local f=function()
+ if i<=n then
+ local k=i
+ local v=h[l[k]]
+ i=i+1
+ return k,v
+ end
end
+ return f,1,h[l[1]]
+ else
+ return function() end
+ end
end
@@ -7855,14 +7855,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fil"] = package.loaded["util-fil"] or true
--- original size: 8607, stripped down to: 6990
+-- original size: 8607, stripped down to: 6727
if not modules then modules={} end modules ['util-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber=tonumber
local byte=string.byte
@@ -7872,280 +7872,280 @@ local files={}
utilities.files=files
local zerobased={}
function files.open(filename,zb)
- local f=io.open(filename,"rb")
- if f then
- zerobased[f]=zb or false
- end
- return f
+ local f=io.open(filename,"rb")
+ if f then
+ zerobased[f]=zb or false
+ end
+ return f
end
function files.close(f)
- zerobased[f]=nil
- f:close()
+ zerobased[f]=nil
+ f:close()
end
function files.size(f)
- local current=f:seek()
- local size=f:seek("end")
- f:seek("set",current)
- return size
+ local current=f:seek()
+ local size=f:seek("end")
+ f:seek("set",current)
+ return size
end
files.getsize=files.size
function files.setposition(f,n)
- if zerobased[f] then
- f:seek("set",n)
- else
- f:seek("set",n-1)
- end
+ if zerobased[f] then
+ f:seek("set",n)
+ else
+ f:seek("set",n-1)
+ end
end
function files.getposition(f)
- if zerobased[f] then
- return f:seek()
- else
- return f:seek()+1
- end
+ if zerobased[f] then
+ return f:seek()
+ else
+ return f:seek()+1
+ end
end
function files.look(f,n,chars)
- local p=f:seek()
- local s=f:read(n)
- f:seek("set",p)
- if chars then
- return s
- else
- return byte(s,1,#s)
- end
+ local p=f:seek()
+ local s=f:read(n)
+ f:seek("set",p)
+ if chars then
+ return s
+ else
+ return byte(s,1,#s)
+ end
end
function files.skip(f,n)
- if n==1 then
- f:read(n)
- else
- f:seek("set",f:seek()+n)
- end
+ if n==1 then
+ f:read(n)
+ else
+ f:seek("set",f:seek()+n)
+ end
end
function files.readbyte(f)
- return byte(f:read(1))
+ return byte(f:read(1))
end
function files.readbytes(f,n)
- return byte(f:read(n),1,n)
+ return byte(f:read(n),1,n)
end
function files.readbytetable(f,n)
- local s=f:read(n or 1)
- return { byte(s,1,#s) }
+ local s=f:read(n or 1)
+ return { byte(s,1,#s) }
end
function files.readchar(f)
- return f:read(1)
+ return f:read(1)
end
function files.readstring(f,n)
- return f:read(n or 1)
+ return f:read(n or 1)
end
-function files.readinteger1(f)
- local n=byte(f:read(1))
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+function files.readinteger1(f)
+ local n=byte(f:read(1))
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-files.readcardinal1=files.readbyte
+files.readcardinal1=files.readbyte
files.readcardinal=files.readcardinal1
files.readinteger=files.readinteger1
files.readsignedbyte=files.readinteger1
function files.readcardinal2(f)
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
end
function files.readcardinal2le(f)
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
end
function files.readinteger2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function files.readinteger2le(f)
- local b,a=byte(f:read(2),1,2)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local b,a=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function files.readcardinal3(f)
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
end
function files.readcardinal3le(f)
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
end
function files.readinteger3(f)
- local a,b,c=byte(f:read(3),1,3)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local a,b,c=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function files.readinteger3le(f)
- local c,b,a=byte(f:read(3),1,3)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local c,b,a=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function files.readcardinal4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function files.readcardinal4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function files.readinteger4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function files.readinteger4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local d,c,b,a=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function files.readfixed2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- tonumber((a-0x100).."."..b)
- else
- tonumber((a ).."."..b)
- end
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function files.readfixed4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
- else
- tonumber((0x100*a+b ).."."..(0x100*c+d))
- end
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
end
if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function files.read2dot14(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- local n=-(0x100*a+b)
- return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- else
- local n=0x100*a+b
- return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- end
+ local extract=bit32.extract
+ local band=bit32.band
+ function files.read2dot14(f)
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+ else
+ local n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function files.skipshort(f,n)
- f:read(2*(n or 1))
+ f:read(2*(n or 1))
end
function files.skiplong(f,n)
- f:read(4*(n or 1))
+ f:read(4*(n or 1))
end
if bit32 then
- local rshift=bit32.rshift
- function files.writecardinal2(f,n)
- local a=char(n%256)
- n=rshift(n,8)
- local b=char(n%256)
- f:write(b,a)
- end
-else
- local floor=math.floor
- function files.writecardinal2(f,n)
- local a=char(n%256)
- n=floor(n/256)
- local b=char(n%256)
- f:write(b,a)
- end
-end
-function files.writecardinal4(f,n)
+ local rshift=bit32.rshift
+ function files.writecardinal2(f,n)
local a=char(n%256)
n=rshift(n,8)
local b=char(n%256)
- n=rshift(n,8)
- local c=char(n%256)
- n=rshift(n,8)
- local d=char(n%256)
- f:write(d,c,b,a)
+ f:write(b,a)
+ end
+else
+ local floor=math.floor
+ function files.writecardinal2(f,n)
+ local a=char(n%256)
+ n=floor(n/256)
+ local b=char(n%256)
+ f:write(b,a)
+ end
+end
+function files.writecardinal4(f,n)
+ local a=char(n%256)
+ n=rshift(n,8)
+ local b=char(n%256)
+ n=rshift(n,8)
+ local c=char(n%256)
+ n=rshift(n,8)
+ local d=char(n%256)
+ f:write(d,c,b,a)
end
function files.writestring(f,s)
- f:write(char(byte(s,1,#s)))
+ f:write(char(byte(s,1,#s)))
end
function files.writebyte(f,b)
- f:write(char(b))
+ f:write(char(b))
end
if fio and fio.readcardinal1 then
- files.readcardinal1=fio.readcardinal1
- files.readcardinal2=fio.readcardinal2
- files.readcardinal3=fio.readcardinal3
- files.readcardinal4=fio.readcardinal4
- files.readinteger1=fio.readinteger1
- files.readinteger2=fio.readinteger2
- files.readinteger3=fio.readinteger3
- files.readinteger4=fio.readinteger4
- files.readfixed2=fio.readfixed2
- files.readfixed4=fio.readfixed4
- files.read2dot14=fio.read2dot14
- files.setposition=fio.setposition
- files.getposition=fio.getposition
- files.readbyte=files.readcardinal1
- files.readsignedbyte=files.readinteger1
- files.readcardinal=files.readcardinal1
- files.readinteger=files.readinteger1
- local skipposition=fio.skipposition
- files.skipposition=skipposition
- files.readbytes=fio.readbytes
- files.readbytetable=fio.readbytetable
- function files.skipshort(f,n)
- skipposition(f,2*(n or 1))
- end
- function files.skiplong(f,n)
- skipposition(f,4*(n or 1))
- end
+ files.readcardinal1=fio.readcardinal1
+ files.readcardinal2=fio.readcardinal2
+ files.readcardinal3=fio.readcardinal3
+ files.readcardinal4=fio.readcardinal4
+ files.readinteger1=fio.readinteger1
+ files.readinteger2=fio.readinteger2
+ files.readinteger3=fio.readinteger3
+ files.readinteger4=fio.readinteger4
+ files.readfixed2=fio.readfixed2
+ files.readfixed4=fio.readfixed4
+ files.read2dot14=fio.read2dot14
+ files.setposition=fio.setposition
+ files.getposition=fio.getposition
+ files.readbyte=files.readcardinal1
+ files.readsignedbyte=files.readinteger1
+ files.readcardinal=files.readcardinal1
+ files.readinteger=files.readinteger1
+ local skipposition=fio.skipposition
+ files.skipposition=skipposition
+ files.readbytes=fio.readbytes
+ files.readbytetable=fio.readbytetable
+ function files.skipshort(f,n)
+ skipposition(f,2*(n or 1))
+ end
+ function files.skiplong(f,n)
+ skipposition(f,4*(n or 1))
+ end
end
if fio and fio.readcardinaltable then
- files.readcardinaltable=fio.readcardinaltable
- files.readintegertable=fio.readintegertable
+ files.readcardinaltable=fio.readcardinaltable
+ files.readintegertable=fio.readintegertable
else
- local readcardinal1=files.readcardinal1
- local readcardinal2=files.readcardinal2
- local readcardinal3=files.readcardinal3
- local readcardinal4=files.readcardinal4
- function files.readcardinaltable(f,n,b)
- local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
- return t
- end
- local readinteger1=files.readinteger1
- local readinteger2=files.readinteger2
- local readinteger3=files.readinteger3
- local readinteger4=files.readinteger4
- function files.readintegertable(f,n,b)
- local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
- return t
- end
+ local readcardinal1=files.readcardinal1
+ local readcardinal2=files.readcardinal2
+ local readcardinal3=files.readcardinal3
+ local readcardinal4=files.readcardinal4
+ function files.readcardinaltable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readcardinal1(f) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
+ return t
+ end
+ local readinteger1=files.readinteger1
+ local readinteger2=files.readinteger2
+ local readinteger3=files.readinteger3
+ local readinteger4=files.readinteger4
+ function files.readintegertable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readinteger1(f) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
+ return t
+ end
end
@@ -8155,14 +8155,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sac"] = package.loaded["util-sac"] or true
--- original size: 11065, stripped down to: 8695
+-- original size: 11065, stripped down to: 8209
if not modules then modules={} end modules ['util-sac']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local byte,sub=string.byte,string.sub
local tonumber=tonumber
@@ -8170,397 +8170,397 @@ utilities=utilities or {}
local streams={}
utilities.streams=streams
function streams.open(filename,zerobased)
- local f=filename and io.loaddata(filename)
- if f then
- return { f,1,#f,zerobased or false }
- end
+ local f=filename and io.loaddata(filename)
+ if f then
+ return { f,1,#f,zerobased or false }
+ end
end
function streams.openstring(f,zerobased)
- if f then
- return { f,1,#f,zerobased or false }
- end
+ if f then
+ return { f,1,#f,zerobased or false }
+ end
end
function streams.close()
end
function streams.size(f)
- return f and f[3] or 0
+ return f and f[3] or 0
end
function streams.setposition(f,i)
- if f[4] then
- if i<=0 then
- f[2]=1
- else
- f[2]=i+1
- end
+ if f[4] then
+ if i<=0 then
+ f[2]=1
else
- if i<=1 then
- f[2]=1
- else
- f[2]=i
- end
+ f[2]=i+1
end
-end
-function streams.getposition(f)
- if f[4] then
- return f[2]-1
+ else
+ if i<=1 then
+ f[2]=1
else
- return f[2]
+ f[2]=i
end
+ end
+end
+function streams.getposition(f)
+ if f[4] then
+ return f[2]-1
+ else
+ return f[2]
+ end
end
function streams.look(f,n,chars)
- local b=f[2]
- local e=b+n-1
- if chars then
- return sub(f[1],b,e)
- else
- return byte(f[1],b,e)
- end
+ local b=f[2]
+ local e=b+n-1
+ if chars then
+ return sub(f[1],b,e)
+ else
+ return byte(f[1],b,e)
+ end
end
function streams.skip(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readbyte(f)
- local i=f[2]
- f[2]=i+1
- return byte(f[1],i)
+ local i=f[2]
+ f[2]=i+1
+ return byte(f[1],i)
end
function streams.readbytes(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return byte(f[1],i,j-1)
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return byte(f[1],i,j-1)
end
function streams.readbytetable(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return { byte(f[1],i,j-1) }
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return { byte(f[1],i,j-1) }
end
function streams.skipbytes(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readchar(f)
- local i=f[2]
- f[2]=i+1
- return sub(f[1],i,i)
+ local i=f[2]
+ f[2]=i+1
+ return sub(f[1],i,i)
end
function streams.readstring(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return sub(f[1],i,j-1)
-end
-function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- local n=byte(f[1],i)
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return sub(f[1],i,j-1)
+end
+function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ local n=byte(f[1],i)
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-streams.readcardinal1=streams.readbyte
+streams.readcardinal1=streams.readbyte
streams.readcardinal=streams.readcardinal1
streams.readinteger=streams.readinteger1
function streams.readcardinal2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readcardinal2LE(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readinteger2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readinteger2le(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readcardinal3(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readcardinal3le(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readinteger3(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readinteger3le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readcardinal4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function streams.readinteger4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function streams.readinteger4le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local d,c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local d,c,b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function streams.readfixed2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- tonumber((a-0x100).."."..b)
- else
- tonumber((a ).."."..b)
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function streams.readfixed4(f)
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
+end
+if bit32 then
+ local extract=bit32.extract
+ local band=bit32.band
+ function streams.read2dot14(f)
local i=f[2]
- local j=i+3
+ local j=i+1
f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
+ local a,b=byte(f[1],i,j)
if a>=0x80 then
- tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
else
- tonumber((0x100*a+b ).."."..(0x100*c+d))
- end
-end
-if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function streams.read2dot14(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- local n=-(0x100*a+b)
- return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- else
- local n=0x100*a+b
- return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- end
+ local n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function streams.skipshort(f,n)
- f[2]=f[2]+2*(n or 1)
+ f[2]=f[2]+2*(n or 1)
end
function streams.skiplong(f,n)
- f[2]=f[2]+4*(n or 1)
+ f[2]=f[2]+4*(n or 1)
end
if sio and sio.readcardinal2 then
- local readcardinal1=sio.readcardinal1
- local readcardinal2=sio.readcardinal2
- local readcardinal3=sio.readcardinal3
- local readcardinal4=sio.readcardinal4
- local readinteger1=sio.readinteger1
- local readinteger2=sio.readinteger2
- local readinteger3=sio.readinteger3
- local readinteger4=sio.readinteger4
- local readfixed2=sio.readfixed2
- local readfixed4=sio.readfixed4
- local read2dot14=sio.read2dot14
- local readbytes=sio.readbytes
- local readbytetable=sio.readbytetable
- function streams.readcardinal1(f)
- local i=f[2]
- f[2]=i+1
- return readcardinal1(f[1],i)
- end
- function streams.readcardinal2(f)
- local i=f[2]
- f[2]=i+2
- return readcardinal2(f[1],i)
- end
- function streams.readcardinal3(f)
- local i=f[2]
- f[2]=i+3
- return readcardinal3(f[1],i)
- end
- function streams.readcardinal4(f)
- local i=f[2]
- f[2]=i+4
- return readcardinal4(f[1],i)
- end
- function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- return readinteger1(f[1],i)
- end
- function streams.readinteger2(f)
- local i=f[2]
- f[2]=i+2
- return readinteger2(f[1],i)
- end
- function streams.readinteger3(f)
- local i=f[2]
- f[2]=i+3
- return readinteger3(f[1],i)
- end
- function streams.readinteger4(f)
- local i=f[2]
- f[2]=i+4
- return readinteger4(f[1],i)
- end
- function streams.read2dot4(f)
- local i=f[2]
- f[2]=i+2
- return read2dot4(f[1],i)
- end
- function streams.readbytes(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytes(f[1],i,n)
+ local readcardinal1=sio.readcardinal1
+ local readcardinal2=sio.readcardinal2
+ local readcardinal3=sio.readcardinal3
+ local readcardinal4=sio.readcardinal4
+ local readinteger1=sio.readinteger1
+ local readinteger2=sio.readinteger2
+ local readinteger3=sio.readinteger3
+ local readinteger4=sio.readinteger4
+ local readfixed2=sio.readfixed2
+ local readfixed4=sio.readfixed4
+ local read2dot14=sio.read2dot14
+ local readbytes=sio.readbytes
+ local readbytetable=sio.readbytetable
+ function streams.readcardinal1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readcardinal1(f[1],i)
+ end
+ function streams.readcardinal2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readcardinal2(f[1],i)
+ end
+ function streams.readcardinal3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readcardinal3(f[1],i)
+ end
+ function streams.readcardinal4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readcardinal4(f[1],i)
+ end
+ function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readinteger1(f[1],i)
+ end
+ function streams.readinteger2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readinteger2(f[1],i)
+ end
+ function streams.readinteger3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readinteger3(f[1],i)
+ end
+ function streams.readinteger4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readinteger4(f[1],i)
+ end
+ function streams.read2dot4(f)
+ local i=f[2]
+ f[2]=i+2
+ return read2dot4(f[1],i)
+ end
+ function streams.readbytes(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- function streams.readbytetable(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytetable(f[1],i,n)
+ return readbytes(f[1],i,n)
+ end
+ function streams.readbytetable(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- streams.readbyte=streams.readcardinal1
- streams.readsignedbyte=streams.readinteger1
- streams.readcardinal=streams.readcardinal1
- streams.readinteger=streams.readinteger1
+ return readbytetable(f[1],i,n)
+ end
+ streams.readbyte=streams.readcardinal1
+ streams.readsignedbyte=streams.readinteger1
+ streams.readcardinal=streams.readcardinal1
+ streams.readinteger=streams.readinteger1
end
if sio and sio.readcardinaltable then
- local readcardinaltable=sio.readcardinaltable
- local readintegertable=sio.readintegertable
- function utilities.streams.readcardinaltable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readcardinaltable(f[1],i,n,b)
+ local readcardinaltable=sio.readcardinaltable
+ local readintegertable=sio.readintegertable
+ function utilities.streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- function utilities.streams.readintegertable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readintegertable(f[1],i,n,b)
+ return readcardinaltable(f[1],i,n,b)
+ end
+ function utilities.streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
+ return readintegertable(f[1],i,n,b)
+ end
else
- local readcardinal1=streams.readcardinal1
- local readcardinal2=streams.readcardinal2
- local readcardinal3=streams.readcardinal3
- local readcardinal4=streams.readcardinal4
- function streams.readcardinaltable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
- return t
+ local readcardinal1=streams.readcardinal1
+ local readcardinal2=streams.readcardinal2
+ local readcardinal3=streams.readcardinal3
+ local readcardinal4=streams.readcardinal4
+ function streams.readcardinaltable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- local readinteger1=streams.readinteger1
- local readinteger2=streams.readinteger2
- local readinteger3=streams.readinteger3
- local readinteger4=streams.readinteger4
- function streams.readintegertable(f,n,b)
- local i=f[2]
- local s=f[3]
- local p=i+n*b
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
- return t
+ local t={}
+ if b==1 then for i=1,n do t[i]=readcardinal1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f[1],i) end end
+ return t
+ end
+ local readinteger1=streams.readinteger1
+ local readinteger2=streams.readinteger2
+ local readinteger3=streams.readinteger3
+ local readinteger4=streams.readinteger4
+ function streams.readintegertable(f,n,b)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n*b
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
+ local t={}
+ if b==1 then for i=1,n do t[i]=readinteger1(f[1],i) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f[1],i) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f[1],i) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f[1],i) end end
+ return t
+ end
end
@@ -8570,168 +8570,168 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sto"] = package.loaded["util-sto"] or true
--- original size: 6661, stripped down to: 3245
+-- original size: 6661, stripped down to: 3074
if not modules then modules={} end modules ['util-sto']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type
utilities=utilities or {}
utilities.storage=utilities.storage or {}
local storage=utilities.storage
function storage.mark(t)
- if not t then
- print("\nfatal error: storage cannot be marked\n")
- os.exit()
- return
- end
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ if not t then
+ print("\nfatal error: storage cannot be marked\n")
+ os.exit()
+ return
+ end
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.allocate(t)
- t=t or {}
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ t=t or {}
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.marked(t)
- local m=getmetatable(t)
- return m and m.__storage__
+ local m=getmetatable(t)
+ return m and m.__storage__
end
function storage.checked(t)
- if not t then
- report("\nfatal error: storage has not been allocated\n")
- os.exit()
- return
- end
- return t
+ if not t then
+ report("\nfatal error: storage has not been allocated\n")
+ os.exit()
+ return
+ end
+ return t
end
function storage.setinitializer(data,initialize)
- local m=getmetatable(data) or {}
- m.__index=function(data,k)
- m.__index=nil
- initialize()
- return data[k]
- end
- setmetatable(data,m)
+ local m=getmetatable(data) or {}
+ m.__index=function(data,k)
+ m.__index=nil
+ initialize()
+ return data[k]
+ end
+ setmetatable(data,m)
end
local keyisvalue={ __index=function(t,k)
- t[k]=k
- return k
+ t[k]=k
+ return k
end }
function storage.sparse(t)
- t=t or {}
- setmetatable(t,keyisvalue)
- return t
-end
-local function f_empty () return "" end
-local function f_self (t,k) t[k]=k return k end
-local function f_table (t,k) local v={} t[k]=v return v end
-local function f_number(t,k) t[k]=0 return 0 end
-local function f_ignore() end
+ t=t or {}
+ setmetatable(t,keyisvalue)
+ return t
+end
+local function f_empty () return "" end
+local function f_self (t,k) t[k]=k return k end
+local function f_table (t,k) local v={} t[k]=v return v end
+local function f_number(t,k) t[k]=0 return 0 end
+local function f_ignore() end
local f_index={
- ["empty"]=f_empty,
- ["self"]=f_self,
- ["table"]=f_table,
- ["number"]=f_number,
+ ["empty"]=f_empty,
+ ["self"]=f_self,
+ ["table"]=f_table,
+ ["number"]=f_number,
}
function table.setmetatableindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- else
- setmetatable(t,{ __index=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ else
+ setmetatable(t,{ __index=i })
+ end
+ return t
end
local f_index={
- ["ignore"]=f_ignore,
+ ["ignore"]=f_ignore,
}
function table.setmetatablenewindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__newindex=i
- else
- setmetatable(t,{ __newindex=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__newindex=i
+ else
+ setmetatable(t,{ __newindex=i })
+ end
+ return t
end
function table.setmetatablecall(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- if m then
- m.__call=f
- else
- setmetatable(t,{ __call=f })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__call=f
+ else
+ setmetatable(t,{ __call=f })
+ end
+ return t
end
function table.setmetatableindices(t,f,n,c)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- m.__newindex=n
- m.__call=c
- else
- setmetatable(t,{
- __index=i,
- __newindex=n,
- __call=c,
- })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ m.__newindex=n
+ m.__call=c
+ else
+ setmetatable(t,{
+ __index=i,
+ __newindex=n,
+ __call=c,
+ })
+ end
+ return t
end
function table.setmetatablekey(t,key,value)
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m[key]=value
- return t
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m[key]=value
+ return t
end
function table.getmetatablekey(t,key,value)
- local m=getmetatable(t)
- return m and m[key]
+ local m=getmetatable(t)
+ return m and m[key]
end
function table.makeweak(t)
- if not t then
- t={}
- end
- local m=getmetatable(t)
- if m then
- m.__mode="v"
- else
- setmetatable(t,{ __mode="v" })
- end
- return t
+ if not t then
+ t={}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__mode="v"
+ else
+ setmetatable(t,{ __mode="v" })
+ end
+ return t
end
@@ -8741,14 +8741,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 23400, stripped down to: 16473
+-- original size: 23400, stripped down to: 15802
if not modules then modules={} end modules ['util-prs']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local lpeg,table,string=lpeg,table,string
local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp
@@ -8790,8 +8790,8 @@ local noparent=1-(lparent+rparent)
local nobracket=1-(lbracket+rbracket)
local escape,left,right=P("\\"),P('{'),P('}')
lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+ [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
+ [2]=left*V(1)*right
}
local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -8799,9 +8799,9 @@ local nestedbrackets=P { lbracket*(nobracket+V(1))^0*rbracket }
local spaces=space^0
local argument=Cs((lbrace/"")*((nobrace+nestedbraces)^0)*(rbrace/""))
local content=(1-endofstring)^0
-lpegpatterns.nestedbraces=nestedbraces
+lpegpatterns.nestedbraces=nestedbraces
lpegpatterns.nestedparents=nestedparents
-lpegpatterns.nested=nestedbraces
+lpegpatterns.nested=nestedbraces
lpegpatterns.argument=argument
lpegpatterns.content=content
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
@@ -8813,7 +8813,7 @@ local key=C((1-space-equal-comma)^1)
local pattern_b=spaces*comma^0*spaces*(key*((spaces*equal*spaces*value)+C("")))
local hash={}
local function set(key,value)
- hash[key]=value
+ hash[key]=value
end
local pattern_a_s=(pattern_a/set)^1
local pattern_b_s=(pattern_b/set)^1
@@ -8824,300 +8824,300 @@ patterns.settings_to_hash_b=pattern_b_s
patterns.settings_to_hash_c=pattern_c_s
patterns.settings_to_hash_d=pattern_d_s
function parsers.make_settings_to_hash_pattern(set,how)
- if how=="strict" then
- return (pattern_c/set)^1
- elseif how=="tolerant" then
- return (pattern_b/set)^1
- else
- return (pattern_a/set)^1
- end
+ if how=="strict" then
+ return (pattern_c/set)^1
+ elseif how=="tolerant" then
+ return (pattern_b/set)^1
+ else
+ return (pattern_a/set)^1
+ end
end
function parsers.settings_to_hash(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_a_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_a_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_colon_too(str)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- else
- hash={}
- lpegmatch(pattern_d_s,str)
- return hash
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ else
+ hash={}
+ lpegmatch(pattern_d_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_tolerant(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_b_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_b_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_strict(str,existing)
- if not str or str=="" then
- return nil
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
- elseif str and str~="" then
- hash=existing or {}
- lpegmatch(pattern_c_s,str)
- return next(hash) and hash
+ if not str or str=="" then
+ return nil
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
+ else
+ return str
end
+ elseif str and str~="" then
+ hash=existing or {}
+ lpegmatch(pattern_c_s,str)
+ return next(hash) and hash
+ end
end
local separator=comma*space^0
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-comma))^0)
local pattern=spaces*Ct(value*(separator*value)^0)
patterns.settings_to_array=pattern
function parsers.settings_to_array(str,strict)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- elseif strict then
- if find(str,"{",1,true) then
- return lpegmatch(pattern,str)
- else
- return { str }
- end
- elseif find(str,",",1,true) then
- return lpegmatch(pattern,str)
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ elseif strict then
+ if find(str,"{",1,true) then
+ return lpegmatch(pattern,str)
else
- return { str }
+ return { str }
end
+ elseif find(str,",",1,true) then
+ return lpegmatch(pattern,str)
+ else
+ return { str }
+ end
end
function parsers.settings_to_numbers(str)
- if not str or str=="" then
- return {}
- end
- if type(str)=="table" then
- elseif find(str,",",1,true) then
- str=lpegmatch(pattern,str)
- else
- return { tonumber(str) }
- end
- for i=1,#str do
- str[i]=tonumber(str[i])
- end
- return str
+ if not str or str=="" then
+ return {}
+ end
+ if type(str)=="table" then
+ elseif find(str,",",1,true) then
+ str=lpegmatch(pattern,str)
+ else
+ return { tonumber(str) }
+ end
+ for i=1,#str do
+ str[i]=tonumber(str[i])
+ end
+ return str
end
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
local pattern=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_obey_fences(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache_a={}
local cache_b={}
function parsers.groupedsplitat(symbol,withaction)
- if not symbol then
- symbol=","
- end
- local pattern=(withaction and cache_b or cache_a)[symbol]
- if not pattern then
- local symbols=S(symbol)
- local separator=space^0*symbols*space^0
- local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
- if withaction then
- local withvalue=Carg(1)*value/function(f,s) return f(s) end
- pattern=spaces*withvalue*(separator*withvalue)^0
- cache_b[symbol]=pattern
- else
- pattern=spaces*Ct(value*(separator*value)^0)
- cache_a[symbol]=pattern
- end
- end
- return pattern
+ if not symbol then
+ symbol=","
+ end
+ local pattern=(withaction and cache_b or cache_a)[symbol]
+ if not pattern then
+ local symbols=S(symbol)
+ local separator=space^0*symbols*space^0
+ local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
+ if withaction then
+ local withvalue=Carg(1)*value/function(f,s) return f(s) end
+ pattern=spaces*withvalue*(separator*withvalue)^0
+ cache_b[symbol]=pattern
+ else
+ pattern=spaces*Ct(value*(separator*value)^0)
+ cache_a[symbol]=pattern
+ end
+ end
+ return pattern
end
local pattern_a=parsers.groupedsplitat(",",false)
local pattern_b=parsers.groupedsplitat(",",true)
function parsers.stripped_settings_to_array(str)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_a,str)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_a,str)
+ end
end
function parsers.process_stripped_settings(str,action)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_b,str,1,action)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_b,str,1,action)
+ end
end
local function set(t,v)
- t[#t+1]=v
+ t[#t+1]=v
end
local value=P(Carg(1)*value)/set
local pattern=value*(separator*value)^0*Carg(1)
function parsers.add_settings_to_array(t,str)
- return lpegmatch(pattern,str,nil,t)
+ return lpegmatch(pattern,str,nil,t)
end
function parsers.hash_to_string(h,separator,yes,no,strict,omit)
- if h then
- local t,tn,s={},0,sortedkeys(h)
- omit=omit and tohash(omit)
- for i=1,#s do
- local key=s[i]
- if not omit or not omit[key] then
- local value=h[key]
- if type(value)=="boolean" then
- if yes and no then
- if value then
- tn=tn+1
- t[tn]=key..'='..yes
- elseif not strict then
- tn=tn+1
- t[tn]=key..'='..no
- end
- elseif value or not strict then
- tn=tn+1
- t[tn]=key..'='..tostring(value)
- end
- else
- tn=tn+1
- t[tn]=key..'='..value
- end
- end
+ if h then
+ local t,tn,s={},0,sortedkeys(h)
+ omit=omit and tohash(omit)
+ for i=1,#s do
+ local key=s[i]
+ if not omit or not omit[key] then
+ local value=h[key]
+ if type(value)=="boolean" then
+ if yes and no then
+ if value then
+ tn=tn+1
+ t[tn]=key..'='..yes
+ elseif not strict then
+ tn=tn+1
+ t[tn]=key..'='..no
+ end
+ elseif value or not strict then
+ tn=tn+1
+ t[tn]=key..'='..tostring(value)
+ end
+ else
+ tn=tn+1
+ t[tn]=key..'='..value
end
- return concat(t,separator or ",")
- else
- return ""
+ end
end
+ return concat(t,separator or ",")
+ else
+ return ""
+ end
end
function parsers.array_to_string(a,separator)
- if a then
- return concat(a,separator or ",")
- else
- return ""
- end
+ if a then
+ return concat(a,separator or ",")
+ else
+ return ""
+ end
end
local pattern=Cf(Ct("")*Cg(C((1-S(", "))^1)*S(", ")^0*Cc(true))^1,rawset)
function utilities.parsers.settings_to_set(str)
- return str and lpegmatch(pattern,str) or {}
+ return str and lpegmatch(pattern,str) or {}
end
hashes.settings_to_set=table.setmetatableindex(function(t,k)
- local v=k and lpegmatch(pattern,k) or {}
- t[k]=v
- return v
+ local v=k and lpegmatch(pattern,k) or {}
+ t[k]=v
+ return v
end)
getmetatable(hashes.settings_to_set).__mode="kv"
function parsers.simple_hash_to_string(h,separator)
- local t,tn={},0
- for k,v in sortedhash(h) do
- if v then
- tn=tn+1
- t[tn]=k
- end
+ local t,tn={},0
+ for k,v in sortedhash(h) do
+ if v then
+ tn=tn+1
+ t[tn]=k
end
- return concat(t,separator or ",")
+ end
+ return concat(t,separator or ",")
end
local str=Cs(lpegpatterns.unquoted)+C((1-whitespace-equal)^1)
local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset)
local splitter=setting^1
function utilities.parsers.options_to_hash(str,target)
- return str and lpegmatch(splitter,str,1,target or {}) or {}
+ return str and lpegmatch(splitter,str,1,target or {}) or {}
end
local splitter=lpeg.tsplitat(" ")
function utilities.parsers.options_to_array(str)
- return str and lpegmatch(splitter,str) or {}
+ return str and lpegmatch(splitter,str) or {}
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1)
local pattern_a=spaces*Ct(value*(separator*value)^0)
local function repeater(n,str)
- if not n then
- return str
+ if not n then
+ return str
+ else
+ local s=lpegmatch(pattern_a,str)
+ if n==1 then
+ return unpack(s)
else
- local s=lpegmatch(pattern_a,str)
- if n==1 then
- return unpack(s)
- else
- local t,tn={},0
- for i=1,n do
- for j=1,#s do
- tn=tn+1
- t[tn]=s[j]
- end
- end
- return unpack(t)
+ local t,tn={},0
+ for i=1,n do
+ for j=1,#s do
+ tn=tn+1
+ t[tn]=s[j]
end
+ end
+ return unpack(t)
end
+ end
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+(C(digit^1)/tonumber*lparent*Cs((noparent+nestedparents)^1)*rparent)/repeater+C((nestedbraces+(1-comma))^1)
local pattern_b=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_with_repeat(str,expand)
- if expand then
- return lpegmatch(pattern_b,str) or {}
- else
- return lpegmatch(pattern_a,str) or {}
- end
+ if expand then
+ return lpegmatch(pattern_b,str) or {}
+ else
+ return lpegmatch(pattern_a,str) or {}
+ end
end
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace
local pattern=Ct((space+value)^0)
function parsers.arguments_to_table(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function parsers.getparameters(self,class,parentclass,settings)
- local sc=self[class]
- if not sc then
- sc={}
- self[class]=sc
- if parentclass then
- local sp=self[parentclass]
- if not sp then
- sp={}
- self[parentclass]=sp
- end
- setmetatableindex(sc,sp)
- end
+ local sc=self[class]
+ if not sc then
+ sc={}
+ self[class]=sc
+ if parentclass then
+ local sp=self[parentclass]
+ if not sp then
+ sp={}
+ self[parentclass]=sp
+ end
+ setmetatableindex(sc,sp)
end
- parsers.settings_to_hash(settings,sc)
+ end
+ parsers.settings_to_hash(settings,sc)
end
function parsers.listitem(str)
- return gmatch(str,"[^, ]+")
+ return gmatch(str,"[^, ]+")
end
local pattern=Cs { "start",
- start=V("one")+V("two")+V("three"),
- rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
- thousand=digit*digit*digit,
- one=digit*V("rest"),
- two=digit*digit*V("rest"),
- three=V("thousand")*V("rest"),
+ start=V("one")+V("two")+V("three"),
+ rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
+ thousand=digit*digit*digit,
+ one=digit*V("rest"),
+ two=digit*digit*V("rest"),
+ three=V("thousand")*V("rest"),
}
lpegpatterns.splitthousands=pattern
function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local optionalwhitespace=whitespace^0
lpegpatterns.words=Ct((Cs((1-punctuation-whitespace)^1)+anything)^1)
@@ -9131,75 +9131,75 @@ local key=C((1-equal)^1)
local value=dquote*C((1-dquote-escape*dquote)^0)*dquote
local pattern=Cf(Ct("")*(Cg(key*equal*value)*separator^0)^1,rawset)^0*P(-1)
function parsers.keq_to_hash(str)
- if str and str~="" then
- return lpegmatch(pattern,str)
- else
- return {}
- end
+ if str and str~="" then
+ return lpegmatch(pattern,str)
+ else
+ return {}
+ end
end
local defaultspecification={ separator=",",quote='"' }
function parsers.csvsplitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=specification.quote
- local separator=S(separator~="" and separator or ",")
- local whatever=C((1-separator-newline)^0)
- if quotechar and quotechar~="" then
- local quotedata=nil
- for chr in gmatch(quotechar,".") do
- local quotechar=P(chr)
- local quoteword=quotechar*C((1-quotechar)^0)*quotechar
- if quotedata then
- quotedata=quotedata+quoteword
- else
- quotedata=quoteword
- end
- end
- whatever=quotedata+whatever
- end
- local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
- return function(data)
- return lpegmatch(parser,data)
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=specification.quote
+ local separator=S(separator~="" and separator or ",")
+ local whatever=C((1-separator-newline)^0)
+ if quotechar and quotechar~="" then
+ local quotedata=nil
+ for chr in gmatch(quotechar,".") do
+ local quotechar=P(chr)
+ local quoteword=quotechar*C((1-quotechar)^0)*quotechar
+ if quotedata then
+ quotedata=quotedata+quoteword
+ else
+ quotedata=quoteword
+ end
end
+ whatever=quotedata+whatever
+ end
+ local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
+ return function(data)
+ return lpegmatch(parser,data)
+ end
end
function parsers.rfc4180splitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=P(specification.quote)
- local dquotechar=quotechar*quotechar
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=P(specification.quote)
+ local dquotechar=quotechar*quotechar
/specification.quote
- local separator=S(separator~="" and separator or ",")
- local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
- local non_escaped=C((1-quotechar-newline-separator)^1)
- local field=escaped+non_escaped+Cc("")
- local record=Ct(field*(separator*field)^1)
- local headerline=record*Cp()
- local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
- local headeryes=Ct(morerecords)
- local headernop=Ct(record*morerecords)
- return function(data,getheader)
- if getheader then
- local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(headeryes,data,position)
- return data,header
- else
- return lpegmatch(headernop,data)
- end
- end
+ local separator=S(separator~="" and separator or ",")
+ local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
+ local non_escaped=C((1-quotechar-newline-separator)^1)
+ local field=escaped+non_escaped+Cc("")
+ local record=Ct(field*(separator*field)^1)
+ local headerline=record*Cp()
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
+ return function(data,getheader)
+ if getheader then
+ local header,position=lpegmatch(headerline,data)
+ local data=lpegmatch(headeryes,data,position)
+ return data,header
+ else
+ return lpegmatch(headernop,data)
+ end
+ end
end
local function ranger(first,last,n,action)
- if not first then
- elseif last==true then
- for i=first,n or first do
- action(i)
- end
- elseif last then
- for i=first,last do
- action(i)
- end
- else
- action(first)
+ if not first then
+ elseif last==true then
+ for i=first,n or first do
+ action(i)
+ end
+ elseif last then
+ for i=first,last do
+ action(i)
end
+ else
+ action(first)
+ end
end
local cardinal=lpegpatterns.cardinal/tonumber
local spacers=lpegpatterns.spacer^0
@@ -9207,89 +9207,89 @@ local endofstring=lpegpatterns.endofstring
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
function parsers.stepper(str,n,action)
- if type(n)=="function" then
- lpegmatch(stepper,str,1,false,n or print)
- else
- lpegmatch(stepper,str,1,n,action or print)
- end
+ if type(n)=="function" then
+ lpegmatch(stepper,str,1,false,n or print)
+ else
+ lpegmatch(stepper,str,1,n,action or print)
+ end
end
local pattern_math=Cs((P("%")/"\\percent "+P("^")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
local pattern_text=Cs((P("%")/"\\percent "+(P("^")/"\\high")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
patterns.unittotex=pattern
function parsers.unittotex(str,textmode)
- return lpegmatch(textmode and pattern_text or pattern_math,str)
+ return lpegmatch(textmode and pattern_text or pattern_math,str)
end
local pattern=Cs((P("^")/"<sup>"*lpegpatterns.integer*Cc("</sup>")+anything)^0)
function parsers.unittoxml(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache={}
local spaces=lpegpatterns.space^0
local dummy=function() end
setmetatableindex(cache,function(t,k)
- local separator=P(k)
- local value=(1-separator)^0
- local pattern=spaces*C(value)*separator^0*Cp()
- t[k]=pattern
- return pattern
+ local separator=P(k)
+ local value=(1-separator)^0
+ local pattern=spaces*C(value)*separator^0*Cp()
+ t[k]=pattern
+ return pattern
end)
local commalistiterator=cache[","]
function utilities.parsers.iterator(str,separator)
- local n=#str
- if n==0 then
- return dummy
- else
- local pattern=separator and cache[separator] or commalistiterator
- local p=1
- return function()
- if p<=n then
- local s,e=lpegmatch(pattern,str,p)
- if e then
- p=e
- return s
- end
- end
+ local n=#str
+ if n==0 then
+ return dummy
+ else
+ local pattern=separator and cache[separator] or commalistiterator
+ local p=1
+ return function()
+ if p<=n then
+ local s,e=lpegmatch(pattern,str,p)
+ if e then
+ p=e
+ return s
end
+ end
end
+ end
end
local function initialize(t,name)
- local source=t[name]
- if source then
- local result={}
- for k,v in next,t[name] do
- result[k]=v
- end
- return result
- else
- return {}
+ local source=t[name]
+ if source then
+ local result={}
+ for k,v in next,t[name] do
+ result[k]=v
end
+ return result
+ else
+ return {}
+ end
end
local function fetch(t,name)
- return t[name] or {}
+ return t[name] or {}
end
local function process(result,more)
- for k,v in next,more do
- result[k]=v
- end
- return result
+ for k,v in next,more do
+ result[k]=v
+ end
+ return result
end
local name=C((1-S(", "))^1)
local parser=(Carg(1)*name/initialize)*(S(", ")^1*(Carg(1)*name/fetch))^0
local merge=Cf(parser,process)
function utilities.parsers.mergehashes(hash,list)
- return lpegmatch(merge,list,1,hash)
+ return lpegmatch(merge,list,1,hash)
end
function utilities.parsers.runtime(time)
- if not time then
- time=os.runtime()
- end
- local days=div(time,24*60*60)
- time=mod(time,24*60*60)
- local hours=div(time,60*60)
- time=mod(time,60*60)
- local minutes=div(time,60)
- local seconds=mod(time,60)
- return days,hours,minutes,seconds
+ if not time then
+ time=os.runtime()
+ end
+ local days=div(time,24*60*60)
+ time=mod(time,24*60*60)
+ local hours=div(time,60*60)
+ time=mod(time,60*60)
+ local minutes=div(time,60)
+ local seconds=mod(time,60)
+ return days,hours,minutes,seconds
end
local spacing=whitespace^0
local apply=P("->")
@@ -9297,11 +9297,11 @@ local method=C((1-apply)^1)
local token=lbrace*C((1-rbrace)^1)*rbrace+C(anything^1)
local pattern=spacing*(method*spacing*apply+Carg(1))*spacing*token
function utilities.parsers.splitmethod(str,default)
- if str then
- return lpegmatch(pattern,str,1,default or false)
- else
- return default or false,""
- end
+ if str then
+ return lpegmatch(pattern,str,1,default or false)
+ else
+ return default or false,""
+ end
end
@@ -9311,14 +9311,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fmt"] = package.loaded["util-fmt"] or true
--- original size: 2274, stripped down to: 1781
+-- original size: 2274, stripped down to: 1607
if not modules then modules={} end modules ['util-fmt']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.formatters=utilities.formatters or {}
@@ -9329,60 +9329,60 @@ local strip=string.strip
local lpegmatch=lpeg.match
local stripper=lpeg.patterns.stripzeros
function formatters.stripzeros(str)
- return lpegmatch(stripper,str)
+ return lpegmatch(stripper,str)
end
function formatters.formatcolumns(result,between)
- if result and #result>0 then
- between=between or " "
- local widths,numbers={},{}
- local first=result[1]
- local n=#first
- for i=1,n do
- widths[i]=0
- end
- for i=1,#result do
- local r=result[i]
- for j=1,n do
- local rj=r[j]
- local tj=type(rj)
- if tj=="number" then
- numbers[j]=true
- end
- if tj~="string" then
- rj=tostring(rj)
- r[j]=rj
- end
- local w=#rj
- if w>widths[j] then
- widths[j]=w
- end
- end
+ if result and #result>0 then
+ between=between or " "
+ local widths,numbers={},{}
+ local first=result[1]
+ local n=#first
+ for i=1,n do
+ widths[i]=0
+ end
+ for i=1,#result do
+ local r=result[i]
+ for j=1,n do
+ local rj=r[j]
+ local tj=type(rj)
+ if tj=="number" then
+ numbers[j]=true
+ end
+ if tj~="string" then
+ rj=tostring(rj)
+ r[j]=rj
+ end
+ local w=#rj
+ if w>widths[j] then
+ widths[j]=w
end
- for i=1,n do
- local w=widths[i]
- if numbers[i] then
- if w>80 then
- widths[i]="%s"..between
- else
- widths[i]="%0"..w.."i"..between
- end
- else
- if w>80 then
- widths[i]="%s"..between
- elseif w>0 then
- widths[i]="%-"..w.."s"..between
- else
- widths[i]="%s"
- end
- end
+ end
+ end
+ for i=1,n do
+ local w=widths[i]
+ if numbers[i] then
+ if w>80 then
+ widths[i]="%s"..between
+ else
+ widths[i]="%0"..w.."i"..between
end
- local template=strip(concat(widths))
- for i=1,#result do
- local str=format(template,unpack(result[i]))
- result[i]=strip(str)
+ else
+ if w>80 then
+ widths[i]="%s"..between
+ elseif w>0 then
+ widths[i]="%-"..w.."s"..between
+ else
+ widths[i]="%s"
end
+ end
end
- return result
+ local template=strip(concat(widths))
+ for i=1,#result do
+ local str=format(template,unpack(result[i]))
+ result[i]=strip(str)
+ end
+ end
+ return result
end
@@ -9414,7 +9414,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true
--- original size: 4870, stripped down to: 3861
+-- original size: 4870, stripped down to: 3527
local type,tostring,setmetatable=type,tostring,setmetatable
@@ -9427,67 +9427,67 @@ local tcp6=socket.tcp6
local getaddrinfo=socket.dns.getaddrinfo
local defaulthost="0.0.0.0"
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("socket")
- report(fmt,first,...)
- elseif fmt then
- fmt="socket: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("socket")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="socket: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
socket.report=report
function socket.connect4(address,port,laddress,lport)
- return connect(address,port,laddress,lport,"inet")
+ return connect(address,port,laddress,lport,"inet")
end
function socket.connect6(address,port,laddress,lport)
- return connect(address,port,laddress,lport,"inet6")
+ return connect(address,port,laddress,lport,"inet6")
end
function socket.bind(host,port,backlog)
- if host=="*" or host=="" then
- host=defaulthost
- end
- local addrinfo,err=getaddrinfo(host)
- if not addrinfo then
- return nil,err
- end
- for i=1,#addrinfo do
- local alt=addrinfo[i]
- local sock,err=(alt.family=="inet" and tcp4 or tcp6)()
- if not sock then
- return nil,err or "unknown error"
- end
- sock:setoption("reuseaddr",true)
- local res,err=sock:bind(alt.addr,port)
- if res then
- res,err=sock:listen(backlog)
- if res then
- return sock
- else
- sock:close()
- end
- else
- sock:close()
- end
+ if host=="*" or host=="" then
+ host=defaulthost
+ end
+ local addrinfo,err=getaddrinfo(host)
+ if not addrinfo then
+ return nil,err
+ end
+ for i=1,#addrinfo do
+ local alt=addrinfo[i]
+ local sock,err=(alt.family=="inet" and tcp4 or tcp6)()
+ if not sock then
+ return nil,err or "unknown error"
+ end
+ sock:setoption("reuseaddr",true)
+ local res,err=sock:bind(alt.addr,port)
+ if res then
+ res,err=sock:listen(backlog)
+ if res then
+ return sock
+ else
+ sock:close()
+ end
+ else
+ sock:close()
end
- return nil,"invalid address"
+ end
+ return nil,"invalid address"
end
socket.try=socket.newtry()
function socket.choose(list)
- return function(name,opt1,opt2)
- if type(name)~="string" then
- name,opt1,opt2="default",name,opt1
- end
- local f=list[name or "nil"]
- if f then
- return f(opt1,opt2)
- else
- report("error: unknown key '%s'",tostring(name))
- end
+ return function(name,opt1,opt2)
+ if type(name)~="string" then
+ name,opt1,opt2="default",name,opt1
+ end
+ local f=list[name or "nil"]
+ if f then
+ return f(opt1,opt2)
+ else
+ report("error: unknown key '%s'",tostring(name))
end
+ end
end
local sourcet={}
local sinkt={}
@@ -9495,88 +9495,88 @@ socket.sourcet=sourcet
socket.sinkt=sinkt
socket.BLOCKSIZE=2048
sinkt["close-when-done"]=function(sock)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function(self,chunk,err)
- if chunk then
- return sock:send(chunk)
- else
- sock:close()
- return 1
- end
- end
- }
- )
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },
+ {
+ __call=function(self,chunk,err)
+ if chunk then
+ return sock:send(chunk)
+ else
+ sock:close()
+ return 1
+ end
+ end
+ }
+ )
end
sinkt["keep-open"]=function(sock)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function(self,chunk,err)
- if chunk then
- return sock:send(chunk)
- else
- return 1
- end
- end
- }
- )
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },{
+ __call=function(self,chunk,err)
+ if chunk then
+ return sock:send(chunk)
+ else
+ return 1
+ end
+ end
+ }
+ )
end
sinkt["default"]=sinkt["keep-open"]
socket.sink=socket.choose(sinkt)
sourcet["by-length"]=function(sock,length)
- local blocksize=socket.BLOCKSIZE
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function()
- if length<=0 then
- return nil
- end
- local chunk,err=sock:receive(min(blocksize,length))
- if err then
- return nil,err
- end
- length=length-#chunk
- return chunk
- end
- }
- )
+ local blocksize=socket.BLOCKSIZE
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },
+ {
+ __call=function()
+ if length<=0 then
+ return nil
+ end
+ local chunk,err=sock:receive(min(blocksize,length))
+ if err then
+ return nil,err
+ end
+ length=length-#chunk
+ return chunk
+ end
+ }
+ )
end
sourcet["until-closed"]=function(sock)
- local blocksize=socket.BLOCKSIZE
- local done=false
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function()
- if done then
- return nil
- end
- local chunk,status,partial=sock:receive(blocksize)
- if not status then
- return chunk
- elseif status=="closed" then
- sock:close()
- done=true
- return partial
- else
- return nil,status
- end
- end
- }
- )
+ local blocksize=socket.BLOCKSIZE
+ local done=false
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },{
+ __call=function()
+ if done then
+ return nil
+ end
+ local chunk,status,partial=sock:receive(blocksize)
+ if not status then
+ return chunk
+ elseif status=="closed" then
+ sock:close()
+ done=true
+ return partial
+ else
+ return nil,status
+ end
+ end
+ }
+ )
end
sourcet["default"]=sourcet["until-closed"]
socket.source=socket.choose(sourcet)
@@ -9590,7 +9590,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
--- original size: 25844, stripped down to: 16066
+-- original size: 25844, stripped down to: 14821
local socket=socket or require("socket")
@@ -9608,333 +9608,333 @@ local resumecoroutine=coroutine.resume
local yieldcoroutine=coroutine.yield
local runningcoroutine=coroutine.running
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("copas")
- report(fmt,first,...)
- elseif fmt then
- fmt="copas: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("copas")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="copas: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
local copas={
- _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project",
- _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services",
- _VERSION="Copas 2.0.1",
- autoclose=true,
- running=false,
- report=report,
+ _COPYRIGHT="Copyright (C) 2005-2016 Kepler Project",
+ _DESCRIPTION="Coroutine Oriented Portable Asynchronous Services",
+ _VERSION="Copas 2.0.1",
+ autoclose=true,
+ running=false,
+ report=report,
}
local function statushandler(status,...)
- if status then
- return...
- end
- local err=(...)
- if type(err)=="table" then
- err=err[1]
- end
- report("error: %s",tostring(err))
- return nil,err
+ if status then
+ return...
+ end
+ local err=(...)
+ if type(err)=="table" then
+ err=err[1]
+ end
+ report("error: %s",tostring(err))
+ return nil,err
end
function socket.protect(func)
- return function(...)
- return statushandler(pcall(func,...))
- end
+ return function(...)
+ return statushandler(pcall(func,...))
+ end
end
function socket.newtry(finalizer)
- return function (...)
- local status=(...)
- if not status then
- local detail=select(2,...)
- pcall(finalizer,detail)
- report("error: %s",tostring(detail))
- return
- end
- return...
+ return function (...)
+ local status=(...)
+ if not status then
+ local detail=select(2,...)
+ pcall(finalizer,detail)
+ report("error: %s",tostring(detail))
+ return
end
+ return...
+ end
end
local function newset()
- local reverse={}
- local set={}
- local queue={}
- setmetatable(set,{
- __index={
- insert=function(set,value)
- if not reverse[value] then
- local n=#set+1
- set[n]=value
- reverse[value]=n
- end
- end,
- remove=function(set,value)
- local index=reverse[value]
- if index then
- reverse[value]=nil
- local n=#set
- local top=set[n]
- set[n]=nil
- if top~=value then
- reverse[top]=index
- set[index]=top
- end
- end
- end,
- push=function (set,key,itm)
- local entry=queue[key]
- if entry==nil then
- queue[key]={ itm }
- else
- entry[#entry+1]=itm
- end
- end,
- pop=function (set,key)
- local top=queue[key]
- if top~=nil then
- local ret=remove(top,1)
- if top[1]==nil then
- queue[key]=nil
- end
- return ret
- end
- end
- }
- } )
- return set
-end
-local _sleeping={
- times={},
- cos={},
- lethargy={},
- insert=function()
- end,
- remove=function()
+ local reverse={}
+ local set={}
+ local queue={}
+ setmetatable(set,{
+ __index={
+ insert=function(set,value)
+ if not reverse[value] then
+ local n=#set+1
+ set[n]=value
+ reverse[value]=n
+ end
end,
- push=function(self,sleeptime,co)
- if not co then
- return
- end
- if sleeptime<0 then
- self.lethargy[co]=true
- return
- else
- sleeptime=gettime()+sleeptime
+ remove=function(set,value)
+ local index=reverse[value]
+ if index then
+ reverse[value]=nil
+ local n=#set
+ local top=set[n]
+ set[n]=nil
+ if top~=value then
+ reverse[top]=index
+ set[index]=top
end
- local t=self.times
- local c=self.cos
- local i=1
- local n=#t
- while i<=n and t[i]<=sleeptime do
- i=i+1
- end
- insert(t,i,sleeptime)
- insert(c,i,co)
- end,
- getnext=
- function(self)
- local t=self.times
- local delay=t[1] and t[1]-gettime() or nil
- return delay and max(delay,0) or nil
+ end
end,
- pop=
- function(self,time)
- local t=self.times
- local c=self.cos
- if #t==0 or time<t[1] then
- return
- end
- local co=c[1]
- remove(t,1)
- remove(c,1)
- return co
+ push=function (set,key,itm)
+ local entry=queue[key]
+ if entry==nil then
+ queue[key]={ itm }
+ else
+ entry[#entry+1]=itm
+ end
end,
- wakeup=function(self,co)
- local let=self.lethargy
- if let[co] then
- self:push(0,co)
- let[co]=nil
- else
- local c=self.cos
- local t=self.times
- for i=1,#c do
- if c[i]==co then
- remove(c,i)
- remove(t,i)
- self:push(0,co)
- return
- end
- end
- end
+ pop=function (set,key)
+ local top=queue[key]
+ if top~=nil then
+ local ret=remove(top,1)
+ if top[1]==nil then
+ queue[key]=nil
+ end
+ return ret
+ end
+ end
+ }
+ } )
+ return set
+end
+local _sleeping={
+ times={},
+ cos={},
+ lethargy={},
+ insert=function()
+ end,
+ remove=function()
+ end,
+ push=function(self,sleeptime,co)
+ if not co then
+ return
+ end
+ if sleeptime<0 then
+ self.lethargy[co]=true
+ return
+ else
+ sleeptime=gettime()+sleeptime
+ end
+ local t=self.times
+ local c=self.cos
+ local i=1
+ local n=#t
+ while i<=n and t[i]<=sleeptime do
+ i=i+1
+ end
+ insert(t,i,sleeptime)
+ insert(c,i,co)
+ end,
+ getnext=
+ function(self)
+ local t=self.times
+ local delay=t[1] and t[1]-gettime() or nil
+ return delay and max(delay,0) or nil
+ end,
+ pop=
+ function(self,time)
+ local t=self.times
+ local c=self.cos
+ if #t==0 or time<t[1] then
+ return
+ end
+ local co=c[1]
+ remove(t,1)
+ remove(c,1)
+ return co
+ end,
+ wakeup=function(self,co)
+ local let=self.lethargy
+ if let[co] then
+ self:push(0,co)
+ let[co]=nil
+ else
+ local c=self.cos
+ local t=self.times
+ for i=1,#c do
+ if c[i]==co then
+ remove(c,i)
+ remove(t,i)
+ self:push(0,co)
+ return
end
+ end
+ end
+ end
}
local _servers=newset()
local _reading=newset()
local _writing=newset()
local _reading_log={}
local _writing_log={}
-local _is_timeout={
- timeout=true,
- wantread=true,
- wantwrite=true,
+local _is_timeout={
+ timeout=true,
+ wantread=true,
+ wantwrite=true,
}
local function isTCP(socket)
- return not find(tostring(socket),"^udp")
+ return not find(tostring(socket),"^udp")
end
local function copasreceive(client,pattern,part)
- if not pattern or pattern=="" then
- pattern="*l"
- end
- local current_log=_reading_log
- local s,err
- repeat
- s,err,part=client:receive(pattern,part)
- if s or (not _is_timeout[err]) then
- current_log[client]=nil
- return s,err,part
- end
- if err=="wantwrite" then
- current_log=_writing_log
- current_log[client]=gettime()
- yieldcoroutine(client,_writing)
- else
- current_log=_reading_log
- current_log[client]=gettime()
- yieldcoroutine(client,_reading)
- end
- until false
+ if not pattern or pattern=="" then
+ pattern="*l"
+ end
+ local current_log=_reading_log
+ local s,err
+ repeat
+ s,err,part=client:receive(pattern,part)
+ if s or (not _is_timeout[err]) then
+ current_log[client]=nil
+ return s,err,part
+ end
+ if err=="wantwrite" then
+ current_log=_writing_log
+ current_log[client]=gettime()
+ yieldcoroutine(client,_writing)
+ else
+ current_log=_reading_log
+ current_log[client]=gettime()
+ yieldcoroutine(client,_reading)
+ end
+ until false
end
local function copasreceivefrom(client,size)
- local s,err,port
- if not size or size==0 then
- size=UDP_DATAGRAM_MAX
- end
- repeat
- s,err,port=client:receivefrom(size)
- if s or err~="timeout" then
- _reading_log[client]=nil
- return s,err,port
- end
- _reading_log[client]=gettime()
- yieldcoroutine(client,_reading)
- until false
+ local s,err,port
+ if not size or size==0 then
+ size=UDP_DATAGRAM_MAX
+ end
+ repeat
+ s,err,port=client:receivefrom(size)
+ if s or err~="timeout" then
+ _reading_log[client]=nil
+ return s,err,port
+ end
+ _reading_log[client]=gettime()
+ yieldcoroutine(client,_reading)
+ until false
end
local function copasreceivepartial(client,pattern,part)
- if not pattern or pattern=="" then
- pattern="*l"
- end
- local logger=_reading_log
- local queue=_reading
- local s,err
- repeat
- s,err,part=client:receive(pattern,part)
- if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then
- logger[client]=nil
- return s,err,part
- end
- if err=="wantwrite" then
- logger=_writing_log
- queue=_writing
- else
- logger=_reading_log
- queue=_reading
- end
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- until false
+ if not pattern or pattern=="" then
+ pattern="*l"
+ end
+ local logger=_reading_log
+ local queue=_reading
+ local s,err
+ repeat
+ s,err,part=client:receive(pattern,part)
+ if s or (type(pattern)=="number" and part~="" and part) or not _is_timeout[err] then
+ logger[client]=nil
+ return s,err,part
+ end
+ if err=="wantwrite" then
+ logger=_writing_log
+ queue=_writing
+ else
+ logger=_reading_log
+ queue=_reading
+ end
+ logger[client]=gettime()
+ yieldcoroutine(client,queue)
+ until false
end
local function copassend(client,data,from,to)
- if not from then
- from=1
- end
- local lastIndex=from-1
- local logger=_writing_log
- local queue=_writing
- local s,err
- repeat
- s,err,lastIndex=client:send(data,lastIndex+1,to)
- if random(100)>90 then
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- end
- if s or not _is_timeout[err] then
- logger[client]=nil
- return s,err,lastIndex
- end
- if err=="wantread" then
- logger=_reading_log
- queue=_reading
- else
- logger=_writing_log
- queue=_writing
- end
- logger[client]=gettime()
- yieldcoroutine(client,queue)
- until false
+ if not from then
+ from=1
+ end
+ local lastIndex=from-1
+ local logger=_writing_log
+ local queue=_writing
+ local s,err
+ repeat
+ s,err,lastIndex=client:send(data,lastIndex+1,to)
+ if random(100)>90 then
+ logger[client]=gettime()
+ yieldcoroutine(client,queue)
+ end
+ if s or not _is_timeout[err] then
+ logger[client]=nil
+ return s,err,lastIndex
+ end
+ if err=="wantread" then
+ logger=_reading_log
+ queue=_reading
+ else
+ logger=_writing_log
+ queue=_writing
+ end
+ logger[client]=gettime()
+ yieldcoroutine(client,queue)
+ until false
end
local function copassendto(client,data,ip,port)
- repeat
- local s,err=client:sendto(data,ip,port)
- if random(100)>90 then
- _writing_log[client]=gettime()
- yieldcoroutine(client,_writing)
- end
- if s or err~="timeout" then
- _writing_log[client]=nil
- return s,err
- end
- _writing_log[client]=gettime()
- yieldcoroutine(client,_writing)
- until false
+ repeat
+ local s,err=client:sendto(data,ip,port)
+ if random(100)>90 then
+ _writing_log[client]=gettime()
+ yieldcoroutine(client,_writing)
+ end
+ if s or err~="timeout" then
+ _writing_log[client]=nil
+ return s,err
+ end
+ _writing_log[client]=gettime()
+ yieldcoroutine(client,_writing)
+ until false
end
local function copasconnect(skt,host,port)
- skt:settimeout(0)
- local ret,err,tried_more_than_once
- repeat
- ret,err=skt:connect (host,port)
- if ret or (err~="timeout" and err~="Operation already in progress") then
- if not ret and err=="already connected" and tried_more_than_once then
- ret=1
- err=nil
- end
- _writing_log[skt]=nil
- return ret,err
- end
- tried_more_than_once=tried_more_than_once or true
- _writing_log[skt]=gettime()
- yieldcoroutine(skt,_writing)
- until false
+ skt:settimeout(0)
+ local ret,err,tried_more_than_once
+ repeat
+ ret,err=skt:connect (host,port)
+ if ret or (err~="timeout" and err~="Operation already in progress") then
+ if not ret and err=="already connected" and tried_more_than_once then
+ ret=1
+ err=nil
+ end
+ _writing_log[skt]=nil
+ return ret,err
+ end
+ tried_more_than_once=tried_more_than_once or true
+ _writing_log[skt]=gettime()
+ yieldcoroutine(skt,_writing)
+ until false
end
local function copasdohandshake(skt,sslt)
- if not ssl then
- ssl=require("ssl")
- end
- if not ssl then
- report("error: no ssl library")
- return
- end
- local nskt,err=ssl.wrap(skt,sslt)
- if not nskt then
- report("error: %s",tostring(err))
- return
- end
- nskt:settimeout(0)
- local queue
- repeat
- local success,err=nskt:dohandshake()
- if success then
- return nskt
- elseif err=="wantwrite" then
- queue=_writing
- elseif err=="wantread" then
- queue=_reading
- else
- report("error: %s",tostring(err))
- return
- end
- yieldcoroutine(nskt,queue)
- until false
+ if not ssl then
+ ssl=require("ssl")
+ end
+ if not ssl then
+ report("error: no ssl library")
+ return
+ end
+ local nskt,err=ssl.wrap(skt,sslt)
+ if not nskt then
+ report("error: %s",tostring(err))
+ return
+ end
+ nskt:settimeout(0)
+ local queue
+ repeat
+ local success,err=nskt:dohandshake()
+ if success then
+ return nskt
+ elseif err=="wantwrite" then
+ queue=_writing
+ elseif err=="wantread" then
+ queue=_reading
+ else
+ report("error: %s",tostring(err))
+ return
+ end
+ yieldcoroutine(nskt,queue)
+ until false
end
local function copasflush(client)
end
@@ -9948,326 +9948,326 @@ copas.copasreceivePartial=copasreceivepartial
copas.dohandshake=copasdohandshake
copas.flush=copasflush
local function _skt_mt_tostring(self)
- return tostring(self.socket).." (copas wrapped)"
+ return tostring(self.socket).." (copas wrapped)"
end
local _skt_mt_tcp_index={
- send=function(self,data,from,to)
- return copassend (self.socket,data,from,to)
- end,
- receive=function (self,pattern,prefix)
- if self.timeout==0 then
- return copasreceivePartial(self.socket,pattern,prefix)
- else
- return copasreceive(self.socket,pattern,prefix)
- end
- end,
- flush=function (self)
- return copasflush(self.socket)
- end,
- settimeout=function (self,time)
- self.timeout=time
- return true
- end,
- connect=function(self,...)
- local res,err=copasconnect(self.socket,...)
- if res and self.ssl_params then
- res,err=self:dohandshake()
- end
- return res,err
- end,
- close=function(self,...)
- return self.socket:close(...)
- end,
- bind=function(self,...)
- return self.socket:bind(...)
- end,
- getsockname=function(self,...)
- return self.socket:getsockname(...)
- end,
- getstats=function(self,...)
- return self.socket:getstats(...)
- end,
- setstats=function(self,...)
- return self.socket:setstats(...)
- end,
- listen=function(self,...)
- return self.socket:listen(...)
- end,
- accept=function(self,...)
- return self.socket:accept(...)
- end,
- setoption=function(self,...)
- return self.socket:setoption(...)
- end,
- getpeername=function(self,...)
- return self.socket:getpeername(...)
- end,
- shutdown=function(self,...)
- return self.socket:shutdown(...)
- end,
- dohandshake=function(self,sslt)
- self.ssl_params=sslt or self.ssl_params
- local nskt,err=copasdohandshake(self.socket,self.ssl_params)
- if not nskt then
- return nskt,err
- end
- self.socket=nskt
- return self
- end,
+ send=function(self,data,from,to)
+ return copassend (self.socket,data,from,to)
+ end,
+ receive=function (self,pattern,prefix)
+ if self.timeout==0 then
+ return copasreceivePartial(self.socket,pattern,prefix)
+ else
+ return copasreceive(self.socket,pattern,prefix)
+ end
+ end,
+ flush=function (self)
+ return copasflush(self.socket)
+ end,
+ settimeout=function (self,time)
+ self.timeout=time
+ return true
+ end,
+ connect=function(self,...)
+ local res,err=copasconnect(self.socket,...)
+ if res and self.ssl_params then
+ res,err=self:dohandshake()
+ end
+ return res,err
+ end,
+ close=function(self,...)
+ return self.socket:close(...)
+ end,
+ bind=function(self,...)
+ return self.socket:bind(...)
+ end,
+ getsockname=function(self,...)
+ return self.socket:getsockname(...)
+ end,
+ getstats=function(self,...)
+ return self.socket:getstats(...)
+ end,
+ setstats=function(self,...)
+ return self.socket:setstats(...)
+ end,
+ listen=function(self,...)
+ return self.socket:listen(...)
+ end,
+ accept=function(self,...)
+ return self.socket:accept(...)
+ end,
+ setoption=function(self,...)
+ return self.socket:setoption(...)
+ end,
+ getpeername=function(self,...)
+ return self.socket:getpeername(...)
+ end,
+ shutdown=function(self,...)
+ return self.socket:shutdown(...)
+ end,
+ dohandshake=function(self,sslt)
+ self.ssl_params=sslt or self.ssl_params
+ local nskt,err=copasdohandshake(self.socket,self.ssl_params)
+ if not nskt then
+ return nskt,err
+ end
+ self.socket=nskt
+ return self
+ end,
}
local _skt_mt_tcp={
- __tostring=_skt_mt_tostring,
- __index=_skt_mt_tcp_index,
+ __tostring=_skt_mt_tostring,
+ __index=_skt_mt_tcp_index,
}
local _skt_mt_udp_index={
- sendto=function (self,...)
- return copassendto(self.socket,...)
- end,
- receive=function (self,size)
- return copasreceive(self.socket,size or UDP_DATAGRAM_MAX)
- end,
- receivefrom=function (self,size)
- return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX)
- end,
- setpeername=function(self,...)
- return self.socket:getpeername(...)
- end,
- setsockname=function(self,...)
- return self.socket:setsockname(...)
- end,
- close=function(self,...)
- return true
- end
+ sendto=function (self,...)
+ return copassendto(self.socket,...)
+ end,
+ receive=function (self,size)
+ return copasreceive(self.socket,size or UDP_DATAGRAM_MAX)
+ end,
+ receivefrom=function (self,size)
+ return copasreceivefrom(self.socket,size or UDP_DATAGRAM_MAX)
+ end,
+ setpeername=function(self,...)
+ return self.socket:getpeername(...)
+ end,
+ setsockname=function(self,...)
+ return self.socket:setsockname(...)
+ end,
+ close=function(self,...)
+ return true
+ end
}
local _skt_mt_udp={
- __tostring=_skt_mt_tostring,
- __index=_skt_mt_udp_index,
+ __tostring=_skt_mt_tostring,
+ __index=_skt_mt_udp_index,
}
for k,v in next,_skt_mt_tcp_index do
- if not _skt_mt_udp_index[k] then
- _skt_mt_udp_index[k]=v
- end
+ if not _skt_mt_udp_index[k] then
+ _skt_mt_udp_index[k]=v
+ end
end
local function wrap(skt,sslt)
- if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
- return skt
- end
- skt:settimeout(0)
- if isTCP(skt) then
- return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp)
- else
- return setmetatable ({ socket=skt },_skt_mt_udp)
- end
+ if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
+ return skt
+ end
+ skt:settimeout(0)
+ if isTCP(skt) then
+ return setmetatable ({ socket=skt,ssl_params=sslt },_skt_mt_tcp)
+ else
+ return setmetatable ({ socket=skt },_skt_mt_udp)
+ end
end
copas.wrap=wrap
function copas.handler(handler,sslparams)
- return function (skt,...)
- skt=wrap(skt)
- if sslparams then
- skt:dohandshake(sslparams)
- end
- return handler(skt,...)
+ return function (skt,...)
+ skt=wrap(skt)
+ if sslparams then
+ skt:dohandshake(sslparams)
end
+ return handler(skt,...)
+ end
end
local _errhandlers={}
function copas.setErrorHandler(err)
- local co=runningcoroutine()
- if co then
- _errhandlers[co]=err
- end
+ local co=runningcoroutine()
+ if co then
+ _errhandlers[co]=err
+ end
end
local function _deferror (msg,co,skt)
- report("%s (%s) (%s)",msg,tostring(co),tostring(skt))
+ report("%s (%s) (%s)",msg,tostring(co),tostring(skt))
end
local function _doTick (co,skt,...)
- if not co then
- return
+ if not co then
+ return
+ end
+ local ok,res,new_q=resumecoroutine(co,skt,...)
+ if ok and res and new_q then
+ new_q:insert(res)
+ new_q:push(res,co)
+ else
+ if not ok then
+ pcall(_errhandlers[co] or _deferror,res,co,skt)
end
- local ok,res,new_q=resumecoroutine(co,skt,...)
- if ok and res and new_q then
- new_q:insert(res)
- new_q:push(res,co)
- else
- if not ok then
- pcall(_errhandlers[co] or _deferror,res,co,skt)
- end
- if skt and copas.autoclose and isTCP(skt) then
- skt:close()
- end
- _errhandlers[co]=nil
+ if skt and copas.autoclose and isTCP(skt) then
+ skt:close()
end
+ _errhandlers[co]=nil
+ end
end
local function _accept(input,handler)
- local client=input:accept()
- if client then
- client:settimeout(0)
- local co=createcoroutine(handler)
- _doTick (co,client)
- end
- return client
+ local client=input:accept()
+ if client then
+ client:settimeout(0)
+ local co=createcoroutine(handler)
+ _doTick (co,client)
+ end
+ return client
end
local function _tickRead(skt)
- _doTick(_reading:pop(skt),skt)
+ _doTick(_reading:pop(skt),skt)
end
local function _tickWrite(skt)
- _doTick(_writing:pop(skt),skt)
+ _doTick(_writing:pop(skt),skt)
end
local function addTCPserver(server,handler,timeout)
- server:settimeout(timeout or 0)
- _servers[server]=handler
- _reading:insert(server)
+ server:settimeout(timeout or 0)
+ _servers[server]=handler
+ _reading:insert(server)
end
local function addUDPserver(server,handler,timeout)
- server:settimeout(timeout or 0)
- local co=createcoroutine(handler)
- _reading:insert(server)
- _doTick(co,server)
+ server:settimeout(timeout or 0)
+ local co=createcoroutine(handler)
+ _reading:insert(server)
+ _doTick(co,server)
end
function copas.addserver(server,handler,timeout)
- if isTCP(server) then
- addTCPserver(server,handler,timeout)
- else
- addUDPserver(server,handler,timeout)
- end
+ if isTCP(server) then
+ addTCPserver(server,handler,timeout)
+ else
+ addUDPserver(server,handler,timeout)
+ end
end
function copas.removeserver(server,keep_open)
- local s=server
- local mt=getmetatable(server)
- if mt==_skt_mt_tcp or mt==_skt_mt_udp then
- s=server.socket
- end
- _servers[s]=nil
- _reading:remove(s)
- if keep_open then
- return true
- end
- return server:close()
+ local s=server
+ local mt=getmetatable(server)
+ if mt==_skt_mt_tcp or mt==_skt_mt_udp then
+ s=server.socket
+ end
+ _servers[s]=nil
+ _reading:remove(s)
+ if keep_open then
+ return true
+ end
+ return server:close()
end
function copas.addthread(handler,...)
- local thread=createcoroutine(function(_,...) return handler(...) end)
- _doTick(thread,nil,...)
- return thread
+ local thread=createcoroutine(function(_,...) return handler(...) end)
+ _doTick(thread,nil,...)
+ return thread
end
local _tasks={}
local function addtaskRead(task)
- task.def_tick=_tickRead
- _tasks[task]=true
+ task.def_tick=_tickRead
+ _tasks[task]=true
end
local function addtaskWrite(task)
- task.def_tick=_tickWrite
- _tasks[task]=true
+ task.def_tick=_tickWrite
+ _tasks[task]=true
end
local function tasks()
- return next,_tasks
+ return next,_tasks
end
local _readable_t={
- events=function(self)
- local i=0
- return function ()
- i=i+1
- return self._evs[i]
- end
- end,
- tick=function(self,input)
- local handler=_servers[input]
- if handler then
- input=_accept(input,handler)
- else
- _reading:remove(input)
- self.def_tick(input)
- end
- end
+ events=function(self)
+ local i=0
+ return function ()
+ i=i+1
+ return self._evs[i]
+ end
+ end,
+ tick=function(self,input)
+ local handler=_servers[input]
+ if handler then
+ input=_accept(input,handler)
+ else
+ _reading:remove(input)
+ self.def_tick(input)
+ end
+ end
}
addtaskRead(_readable_t)
local _writable_t={
- events=function(self)
- local i=0
- return function()
- i=i+1
- return self._evs[i]
- end
- end,
- tick=function(self,output)
- _writing:remove(output)
- self.def_tick(output)
- end
+ events=function(self)
+ local i=0
+ return function()
+ i=i+1
+ return self._evs[i]
+ end
+ end,
+ tick=function(self,output)
+ _writing:remove(output)
+ self.def_tick(output)
+ end
}
addtaskWrite(_writable_t)
local _sleeping_t={
- tick=function(self,time,...)
- _doTick(_sleeping:pop(time),...)
- end
+ tick=function(self,time,...)
+ _doTick(_sleeping:pop(time),...)
+ end
}
function copas.sleep(sleeptime)
- yieldcoroutine((sleeptime or 0),_sleeping)
+ yieldcoroutine((sleeptime or 0),_sleeping)
end
function copas.wakeup(co)
- _sleeping:wakeup(co)
+ _sleeping:wakeup(co)
end
local last_cleansing=0
local function _select(timeout)
- local now=gettime()
- local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout)
- _readable_t._evs=r_evs
- _writable_t._evs=w_evs
- if (last_cleansing-now)>WATCH_DOG_TIMEOUT then
- last_cleansing=now
- for skt,time in next,_reading_log do
- if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
- local n=#r_evs+1
- _reading_log[skt]=nil
- r_evs[n]=skt
- r_evs[skt]=n
- end
- end
- for skt,time in next,_writing_log do
- if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
- local n=#w_evs+1
- _writing_log[skt]=nil
- w_evs[n]=skt
- w_evs[skt]=n
- end
- end
+ local now=gettime()
+ local r_evs,w_evs,err=selectsocket(_reading,_writing,timeout)
+ _readable_t._evs=r_evs
+ _writable_t._evs=w_evs
+ if (last_cleansing-now)>WATCH_DOG_TIMEOUT then
+ last_cleansing=now
+ for skt,time in next,_reading_log do
+ if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
+ local n=#r_evs+1
+ _reading_log[skt]=nil
+ r_evs[n]=skt
+ r_evs[skt]=n
+ end
end
- if err=="timeout" and #r_evs+#w_evs>0 then
- return nil
- else
- return err
+ for skt,time in next,_writing_log do
+ if not w_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
+ local n=#w_evs+1
+ _writing_log[skt]=nil
+ w_evs[n]=skt
+ w_evs[skt]=n
+ end
end
+ end
+ if err=="timeout" and #r_evs+#w_evs>0 then
+ return nil
+ else
+ return err
+ end
end
local function copasfinished()
- return not (next(_reading) or next(_writing) or _sleeping:getnext())
+ return not (next(_reading) or next(_writing) or _sleeping:getnext())
end
local function copasstep(timeout)
- _sleeping_t:tick(gettime())
- local nextwait=_sleeping:getnext()
- if nextwait then
- timeout=timeout and min(nextwait,timeout) or nextwait
- elseif copasfinished() then
- return false
- end
- local err=_select(timeout)
- if err then
- if err=="timeout" then
- return false
- end
- return nil,err
+ _sleeping_t:tick(gettime())
+ local nextwait=_sleeping:getnext()
+ if nextwait then
+ timeout=timeout and min(nextwait,timeout) or nextwait
+ elseif copasfinished() then
+ return false
+ end
+ local err=_select(timeout)
+ if err then
+ if err=="timeout" then
+ return false
end
- for task in tasks() do
- for event in task:events() do
- task:tick(event)
- end
+ return nil,err
+ end
+ for task in tasks() do
+ for event in task:events() do
+ task:tick(event)
end
- return true
+ end
+ return true
end
copas.finished=copasfinished
copas.step=copasstep
function copas.loop(timeout)
- copas.running=true
- while not copasfinished() do
- copasstep(timeout)
- end
- copas.running=false
+ copas.running=true
+ while not copasfinished() do
+ copasstep(timeout)
+ end
+ copas.running=false
end
package.loaded["copas"]=copas
@@ -10278,321 +10278,321 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true
--- original size: 8709, stripped down to: 6105
+-- original size: 8709, stripped down to: 5411
local select,unpack=select,unpack
local insert,remove=table.insert,table.remove
local sub=string.sub
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("ltn12")
- report(fmt,first,...)
- elseif fmt then
- fmt="ltn12: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("ltn12")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="ltn12: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
local filter={}
local source={}
local sink={}
local pump={}
local ltn12={
- _VERSION="LTN12 1.0.3",
- BLOCKSIZE=2048,
- filter=filter,
- source=source,
- sink=sink,
- pump=pump,
- report=report,
+ _VERSION="LTN12 1.0.3",
+ BLOCKSIZE=2048,
+ filter=filter,
+ source=source,
+ sink=sink,
+ pump=pump,
+ report=report,
}
function filter.cycle(low,ctx,extra)
- if low then
- return function(chunk)
- return (low(ctx,chunk,extra))
- end
+ if low then
+ return function(chunk)
+ return (low(ctx,chunk,extra))
end
+ end
end
function filter.chain(...)
- local arg={... }
- local n=select('#',...)
- local top=1
- local index=1
- local retry=""
- return function(chunk)
- retry=chunk and retry
- while true do
- local action=arg[index]
- if index==top then
- chunk=action(chunk)
- if chunk=="" or top==n then
- return chunk
- elseif chunk then
- index=index+1
- else
- top=top+1
- index=top
- end
- else
- chunk=action(chunk or "")
- if chunk=="" then
- index=index-1
- chunk=retry
- elseif chunk then
- if index==n then
- return chunk
- else
- index=index+1
- end
- else
- report("error: filter returned inappropriate 'nil'")
- return
- end
- end
+ local arg={... }
+ local n=select('#',...)
+ local top=1
+ local index=1
+ local retry=""
+ return function(chunk)
+ retry=chunk and retry
+ while true do
+ local action=arg[index]
+ if index==top then
+ chunk=action(chunk)
+ if chunk=="" or top==n then
+ return chunk
+ elseif chunk then
+ index=index+1
+ else
+ top=top+1
+ index=top
+ end
+ else
+ chunk=action(chunk or "")
+ if chunk=="" then
+ index=index-1
+ chunk=retry
+ elseif chunk then
+ if index==n then
+ return chunk
+ else
+ index=index+1
+ end
+ else
+ report("error: filter returned inappropriate 'nil'")
+ return
end
+ end
end
+ end
end
local function empty()
- return nil
+ return nil
end
function source.empty()
- return empty
+ return empty
end
local function sourceerror(err)
- return function()
- return nil,err
- end
+ return function()
+ return nil,err
+ end
end
source.error=sourceerror
function source.file(handle,io_err)
- if handle then
- local blocksize=ltn12.BLOCKSIZE
- return function()
- local chunk=handle:read(blocksize)
- if not chunk then
- handle:close()
- end
- return chunk
- end
- else
- return sourceerror(io_err or "unable to open file")
+ if handle then
+ local blocksize=ltn12.BLOCKSIZE
+ return function()
+ local chunk=handle:read(blocksize)
+ if not chunk then
+ handle:close()
+ end
+ return chunk
end
+ else
+ return sourceerror(io_err or "unable to open file")
+ end
end
function source.simplify(src)
- return function()
- local chunk,err_or_new=src()
- if err_or_new then
- src=err_or_new
- end
- if chunk then
- return chunk
- else
- return nil,err_or_new
- end
+ return function()
+ local chunk,err_or_new=src()
+ if err_or_new then
+ src=err_or_new
+ end
+ if chunk then
+ return chunk
+ else
+ return nil,err_or_new
end
+ end
end
function source.string(s)
- if s then
- local blocksize=ltn12.BLOCKSIZE
- local i=1
- return function()
- local nexti=i+blocksize
- local chunk=sub(s,i,nexti-1)
- i=nexti
- if chunk~="" then
- return chunk
- else
- return nil
- end
- end
- else return source.empty() end
+ if s then
+ local blocksize=ltn12.BLOCKSIZE
+ local i=1
+ return function()
+ local nexti=i+blocksize
+ local chunk=sub(s,i,nexti-1)
+ i=nexti
+ if chunk~="" then
+ return chunk
+ else
+ return nil
+ end
+ end
+ else return source.empty() end
end
function source.rewind(src)
- local t={}
- return function(chunk)
- if chunk then
- insert(t,chunk)
- else
- chunk=remove(t)
- if chunk then
- return chunk
- else
- return src()
- end
- end
+ local t={}
+ return function(chunk)
+ if chunk then
+ insert(t,chunk)
+ else
+ chunk=remove(t)
+ if chunk then
+ return chunk
+ else
+ return src()
+ end
end
+ end
end
function source.chain(src,f,...)
- if... then
- f=filter.chain(f,...)
+ if... then
+ f=filter.chain(f,...)
+ end
+ local last_in=""
+ local last_out=""
+ local state="feeding"
+ local err
+ return function()
+ if not last_out then
+ report("error: source is empty")
+ return
end
- local last_in=""
- local last_out=""
- local state="feeding"
- local err
- return function()
+ while true do
+ if state=="feeding" then
+ last_in,err=src()
+ if err then
+ return nil,err
+ end
+ last_out=f(last_in)
if not last_out then
- report("error: source is empty")
- return
+ if last_in then
+ report("error: filter returned inappropriate 'nil'")
+ end
+ return nil
+ elseif last_out~="" then
+ state="eating"
+ if last_in then
+ last_in=""
+ end
+ return last_out
end
- while true do
- if state=="feeding" then
- last_in,err=src()
- if err then
- return nil,err
- end
- last_out=f(last_in)
- if not last_out then
- if last_in then
- report("error: filter returned inappropriate 'nil'")
- end
- return nil
- elseif last_out~="" then
- state="eating"
- if last_in then
- last_in=""
- end
- return last_out
- end
- else
- last_out=f(last_in)
- if last_out=="" then
- if last_in=="" then
- state="feeding"
- else
- report("error: filter returned nothing")
- return
- end
- elseif not last_out then
- if last_in then
- report("filter returned inappropriate 'nil'")
- end
- return nil
- else
- return last_out
- end
- end
+ else
+ last_out=f(last_in)
+ if last_out=="" then
+ if last_in=="" then
+ state="feeding"
+ else
+ report("error: filter returned nothing")
+ return
+ end
+ elseif not last_out then
+ if last_in then
+ report("filter returned inappropriate 'nil'")
+ end
+ return nil
+ else
+ return last_out
end
+ end
end
+ end
end
function source.cat(...)
- local arg={... }
- local src=remove(arg,1)
- return function()
- while src do
- local chunk,err=src()
- if chunk then
- return chunk
- end
- if err then
- return nil,err
- end
- src=remove(arg,1)
- end
+ local arg={... }
+ local src=remove(arg,1)
+ return function()
+ while src do
+ local chunk,err=src()
+ if chunk then
+ return chunk
+ end
+ if err then
+ return nil,err
+ end
+ src=remove(arg,1)
end
+ end
end
function sink.table(t)
- if not t then
- t={}
- end
- local f=function(chunk,err)
- if chunk then
- insert(t,chunk)
- end
- return 1
+ if not t then
+ t={}
+ end
+ local f=function(chunk,err)
+ if chunk then
+ insert(t,chunk)
end
- return f,t
+ return 1
+ end
+ return f,t
end
function sink.simplify(snk)
- return function(chunk,err)
- local ret,err_or_new=snk(chunk,err)
- if not ret then
- return nil,err_or_new
- end
- if err_or_new then
- snk=err_or_new
- end
- return 1
+ return function(chunk,err)
+ local ret,err_or_new=snk(chunk,err)
+ if not ret then
+ return nil,err_or_new
end
+ if err_or_new then
+ snk=err_or_new
+ end
+ return 1
+ end
end
local function null()
- return 1
+ return 1
end
function sink.null()
- return null
+ return null
end
local function sinkerror(err)
- return function()
- return nil,err
- end
+ return function()
+ return nil,err
+ end
end
sink.error=sinkerror
function sink.file(handle,io_err)
- if handle then
- return function(chunk,err)
- if not chunk then
- handle:close()
- return 1
- else
- return handle:write(chunk)
- end
- end
- else
- return sinkerror(io_err or "unable to open file")
+ if handle then
+ return function(chunk,err)
+ if not chunk then
+ handle:close()
+ return 1
+ else
+ return handle:write(chunk)
+ end
end
+ else
+ return sinkerror(io_err or "unable to open file")
+ end
end
function sink.chain(f,snk,...)
- if... then
- local args={ f,snk,... }
- snk=remove(args,#args)
- f=filter.chain(unpack(args))
- end
- return function(chunk,err)
- if chunk~="" then
- local filtered=f(chunk)
- local done=chunk and ""
- while true do
- local ret,snkerr=snk(filtered,err)
- if not ret then
- return nil,snkerr
- end
- if filtered==done then
- return 1
- end
- filtered=f(done)
- end
- else
- return 1
+ if... then
+ local args={ f,snk,... }
+ snk=remove(args,#args)
+ f=filter.chain(unpack(args))
+ end
+ return function(chunk,err)
+ if chunk~="" then
+ local filtered=f(chunk)
+ local done=chunk and ""
+ while true do
+ local ret,snkerr=snk(filtered,err)
+ if not ret then
+ return nil,snkerr
+ end
+ if filtered==done then
+ return 1
end
+ filtered=f(done)
+ end
+ else
+ return 1
end
+ end
end
function pump.step(src,snk)
- local chunk,src_err=src()
- local ret,snk_err=snk(chunk,src_err)
- if chunk and ret then
- return 1
- else
- return nil,src_err or snk_err
- end
+ local chunk,src_err=src()
+ local ret,snk_err=snk(chunk,src_err)
+ if chunk and ret then
+ return 1
+ else
+ return nil,src_err or snk_err
+ end
end
function pump.all(src,snk,step)
- if not step then
- step=pump.step
- end
- while true do
- local ret,err=step(src,snk)
- if not ret then
- if err then
- return nil,err
- else
- return 1
- end
- end
+ if not step then
+ step=pump.step
+ end
+ while true do
+ local ret,err=step(src,snk)
+ if not ret then
+ if err then
+ return nil,err
+ else
+ return 1
+ end
end
+ end
end
package.loaded["ltn12"]=ltn12
@@ -10603,7 +10603,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true
--- original size: 2328, stripped down to: 1930
+-- original size: 2328, stripped down to: 1874
local type,tostring=type,tostring
@@ -10611,17 +10611,17 @@ local mime=require("mime.core")
local ltn12=ltn12 or require("ltn12")
local filtercycle=ltn12.filter.cycle
local function report(fmt,first,...)
- if logs then
- report=logs and logs.reporter("mime")
- report(fmt,first,...)
- elseif fmt then
- fmt="mime: "..fmt
- if first then
- print(format(fmt,first,...))
- else
- print(fmt)
- end
+ if logs then
+ report=logs and logs.reporter("mime")
+ report(fmt,first,...)
+ elseif fmt then
+ fmt="mime: "..fmt
+ if first then
+ print(format(fmt,first,...))
+ else
+ print(fmt)
end
+ end
end
mime.report=report
local encodet={}
@@ -10639,48 +10639,48 @@ local mime_qpwrp=mime.qpwrp
local mime_eol=mime_eol
local mime_dot=mime_dot
encodet['base64']=function()
- return filtercycle(mime_b64,"")
+ return filtercycle(mime_b64,"")
end
encodet['quoted-printable']=function(mode)
- return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n")
+ return filtercycle(mime_qp,"",mode=="binary" and "=0D=0A" or "\r\n")
end
decodet['base64']=function()
- return filtercycle(mime_unb64,"")
+ return filtercycle(mime_unb64,"")
end
decodet['quoted-printable']=function()
- return filtercycle(mime_unqp,"")
+ return filtercycle(mime_unqp,"")
end
local wraptext=function(length)
- if not length then
- length=76
- end
- return filtercycle(mime_wrp,length,length)
+ if not length then
+ length=76
+ end
+ return filtercycle(mime_wrp,length,length)
end
local wrapquoted=function()
- return filtercycle(mime_qpwrp,76,76)
+ return filtercycle(mime_qpwrp,76,76)
end
wrapt['text']=wraptext
wrapt['base64']=wraptext
wrapt['default']=wraptext
wrapt['quoted-printable']=wrapquoted
function mime.normalize(marker)
- return filtercycle(mime_eol,0,marker)
+ return filtercycle(mime_eol,0,marker)
end
function mime.stuff()
- return filtercycle(mime_dot,2)
+ return filtercycle(mime_dot,2)
end
local function choose(list)
- return function(name,opt1,opt2)
- if type(name)~="string" then
- name,opt1,opt2="default",name,opt1
- end
- local filter=list[name or "nil"]
- if filter then
- return filter(opt1,opt2)
- else
- report("error: unknown key '%s'",tostring(name))
- end
+ return function(name,opt1,opt2)
+ if type(name)~="string" then
+ name,opt1,opt2="default",name,opt1
+ end
+ local filter=list[name or "nil"]
+ if filter then
+ return filter(opt1,opt2)
+ else
+ report("error: unknown key '%s'",tostring(name))
end
+ end
end
mime.encode=choose(encodet)
mime.decode=choose(decodet)
@@ -10694,7 +10694,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true
--- original size: 6863, stripped down to: 5657
+-- original size: 6863, stripped down to: 5269
local tonumber,tostring,type=tonumber,tostring,type
@@ -10702,246 +10702,246 @@ local gsub,sub,match,find,format,byte,char=string.gsub,string.sub,string.match,s
local insert=table.insert
local socket=socket or require("socket")
local url={
- _VERSION="URL 1.0.3",
+ _VERSION="URL 1.0.3",
}
socket.url=url
function url.escape(s)
- return (gsub(s,"([^A-Za-z0-9_])",function(c)
- return format("%%%02x",byte(c))
- end))
+ return (gsub(s,"([^A-Za-z0-9_])",function(c)
+ return format("%%%02x",byte(c))
+ end))
end
local function make_set(t)
- local s={}
- for i=1,#t do
- s[t[i]]=true
- end
- return s
+ local s={}
+ for i=1,#t do
+ s[t[i]]=true
+ end
+ return s
end
local segment_set=make_set {
- "-","_",".","!","~","*","'","(",
- ")",":","@","&","=","+","$",",",
+ "-","_",".","!","~","*","'","(",
+ ")",":","@","&","=","+","$",",",
}
local function protect_segment(s)
- return gsub(s,"([^A-Za-z0-9_])",function(c)
- if segment_set[c] then
- return c
- else
- return format("%%%02X",byte(c))
- end
- end)
+ return gsub(s,"([^A-Za-z0-9_])",function(c)
+ if segment_set[c] then
+ return c
+ else
+ return format("%%%02X",byte(c))
+ end
+ end)
end
function url.unescape(s)
- return (gsub(s,"%%(%x%x)",function(hex)
- return char(tonumber(hex,16))
- end))
+ return (gsub(s,"%%(%x%x)",function(hex)
+ return char(tonumber(hex,16))
+ end))
end
local function absolute_path(base_path,relative_path)
- if find(relative_path,"^/") then
- return relative_path
- end
- local path=gsub(base_path,"[^/]*$","")
- path=path..relative_path
- path=gsub(path,"([^/]*%./)",function (s)
- if s~="./" then
- return s
- else
- return ""
- end
+ if find(relative_path,"^/") then
+ return relative_path
+ end
+ local path=gsub(base_path,"[^/]*$","")
+ path=path..relative_path
+ path=gsub(path,"([^/]*%./)",function (s)
+ if s~="./" then
+ return s
+ else
+ return ""
+ end
+ end)
+ path=gsub(path,"/%.$","/")
+ local reduced
+ while reduced~=path do
+ reduced=path
+ path=gsub(reduced,"([^/]*/%.%./)",function (s)
+ if s~="../../" then
+ return ""
+ else
+ return s
+ end
end)
- path=gsub(path,"/%.$","/")
- local reduced
- while reduced~=path do
- reduced=path
- path=gsub(reduced,"([^/]*/%.%./)",function (s)
- if s~="../../" then
- return ""
- else
- return s
- end
- end)
+ end
+ path=gsub(reduced,"([^/]*/%.%.)$",function (s)
+ if s~="../.." then
+ return ""
+ else
+ return s
end
- path=gsub(reduced,"([^/]*/%.%.)$",function (s)
- if s~="../.." then
- return ""
- else
- return s
- end
- end)
- return path
+ end)
+ return path
end
function url.parse(url,default)
- local parsed={}
- for k,v in next,default or parsed do
- parsed[k]=v
- end
- if not url or url=="" then
- return nil,"invalid url"
- end
- url=gsub(url,"#(.*)$",function(f)
- parsed.fragment=f
- return ""
- end)
- url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s)
- parsed.scheme=s
- return ""
- end)
- url=gsub(url,"^//([^/]*)",function(n)
- parsed.authority=n
- return ""
- end)
- url=gsub(url,"%?(.*)",function(q)
- parsed.query=q
- return ""
- end)
- url=gsub(url,"%;(.*)",function(p)
- parsed.params=p
- return ""
- end)
- if url~="" then
- parsed.path=url
- end
- local authority=parsed.authority
- if not authority then
- return parsed
- end
- authority=gsub(authority,"^([^@]*)@",function(u)
- parsed.userinfo=u
- return ""
- end)
- authority=gsub(authority,":([^:%]]*)$",function(p)
- parsed.port=p
- return ""
- end)
- if authority~="" then
- parsed.host=match(authority,"^%[(.+)%]$") or authority
- end
- local userinfo=parsed.userinfo
- if not userinfo then
- return parsed
- end
- userinfo=gsub(userinfo,":([^:]*)$",function(p)
- parsed.password=p
- return ""
- end)
- parsed.user=userinfo
+ local parsed={}
+ for k,v in next,default or parsed do
+ parsed[k]=v
+ end
+ if not url or url=="" then
+ return nil,"invalid url"
+ end
+ url=gsub(url,"#(.*)$",function(f)
+ parsed.fragment=f
+ return ""
+ end)
+ url=gsub(url,"^([%w][%w%+%-%.]*)%:",function(s)
+ parsed.scheme=s
+ return ""
+ end)
+ url=gsub(url,"^//([^/]*)",function(n)
+ parsed.authority=n
+ return ""
+ end)
+ url=gsub(url,"%?(.*)",function(q)
+ parsed.query=q
+ return ""
+ end)
+ url=gsub(url,"%;(.*)",function(p)
+ parsed.params=p
+ return ""
+ end)
+ if url~="" then
+ parsed.path=url
+ end
+ local authority=parsed.authority
+ if not authority then
return parsed
+ end
+ authority=gsub(authority,"^([^@]*)@",function(u)
+ parsed.userinfo=u
+ return ""
+ end)
+ authority=gsub(authority,":([^:%]]*)$",function(p)
+ parsed.port=p
+ return ""
+ end)
+ if authority~="" then
+ parsed.host=match(authority,"^%[(.+)%]$") or authority
+ end
+ local userinfo=parsed.userinfo
+ if not userinfo then
+ return parsed
+ end
+ userinfo=gsub(userinfo,":([^:]*)$",function(p)
+ parsed.password=p
+ return ""
+ end)
+ parsed.user=userinfo
+ return parsed
end
function url.build(parsed)
- local url=parsed.path or ""
- if parsed.params then
- url=url..";"..parsed.params
- end
- if parsed.query then
- url=url.."?"..parsed.query
- end
- local authority=parsed.authority
- if parsed.host then
- authority=parsed.host
- if find(authority,":") then
- authority="["..authority.."]"
- end
- if parsed.port then
- authority=authority..":"..tostring(parsed.port)
- end
- local userinfo=parsed.userinfo
- if parsed.user then
- userinfo=parsed.user
- if parsed.password then
- userinfo=userinfo..":"..parsed.password
- end
- end
- if userinfo then authority=userinfo.."@"..authority end
+ local url=parsed.path or ""
+ if parsed.params then
+ url=url..";"..parsed.params
+ end
+ if parsed.query then
+ url=url.."?"..parsed.query
+ end
+ local authority=parsed.authority
+ if parsed.host then
+ authority=parsed.host
+ if find(authority,":") then
+ authority="["..authority.."]"
+ end
+ if parsed.port then
+ authority=authority..":"..tostring(parsed.port)
end
- if authority then
- url="//"..authority..url
- end
- if parsed.scheme then
- url=parsed.scheme..":"..url
- end
- if parsed.fragment then
- url=url.."#"..parsed.fragment
+ local userinfo=parsed.userinfo
+ if parsed.user then
+ userinfo=parsed.user
+ if parsed.password then
+ userinfo=userinfo..":"..parsed.password
+ end
end
- return url
+ if userinfo then authority=userinfo.."@"..authority end
+ end
+ if authority then
+ url="//"..authority..url
+ end
+ if parsed.scheme then
+ url=parsed.scheme..":"..url
+ end
+ if parsed.fragment then
+ url=url.."#"..parsed.fragment
+ end
+ return url
end
function url.absolute(base_url,relative_url)
- local base_parsed
- if type(base_url)=="table" then
- base_parsed=base_url
- base_url=url.build(base_parsed)
- else
- base_parsed=url.parse(base_url)
- end
- local relative_parsed=url.parse(relative_url)
- if not base_parsed then
- return relative_url
- elseif not relative_parsed then
- return base_url
- elseif relative_parsed.scheme then
- return relative_url
- else
- relative_parsed.scheme=base_parsed.scheme
- if not relative_parsed.authority then
- relative_parsed.authority=base_parsed.authority
- if not relative_parsed.path then
- relative_parsed.path=base_parsed.path
- if not relative_parsed.params then
- relative_parsed.params=base_parsed.params
- if not relative_parsed.query then
- relative_parsed.query=base_parsed.query
- end
- end
- else
- relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path)
- end
+ local base_parsed
+ if type(base_url)=="table" then
+ base_parsed=base_url
+ base_url=url.build(base_parsed)
+ else
+ base_parsed=url.parse(base_url)
+ end
+ local relative_parsed=url.parse(relative_url)
+ if not base_parsed then
+ return relative_url
+ elseif not relative_parsed then
+ return base_url
+ elseif relative_parsed.scheme then
+ return relative_url
+ else
+ relative_parsed.scheme=base_parsed.scheme
+ if not relative_parsed.authority then
+ relative_parsed.authority=base_parsed.authority
+ if not relative_parsed.path then
+ relative_parsed.path=base_parsed.path
+ if not relative_parsed.params then
+ relative_parsed.params=base_parsed.params
+ if not relative_parsed.query then
+ relative_parsed.query=base_parsed.query
+ end
end
- return url.build(relative_parsed)
+ else
+ relative_parsed.path=absolute_path(base_parsed.path or "",relative_parsed.path)
+ end
end
+ return url.build(relative_parsed)
+ end
end
function url.parse_path(path)
- local parsed={}
- path=path or ""
- gsub(path,"([^/]+)",function (s)
- insert(parsed,s)
- end)
- for i=1,#parsed do
- parsed[i]=url.unescape(parsed[i])
- end
- if sub(path,1,1)=="/" then
- parsed.is_absolute=1
- end
- if sub(path,-1,-1)=="/" then
- parsed.is_directory=1
- end
- return parsed
+ local parsed={}
+ path=path or ""
+ gsub(path,"([^/]+)",function (s)
+ insert(parsed,s)
+ end)
+ for i=1,#parsed do
+ parsed[i]=url.unescape(parsed[i])
+ end
+ if sub(path,1,1)=="/" then
+ parsed.is_absolute=1
+ end
+ if sub(path,-1,-1)=="/" then
+ parsed.is_directory=1
+ end
+ return parsed
end
function url.build_path(parsed,unsafe)
- local path=""
- local n=#parsed
- if unsafe then
- for i=1,n-1 do
- path=path..parsed[i].."/"
- end
- if n>0 then
- path=path..parsed[n]
- if parsed.is_directory then
- path=path.."/"
- end
- end
- else
- for i=1,n-1 do
- path=path..protect_segment(parsed[i]).."/"
- end
- if n>0 then
- path=path..protect_segment(parsed[n])
- if parsed.is_directory then
- path=path.."/"
- end
- end
+ local path=""
+ local n=#parsed
+ if unsafe then
+ for i=1,n-1 do
+ path=path..parsed[i].."/"
end
- if parsed.is_absolute then
- path="/"..path
+ if n>0 then
+ path=path..parsed[n]
+ if parsed.is_directory then
+ path=path.."/"
+ end
end
- return path
+ else
+ for i=1,n-1 do
+ path=path..protect_segment(parsed[i]).."/"
+ end
+ if n>0 then
+ path=path..protect_segment(parsed[n])
+ if parsed.is_directory then
+ path=path.."/"
+ end
+ end
+ end
+ if parsed.is_absolute then
+ path="/"..path
+ end
+ return path
end
package.loaded["socket.url"]=url
@@ -10952,7 +10952,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true
--- original size: 5721, stripped down to: 3878
+-- original size: 5721, stripped down to: 3754
local next=next
@@ -10962,128 +10962,128 @@ local socket=socket or require("socket")
local headers={}
socket.headers=headers
local canonic={
- ["accept"]="Accept",
- ["accept-charset"]="Accept-Charset",
- ["accept-encoding"]="Accept-Encoding",
- ["accept-language"]="Accept-Language",
- ["accept-ranges"]="Accept-Ranges",
- ["action"]="Action",
- ["alternate-recipient"]="Alternate-Recipient",
- ["age"]="Age",
- ["allow"]="Allow",
- ["arrival-date"]="Arrival-Date",
- ["authorization"]="Authorization",
- ["bcc"]="Bcc",
- ["cache-control"]="Cache-Control",
- ["cc"]="Cc",
- ["comments"]="Comments",
- ["connection"]="Connection",
- ["content-description"]="Content-Description",
- ["content-disposition"]="Content-Disposition",
- ["content-encoding"]="Content-Encoding",
- ["content-id"]="Content-ID",
- ["content-language"]="Content-Language",
- ["content-length"]="Content-Length",
- ["content-location"]="Content-Location",
- ["content-md5"]="Content-MD5",
- ["content-range"]="Content-Range",
- ["content-transfer-encoding"]="Content-Transfer-Encoding",
- ["content-type"]="Content-Type",
- ["cookie"]="Cookie",
- ["date"]="Date",
- ["diagnostic-code"]="Diagnostic-Code",
- ["dsn-gateway"]="DSN-Gateway",
- ["etag"]="ETag",
- ["expect"]="Expect",
- ["expires"]="Expires",
- ["final-log-id"]="Final-Log-ID",
- ["final-recipient"]="Final-Recipient",
- ["from"]="From",
- ["host"]="Host",
- ["if-match"]="If-Match",
- ["if-modified-since"]="If-Modified-Since",
- ["if-none-match"]="If-None-Match",
- ["if-range"]="If-Range",
- ["if-unmodified-since"]="If-Unmodified-Since",
- ["in-reply-to"]="In-Reply-To",
- ["keywords"]="Keywords",
- ["last-attempt-date"]="Last-Attempt-Date",
- ["last-modified"]="Last-Modified",
- ["location"]="Location",
- ["max-forwards"]="Max-Forwards",
- ["message-id"]="Message-ID",
- ["mime-version"]="MIME-Version",
- ["original-envelope-id"]="Original-Envelope-ID",
- ["original-recipient"]="Original-Recipient",
- ["pragma"]="Pragma",
- ["proxy-authenticate"]="Proxy-Authenticate",
- ["proxy-authorization"]="Proxy-Authorization",
- ["range"]="Range",
- ["received"]="Received",
- ["received-from-mta"]="Received-From-MTA",
- ["references"]="References",
- ["referer"]="Referer",
- ["remote-mta"]="Remote-MTA",
- ["reply-to"]="Reply-To",
- ["reporting-mta"]="Reporting-MTA",
- ["resent-bcc"]="Resent-Bcc",
- ["resent-cc"]="Resent-Cc",
- ["resent-date"]="Resent-Date",
- ["resent-from"]="Resent-From",
- ["resent-message-id"]="Resent-Message-ID",
- ["resent-reply-to"]="Resent-Reply-To",
- ["resent-sender"]="Resent-Sender",
- ["resent-to"]="Resent-To",
- ["retry-after"]="Retry-After",
- ["return-path"]="Return-Path",
- ["sender"]="Sender",
- ["server"]="Server",
- ["smtp-remote-recipient"]="SMTP-Remote-Recipient",
- ["status"]="Status",
- ["subject"]="Subject",
- ["te"]="TE",
- ["to"]="To",
- ["trailer"]="Trailer",
- ["transfer-encoding"]="Transfer-Encoding",
- ["upgrade"]="Upgrade",
- ["user-agent"]="User-Agent",
- ["vary"]="Vary",
- ["via"]="Via",
- ["warning"]="Warning",
- ["will-retry-until"]="Will-Retry-Until",
- ["www-authenticate"]="WWW-Authenticate",
- ["x-mailer"]="X-Mailer",
+ ["accept"]="Accept",
+ ["accept-charset"]="Accept-Charset",
+ ["accept-encoding"]="Accept-Encoding",
+ ["accept-language"]="Accept-Language",
+ ["accept-ranges"]="Accept-Ranges",
+ ["action"]="Action",
+ ["alternate-recipient"]="Alternate-Recipient",
+ ["age"]="Age",
+ ["allow"]="Allow",
+ ["arrival-date"]="Arrival-Date",
+ ["authorization"]="Authorization",
+ ["bcc"]="Bcc",
+ ["cache-control"]="Cache-Control",
+ ["cc"]="Cc",
+ ["comments"]="Comments",
+ ["connection"]="Connection",
+ ["content-description"]="Content-Description",
+ ["content-disposition"]="Content-Disposition",
+ ["content-encoding"]="Content-Encoding",
+ ["content-id"]="Content-ID",
+ ["content-language"]="Content-Language",
+ ["content-length"]="Content-Length",
+ ["content-location"]="Content-Location",
+ ["content-md5"]="Content-MD5",
+ ["content-range"]="Content-Range",
+ ["content-transfer-encoding"]="Content-Transfer-Encoding",
+ ["content-type"]="Content-Type",
+ ["cookie"]="Cookie",
+ ["date"]="Date",
+ ["diagnostic-code"]="Diagnostic-Code",
+ ["dsn-gateway"]="DSN-Gateway",
+ ["etag"]="ETag",
+ ["expect"]="Expect",
+ ["expires"]="Expires",
+ ["final-log-id"]="Final-Log-ID",
+ ["final-recipient"]="Final-Recipient",
+ ["from"]="From",
+ ["host"]="Host",
+ ["if-match"]="If-Match",
+ ["if-modified-since"]="If-Modified-Since",
+ ["if-none-match"]="If-None-Match",
+ ["if-range"]="If-Range",
+ ["if-unmodified-since"]="If-Unmodified-Since",
+ ["in-reply-to"]="In-Reply-To",
+ ["keywords"]="Keywords",
+ ["last-attempt-date"]="Last-Attempt-Date",
+ ["last-modified"]="Last-Modified",
+ ["location"]="Location",
+ ["max-forwards"]="Max-Forwards",
+ ["message-id"]="Message-ID",
+ ["mime-version"]="MIME-Version",
+ ["original-envelope-id"]="Original-Envelope-ID",
+ ["original-recipient"]="Original-Recipient",
+ ["pragma"]="Pragma",
+ ["proxy-authenticate"]="Proxy-Authenticate",
+ ["proxy-authorization"]="Proxy-Authorization",
+ ["range"]="Range",
+ ["received"]="Received",
+ ["received-from-mta"]="Received-From-MTA",
+ ["references"]="References",
+ ["referer"]="Referer",
+ ["remote-mta"]="Remote-MTA",
+ ["reply-to"]="Reply-To",
+ ["reporting-mta"]="Reporting-MTA",
+ ["resent-bcc"]="Resent-Bcc",
+ ["resent-cc"]="Resent-Cc",
+ ["resent-date"]="Resent-Date",
+ ["resent-from"]="Resent-From",
+ ["resent-message-id"]="Resent-Message-ID",
+ ["resent-reply-to"]="Resent-Reply-To",
+ ["resent-sender"]="Resent-Sender",
+ ["resent-to"]="Resent-To",
+ ["retry-after"]="Retry-After",
+ ["return-path"]="Return-Path",
+ ["sender"]="Sender",
+ ["server"]="Server",
+ ["smtp-remote-recipient"]="SMTP-Remote-Recipient",
+ ["status"]="Status",
+ ["subject"]="Subject",
+ ["te"]="TE",
+ ["to"]="To",
+ ["trailer"]="Trailer",
+ ["transfer-encoding"]="Transfer-Encoding",
+ ["upgrade"]="Upgrade",
+ ["user-agent"]="User-Agent",
+ ["vary"]="Vary",
+ ["via"]="Via",
+ ["warning"]="Warning",
+ ["will-retry-until"]="Will-Retry-Until",
+ ["www-authenticate"]="WWW-Authenticate",
+ ["x-mailer"]="X-Mailer",
}
headers.canonic=setmetatable(canonic,{
- __index=function(t,k)
- socket.report("invalid header: %s",k)
- t[k]=k
- return k
- end
+ __index=function(t,k)
+ socket.report("invalid header: %s",k)
+ t[k]=k
+ return k
+ end
})
function headers.normalize(headers)
- if not headers then
- return {}
- end
- local normalized={}
- for k,v in next,headers do
- normalized[#normalized+1]=canonic[k]..": "..v
- end
- normalized[#normalized+1]=""
- normalized[#normalized+1]=""
- return concat(normalized,"\r\n")
+ if not headers then
+ return {}
+ end
+ local normalized={}
+ for k,v in next,headers do
+ normalized[#normalized+1]=canonic[k]..": "..v
+ end
+ normalized[#normalized+1]=""
+ normalized[#normalized+1]=""
+ return concat(normalized,"\r\n")
end
function headers.lower(lowered,headers)
- if not lowered then
- return {}
- end
- if not headers then
- lowered,headers={},lowered
- end
- for k,v in next,headers do
- lowered[lower(k)]=v
- end
- return lowered
+ if not lowered then
+ return {}
+ end
+ if not headers then
+ lowered,headers={},lowered
+ end
+ for k,v in next,headers do
+ lowered[lower(k)]=v
+ end
+ return lowered
end
socket.headers=headers
package.loaded["socket.headers"]=headers
@@ -11095,13 +11095,13 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true
--- original size: 3116, stripped down to: 2643
+-- original size: 3116, stripped down to: 2533
local setmetatable,next,type,tonumber=setmetatable,next,type,tonumber
local find,upper=string.find,string.upper
local socket=socket or require("socket")
-local ltn12=ltn12 or require("ltn12")
+local ltn12=ltn12 or require("ltn12")
local skipsocket=socket.skip
local sinksocket=socket.sink
local tcpsocket=socket.tcp
@@ -11109,111 +11109,111 @@ local ltn12pump=ltn12.pump
local pumpall=ltn12pump.all
local pumpstep=ltn12pump.step
local tp={
- TIMEOUT=60,
+ TIMEOUT=60,
}
socket.tp=tp
local function get_reply(c)
- local line,err=c:receive()
- local reply=line
- if err then return
- nil,err
- end
- local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
- if not code then
- return nil,"invalid server reply"
- end
- if sep=="-" then
- local current
- repeat
- line,err=c:receive()
- if err then
- return nil,err
- end
- current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
- reply=reply.."\n"..line
- until code==current and sep==" "
- end
- return code,reply
+ local line,err=c:receive()
+ local reply=line
+ if err then return
+ nil,err
+ end
+ local code,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
+ if not code then
+ return nil,"invalid server reply"
+ end
+ if sep=="-" then
+ local current
+ repeat
+ line,err=c:receive()
+ if err then
+ return nil,err
+ end
+ current,sep=skipsocket(2,find(line,"^(%d%d%d)(.?)"))
+ reply=reply.."\n"..line
+ until code==current and sep==" "
+ end
+ return code,reply
end
local methods={}
local mt={ __index=methods }
function methods.getpeername(self)
- return self.c:getpeername()
+ return self.c:getpeername()
end
function methods.getsockname(self)
- return self.c:getpeername()
+ return self.c:getpeername()
end
function methods.check(self,ok)
- local code,reply=get_reply(self.c)
- if not code then
- return nil,reply
- end
- local c=tonumber(code)
- local t=type(ok)
- if t=="function" then
- return ok(c,reply)
- elseif t=="table" then
- for i=1,#ok do
- if find(code,ok[i]) then
- return c,reply
- end
- end
- return nil,reply
- elseif find(code,ok) then
+ local code,reply=get_reply(self.c)
+ if not code then
+ return nil,reply
+ end
+ local c=tonumber(code)
+ local t=type(ok)
+ if t=="function" then
+ return ok(c,reply)
+ elseif t=="table" then
+ for i=1,#ok do
+ if find(code,ok[i]) then
return c,reply
- else
- return nil,reply
+ end
end
+ return nil,reply
+ elseif find(code,ok) then
+ return c,reply
+ else
+ return nil,reply
+ end
end
function methods.command(self,cmd,arg)
- cmd=upper(cmd)
- if arg then
- cmd=cmd.." "..arg.."\r\n"
- else
- cmd=cmd.."\r\n"
- end
- return self.c:send(cmd)
+ cmd=upper(cmd)
+ if arg then
+ cmd=cmd.." "..arg.."\r\n"
+ else
+ cmd=cmd.."\r\n"
+ end
+ return self.c:send(cmd)
end
function methods.sink(self,snk,pat)
- local chunk,err=self.c:receive(pat)
- return snk(chunk,err)
+ local chunk,err=self.c:receive(pat)
+ return snk(chunk,err)
end
function methods.send(self,data)
- return self.c:send(data)
+ return self.c:send(data)
end
function methods.receive(self,pat)
- return self.c:receive(pat)
+ return self.c:receive(pat)
end
function methods.getfd(self)
- return self.c:getfd()
+ return self.c:getfd()
end
function methods.dirty(self)
- return self.c:dirty()
+ return self.c:dirty()
end
function methods.getcontrol(self)
- return self.c
+ return self.c
end
function methods.source(self,source,step)
- local sink=sinksocket("keep-open",self.c)
- local ret,err=pumpall(source,sink,step or pumpstep)
- return ret,err
+ local sink=sinksocket("keep-open",self.c)
+ local ret,err=pumpall(source,sink,step or pumpstep)
+ return ret,err
end
function methods.close(self)
- self.c:close()
- return 1
+ self.c:close()
+ return 1
end
function tp.connect(host,port,timeout,create)
- local c,e=(create or tcpsocket)()
- if not c then
- return nil,e
- end
- c:settimeout(timeout or tp.TIMEOUT)
- local r,e=c:connect(host,port)
- if not r then
- c:close()
- return nil,e
- end
- return setmetatable({ c=c },mt)
+ local c,e=(create or tcpsocket)()
+ if not c then
+ return nil,e
+ end
+ c:settimeout(timeout or tp.TIMEOUT)
+ local r,e=c:connect(host,port)
+ if not r then
+ c:close()
+ return nil,e
+ end
+ return setmetatable({ c=c },mt)
end
package.loaded["socket.tp"]=tp
@@ -11224,16 +11224,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true
--- original size: 12577, stripped down to: 10069
+-- original size: 12577, stripped down to: 9577
local tostring,tonumber,setmetatable,next,type=tostring,tonumber,setmetatable,next,type
local find,lower,format,gsub,match=string.find,string.lower,string.format,string.gsub,string.match
local concat=table.concat
-local socket=socket or require("socket")
-local url=socket.url or require("socket.url")
-local ltn12=ltn12 or require("ltn12")
-local mime=mime or require("mime")
+local socket=socket or require("socket")
+local url=socket.url or require("socket.url")
+local ltn12=ltn12 or require("ltn12")
+local mime=mime or require("mime")
local headers=socket.headers or require("socket.headers")
local normalizeheaders=headers.normalize
local parseurl=url.parse
@@ -11257,345 +11257,345 @@ local sinktable=ltn12.sink.table
local lowerheaders=headers.lower
local mimeb64=mime.b64
local http={
- TIMEOUT=60,
- USERAGENT=socket._VERSION,
+ TIMEOUT=60,
+ USERAGENT=socket._VERSION,
}
socket.http=http
local PORT=80
local SCHEMES={
- http=true,
+ http=true,
}
local function receiveheaders(sock,headers)
- if not headers then
- headers={}
- end
- local line,err=sock:receive()
+ if not headers then
+ headers={}
+ end
+ local line,err=sock:receive()
+ if err then
+ return nil,err
+ end
+ while line~="" do
+ local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
+ if not (name and value) then
+ return nil,"malformed reponse headers"
+ end
+ name=lower(name)
+ line,err=sock:receive()
if err then
+ return nil,err
+ end
+ while find(line,"^%s") do
+ value=value..line
+ line=sock:receive()
+ if err then
return nil,err
+ end
end
- while line~="" do
- local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
- if not (name and value) then
- return nil,"malformed reponse headers"
- end
- name=lower(name)
- line,err=sock:receive()
+ local found=headers[name]
+ if found then
+ value=found..", "..value
+ end
+ headers[name]=value
+ end
+ return headers
+end
+socket.sourcet["http-chunked"]=function(sock,headers)
+ return setmetatable (
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },{
+ __call=function()
+ local line,err=sock:receive()
if err then
- return nil,err
+ return nil,err
end
- while find(line,"^%s") do
- value=value..line
- line=sock:receive()
- if err then
- return nil,err
- end
+ local size=tonumber(gsub(line,";.*",""),16)
+ if not size then
+ return nil,"invalid chunk size"
end
- local found=headers[name]
- if found then
- value=found..", "..value
+ if size>0 then
+ local chunk,err,part=sock:receive(size)
+ if chunk then
+ sock:receive()
+ end
+ return chunk,err
+ else
+ headers,err=receiveheaders(sock,headers)
+ if not headers then
+ return nil,err
+ end
end
- headers[name]=value
- end
- return headers
-end
-socket.sourcet["http-chunked"]=function(sock,headers)
- return setmetatable (
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },{
- __call=function()
- local line,err=sock:receive()
- if err then
- return nil,err
- end
- local size=tonumber(gsub(line,";.*",""),16)
- if not size then
- return nil,"invalid chunk size"
- end
- if size>0 then
- local chunk,err,part=sock:receive(size)
- if chunk then
- sock:receive()
- end
- return chunk,err
- else
- headers,err=receiveheaders(sock,headers)
- if not headers then
- return nil,err
- end
- end
- end
- }
- )
+ end
+ }
+ )
end
socket.sinkt["http-chunked"]=function(sock)
- return setmetatable(
- {
- getfd=function() return sock:getfd() end,
- dirty=function() return sock:dirty() end,
- },
- {
- __call=function(self,chunk,err)
- if not chunk then
- chunk=""
- end
- return sock:send(format("%X\r\n%s\r\n",#chunk,chunk))
- end
- })
+ return setmetatable(
+ {
+ getfd=function() return sock:getfd() end,
+ dirty=function() return sock:dirty() end,
+ },
+ {
+ __call=function(self,chunk,err)
+ if not chunk then
+ chunk=""
+ end
+ return sock:send(format("%X\r\n%s\r\n",#chunk,chunk))
+ end
+ })
end
local methods={}
local mt={ __index=methods }
local function openhttp(host,port,create)
- local c=trysocket((create or tcpsocket)())
- local h=setmetatable({ c=c },mt)
- local try=newtrysocket(function() h:close() end)
- h.try=try
- try(c:settimeout(http.TIMEOUT))
- try(c:connect(host,port or PORT))
- return h
+ local c=trysocket((create or tcpsocket)())
+ local h=setmetatable({ c=c },mt)
+ local try=newtrysocket(function() h:close() end)
+ h.try=try
+ try(c:settimeout(http.TIMEOUT))
+ try(c:connect(host,port or PORT))
+ return h
end
http.open=openhttp
function methods.sendrequestline(self,method,uri)
- local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri)
- return self.try(self.c:send(requestline))
+ local requestline=format("%s %s HTTP/1.1\r\n",method or "GET",uri)
+ return self.try(self.c:send(requestline))
end
function methods.sendheaders(self,headers)
- self.try(self.c:send(normalizeheaders(headers)))
- return 1
+ self.try(self.c:send(normalizeheaders(headers)))
+ return 1
end
function methods.sendbody(self,headers,source,step)
- if not source then
- source=emptysource()
- end
- if not step then
- step=pumpstep
- end
- local mode="http-chunked"
- if headers["content-length"] then
- mode="keep-open"
- end
- return self.try(pumpall(source,sinksocket(mode,self.c),step))
+ if not source then
+ source=emptysource()
+ end
+ if not step then
+ step=pumpstep
+ end
+ local mode="http-chunked"
+ if headers["content-length"] then
+ mode="keep-open"
+ end
+ return self.try(pumpall(source,sinksocket(mode,self.c),step))
end
function methods.receivestatusline(self)
- local try=self.try
- local status=try(self.c:receive(5))
- if status~="HTTP/" then
- return nil,status
- end
- status=try(self.c:receive("*l",status))
- local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)"))
- return try(tonumber(code),status)
+ local try=self.try
+ local status=try(self.c:receive(5))
+ if status~="HTTP/" then
+ return nil,status
+ end
+ status=try(self.c:receive("*l",status))
+ local code=skipsocket(2,find(status,"HTTP/%d*%.%d* (%d%d%d)"))
+ return try(tonumber(code),status)
end
function methods.receiveheaders(self)
- return self.try(receiveheaders(self.c))
+ return self.try(receiveheaders(self.c))
end
function methods.receivebody(self,headers,sink,step)
- if not sink then
- sink=sinknull()
- end
- if not step then
- step=pumpstep
- end
- local length=tonumber(headers["content-length"])
- local encoding=headers["transfer-encoding"]
- local mode="default"
- if encoding and encoding~="identity" then
- mode="http-chunked"
- elseif length then
- mode="by-length"
- end
- return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step))
+ if not sink then
+ sink=sinknull()
+ end
+ if not step then
+ step=pumpstep
+ end
+ local length=tonumber(headers["content-length"])
+ local encoding=headers["transfer-encoding"]
+ local mode="default"
+ if encoding and encoding~="identity" then
+ mode="http-chunked"
+ elseif length then
+ mode="by-length"
+ end
+ return self.try(pumpall(sourcesocket(mode,self.c,length),sink,step))
end
function methods.receive09body(self,status,sink,step)
- local source=rewindsource(sourcesocket("until-closed",self.c))
- source(status)
- return self.try(pumpall(source,sink,step))
+ local source=rewindsource(sourcesocket("until-closed",self.c))
+ source(status)
+ return self.try(pumpall(source,sink,step))
end
function methods.close(self)
- return self.c:close()
+ return self.c:close()
end
local function adjusturi(request)
- if not request.proxy and not http.PROXY then
- request={
- path=trysocket(request.path,"invalid path 'nil'"),
- params=request.params,
- query=request.query,
- fragment=request.fragment,
- }
- end
- return buildurl(request)
+ if not request.proxy and not http.PROXY then
+ request={
+ path=trysocket(request.path,"invalid path 'nil'"),
+ params=request.params,
+ query=request.query,
+ fragment=request.fragment,
+ }
+ end
+ return buildurl(request)
end
local function adjustheaders(request)
- local headers={
- ["user-agent"]=http.USERAGENT,
- ["host"]=gsub(request.authority,"^.-@",""),
- ["connection"]="close, TE",
- ["te"]="trailers"
- }
- local username=request.user
- local password=request.password
+ local headers={
+ ["user-agent"]=http.USERAGENT,
+ ["host"]=gsub(request.authority,"^.-@",""),
+ ["connection"]="close, TE",
+ ["te"]="trailers"
+ }
+ local username=request.user
+ local password=request.password
+ if username and password then
+ headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password)))
+ end
+ local proxy=request.proxy or http.PROXY
+ if proxy then
+ proxy=parseurl(proxy)
+ local username=proxy.user
+ local password=proxy.password
if username and password then
- headers["authorization"]="Basic "..(mimeb64(username..":"..unescapeurl(password)))
- end
- local proxy=request.proxy or http.PROXY
- if proxy then
- proxy=parseurl(proxy)
- local username=proxy.user
- local password=proxy.password
- if username and password then
- headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password))
- end
- end
- local requestheaders=request.headers
- if requestheaders then
- headers=lowerheaders(headers,requestheaders)
+ headers["proxy-authorization"]="Basic "..(mimeb64(username..":"..password))
end
- return headers
+ end
+ local requestheaders=request.headers
+ if requestheaders then
+ headers=lowerheaders(headers,requestheaders)
+ end
+ return headers
end
local default={
- host="",
- port=PORT,
- path="/",
- scheme="http"
+ host="",
+ port=PORT,
+ path="/",
+ scheme="http"
}
local function adjustrequest(originalrequest)
- local url=originalrequest.url
- local request=url and parseurl(url,default) or {}
- for k,v in next,originalrequest do
- request[k]=v
- end
- local host=request.host
- local port=request.port
- local uri=request.uri
- if not host or host=="" then
- trysocket(nil,"invalid host '"..tostring(host).."'")
- end
- if port=="" then
- request.port=PORT
- end
- if not uri or uri=="" then
- request.uri=adjusturi(request)
- end
- request.headers=adjustheaders(request)
- local proxy=request.proxy or http.PROXY
- if proxy then
- proxy=parseurl(proxy)
- request.host=proxy.host
- request.port=proxy.port or 3128
- end
- return request
+ local url=originalrequest.url
+ local request=url and parseurl(url,default) or {}
+ for k,v in next,originalrequest do
+ request[k]=v
+ end
+ local host=request.host
+ local port=request.port
+ local uri=request.uri
+ if not host or host=="" then
+ trysocket(nil,"invalid host '"..tostring(host).."'")
+ end
+ if port=="" then
+ request.port=PORT
+ end
+ if not uri or uri=="" then
+ request.uri=adjusturi(request)
+ end
+ request.headers=adjustheaders(request)
+ local proxy=request.proxy or http.PROXY
+ if proxy then
+ proxy=parseurl(proxy)
+ request.host=proxy.host
+ request.port=proxy.port or 3128
+ end
+ return request
end
local maxredericts=4
local validredirects={ [301]=true,[302]=true,[303]=true,[307]=true }
local validmethods={ [false]=true,GET=true,HEAD=true }
local function shouldredirect(request,code,headers)
- local location=headers.location
- if not location then
- return false
- end
- location=gsub(location,"%s","")
- if location=="" then
- return false
- end
- local scheme=match(location,"^([%w][%w%+%-%.]*)%:")
- if scheme and not SCHEMES[scheme] then
- return false
- end
- local method=request.method
- local redirect=request.redirect
- local redirects=request.nredirects or 0
- return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts
+ local location=headers.location
+ if not location then
+ return false
+ end
+ location=gsub(location,"%s","")
+ if location=="" then
+ return false
+ end
+ local scheme=match(location,"^([%w][%w%+%-%.]*)%:")
+ if scheme and not SCHEMES[scheme] then
+ return false
+ end
+ local method=request.method
+ local redirect=request.redirect
+ local redirects=request.nredirects or 0
+ return redirect and validredirects[code] and validmethods[method] and redirects<=maxredericts
end
local function shouldreceivebody(request,code)
- if request.method=="HEAD" then
- return nil
- end
- if code==204 or code==304 then
- return nil
- end
- if code>=100 and code<200 then
- return nil
- end
- return 1
+ if request.method=="HEAD" then
+ return nil
+ end
+ if code==204 or code==304 then
+ return nil
+ end
+ if code>=100 and code<200 then
+ return nil
+ end
+ return 1
end
local tredirect,trequest,srequest
tredirect=function(request,location)
- local result,code,headers,status=trequest {
- url=absoluteurl(request.url,location),
- source=request.source,
- sink=request.sink,
- headers=request.headers,
- proxy=request.proxy,
- nredirects=(request.nredirects or 0)+1,
- create=request.create,
- }
- if not headers then
- headers={}
- end
- if not headers.location then
- headers.location=location
- end
- return result,code,headers,status
+ local result,code,headers,status=trequest {
+ url=absoluteurl(request.url,location),
+ source=request.source,
+ sink=request.sink,
+ headers=request.headers,
+ proxy=request.proxy,
+ nredirects=(request.nredirects or 0)+1,
+ create=request.create,
+ }
+ if not headers then
+ headers={}
+ end
+ if not headers.location then
+ headers.location=location
+ end
+ return result,code,headers,status
end
trequest=function(originalrequest)
- local request=adjustrequest(originalrequest)
- local connection=openhttp(request.host,request.port,request.create)
- local headers=request.headers
- connection:sendrequestline(request.method,request.uri)
- connection:sendheaders(headers)
- if request.source then
- connection:sendbody(headers,request.source,request.step)
- end
- local code,status=connection:receivestatusline()
- if not code then
- connection:receive09body(status,request.sink,request.step)
- return 1,200
- end
- while code==100 do
- headers=connection:receiveheaders()
- code,status=connection:receivestatusline()
- end
+ local request=adjustrequest(originalrequest)
+ local connection=openhttp(request.host,request.port,request.create)
+ local headers=request.headers
+ connection:sendrequestline(request.method,request.uri)
+ connection:sendheaders(headers)
+ if request.source then
+ connection:sendbody(headers,request.source,request.step)
+ end
+ local code,status=connection:receivestatusline()
+ if not code then
+ connection:receive09body(status,request.sink,request.step)
+ return 1,200
+ end
+ while code==100 do
headers=connection:receiveheaders()
- if shouldredirect(request,code,headers) and not request.source then
- connection:close()
- return tredirect(originalrequest,headers.location)
- end
- if shouldreceivebody(request,code) then
- connection:receivebody(headers,request.sink,request.step)
- end
+ code,status=connection:receivestatusline()
+ end
+ headers=connection:receiveheaders()
+ if shouldredirect(request,code,headers) and not request.source then
connection:close()
- return 1,code,headers,status
+ return tredirect(originalrequest,headers.location)
+ end
+ if shouldreceivebody(request,code) then
+ connection:receivebody(headers,request.sink,request.step)
+ end
+ connection:close()
+ return 1,code,headers,status
end
local function genericform(url,body)
- local buffer={}
- local request={
- url=url,
- sink=sinktable(buffer),
- target=buffer,
+ local buffer={}
+ local request={
+ url=url,
+ sink=sinktable(buffer),
+ target=buffer,
+ }
+ if body then
+ request.source=stringsource(body)
+ request.method="POST"
+ request.headers={
+ ["content-length"]=#body,
+ ["content-type"]="application/x-www-form-urlencoded"
}
- if body then
- request.source=stringsource(body)
- request.method="POST"
- request.headers={
- ["content-length"]=#body,
- ["content-type"]="application/x-www-form-urlencoded"
- }
- end
- return request
+ end
+ return request
end
http.genericform=genericform
srequest=function(url,body)
- local request=genericform(url,body)
- local _,code,headers,status=trequest(request)
- return concat(request.target),code,headers,status
+ local request=genericform(url,body)
+ local _,code,headers,status=trequest(request)
+ return concat(request.target),code,headers,status
end
http.request=protectsocket(function(request,body)
- if type(request)=="string" then
- return srequest(request,body)
- else
- return trequest(request)
- end
+ if type(request)=="string" then
+ return srequest(request,body)
+ else
+ return trequest(request)
+ end
end)
package.loaded["socket.http"]=http
@@ -11606,16 +11606,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true
--- original size: 10357, stripped down to: 8900
+-- original size: 10357, stripped down to: 8548
local setmetatable,type,next=setmetatable,type,next
local find,format,gsub,match=string.find,string.format,string.gsub,string.match
local concat=table.concat
local mod=math.mod
-local socket=socket or require("socket")
+local socket=socket or require("socket")
local url=socket.url or require("socket.url")
-local tp=socket.tp or require("socket.tp")
+local tp=socket.tp or require("socket.tp")
local ltn12=ltn12 or require("ltn12")
local tcpsocket=socket.tcp
local trysocket=socket.try
@@ -11633,341 +11633,341 @@ local pumpstep=ltn12.pump.step
local sourcestring=ltn12.source.string
local sinktable=ltn12.sink.table
local ftp={
- TIMEOUT=60,
- USER="ftp",
- PASSWORD="anonymous@anonymous.org",
+ TIMEOUT=60,
+ USER="ftp",
+ PASSWORD="anonymous@anonymous.org",
}
socket.ftp=ftp
local PORT=21
local methods={}
local mt={ __index=methods }
function ftp.open(server,port,create)
- local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create))
- local f=setmetatable({ tp=tp },metat)
- f.try=newtrysocket(function() f:close() end)
- return f
+ local tp=trysocket(tp.connect(server,port or PORT,ftp.TIMEOUT,create))
+ local f=setmetatable({ tp=tp },metat)
+ f.try=newtrysocket(function() f:close() end)
+ return f
end
function methods.portconnect(self)
- local try=self.try
- local server=self.server
- try(server:settimeout(ftp.TIMEOUT))
- self.data=try(server:accept())
- try(self.data:settimeout(ftp.TIMEOUT))
+ local try=self.try
+ local server=self.server
+ try(server:settimeout(ftp.TIMEOUT))
+ self.data=try(server:accept())
+ try(self.data:settimeout(ftp.TIMEOUT))
end
function methods.pasvconnect(self)
- local try=self.try
- self.data=try(tcpsocket())
- self(self.data:settimeout(ftp.TIMEOUT))
- self(self.data:connect(self.pasvt.address,self.pasvt.port))
+ local try=self.try
+ self.data=try(tcpsocket())
+ self(self.data:settimeout(ftp.TIMEOUT))
+ self(self.data:connect(self.pasvt.address,self.pasvt.port))
end
function methods.login(self,user,password)
- local try=self.try
- local tp=self.tp
- try(tp:command("user",user or ftp.USER))
- local code,reply=try(tp:check{"2..",331})
- if code==331 then
- try(tp:command("pass",password or ftp.PASSWORD))
- try(tp:check("2.."))
- end
- return 1
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("user",user or ftp.USER))
+ local code,reply=try(tp:check{"2..",331})
+ if code==331 then
+ try(tp:command("pass",password or ftp.PASSWORD))
+ try(tp:check("2.."))
+ end
+ return 1
end
function methods.pasv(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("pasv"))
- local code,reply=try(self.tp:check("2.."))
- local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
- local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern))
- try(a and b and c and d and p1 and p2,reply)
- local address=format("%d.%d.%d.%d",a,b,c,d)
- local port=p1*256+p2
- local server=self.server
- self.pasvt={
- address=address,
- port=port,
- }
- if server then
- server:close()
- self.server=nil
- end
- return address,port
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("pasv"))
+ local code,reply=try(self.tp:check("2.."))
+ local pattern="(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
+ local a,b,c,d,p1,p2=skipsocket(2,find(reply,pattern))
+ try(a and b and c and d and p1 and p2,reply)
+ local address=format("%d.%d.%d.%d",a,b,c,d)
+ local port=p1*256+p2
+ local server=self.server
+ self.pasvt={
+ address=address,
+ port=port,
+ }
+ if server then
+ server:close()
+ self.server=nil
+ end
+ return address,port
end
function methods.epsv(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("epsv"))
- local code,reply=try(tp:check("229"))
- local pattern="%((.)(.-)%1(.-)%1(.-)%1%)"
- local d,prt,address,port=match(reply,pattern)
- try(port,"invalid epsv response")
- local address=tp:getpeername()
- local server=self.server
- self.pasvt={
- address=address,
- port=port,
- }
- if self.server then
- server:close()
- self.server=nil
- end
- return address,port
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("epsv"))
+ local code,reply=try(tp:check("229"))
+ local pattern="%((.)(.-)%1(.-)%1(.-)%1%)"
+ local d,prt,address,port=match(reply,pattern)
+ try(port,"invalid epsv response")
+ local address=tp:getpeername()
+ local server=self.server
+ self.pasvt={
+ address=address,
+ port=port,
+ }
+ if self.server then
+ server:close()
+ self.server=nil
+ end
+ return address,port
end
function methods.port(self,address,port)
- local try=self.try
- local tp=self.tp
- self.pasvt=nil
- if not address then
- address,port=try(tp:getsockname())
- self.server=try(bindsocket(address,0))
- address,port=try(self.server:getsockname())
- try(self.server:settimeout(ftp.TIMEOUT))
- end
- local pl=mod(port,256)
- local ph=(port-pl)/256
- local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",")
- try(tp:command("port",arg))
- try(tp:check("2.."))
- return 1
+ local try=self.try
+ local tp=self.tp
+ self.pasvt=nil
+ if not address then
+ address,port=try(tp:getsockname())
+ self.server=try(bindsocket(address,0))
+ address,port=try(self.server:getsockname())
+ try(self.server:settimeout(ftp.TIMEOUT))
+ end
+ local pl=mod(port,256)
+ local ph=(port-pl)/256
+ local arg=gsub(format("%s,%d,%d",address,ph,pl),"%.",",")
+ try(tp:command("port",arg))
+ try(tp:check("2.."))
+ return 1
end
function methods.eprt(self,family,address,port)
- local try=self.try
- local tp=self.tp
- self.pasvt=nil
- if not address then
- address,port=try(tp:getsockname())
- self.server=try(bindsocket(address,0))
- address,port=try(self.server:getsockname())
- try(self.server:settimeout(ftp.TIMEOUT))
- end
- local arg=format("|%s|%s|%d|",family,address,port)
- try(tp:command("eprt",arg))
- try(tp:check("2.."))
- return 1
+ local try=self.try
+ local tp=self.tp
+ self.pasvt=nil
+ if not address then
+ address,port=try(tp:getsockname())
+ self.server=try(bindsocket(address,0))
+ address,port=try(self.server:getsockname())
+ try(self.server:settimeout(ftp.TIMEOUT))
+ end
+ local arg=format("|%s|%s|%d|",family,address,port)
+ try(tp:command("eprt",arg))
+ try(tp:check("2.."))
+ return 1
end
function methods.send(self,sendt)
- local try=self.try
- local tp=self.tp
- try(self.pasvt or self.server,"need port or pasv first")
- if self.pasvt then
- self:pasvconnect()
- end
- local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]",""))
- if argument=="" then
- argument=nil
- end
- local command=sendt.command or "stor"
- try(tp:command(command,argument))
- local code,reply=try(tp:check{"2..","1.."})
- if not self.pasvt then
- self:portconnect()
- end
- local step=sendt.step or pumpstep
- local readt={ tp }
- local checkstep=function(src,snk)
- local readyt=selectsocket(readt,nil,0)
- if readyt[tp] then
- code=try(tp:check("2.."))
- end
- return step(src,snk)
- end
- local sink=sinksocket("close-when-done",self.data)
- try(pumpall(sendt.source,sink,checkstep))
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- self.data:close()
- local sent=skipsocket(1,self.data:getstats())
- self.data=nil
- return sent
+ local try=self.try
+ local tp=self.tp
+ try(self.pasvt or self.server,"need port or pasv first")
+ if self.pasvt then
+ self:pasvconnect()
+ end
+ local argument=sendt.argument or unescapeurl(gsub(sendt.path or "","^[/\\]",""))
+ if argument=="" then
+ argument=nil
+ end
+ local command=sendt.command or "stor"
+ try(tp:command(command,argument))
+ local code,reply=try(tp:check{"2..","1.."})
+ if not self.pasvt then
+ self:portconnect()
+ end
+ local step=sendt.step or pumpstep
+ local readt={ tp }
+ local checkstep=function(src,snk)
+ local readyt=selectsocket(readt,nil,0)
+ if readyt[tp] then
+ code=try(tp:check("2.."))
+ end
+ return step(src,snk)
+ end
+ local sink=sinksocket("close-when-done",self.data)
+ try(pumpall(sendt.source,sink,checkstep))
+ if find(code,"1..") then
+ try(tp:check("2.."))
+ end
+ self.data:close()
+ local sent=skipsocket(1,self.data:getstats())
+ self.data=nil
+ return sent
end
function methods.receive(self,recvt)
- local try=self.try
- local tp=self.tp
- try(self.pasvt or self.server,"need port or pasv first")
- if self.pasvt then self:pasvconnect() end
- local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]",""))
- if argument=="" then
- argument=nil
- end
- local command=recvt.command or "retr"
- try(tp:command(command,argument))
- local code,reply=try(tp:check{"1..","2.."})
- if code>=200 and code<=299 then
- recvt.sink(reply)
- return 1
- end
- if not self.pasvt then
- self:portconnect()
- end
- local source=sourcesocket("until-closed",self.data)
- local step=recvt.step or pumpstep
- try(pumpall(source,recvt.sink,step))
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- self.data:close()
- self.data=nil
+ local try=self.try
+ local tp=self.tp
+ try(self.pasvt or self.server,"need port or pasv first")
+ if self.pasvt then self:pasvconnect() end
+ local argument=recvt.argument or unescapeurl(gsub(recvt.path or "","^[/\\]",""))
+ if argument=="" then
+ argument=nil
+ end
+ local command=recvt.command or "retr"
+ try(tp:command(command,argument))
+ local code,reply=try(tp:check{"1..","2.."})
+ if code>=200 and code<=299 then
+ recvt.sink(reply)
return 1
+ end
+ if not self.pasvt then
+ self:portconnect()
+ end
+ local source=sourcesocket("until-closed",self.data)
+ local step=recvt.step or pumpstep
+ try(pumpall(source,recvt.sink,step))
+ if find(code,"1..") then
+ try(tp:check("2.."))
+ end
+ self.data:close()
+ self.data=nil
+ return 1
end
function methods.cwd(self,dir)
- local try=self.try
- local tp=self.tp
- try(tp:command("cwd",dir))
- try(tp:check(250))
- return 1
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("cwd",dir))
+ try(tp:check(250))
+ return 1
end
function methods.type(self,typ)
- local try=self.try
- local tp=self.tp
- try(tp:command("type",typ))
- try(tp:check(200))
- return 1
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("type",typ))
+ try(tp:check(200))
+ return 1
end
function methods.greet(self)
- local try=self.try
- local tp=self.tp
- local code=try(tp:check{"1..","2.."})
- if find(code,"1..") then
- try(tp:check("2.."))
- end
- return 1
+ local try=self.try
+ local tp=self.tp
+ local code=try(tp:check{"1..","2.."})
+ if find(code,"1..") then
+ try(tp:check("2.."))
+ end
+ return 1
end
function methods.quit(self)
- local try=self.try
- try(self.tp:command("quit"))
- try(self.tp:check("2.."))
- return 1
+ local try=self.try
+ try(self.tp:command("quit"))
+ try(self.tp:check("2.."))
+ return 1
end
function methods.close(self)
- local data=self.data
- if data then
- data:close()
- end
- local server=self.server
- if server then
- server:close()
- end
- local tp=self.tp
- if tp then
- tp:close()
- end
+ local data=self.data
+ if data then
+ data:close()
+ end
+ local server=self.server
+ if server then
+ server:close()
+ end
+ local tp=self.tp
+ if tp then
+ tp:close()
+ end
end
local function override(t)
- if t.url then
- local u=parseurl(t.url)
- for k,v in next,t do
- u[k]=v
- end
- return u
- else
- return t
+ if t.url then
+ local u=parseurl(t.url)
+ for k,v in next,t do
+ u[k]=v
end
+ return u
+ else
+ return t
+ end
end
local function tput(putt)
- putt=override(putt)
- local host=putt.host
- trysocket(host,"missing hostname")
- local f=ftp.open(host,putt.port,putt.create)
- f:greet()
- f:login(putt.user,putt.password)
- local typ=putt.type
- if typ then
- f:type(typ)
- end
- f:epsv()
- local sent=f:send(putt)
- f:quit()
- f:close()
- return sent
+ putt=override(putt)
+ local host=putt.host
+ trysocket(host,"missing hostname")
+ local f=ftp.open(host,putt.port,putt.create)
+ f:greet()
+ f:login(putt.user,putt.password)
+ local typ=putt.type
+ if typ then
+ f:type(typ)
+ end
+ f:epsv()
+ local sent=f:send(putt)
+ f:quit()
+ f:close()
+ return sent
end
local default={
- path="/",
- scheme="ftp",
+ path="/",
+ scheme="ftp",
}
local function genericform(u)
- local t=trysocket(parseurl(u,default))
- trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'")
- trysocket(t.host,"missing hostname")
- local pat="^type=(.)$"
- if t.params then
- local typ=skipsocket(2,find(t.params,pat))
- t.type=typ
- trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'")
- end
- return t
+ local t=trysocket(parseurl(u,default))
+ trysocket(t.scheme=="ftp","wrong scheme '"..t.scheme.."'")
+ trysocket(t.host,"missing hostname")
+ local pat="^type=(.)$"
+ if t.params then
+ local typ=skipsocket(2,find(t.params,pat))
+ t.type=typ
+ trysocket(typ=="a" or typ=="i","invalid type '"..typ.."'")
+ end
+ return t
end
ftp.genericform=genericform
local function sput(u,body)
- local putt=genericform(u)
- putt.source=sourcestring(body)
- return tput(putt)
+ local putt=genericform(u)
+ putt.source=sourcestring(body)
+ return tput(putt)
end
ftp.put=protectsocket(function(putt,body)
- if type(putt)=="string" then
- return sput(putt,body)
- else
- return tput(putt)
- end
+ if type(putt)=="string" then
+ return sput(putt,body)
+ else
+ return tput(putt)
+ end
end)
local function tget(gett)
- gett=override(gett)
- local host=gett.host
- trysocket(host,"missing hostname")
- local f=ftp.open(host,gett.port,gett.create)
- f:greet()
- f:login(gett.user,gett.password)
- if gett.type then
- f:type(gett.type)
- end
- f:epsv()
- f:receive(gett)
- f:quit()
- return f:close()
+ gett=override(gett)
+ local host=gett.host
+ trysocket(host,"missing hostname")
+ local f=ftp.open(host,gett.port,gett.create)
+ f:greet()
+ f:login(gett.user,gett.password)
+ if gett.type then
+ f:type(gett.type)
+ end
+ f:epsv()
+ f:receive(gett)
+ f:quit()
+ return f:close()
end
local function sget(u)
- local gett=genericform(u)
- local t={}
- gett.sink=sinktable(t)
- tget(gett)
- return concat(t)
+ local gett=genericform(u)
+ local t={}
+ gett.sink=sinktable(t)
+ tget(gett)
+ return concat(t)
end
ftp.command=protectsocket(function(cmdt)
- cmdt=override(cmdt)
- local command=cmdt.command
- local argument=cmdt.argument
- local check=cmdt.check
- local host=cmdt.host
- trysocket(host,"missing hostname")
- trysocket(command,"missing command")
- local f=ftp.open(host,cmdt.port,cmdt.create)
- local try=f.try
- local tp=f.tp
- f:greet()
- f:login(cmdt.user,cmdt.password)
- if type(command)=="table" then
- local argument=argument or {}
- for i=1,#command do
- local cmd=command[i]
- try(tp:command(cmd,argument[i]))
- if check and check[i] then
- try(tp:check(check[i]))
- end
- end
- else
- try(tp:command(command,argument))
- if check then
- try(tp:check(check))
- end
+ cmdt=override(cmdt)
+ local command=cmdt.command
+ local argument=cmdt.argument
+ local check=cmdt.check
+ local host=cmdt.host
+ trysocket(host,"missing hostname")
+ trysocket(command,"missing command")
+ local f=ftp.open(host,cmdt.port,cmdt.create)
+ local try=f.try
+ local tp=f.tp
+ f:greet()
+ f:login(cmdt.user,cmdt.password)
+ if type(command)=="table" then
+ local argument=argument or {}
+ for i=1,#command do
+ local cmd=command[i]
+ try(tp:command(cmd,argument[i]))
+ if check and check[i] then
+ try(tp:check(check[i]))
+ end
end
- f:quit()
- return f:close()
+ else
+ try(tp:command(command,argument))
+ if check then
+ try(tp:check(check))
+ end
+ end
+ f:quit()
+ return f:close()
end)
ftp.get=protectsocket(function(gett)
- if type(gett)=="string" then
- return sget(gett)
- else
- return tget(gett)
- end
+ if type(gett)=="string" then
+ return sget(gett)
+ else
+ return tget(gett)
+ end
end)
package.loaded["socket.ftp"]=ftp
@@ -11978,18 +11978,18 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true
--- original size: 7018, stripped down to: 6095
+-- original size: 7018, stripped down to: 5883
local type,setmetatable,next=type,setmetatable,next
local find,lower,format=string.find,string.lower,string.format
local osdate,osgetenv=os.date,os.getenv
local random=math.random
-local socket=socket or require("socket")
+local socket=socket or require("socket")
local headers=socket.headers or require("socket.headers")
-local ltn12=ltn12 or require("ltn12")
+local ltn12=ltn12 or require("ltn12")
local tp=socket.tp or require("socket.tp")
-local mime=mime or require("mime")
+local mime=mime or require("mime")
local mimeb64=mime.b64
local mimestuff=mime.stuff
local skipsocket=socket.skip
@@ -12002,212 +12002,212 @@ local createcoroutine=coroutine.create
local resumecoroutine=coroutine.resume
local yieldcoroutine=coroutine.resume
local smtp={
- TIMEOUT=60,
- SERVER="localhost",
- PORT=25,
- DOMAIN=osgetenv("SERVER_NAME") or "localhost",
- ZONE="-0000",
+ TIMEOUT=60,
+ SERVER="localhost",
+ PORT=25,
+ DOMAIN=osgetenv("SERVER_NAME") or "localhost",
+ ZONE="-0000",
}
socket.smtp=smtp
local methods={}
local mt={ __index=methods }
function methods.greet(self,domain)
- local try=self.try
- local tp=self.tp
- try(tp:check("2.."))
- try(tp:command("EHLO",domain or _M.DOMAIN))
- return skipsocket(1,try(tp:check("2..")))
+ local try=self.try
+ local tp=self.tp
+ try(tp:check("2.."))
+ try(tp:command("EHLO",domain or _M.DOMAIN))
+ return skipsocket(1,try(tp:check("2..")))
end
function methods.mail(self,from)
- local try=self.try
- local tp=self.tp
- try(tp:command("MAIL","FROM:"..from))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("MAIL","FROM:"..from))
+ return try(tp:check("2.."))
end
function methods.rcpt(self,to)
- local try=self.try
- local tp=self.tp
- try(tp:command("RCPT","TO:"..to))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("RCPT","TO:"..to))
+ return try(tp:check("2.."))
end
function methods.data(self,src,step)
- local try=self.try
- local tp=self.tp
- try(tp:command("DATA"))
- try(tp:check("3.."))
- try(tp:source(src,step))
- try(tp:send("\r\n.\r\n"))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("DATA"))
+ try(tp:check("3.."))
+ try(tp:source(src,step))
+ try(tp:send("\r\n.\r\n"))
+ return try(tp:check("2.."))
end
function methods.quit(self)
- local try=self.try
- local tp=self.tp
- try(tp:command("QUIT"))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("QUIT"))
+ return try(tp:check("2.."))
end
function methods.close(self)
- return self.tp:close()
+ return self.tp:close()
end
function methods.login(self,user,password)
- local try=self.try
- local tp=self.tp
- try(tp:command("AUTH","LOGIN"))
- try(tp:check("3.."))
- try(tp:send(mimeb64(user).."\r\n"))
- try(tp:check("3.."))
- try(tp:send(mimeb64(password).."\r\n"))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ try(tp:command("AUTH","LOGIN"))
+ try(tp:check("3.."))
+ try(tp:send(mimeb64(user).."\r\n"))
+ try(tp:check("3.."))
+ try(tp:send(mimeb64(password).."\r\n"))
+ return try(tp:check("2.."))
end
function methods.plain(self,user,password)
- local try=self.try
- local tp=self.tp
- local auth="PLAIN "..mimeb64("\0"..user.."\0"..password)
- try(tp:command("AUTH",auth))
- return try(tp:check("2.."))
+ local try=self.try
+ local tp=self.tp
+ local auth="PLAIN "..mimeb64("\0"..user.."\0"..password)
+ try(tp:command("AUTH",auth))
+ return try(tp:check("2.."))
end
function methods.auth(self,user,password,ext)
- if not user or not password then
- return 1
- end
- local try=self.try
- if find(ext,"AUTH[^\n]+LOGIN") then
- return self:login(user,password)
- elseif find(ext,"AUTH[^\n]+PLAIN") then
- return self:plain(user,password)
- else
- try(nil,"authentication not supported")
- end
+ if not user or not password then
+ return 1
+ end
+ local try=self.try
+ if find(ext,"AUTH[^\n]+LOGIN") then
+ return self:login(user,password)
+ elseif find(ext,"AUTH[^\n]+PLAIN") then
+ return self:plain(user,password)
+ else
+ try(nil,"authentication not supported")
+ end
end
function methods.send(self,mail)
- self:mail(mail.from)
- local receipt=mail.rcpt
- if type(receipt)=="table" then
- for i=1,#receipt do
- self:rcpt(receipt[i])
- end
- elseif receipt then
- self:rcpt(receipt)
+ self:mail(mail.from)
+ local receipt=mail.rcpt
+ if type(receipt)=="table" then
+ for i=1,#receipt do
+ self:rcpt(receipt[i])
end
- self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step)
+ elseif receipt then
+ self:rcpt(receipt)
+ end
+ self:data(ltn12.source.chain(mail.source,mimestuff()),mail.step)
end
local function opensmtp(self,server,port,create)
- if not server or server=="" then
- server=smtp.SERVER
- end
- if not port or port=="" then
- port=smtp.PORT
- end
- local s={
- tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)),
- try=newtrysocket(function()
- s:close()
- end),
- }
- setmetatable(s,mt)
- return s
+ if not server or server=="" then
+ server=smtp.SERVER
+ end
+ if not port or port=="" then
+ port=smtp.PORT
+ end
+ local s={
+ tp=trysocket(tp.connect(server,port,smtp.TIMEOUT,create)),
+ try=newtrysocket(function()
+ s:close()
+ end),
+ }
+ setmetatable(s,mt)
+ return s
end
smtp.open=opensmtp
local nofboundaries=0
local function newboundary()
- nofboundaries=nofboundaries+1
- return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries)
+ nofboundaries=nofboundaries+1
+ return format('%s%05d==%05u',osdate('%d%m%Y%H%M%S'),random(0,99999),nofboundaries)
end
local send_message
local function send_headers(headers)
- yieldcoroutine(normalizeheaders(headers))
+ yieldcoroutine(normalizeheaders(headers))
end
local function send_multipart(message)
- local boundary=newboundary()
- local headers=lowerheaders(message.headers)
- local body=message.body
- local preamble=body.preamble
- local epilogue=body.epilogue
- local content=headers['content-type'] or 'multipart/mixed'
- headers['content-type']=content..'; boundary="'..boundary..'"'
- send_headers(headers)
- if preamble then
- yieldcoroutine(preamble)
- yieldcoroutine("\r\n")
- end
- for i=1,#body do
- yieldcoroutine("\r\n--"..boundary.."\r\n")
- send_message(body[i])
- end
- yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n")
- if epilogue then
- yieldcoroutine(epilogue)
- yieldcoroutine("\r\n")
- end
+ local boundary=newboundary()
+ local headers=lowerheaders(message.headers)
+ local body=message.body
+ local preamble=body.preamble
+ local epilogue=body.epilogue
+ local content=headers['content-type'] or 'multipart/mixed'
+ headers['content-type']=content..'; boundary="'..boundary..'"'
+ send_headers(headers)
+ if preamble then
+ yieldcoroutine(preamble)
+ yieldcoroutine("\r\n")
+ end
+ for i=1,#body do
+ yieldcoroutine("\r\n--"..boundary.."\r\n")
+ send_message(body[i])
+ end
+ yieldcoroutine("\r\n--"..boundary.."--\r\n\r\n")
+ if epilogue then
+ yieldcoroutine(epilogue)
+ yieldcoroutine("\r\n")
+ end
end
local default_content_type='text/plain; charset="UTF-8"'
local function send_source(message)
- local headers=lowerheaders(message.headers)
- if not headers['content-type'] then
- headers['content-type']=default_content_type
- end
- send_headers(headers)
- local getchunk=message.body
- while true do
- local chunk,err=getchunk()
- if err then
- yieldcoroutine(nil,err)
- elseif chunk then
- yieldcoroutine(chunk)
- else
- break
- end
+ local headers=lowerheaders(message.headers)
+ if not headers['content-type'] then
+ headers['content-type']=default_content_type
+ end
+ send_headers(headers)
+ local getchunk=message.body
+ while true do
+ local chunk,err=getchunk()
+ if err then
+ yieldcoroutine(nil,err)
+ elseif chunk then
+ yieldcoroutine(chunk)
+ else
+ break
end
+ end
end
local function send_string(message)
- local headers=lowerheaders(message.headers)
- if not headers['content-type'] then
- headers['content-type']=default_content_type
- end
- send_headers(headers)
- yieldcoroutine(message.body)
+ local headers=lowerheaders(message.headers)
+ if not headers['content-type'] then
+ headers['content-type']=default_content_type
+ end
+ send_headers(headers)
+ yieldcoroutine(message.body)
end
function send_message(message)
- local body=message.body
- if type(body)=="table" then
- send_multipart(message)
- elseif type(body)=="function" then
- send_source(message)
- else
- send_string(message)
- end
+ local body=message.body
+ if type(body)=="table" then
+ send_multipart(message)
+ elseif type(body)=="function" then
+ send_source(message)
+ else
+ send_string(message)
+ end
end
local function adjust_headers(message)
- local headers=lowerheaders(message.headers)
- if not headers["date"] then
- headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE)
- end
- if not headers["x-mailer"] then
- headers["x-mailer"]=socket._VERSION
- end
- headers["mime-version"]="1.0"
- return headers
+ local headers=lowerheaders(message.headers)
+ if not headers["date"] then
+ headers["date"]=osdate("!%a, %d %b %Y %H:%M:%S ")..(message.zone or smtp.ZONE)
+ end
+ if not headers["x-mailer"] then
+ headers["x-mailer"]=socket._VERSION
+ end
+ headers["mime-version"]="1.0"
+ return headers
end
function smtp.message(message)
- message.headers=adjust_headers(message)
- local action=createcoroutine(function()
- send_message(message)
- end)
- return function()
- local ret,a,b=resumecoroutine(action)
- if ret then
- return a,b
- else
- return nil,a
- end
+ message.headers=adjust_headers(message)
+ local action=createcoroutine(function()
+ send_message(message)
+ end)
+ return function()
+ local ret,a,b=resumecoroutine(action)
+ if ret then
+ return a,b
+ else
+ return nil,a
end
+ end
end
smtp.send=protectsocket(function(mail)
- local snd=opensmtp(smtp,mail.server,mail.port,mail.create)
- local ext=snd:greet(mail.domain)
- snd:auth(mail.user,mail.password,ext)
- snd:send(mail)
- snd:quit()
- return snd:close()
+ local snd=opensmtp(smtp,mail.server,mail.port,mail.create)
+ local ext=snd:greet(mail.domain)
+ snd:auth(mail.user,mail.password,ext)
+ snd:send(mail)
+ snd:quit()
+ return snd:close()
end)
package.loaded["socket.smtp"]=smtp
@@ -12218,14 +12218,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-set"] = package.loaded["trac-set"] or true
--- original size: 13340, stripped down to: 9459
+-- original size: 13340, stripped down to: 8826
if not modules then modules={} end modules ['trac-set']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber=type,next,tostring,tonumber
local concat,sortedhash=table.concat,table.sortedhash
@@ -12240,317 +12240,317 @@ utilities.setters=setters
local data={}
local trace_initialize=false
function setters.initialize(filename,name,values)
- local setter=data[name]
- if setter then
- frozen=true
- local data=setter.data
- if data then
- for key,newvalue in sortedhash(values) do
- local newvalue=is_boolean(newvalue,newvalue,true)
- local functions=data[key]
- if functions then
- local oldvalue=functions.value
- if functions.frozen then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
- end
- elseif #functions>0 and not oldvalue then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
- end
- for i=1,#functions do
- functions[i](newvalue)
- end
- functions.value=newvalue
- functions.frozen=functions.frozen or frozen
- else
- if trace_initialize then
- setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
- end
- end
- else
- functions={ default=newvalue,frozen=frozen }
- data[key]=functions
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
- end
- end
+ local setter=data[name]
+ if setter then
+ frozen=true
+ local data=setter.data
+ if data then
+ for key,newvalue in sortedhash(values) do
+ local newvalue=is_boolean(newvalue,newvalue,true)
+ local functions=data[key]
+ if functions then
+ local oldvalue=functions.value
+ if functions.frozen then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
+ end
+ elseif #functions>0 and not oldvalue then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
+ end
+ for i=1,#functions do
+ functions[i](newvalue)
+ end
+ functions.value=newvalue
+ functions.frozen=functions.frozen or frozen
+ else
+ if trace_initialize then
+ setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
end
- return true
+ end
+ else
+ functions={ default=newvalue,frozen=frozen }
+ data[key]=functions
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
+ end
end
+ end
+ return true
end
+ end
end
local function set(t,what,newvalue)
- local data=t.data
- if not data.frozen then
- local done=t.done
- if type(what)=="string" then
- what=settings_to_hash(what)
- end
- if type(what)~="table" then
- return
- end
- if not done then
- done={}
- t.done=done
- end
- for w,value in sortedhash(what) do
- if value=="" then
- value=newvalue
- elseif not value then
- value=false
- else
- value=is_boolean(value,value,true)
- end
- w=topattern(w,true,true)
- for name,functions in sortedhash(data) do
- if done[name] then
- elseif find(name,w) then
- done[name]=true
- for i=1,#functions do
- functions[i](value)
- end
- functions.value=value
- end
- end
+ local data=t.data
+ if not data.frozen then
+ local done=t.done
+ if type(what)=="string" then
+ what=settings_to_hash(what)
+ end
+ if type(what)~="table" then
+ return
+ end
+ if not done then
+ done={}
+ t.done=done
+ end
+ for w,value in sortedhash(what) do
+ if value=="" then
+ value=newvalue
+ elseif not value then
+ value=false
+ else
+ value=is_boolean(value,value,true)
+ end
+ w=topattern(w,true,true)
+ for name,functions in sortedhash(data) do
+ if done[name] then
+ elseif find(name,w) then
+ done[name]=true
+ for i=1,#functions do
+ functions[i](value)
+ end
+ functions.value=value
end
+ end
end
+ end
end
local function reset(t)
- local data=t.data
- if not data.frozen then
- for name,functions in sortedthash(data) do
- for i=1,#functions do
- functions[i](false)
- end
- functions.value=false
- end
+ local data=t.data
+ if not data.frozen then
+ for name,functions in sortedthash(data) do
+ for i=1,#functions do
+ functions[i](false)
+ end
+ functions.value=false
end
+ end
end
local function enable(t,what)
- set(t,what,true)
+ set(t,what,true)
end
local function disable(t,what)
- local data=t.data
- if not what or what=="" then
- t.done={}
- reset(t)
- else
- set(t,what,false)
- end
+ local data=t.data
+ if not what or what=="" then
+ t.done={}
+ reset(t)
+ else
+ set(t,what,false)
+ end
end
function setters.register(t,what,...)
- local data=t.data
- what=lower(what)
- local functions=data[what]
- if not functions then
- functions={}
- data[what]=functions
- if trace_initialize then
- t.report("defining %a",what)
- end
- end
- local default=functions.default
- for i=1,select("#",...) do
- local fnc=select(i,...)
- local typ=type(fnc)
- if typ=="string" then
- if trace_initialize then
- t.report("coupling %a to %a",what,fnc)
- end
- local s=fnc
- fnc=function(value) set(t,s,value) end
- elseif typ~="function" then
- fnc=nil
- end
- if fnc then
- functions[#functions+1]=fnc
- local value=functions.value or default
- if value~=nil then
- fnc(value)
- functions.value=value
- end
- end
+ local data=t.data
+ what=lower(what)
+ local functions=data[what]
+ if not functions then
+ functions={}
+ data[what]=functions
+ if trace_initialize then
+ t.report("defining %a",what)
+ end
+ end
+ local default=functions.default
+ for i=1,select("#",...) do
+ local fnc=select(i,...)
+ local typ=type(fnc)
+ if typ=="string" then
+ if trace_initialize then
+ t.report("coupling %a to %a",what,fnc)
+ end
+ local s=fnc
+ fnc=function(value) set(t,s,value) end
+ elseif typ~="function" then
+ fnc=nil
+ end
+ if fnc then
+ functions[#functions+1]=fnc
+ local value=functions.value or default
+ if value~=nil then
+ fnc(value)
+ functions.value=value
+ end
end
- return false
+ end
+ return false
end
function setters.enable(t,what)
- local e=t.enable
- t.enable,t.done=enable,{}
- enable(t,what)
- t.enable,t.done=e,{}
+ local e=t.enable
+ t.enable,t.done=enable,{}
+ enable(t,what)
+ t.enable,t.done=e,{}
end
function setters.disable(t,what)
- local e=t.disable
- t.disable,t.done=disable,{}
- disable(t,what)
- t.disable,t.done=e,{}
+ local e=t.disable
+ t.disable,t.done=disable,{}
+ disable(t,what)
+ t.disable,t.done=e,{}
end
function setters.reset(t)
- t.done={}
- reset(t)
+ t.done={}
+ reset(t)
end
function setters.list(t)
- local list=table.sortedkeys(t.data)
- local user,system={},{}
- for l=1,#list do
- local what=list[l]
- if find(what,"^%*") then
- system[#system+1]=what
- else
- user[#user+1]=what
- end
+ local list=table.sortedkeys(t.data)
+ local user,system={},{}
+ for l=1,#list do
+ local what=list[l]
+ if find(what,"^%*") then
+ system[#system+1]=what
+ else
+ user[#user+1]=what
end
- return user,system
+ end
+ return user,system
end
function setters.show(t)
- local list=setters.list(t)
- t.report()
- for k=1,#list do
- local name=list[k]
- local functions=t.data[name]
- if functions then
- local value=functions.value
- local default=functions.default
- local modules=#functions
- if default==nil then
- default="unset"
- elseif type(default)=="table" then
- default=concat(default,"|")
- else
- default=tostring(default)
- end
- if value==nil then
- value="unset"
- elseif type(value)=="table" then
- value=concat(value,"|")
- else
- value=tostring(value)
- end
- t.report(name)
- t.report(" modules : %i",modules)
- t.report(" default : %s",default)
- t.report(" value : %s",value)
- t.report()
- end
+ local list=setters.list(t)
+ t.report()
+ for k=1,#list do
+ local name=list[k]
+ local functions=t.data[name]
+ if functions then
+ local value=functions.value
+ local default=functions.default
+ local modules=#functions
+ if default==nil then
+ default="unset"
+ elseif type(default)=="table" then
+ default=concat(default,"|")
+ else
+ default=tostring(default)
+ end
+ if value==nil then
+ value="unset"
+ elseif type(value)=="table" then
+ value=concat(value,"|")
+ else
+ value=tostring(value)
+ end
+ t.report(name)
+ t.report(" modules : %i",modules)
+ t.report(" default : %s",default)
+ t.report(" value : %s",value)
+ t.report()
end
+ end
end
local enable,disable,register,list,show=setters.enable,setters.disable,setters.register,setters.list,setters.show
function setters.report(setter,...)
- print(format("%-15s : %s\n",setter.name,format(...)))
+ print(format("%-15s : %s\n",setter.name,format(...)))
end
local function default(setter,name)
- local d=setter.data[name]
- return d and d.default
+ local d=setter.data[name]
+ return d and d.default
end
local function value(setter,name)
- local d=setter.data[name]
- return d and (d.value or d.default)
+ local d=setter.data[name]
+ return d and (d.value or d.default)
end
function setters.new(name)
- local setter
- setter={
- data=allocate(),
- name=name,
- report=function(...) setters.report (setter,...) end,
- enable=function(...) enable (setter,...) end,
- disable=function(...) disable (setter,...) end,
- reset=function(...) reset (setter,...) end,
- register=function(...) register(setter,...) end,
- list=function(...) list (setter,...) end,
- show=function(...) show (setter,...) end,
- default=function(...) return default (setter,...) end,
- value=function(...) return value (setter,...) end,
- }
- data[name]=setter
- return setter
+ local setter
+ setter={
+ data=allocate(),
+ name=name,
+ report=function(...) setters.report (setter,...) end,
+ enable=function(...) enable (setter,...) end,
+ disable=function(...) disable (setter,...) end,
+ reset=function(...) reset (setter,...) end,
+ register=function(...) register(setter,...) end,
+ list=function(...) list (setter,...) end,
+ show=function(...) show (setter,...) end,
+ default=function(...) return default (setter,...) end,
+ value=function(...) return value (setter,...) end,
+ }
+ data[name]=setter
+ return setter
end
trackers=setters.new("trackers")
directives=setters.new("directives")
experiments=setters.new("experiments")
-local t_enable,t_disable=trackers .enable,trackers .disable
+local t_enable,t_disable=trackers .enable,trackers .disable
local d_enable,d_disable=directives .enable,directives .disable
local e_enable,e_disable=experiments.enable,experiments.disable
-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 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)
function directives.enable(...)
- if trace_directives then
- directives.report("enabling: % t",{...})
- end
- d_enable(...)
+ if trace_directives then
+ directives.report("enabling: % t",{...})
+ end
+ d_enable(...)
end
function directives.disable(...)
- if trace_directives then
- directives.report("disabling: % t",{...})
- end
- d_disable(...)
+ if trace_directives then
+ directives.report("disabling: % t",{...})
+ end
+ d_disable(...)
end
function experiments.enable(...)
- if trace_experiments then
- experiments.report("enabling: % t",{...})
- end
- e_enable(...)
+ if trace_experiments then
+ experiments.report("enabling: % t",{...})
+ end
+ e_enable(...)
end
function experiments.disable(...)
- if trace_experiments then
- experiments.report("disabling: % t",{...})
- end
- e_disable(...)
+ if trace_experiments then
+ experiments.report("disabling: % t",{...})
+ end
+ e_disable(...)
end
directives.register("system.nostatistics",function(v)
- if statistics then
- statistics.enable=not v
- else
- end
+ if statistics then
+ statistics.enable=not v
+ else
+ end
end)
directives.register("system.nolibraries",function(v)
- if libraries then
- libraries=nil
- else
- end
+ if libraries then
+ libraries=nil
+ else
+ end
end)
if environment then
- local engineflags=environment.engineflags
- if engineflags then
- local list=engineflags["c:trackers"] or engineflags["trackers"]
- if type(list)=="string" then
- setters.initialize("commandline flags","trackers",settings_to_hash(list))
- end
- local list=engineflags["c:directives"] or engineflags["directives"]
- if type(list)=="string" then
- setters.initialize("commandline flags","directives",settings_to_hash(list))
- end
+ local engineflags=environment.engineflags
+ if engineflags then
+ local list=engineflags["c:trackers"] or engineflags["trackers"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","trackers",settings_to_hash(list))
end
+ local list=engineflags["c:directives"] or engineflags["directives"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","directives",settings_to_hash(list))
+ end
+ end
end
if texconfig then
- local function set(k,v)
- v=tonumber(v)
- if v then
- texconfig[k]=v
- end
- end
- directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
- directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
- directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
- directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
- directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
- directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
- directives.register("luatex.paramsize",function(v) set("param_size",v) end)
- directives.register("luatex.savesize",function(v) set("save_size",v) end)
- directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
+ local function set(k,v)
+ v=tonumber(v)
+ if v then
+ texconfig[k]=v
+ end
+ end
+ directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
+ directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
+ directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
+ directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
+ directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
+ directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
+ directives.register("luatex.paramsize",function(v) set("param_size",v) end)
+ directives.register("luatex.savesize",function(v) set("save_size",v) end)
+ directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
end
local data=table.setmetatableindex("table")
updaters={
- register=function(what,f)
- local d=data[what]
- d[#d+1]=f
- end,
- apply=function(what,...)
- local d=data[what]
- for i=1,#d do
- d[i](...)
- end
- end,
+ register=function(what,f)
+ local d=data[what]
+ d[#d+1]=f
+ end,
+ apply=function(what,...)
+ local d=data[what]
+ for i=1,#d do
+ d[i](...)
+ end
+ end,
}
@@ -12560,14 +12560,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-log"] = package.loaded["trac-log"] or true
--- original size: 32608, stripped down to: 22574
+-- original size: 32608, stripped down to: 20925
if not modules then modules={} end modules ['trac-log']={
- version=1.001,
- comment="companion to trac-log.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,select,print=next,type,select,print
local format,gmatch,find=string.format,string.gmatch,string.find
@@ -12578,7 +12578,7 @@ local datetime=os.date
local openfile=io.open
local runningtex=tex and (tex.jobname or tex.formatname)
local write_nl=runningtex and texio and texio.write_nl or print
-local write=runningtex and texio and texio.write or io.write
+local write=runningtex and texio and texio.write or io.write
local setmetatableindex=table.setmetatableindex
local formatters=string.formatters
local settings_to_hash=utilities.parsers.settings_to_hash
@@ -12594,404 +12594,404 @@ webpage : http://www.pragma-ade.nl / http://tex.aanhet.net
wiki : http://contextgarden.net
]]
formatters.add (
- formatters,"unichr",
- [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
+ formatters,"unichr",
+ [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
)
formatters.add (
- formatters,"chruni",
- [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
+ formatters,"chruni",
+ [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
)
local function ignore() end
setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end)
local report,subreport,status,settarget,setformats,settranslations
local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters,newline
if runningtex then
- if texio.setescape then
- texio.setescape(0)
- end
- if arg then
- for k,v in next,arg do
- if v=="--ansi" or v=="--c:ansi" then
- variant="ansi"
- break
- end
- end
- end
- local function useluawrites()
- local texio_write_nl=texio.write_nl
- local texio_write=texio.write
- local io_write=io.write
- write_nl=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write_nl("log",...)
- texio_write_nl("term","")
- io_write(...)
- elseif target=="log" then
- texio_write_nl("log",...)
- elseif target=="term" then
- texio_write_nl("term","")
- io_write(...)
- elseif type(target)=="number" then
- texio_write_nl(target,...)
- elseif target~="none" then
- texio_write_nl("log",target,...)
- texio_write_nl("term","")
- io_write(target,...)
- end
- end
- write=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write("log",...)
- io_write(...)
- elseif target=="log" then
- texio_write("log",...)
- elseif target=="term" then
- io_write(...)
- elseif type(target)=="number" then
- texio_write(target,...)
- elseif target~="none" then
- texio_write("log",target,...)
- io_write(target,...)
- end
- end
- texio.write=write
- texio.write_nl=write_nl
- useluawrites=ignore
- end
- local whereto="both"
- local target=nil
- local targets=nil
- local formats=table.setmetatableindex("self")
- local translations=table.setmetatableindex("self")
- local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
- local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="log",
- log="log",
- file="log",
- console="term",
- terminal="term",
- both="term and log",
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="none",
- log="none",
- file="none",
- console="term",
- terminal="term",
- both="term",
- },
- }
- }
- logs.flush=io.flush
- writer=function(...)
- write_nl(target,...)
- end
- newline=function()
- write_nl(target,"\n")
- end
- report=function(a,b,c,...)
- if c~=nil then
- write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,report_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,report_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
- end
- direct=function(a,b,c,...)
- if c~=nil then
- return direct_yes(translations[a],formatters[formats[b]](c,...))
- elseif b then
- return direct_yes(translations[a],formats[b])
- elseif a then
- return direct_nop(translations[a])
- else
- return ""
- end
- end
- subreport=function(a,s,b,c,...)
- if c~=nil then
- write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
- elseif a then
- write_nl(target,subreport_nop(translations[a],translations[s]))
- else
- write_nl(target,"\n")
- end
- end
- subdirect=function(a,s,b,c,...)
- if c~=nil then
- return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
- elseif b then
- return subdirect_yes(translations[a],translations[s],formats[b])
- elseif a then
- return subdirect_nop(translations[a],translations[s])
- else
- return ""
- end
+ if texio.setescape then
+ texio.setescape(0)
+ end
+ if arg then
+ for k,v in next,arg do
+ if v=="--ansi" or v=="--c:ansi" then
+ variant="ansi"
+ break
+ end
end
- status=function(a,b,c,...)
- if c~=nil then
- write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,status_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,status_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
+ end
+ local function useluawrites()
+ local texio_write_nl=texio.write_nl
+ local texio_write=texio.write
+ local io_write=io.write
+ write_nl=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write_nl("log",...)
+ texio_write_nl("term","")
+ io_write(...)
+ elseif target=="log" then
+ texio_write_nl("log",...)
+ elseif target=="term" then
+ texio_write_nl("term","")
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write_nl(target,...)
+ elseif target~="none" then
+ texio_write_nl("log",target,...)
+ texio_write_nl("term","")
+ io_write(target,...)
+ end
end
- settarget=function(askedwhereto)
- whereto=askedwhereto or whereto or "both"
- target=targets[whereto]
- if not target then
- whereto="both"
- target=targets[whereto]
- end
- if target=="term" or target=="term and log" then
- logs.flush=io.flush
- else
- logs.flush=ignore
- end
+ write=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write("log",...)
+ io_write(...)
+ elseif target=="log" then
+ texio_write("log",...)
+ elseif target=="term" then
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write(target,...)
+ elseif target~="none" then
+ texio_write("log",target,...)
+ io_write(target,...)
+ end
end
- local stack={}
- pushtarget=function(newtarget)
- insert(stack,target)
- settarget(newtarget)
+ texio.write=write
+ texio.write_nl=write_nl
+ useluawrites=ignore
+ end
+ local whereto="both"
+ local target=nil
+ local targets=nil
+ local formats=table.setmetatableindex("self")
+ local translations=table.setmetatableindex("self")
+ local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
+ local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="log",
+ log="log",
+ file="log",
+ console="term",
+ terminal="term",
+ both="term and log",
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="none",
+ log="none",
+ file="none",
+ console="term",
+ terminal="term",
+ both="term",
+ },
+ }
+ }
+ logs.flush=io.flush
+ writer=function(...)
+ write_nl(target,...)
+ end
+ newline=function()
+ write_nl(target,"\n")
+ end
+ report=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,report_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,report_nop(translations[a]))
+ else
+ write_nl(target,"\n")
end
- poptarget=function()
- if #stack>0 then
- settarget(remove(stack))
- end
+ end
+ direct=function(a,b,c,...)
+ if c~=nil then
+ return direct_yes(translations[a],formatters[formats[b]](c,...))
+ elseif b then
+ return direct_yes(translations[a],formats[b])
+ elseif a then
+ return direct_nop(translations[a])
+ else
+ return ""
end
- setformats=function(f)
- formats=f
+ end
+ subreport=function(a,s,b,c,...)
+ if c~=nil then
+ write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
+ elseif a then
+ write_nl(target,subreport_nop(translations[a],translations[s]))
+ else
+ write_nl(target,"\n")
end
- settranslations=function(t)
- translations=t
+ end
+ subdirect=function(a,s,b,c,...)
+ if c~=nil then
+ return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
+ elseif b then
+ return subdirect_yes(translations[a],translations[s],formats[b])
+ elseif a then
+ return subdirect_nop(translations[a],translations[s])
+ else
+ return ""
end
- setprocessor=function(f)
- local writeline=write_nl
- write_nl=function(target,...)
- writeline(target,f(...))
- end
+ end
+ status=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,status_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,status_nop(translations[a]))
+ else
+ write_nl(target,"\n")
+ end
+ end
+ settarget=function(askedwhereto)
+ whereto=askedwhereto or whereto or "both"
+ target=targets[whereto]
+ if not target then
+ whereto="both"
+ target=targets[whereto]
+ end
+ if target=="term" or target=="term and log" then
+ logs.flush=io.flush
+ else
+ logs.flush=ignore
+ end
+ end
+ local stack={}
+ pushtarget=function(newtarget)
+ insert(stack,target)
+ settarget(newtarget)
+ end
+ poptarget=function()
+ if #stack>0 then
+ settarget(remove(stack))
+ end
+ end
+ setformats=function(f)
+ formats=f
+ end
+ settranslations=function(t)
+ translations=t
+ end
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(target,...)
+ writeline(target,f(...))
+ end
+ end
+ setformatters=function(specification)
+ local t=nil
+ local f=nil
+ local d=variants.default
+ if not specification then
+ elseif type(specification)=="table" then
+ t=specification.targets
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ t=v.targets
+ f=v.formats
+ variant=specification
+ end
end
- setformatters=function(specification)
- local t=nil
- local f=nil
- local d=variants.default
- if not specification then
- elseif type(specification)=="table" then
- t=specification.targets
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- t=v.targets
- f=v.formats
- variant=specification
- end
- end
- targets=t or d.targets
- target=targets[whereto] or target
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- direct_yes=f.direct_yes
- direct_nop=f.direct_nop
- subdirect_yes=f.subdirect_yes
- subdirect_nop=f.subdirect_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- if variant=="ansi" then
- useluawrites()
- end
- settarget(whereto)
- end
- setformatters(variant)
- setlogfile=ignore
- settimedlog=ignore
+ targets=t or d.targets
+ target=targets[whereto] or target
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ direct_yes=f.direct_yes
+ direct_nop=f.direct_nop
+ subdirect_yes=f.subdirect_yes
+ subdirect_nop=f.subdirect_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ if variant=="ansi" then
+ useluawrites()
+ end
+ settarget(whereto)
+ end
+ setformatters(variant)
+ setlogfile=ignore
+ settimedlog=ignore
else
- local report_yes,subreport_yes,status_yes
- local report_nop,subreport_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- }
- logs.flush=ignore
- writer=function(s)
- write_nl(s)
- end
- newline=function()
- write_nl("\n")
+ local report_yes,subreport_yes,status_yes
+ local report_nop,subreport_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ }
+ logs.flush=ignore
+ writer=function(s)
+ write_nl(s)
+ end
+ newline=function()
+ write_nl("\n")
+ end
+ report=function(a,b,c,...)
+ if c then
+ write_nl(report_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(report_yes(a,b))
+ elseif a then
+ write_nl(report_nop(a))
+ else
+ write_nl("")
end
- report=function(a,b,c,...)
- if c then
- write_nl(report_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(report_yes(a,b))
- elseif a then
- write_nl(report_nop(a))
- else
- write_nl("")
- end
+ end
+ subreport=function(a,sub,b,c,...)
+ if c then
+ write_nl(subreport_yes(a,sub,formatters[b](c,...)))
+ elseif b then
+ write_nl(subreport_yes(a,sub,b))
+ elseif a then
+ write_nl(subreport_nop(a,sub))
+ else
+ write_nl("")
end
- subreport=function(a,sub,b,c,...)
- if c then
- write_nl(subreport_yes(a,sub,formatters[b](c,...)))
- elseif b then
- write_nl(subreport_yes(a,sub,b))
- elseif a then
- write_nl(subreport_nop(a,sub))
- else
- write_nl("")
+ end
+ status=function(a,b,c,...)
+ if c then
+ write_nl(status_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(status_yes(a,b))
+ elseif a then
+ write_nl(status_nop(a))
+ else
+ write_nl("\n")
+ end
+ end
+ direct=ignore
+ subdirect=ignore
+ settarget=ignore
+ pushtarget=ignore
+ poptarget=ignore
+ setformats=ignore
+ settranslations=ignore
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(f(s))
+ end
+ end
+ setformatters=function(specification)
+ local f=nil
+ local d=variants.default
+ if specification then
+ if type(specification)=="table" then
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ f=v.formats
end
+ end
end
- status=function(a,b,c,...)
- if c then
- write_nl(status_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(status_yes(a,b))
- elseif a then
- write_nl(status_nop(a))
- else
- write_nl("\n")
- end
- end
- direct=ignore
- subdirect=ignore
- settarget=ignore
- pushtarget=ignore
- poptarget=ignore
- setformats=ignore
- settranslations=ignore
- setprocessor=function(f)
- local writeline=write_nl
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ end
+ setformatters(variant)
+ setlogfile=function(name,keepopen)
+ if name and name~="" then
+ local localtime=os.localtime
+ local writeline=write_nl
+ if keepopen then
+ local f=io.open(name,"ab")
write_nl=function(s)
- writeline(f(s))
+ writeline(s)
+ f:write(localtime()," | ",s,"\n")
end
- end
- setformatters=function(specification)
- local f=nil
- local d=variants.default
- if specification then
- if type(specification)=="table" then
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- f=v.formats
- end
- end
- end
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- end
- setformatters(variant)
- setlogfile=function(name,keepopen)
- if name and name~="" then
- local localtime=os.localtime
- local writeline=write_nl
- if keepopen then
- local f=io.open(name,"ab")
- write_nl=function(s)
- writeline(s)
- f:write(localtime()," | ",s,"\n")
- end
- else
- write_nl=function(s)
- writeline(s)
- local f=io.open(name,"ab")
- f:write(localtime()," | ",s,"\n")
- f:close()
- end
- end
- end
- setlogfile=ignore
- end
- settimedlog=function()
- local localtime=os.localtime
- local writeline=write_nl
+ else
write_nl=function(s)
- writeline(localtime().." | "..s)
+ writeline(s)
+ local f=io.open(name,"ab")
+ f:write(localtime()," | ",s,"\n")
+ f:close()
end
- settimedlog=ignore
+ end
end
+ setlogfile=ignore
+ end
+ settimedlog=function()
+ local localtime=os.localtime
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(localtime().." | "..s)
+ end
+ settimedlog=ignore
+ end
end
logs.report=report
logs.subreport=subreport
@@ -13013,186 +13013,186 @@ local data={}
local states=nil
local force=false
function logs.reporter(category,subcategory)
- local logger=data[category]
- if not logger then
- local state=states==true
- if not state and type(states)=="table" then
- for c,_ in next,states do
- if find(category,c) then
- state=true
- break
- end
- end
+ local logger=data[category]
+ if not logger then
+ local state=states==true
+ if not state and type(states)=="table" then
+ for c,_ in next,states do
+ if find(category,c) then
+ state=true
+ break
end
- logger={
- reporters={},
- state=state,
- }
- data[category]=logger
- end
- local reporter=logger.reporters[subcategory or "default"]
- if not reporter then
- if subcategory then
- reporter=function(...)
- if force or not logger.state then
- subreport(category,subcategory,...)
- end
- end
- logger.reporters[subcategory]=reporter
- else
- local tag=category
- reporter=function(...)
- if force or not logger.state then
- report(category,...)
- end
- end
- logger.reporters.default=reporter
+ end
+ end
+ logger={
+ reporters={},
+ state=state,
+ }
+ data[category]=logger
+ end
+ local reporter=logger.reporters[subcategory or "default"]
+ if not reporter then
+ if subcategory then
+ reporter=function(...)
+ if force or not logger.state then
+ subreport(category,subcategory,...)
+ end
+ end
+ logger.reporters[subcategory]=reporter
+ else
+ local tag=category
+ reporter=function(...)
+ if force or not logger.state then
+ report(category,...)
end
+ end
+ logger.reporters.default=reporter
end
- return reporter
+ end
+ return reporter
end
logs.new=logs.reporter
local ctxreport=logs.writer
function logs.setmessenger(m)
- ctxreport=m
+ ctxreport=m
end
function logs.messenger(category,subcategory)
- if subcategory then
- return function(...)
- ctxreport(subdirect(category,subcategory,...))
- end
- else
- return function(...)
- ctxreport(direct(category,...))
- end
+ if subcategory then
+ return function(...)
+ ctxreport(subdirect(category,subcategory,...))
end
+ else
+ return function(...)
+ ctxreport(direct(category,...))
+ end
+ end
end
local function setblocked(category,value)
- if category==true or category=="all" then
- category,value="*",true
- elseif category==false then
- category,value="*",false
- elseif value==nil then
- value=true
- end
- if category=="*" then
- states=value
+ if category==true or category=="all" then
+ category,value="*",true
+ elseif category==false then
+ category,value="*",false
+ elseif value==nil then
+ value=true
+ end
+ if category=="*" then
+ states=value
+ for k,v in next,data do
+ v.state=value
+ end
+ else
+ alllocked=false
+ states=settings_to_hash(category,type(states)=="table" and states or nil)
+ for c in next,states do
+ local v=data[c]
+ if v then
+ v.state=value
+ else
+ c=topattern(c,true,true)
for k,v in next,data do
+ if find(k,c) then
v.state=value
+ end
end
- else
- alllocked=false
- states=settings_to_hash(category,type(states)=="table" and states or nil)
- for c in next,states do
- local v=data[c]
- if v then
- v.state=value
- else
- c=topattern(c,true,true)
- for k,v in next,data do
- if find(k,c) then
- v.state=value
- end
- end
- end
- end
+ end
end
+ end
end
function logs.disable(category,value)
- setblocked(category,value==nil and true or value)
+ setblocked(category,value==nil and true or value)
end
function logs.enable(category)
- setblocked(category,false)
+ setblocked(category,false)
end
function logs.categories()
- return sortedkeys(data)
+ return sortedkeys(data)
end
function logs.show()
- local n,c,s,max=0,0,0,0
- for category,v in table.sortedpairs(data) do
- n=n+1
- local state=v.state
- local reporters=v.reporters
- local nc=#category
- if nc>c then
- c=nc
- end
- for subcategory,_ in next,reporters do
- local ns=#subcategory
- if ns>c then
- s=ns
- end
- local m=nc+ns
- if m>max then
- max=m
- end
- end
- local subcategories=concat(sortedkeys(reporters),", ")
- if state==true then
- state="disabled"
- elseif state==false then
- state="enabled"
- else
- state="unknown"
- end
- report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ local n,c,s,max=0,0,0,0
+ for category,v in table.sortedpairs(data) do
+ n=n+1
+ local state=v.state
+ local reporters=v.reporters
+ local nc=#category
+ if nc>c then
+ c=nc
+ end
+ for subcategory,_ in next,reporters do
+ local ns=#subcategory
+ if ns>c then
+ s=ns
+ end
+ local m=nc+ns
+ if m>max then
+ max=m
+ end
+ end
+ local subcategories=concat(sortedkeys(reporters),", ")
+ if state==true then
+ state="disabled"
+ elseif state==false then
+ state="enabled"
+ else
+ state="unknown"
end
- report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
+ report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ end
+ report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
end
local delayed_reporters={}
setmetatableindex(delayed_reporters,function(t,k)
- local v=logs.reporter(k.name)
- t[k]=v
- return v
+ local v=logs.reporter(k.name)
+ t[k]=v
+ return v
end)
function utilities.setters.report(setter,...)
- delayed_reporters[setter](...)
+ delayed_reporters[setter](...)
end
directives.register("logs.blocked",function(v)
- setblocked(v,true)
+ setblocked(v,true)
end)
directives.register("logs.target",function(v)
- settarget(v)
+ settarget(v)
end)
if tex then
- local report=logs.reporter("pages")
- local texgetcount=tex and tex.getcount
- local real,user,sub=0,0,0
- function logs.start_page_number()
- real=texgetcount("realpageno")
- user=texgetcount("userpageno")
- sub=texgetcount("subpageno")
- end
- local timing=false
- local lasttime=nil
- trackers.register("pages.timing",function(v)
- timing=""
- end)
- function logs.stop_page_number()
- if timing then
- local elapsed=statistics.currenttime(statistics)
- local average,page
- if not lasttime or real<2 then
- average=elapsed
- page=elapsed
- else
- average=elapsed/(real-1)
- page=elapsed-lasttime
- end
- lasttime=elapsed
- timing=formatters[", total %0.03f, page %0.03f, average %0.03f"](elapsed,page,average)
- end
- if real<=0 then
- report("flushing page%s",timing)
- elseif user<=0 then
- report("flushing realpage %s%s",real,timing)
- elseif sub<=0 then
- report("flushing realpage %s, userpage %s%s",real,user,timing)
- else
- report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
- end
- logs.flush()
+ local report=logs.reporter("pages")
+ local texgetcount=tex and tex.getcount
+ local real,user,sub=0,0,0
+ function logs.start_page_number()
+ real=texgetcount("realpageno")
+ user=texgetcount("userpageno")
+ sub=texgetcount("subpageno")
+ end
+ local timing=false
+ local lasttime=nil
+ trackers.register("pages.timing",function(v)
+ timing=""
+ end)
+ function logs.stop_page_number()
+ if timing then
+ local elapsed=statistics.currenttime(statistics)
+ local average,page
+ if not lasttime or real<2 then
+ average=elapsed
+ page=elapsed
+ else
+ average=elapsed/(real-1)
+ page=elapsed-lasttime
+ end
+ lasttime=elapsed
+ timing=formatters[", total %0.03f, page %0.03f, average %0.03f"](elapsed,page,average)
end
+ if real<=0 then
+ report("flushing page%s",timing)
+ elseif user<=0 then
+ report("flushing realpage %s%s",real,timing)
+ elseif sub<=0 then
+ report("flushing realpage %s, userpage %s%s",real,user,timing)
+ else
+ report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
+ end
+ logs.flush()
+ end
end
local nesting=0
local verbose=false
@@ -13216,222 +13216,222 @@ logs.help=ignore
local Carg,C,lpegmatch=lpeg.Carg,lpeg.C,lpeg.match
local p_newline=lpeg.patterns.newline
local linewise=(
- Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
+ Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
)^1
local function reportlines(t,str)
- if str then
- lpegmatch(linewise,str,1,t)
- end
+ if str then
+ lpegmatch(linewise,str,1,t)
+ end
end
local function reportbanner(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- t.report()
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ t.report()
+ end
end
local function reportversion(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ end
end
local function reporthelp(t,...)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="string" then
- reportlines(t,helpinfo)
- elseif type(helpinfo)=="table" then
- for i=1,select("#",...) do
- reportlines(t,t.helpinfo[select(i,...)])
- if i<n then
- t.report()
- end
- end
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="string" then
+ reportlines(t,helpinfo)
+ elseif type(helpinfo)=="table" then
+ for i=1,select("#",...) do
+ reportlines(t,t.helpinfo[select(i,...)])
+ if i<n then
+ t.report()
+ end
end
+ end
end
local function reportinfo(t)
- t.report()
- reportlines(t,t.moreinfo)
+ t.report()
+ reportlines(t,t.moreinfo)
end
local function reportexport(t,method)
- report(t.helpinfo)
+ report(t.helpinfo)
end
local reporters={
- lines=reportlines,
- banner=reportbanner,
- version=reportversion,
- help=reporthelp,
- info=reportinfo,
- export=reportexport,
+ lines=reportlines,
+ banner=reportbanner,
+ version=reportversion,
+ help=reporthelp,
+ info=reportinfo,
+ export=reportexport,
}
local exporters={
}
logs.reporters=reporters
logs.exporters=exporters
function logs.application(t)
- t.name=t.name or "unknown"
- t.banner=t.banner
- t.moreinfo=moreinfo
- t.report=logs.reporter(t.name)
- t.help=function(...)
- reporters.banner(t)
- reporters.help(t,...)
- reporters.info(t)
- end
- t.export=function(...)
- reporters.export(t,...)
- end
- t.identify=function()
- reporters.banner(t)
- end
- t.version=function()
- reporters.version(t)
- end
- return t
+ t.name=t.name or "unknown"
+ t.banner=t.banner
+ t.moreinfo=moreinfo
+ t.report=logs.reporter(t.name)
+ t.help=function(...)
+ reporters.banner(t)
+ reporters.help(t,...)
+ reporters.info(t)
+ end
+ t.export=function(...)
+ reporters.export(t,...)
+ end
+ t.identify=function()
+ reporters.banner(t)
+ end
+ t.version=function()
+ reporters.version(t)
+ end
+ return t
end
local f_syslog=formatters["%s %s => %s => %s => %s\r"]
function logs.system(whereto,process,jobname,category,fmt,arg,...)
- local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
- for i=1,10 do
- local f=openfile(whereto,"a")
- if f then
- f:write(message)
- f:close()
- break
- else
- sleep(0.1)
- end
+ local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
+ for i=1,10 do
+ local f=openfile(whereto,"a")
+ if f then
+ f:write(message)
+ f:close()
+ break
+ else
+ sleep(0.1)
end
+ end
end
local report_system=logs.reporter("system","logs")
function logs.obsolete(old,new)
- local o=loadstring("return "..new)()
- if type(o)=="function" then
- return function(...)
- report_system("function %a is obsolete, use %a",old,new)
- loadstring(old.."="..new.." return "..old)()(...)
- end
- elseif type(o)=="table" then
- local t,m={},{}
- m.__index=function(t,k)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- return o[k]
- end
- m.__newindex=function(t,k,v)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- o[k]=v
- end
- if libraries then
- libraries.obsolete[old]=t
- end
- setmetatable(t,m)
- return t
+ local o=loadstring("return "..new)()
+ if type(o)=="function" then
+ return function(...)
+ report_system("function %a is obsolete, use %a",old,new)
+ loadstring(old.."="..new.." return "..old)()(...)
+ end
+ elseif type(o)=="table" then
+ local t,m={},{}
+ m.__index=function(t,k)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ return o[k]
+ end
+ m.__newindex=function(t,k,v)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ o[k]=v
+ end
+ if libraries then
+ libraries.obsolete[old]=t
end
+ setmetatable(t,m)
+ return t
+ end
end
if utilities then
- utilities.report=report_system
+ utilities.report=report_system
end
if tex and tex.error then
- function logs.texerrormessage(...)
- tex.error(format(...))
- end
+ function logs.texerrormessage(...)
+ tex.error(format(...))
+ end
else
- function logs.texerrormessage(...)
- print(format(...))
- end
+ function logs.texerrormessage(...)
+ print(format(...))
+ end
end
io.stdout:setvbuf('no')
io.stderr:setvbuf('no')
if package.helpers.report then
- package.helpers.report=logs.reporter("package loader")
+ package.helpers.report=logs.reporter("package loader")
end
if tex then
- local finalactions={}
- local fatalerrors={}
- local possiblefatal={}
- local loggingerrors=false
- function logs.loggingerrors()
- return loggingerrors
- end
- directives.register("logs.errors",function(v)
- loggingerrors=v
- if type(v)=="string" then
- fatalerrors=settings_to_hash(v)
- else
- fatalerrors={}
- end
- end)
- function logs.registerfinalactions(...)
- insert(finalactions,...)
- end
- local what=nil
- local report=nil
- local state=nil
- local target=nil
- local function startlogging(t,r,w,s)
- target=t
- state=force
- force=true
- report=type(r)=="function" and r or logs.reporter(r)
- what=w
- pushtarget(target)
+ local finalactions={}
+ local fatalerrors={}
+ local possiblefatal={}
+ local loggingerrors=false
+ function logs.loggingerrors()
+ return loggingerrors
+ end
+ directives.register("logs.errors",function(v)
+ loggingerrors=v
+ if type(v)=="string" then
+ fatalerrors=settings_to_hash(v)
+ else
+ fatalerrors={}
+ end
+ end)
+ function logs.registerfinalactions(...)
+ insert(finalactions,...)
+ end
+ local what=nil
+ local report=nil
+ local state=nil
+ local target=nil
+ local function startlogging(t,r,w,s)
+ target=t
+ state=force
+ force=true
+ report=type(r)=="function" and r or logs.reporter(r)
+ what=w
+ pushtarget(target)
+ newline()
+ if s then
+ report("start %s: %s",what,s)
+ else
+ report("start %s",what)
+ end
+ if target=="logfile" then
+ newline()
+ end
+ return report
+ end
+ local function stoplogging()
+ if target=="logfile" then
+ newline()
+ end
+ report("stop %s",what)
+ if target=="logfile" then
+ newline()
+ end
+ poptarget()
+ state=oldstate
+ end
+ function logs.startfilelogging(...)
+ return startlogging("logfile",...)
+ end
+ logs.stopfilelogging=stoplogging
+ local done=false
+ function logs.starterrorlogging(r,w,...)
+ if not done then
+ pushtarget("terminal")
+ newline()
+ logs.report("error logging","start possible issues")
+ poptarget()
+ done=true
+ end
+ if fatalerrors[w] then
+ possiblefatal[w]=true
+ end
+ return startlogging("terminal",r,w,...)
+ end
+ logs.stoperrorlogging=stoplogging
+ function logs.finalactions()
+ if #finalactions>0 then
+ for i=1,#finalactions do
+ finalactions[i]()
+ end
+ if done then
+ pushtarget("terminal")
newline()
- if s then
- report("start %s: %s",what,s)
- else
- report("start %s",what)
- end
- if target=="logfile" then
- newline()
- end
- return report
- end
- local function stoplogging()
- if target=="logfile" then
- newline()
- end
- report("stop %s",what)
- if target=="logfile" then
- newline()
- end
+ logs.report("error logging","stop possible issues")
poptarget()
- state=oldstate
- end
- function logs.startfilelogging(...)
- return startlogging("logfile",...)
- end
- logs.stopfilelogging=stoplogging
- local done=false
- function logs.starterrorlogging(r,w,...)
- if not done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","start possible issues")
- poptarget()
- done=true
- end
- if fatalerrors[w] then
- possiblefatal[w]=true
- end
- return startlogging("terminal",r,w,...)
- end
- logs.stoperrorlogging=stoplogging
- function logs.finalactions()
- if #finalactions>0 then
- for i=1,#finalactions do
- finalactions[i]()
- end
- if done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","stop possible issues")
- poptarget()
- end
- return next(possiblefatal) and sortedkeys(possiblefatal) or false
- end
+ end
+ return next(possiblefatal) and sortedkeys(possiblefatal) or false
end
+ end
end
@@ -13441,14 +13441,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
--- original size: 8684, stripped down to: 6000
+-- original size: 9000, stripped down to: 6003
if not modules then modules={} end modules ['trac-inf']={
- version=1.001,
- comment="companion to trac-inf.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-inf.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber,select=type,tonumber,select
local format,lower,find=string.format,string.lower,string.find
@@ -13463,86 +13463,86 @@ statistics.enable=true
statistics.threshold=0.01
local statusinfo,n,registered,timers={},0,{},{}
setmetatableindex(timers,function(t,k)
- local v={ timing=0,loadtime=0 }
- t[k]=v
- return v
+ local v={ timing=0,loadtime=0 }
+ t[k]=v
+ return v
end)
local function hastiming(instance)
- return instance and timers[instance]
+ return instance and timers[instance]
end
local function resettiming(instance)
- timers[instance or "notimer"]={ timing=0,loadtime=0 }
+ timers[instance or "notimer"]={ timing=0,loadtime=0 }
end
local ticks=clock
local seconds=function(n) return n or 0 end
local function starttiming(instance,reset)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if reset then
- it=0
- timer.loadtime=0
- end
- if it==0 then
- timer.starttime=ticks()
- if not timer.loadtime then
- timer.loadtime=0
- end
- end
- timer.timing=it+1
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if reset then
+ it=0
+ timer.loadtime=0
+ end
+ if it==0 then
+ timer.starttime=ticks()
+ if not timer.loadtime then
+ timer.loadtime=0
+ end
+ end
+ timer.timing=it+1
end
local function stoptiming(instance)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it>1 then
- timer.timing=it-1
- else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- local stoptime=ticks()
- local loadtime=stoptime-starttime
- timer.stoptime=stoptime
- timer.loadtime=timer.loadtime+loadtime
- timer.timing=0
- timer.starttime=0
- return loadtime
- end
- end
- return 0
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
+ timer.timing=it-1
+ else
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ local stoptime=ticks()
+ local loadtime=stoptime-starttime
+ timer.stoptime=stoptime
+ timer.loadtime=timer.loadtime+loadtime
+ timer.timing=0
+ timer.starttime=0
+ return loadtime
+ end
+ end
+ return 0
end
local function elapsed(instance)
- if type(instance)=="number" then
- return instance
- else
- local timer=timers[instance or "notimer"]
- return timer and seconds(timer.loadtime) or 0
- end
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ return timer and seconds(timer.loadtime) or 0
+ end
end
local function currenttime(instance)
- if type(instance)=="number" then
- return instance
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
else
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it>1 then
- else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- return seconds(timer.loadtime+ticks()-starttime)
- end
- end
- return 0
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ return seconds(timer.loadtime+ticks()-starttime)
+ end
end
+ return 0
+ end
end
local function elapsedtime(instance)
- return format("%0.3f",elapsed(instance))
+ return format("%0.3f",elapsed(instance))
end
local function elapsedindeed(instance)
- return elapsed(instance)>statistics.threshold
+ return elapsed(instance)>statistics.threshold
end
local function elapsedseconds(instance,rest)
- if elapsedindeed(instance) then
- return format("%0.3f seconds %s",elapsed(instance),rest or "")
- end
+ if elapsedindeed(instance) then
+ return format("%0.3f seconds %s",elapsed(instance),rest or "")
+ end
end
statistics.hastiming=hastiming
statistics.resettiming=resettiming
@@ -13554,91 +13554,98 @@ statistics.elapsedtime=elapsedtime
statistics.elapsedindeed=elapsedindeed
statistics.elapsedseconds=elapsedseconds
function statistics.register(tag,fnc)
- if statistics.enable and type(fnc)=="function" then
- local rt=registered[tag] or (#statusinfo+1)
- statusinfo[rt]={ tag,fnc }
- registered[tag]=rt
- if #tag>n then n=#tag end
- end
+ if statistics.enable and type(fnc)=="function" then
+ local rt=registered[tag] or (#statusinfo+1)
+ statusinfo[rt]={ tag,fnc }
+ registered[tag]=rt
+ if #tag>n then n=#tag end
+ end
end
local report=logs.reporter("mkiv lua stats")
function statistics.show()
- if statistics.enable then
- local register=statistics.register
- register("used platform",function()
- return format("%s, type: %s, binary subtree: %s",
- os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
- end)
- register("used engine",function()
- return format("%s version %s with functionality level %s, banner: %s",
- LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
- end)
- register("control sequences",function()
- return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
- end)
- register("callbacks",statistics.callbacks)
- if TEXENGINE=="luajittex" and JITSUPPORTED then
- local jitstatus=jit.status
- if jitstatus then
- local jitstatus={ jitstatus() }
- if jitstatus[1] then
- register("luajit options",concat(jitstatus," ",2))
- end
- end
- end
- register("lua properties",function()
- local hashchar=tonumber(status.luatex_hashchars)
- local hashtype=status.luatex_hashtype
- local mask=lua.mask or "ascii"
- return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
- jit and "luajit" or "lua",
- LUAVERSION,
- statistics.memused(),
- hashtype or "default",
- hashchar and 2^hashchar or "unknown",
- mask,
- mask=="utf" and "τεχ" or "tex")
- end)
- register("runtime",statistics.runtime)
- logs.newline()
- for i=1,#statusinfo do
- local s=statusinfo[i]
- local r=s[2]()
- if r then
- report("%s: %s",s[1],r)
- end
+ if statistics.enable then
+ local register=statistics.register
+ register("used platform",function()
+ return format("%s, type: %s, binary subtree: %s",
+ os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
+ end)
+ register("used engine",function()
+ return format("%s version %s with functionality level %s, banner: %s",
+ LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
+ end)
+ register("control sequences",function()
+ return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
+ end)
+ register("callbacks",statistics.callbacks)
+ if TEXENGINE=="luajittex" and JITSUPPORTED then
+ local jitstatus=jit.status
+ if jitstatus then
+ local jitstatus={ jitstatus() }
+ if jitstatus[1] then
+ register("luajit options",concat(jitstatus," ",2))
end
- statistics.enable=false
+ end
+ end
+ register("lua properties",function()
+ local hashchar=tonumber(status.luatex_hashchars)
+ local hashtype=status.luatex_hashtype
+ local mask=lua.mask or "ascii"
+ return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
+ jit and "luajit" or "lua",
+ LUAVERSION,
+ statistics.memused(),
+ hashtype or "default",
+ hashchar and 2^hashchar or "unknown",
+ mask,
+ mask=="utf" and "τεχ" or "tex")
+ end)
+ register("runtime",statistics.runtime)
+ logs.newline()
+ for i=1,#statusinfo do
+ local s=statusinfo[i]
+ local r=s[2]()
+ if r then
+ report("%s: %s",s[1],r)
+ end
end
+ statistics.enable=false
+ end
end
function statistics.memused()
- local round=math.round or math.floor
- return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
+ local round=math.round or math.floor
+ return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
end
starttiming(statistics)
function statistics.formatruntime(runtime)
- return format("%s seconds",runtime)
+ return format("%s seconds",runtime)
end
function statistics.runtime()
- stoptiming(statistics)
- return statistics.formatruntime(elapsedtime(statistics))
+ stoptiming(statistics)
+ local runtime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
end
local report=logs.reporter("system")
-function statistics.timed(action)
- starttiming("run")
- action()
- stoptiming("run")
- report("total runtime: %s seconds",elapsedtime("run"))
+function statistics.timed(action,all)
+ starttiming("run")
+ action()
+ stoptiming("run")
+ local runtime=tonumber(elapsedtime("run"))
+ if all then
+ local alltime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime)
+ else
+ report("total runtime: %0.3f seconds",runtime)
+ end
end
function statistics.tracefunction(base,tag,...)
- for i=1,select("#",...) do
- local name=select(i,...)
- local stat={}
- local func=base[name]
- setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
- base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
- statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
- end
+ for i=1,select("#",...) do
+ local name=select(i,...)
+ local stat={}
+ local func=base[name]
+ setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
+ base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
+ statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
+ end
end
@@ -13648,144 +13655,144 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
--- original size: 5841, stripped down to: 3511
+-- original size: 5841, stripped down to: 3352
if not modules then modules={} end modules ['trac-pro']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
-local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
+local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
local report_system=logs.reporter("system","protection")
namespaces=namespaces or {}
local namespaces=namespaces
local registered={}
local function report_index(k,name)
- if trace_namespaces then
- report_system("reference to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("reference to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("reference to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("reference to %a in protected namespace %a",k,name)
+ end
end
local function report_newindex(k,name)
- if trace_namespaces then
- report_system("assignment to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("assignment to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("assignment to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("assignment to %a in protected namespace %a",k,name)
+ end
end
local function register(name)
- local data=name=="global" and _G or _G[name]
- if not data then
- return
- end
- registered[name]=data
- local m=getmetatable(data)
- if not m then
- m={}
- setmetatable(data,m)
- end
- local index,newindex={},{}
- m.__saved__index=m.__index
- m.__no__index=function(t,k)
- if not index[k] then
- index[k]=true
- report_index(k,name)
- end
- return nil
+ local data=name=="global" and _G or _G[name]
+ if not data then
+ return
+ end
+ registered[name]=data
+ local m=getmetatable(data)
+ if not m then
+ m={}
+ setmetatable(data,m)
+ end
+ local index,newindex={},{}
+ m.__saved__index=m.__index
+ m.__no__index=function(t,k)
+ if not index[k] then
+ index[k]=true
+ report_index(k,name)
end
- m.__saved__newindex=m.__newindex
- m.__no__newindex=function(t,k,v)
- if not newindex[k] then
- newindex[k]=true
- report_newindex(k,name)
- end
- rawset(t,k,v)
+ return nil
+ end
+ m.__saved__newindex=m.__newindex
+ m.__no__newindex=function(t,k,v)
+ if not newindex[k] then
+ newindex[k]=true
+ report_newindex(k,name)
end
- m.__protection__depth=0
+ rawset(t,k,v)
+ end
+ m.__protection__depth=0
end
local function private(name)
- local data=registered[name]
+ local data=registered[name]
+ if not data then
+ data=_G[name]
if not data then
- data=_G[name]
- if not data then
- data={}
- _G[name]=data
- end
- register(name)
+ data={}
+ _G[name]=data
end
- return data
+ register(name)
+ end
+ return data
end
local function protect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>0 then
- m.__protection__depth=pd+1
- else
- m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
- m.__index,m.__newindex=m.__no__index,m.__no__newindex
- m.__protection__depth=1
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>0 then
+ m.__protection__depth=pd+1
+ else
+ m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
+ m.__index,m.__newindex=m.__no__index,m.__no__newindex
+ m.__protection__depth=1
+ end
end
local function unprotect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>1 then
- m.__protection__depth=pd-1
- else
- m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
- m.__protection__depth=0
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>1 then
+ m.__protection__depth=pd-1
+ else
+ m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
+ m.__protection__depth=0
+ end
end
local function protectall()
- for name,_ in next,registered do
- if name~="global" then
- protect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ protect(name)
end
+ end
end
local function unprotectall()
- for name,_ in next,registered do
- if name~="global" then
- unprotect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ unprotect(name)
end
+ end
end
-namespaces.register=register
-namespaces.private=private
+namespaces.register=register
+namespaces.private=private
namespaces.protect=protect
namespaces.unprotect=unprotect
namespaces.protectall=protectall
namespaces.unprotectall=unprotectall
namespaces.private("namespaces") registered={} register("global")
directives.register("system.protect",function(v)
- if v then
- protectall()
- else
- unprotectall()
- end
+ if v then
+ protectall()
+ else
+ unprotectall()
+ end
end)
directives.register("system.checkglobals",function(v)
- if v then
- report_system("enabling global namespace guard")
- protect("global")
- else
- report_system("disabling global namespace guard")
- unprotect("global")
- end
+ if v then
+ report_system("enabling global namespace guard")
+ protect("global")
+ else
+ report_system("disabling global namespace guard")
+ unprotect("global")
+ end
end)
@@ -13795,15 +13802,15 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lua"] = package.loaded["util-lua"] or true
--- original size: 6664, stripped down to: 4800
+-- original size: 6664, stripped down to: 4589
if not modules then modules={} end modules ['util-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment="the strip code is written by Peter Cawley",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ comment="the strip code is written by Peter Cawley",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format
local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage
@@ -13814,151 +13821,151 @@ local report_lua=logs.reporter("system","lua")
local report_mem=logs.reporter("system","lua memory")
local tracestripping=false
local tracememory=false
-luautilities.stripcode=true
+luautilities.stripcode=true
luautilities.alwaysstripcode=false
luautilities.nofstrippedchunks=0
luautilities.nofstrippedbytes=0
local strippedchunks={}
luautilities.strippedchunks=strippedchunks
luautilities.suffixes={
- tma="tma",
- tmc=jit and "tmb" or "tmc",
- lua="lua",
- luc=jit and "lub" or "luc",
- lui="lui",
- luv="luv",
- luj="luj",
- tua="tua",
- tuc="tuc",
+ tma="tma",
+ tmc=jit and "tmb" or "tmc",
+ lua="lua",
+ luc=jit and "lub" or "luc",
+ lui="lui",
+ luv="luv",
+ luj="luj",
+ tua="tua",
+ tuc="tuc",
}
local function register(name)
- if tracestripping then
- report_lua("stripped bytecode from %a",name or "unknown")
- end
- strippedchunks[#strippedchunks+1]=name
- luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
+ if tracestripping then
+ report_lua("stripped bytecode from %a",name or "unknown")
+ end
+ strippedchunks[#strippedchunks+1]=name
+ luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
end
local function stupidcompile(luafile,lucfile,strip)
- local code=io.loaddata(luafile)
- if code and code~="" then
- code=load(code)
- if code then
- code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
- if code and code~="" then
- register(name)
- io.savedata(lucfile,code)
- return true,0
- end
- else
- report_lua("fatal error %a in file %a",1,luafile)
- end
- else
- report_lua("fatal error %a in file %a",2,luafile)
- end
- return false,0
-end
-function luautilities.loadedluacode(fullname,forcestrip,name,macros)
- name=name or fullname
- if macros then
- macros=lua.macros
- end
- local code,message
- if macros then
- code,message=macros.loaded(fullname,true,false)
- else
- code,message=loadfile(fullname)
- end
+ local code=io.loaddata(luafile)
+ if code and code~="" then
+ code=load(code)
if code then
- code()
- else
- report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
- code,message=loadfile(fullname)
- end
- if forcestrip and luautilities.stripcode then
- if type(forcestrip)=="function" then
- forcestrip=forcestrip(fullname)
- end
- if forcestrip or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
- elseif luautilities.alwaysstripcode then
+ code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
+ if code and code~="" then
register(name)
- return load(dump(code,true)),0
+ io.savedata(lucfile,code)
+ return true,0
+ end
else
- return code,0
+ report_lua("fatal error %a in file %a",1,luafile)
end
+ else
+ report_lua("fatal error %a in file %a",2,luafile)
+ end
+ return false,0
+end
+function luautilities.loadedluacode(fullname,forcestrip,name,macros)
+ name=name or fullname
+ if macros then
+ macros=lua.macros
+ end
+ local code,message
+ if macros then
+ code,message=macros.loaded(fullname,true,false)
+ else
+ code,message=loadfile(fullname)
+ end
+ if code then
+ code()
+ else
+ report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
+ code,message=loadfile(fullname)
+ end
+ if forcestrip and luautilities.stripcode then
+ if type(forcestrip)=="function" then
+ forcestrip=forcestrip(fullname)
+ end
+ if forcestrip or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
+ elseif luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.strippedloadstring(code,name,forcestrip)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.loadstring(code,name)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- return code,0
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ return code,0
end
function luautilities.compile(luafile,lucfile,cleanup,strip,fallback)
- report_lua("compiling %a into %a",luafile,lucfile)
- os.remove(lucfile)
- local done=stupidcompile(luafile,lucfile,strip~=false)
- if done then
- report_lua("dumping %a into %a stripped",luafile,lucfile)
- if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
- report_lua("removing %a",luafile)
- os.remove(luafile)
- end
- end
- return done
+ report_lua("compiling %a into %a",luafile,lucfile)
+ os.remove(lucfile)
+ local done=stupidcompile(luafile,lucfile,strip~=false)
+ if done then
+ report_lua("dumping %a into %a stripped",luafile,lucfile)
+ if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+ report_lua("removing %a",luafile)
+ os.remove(luafile)
+ end
+ end
+ return done
end
function luautilities.loadstripped(...)
- local l=load(...)
- if l then
- return load(dump(l,true))
- end
+ local l=load(...)
+ if l then
+ return load(dump(l,true))
+ end
end
local finalizers={}
setmetatable(finalizers,{
- __gc=function(t)
- for i=1,#t do
- pcall(t[i])
- end
+ __gc=function(t)
+ for i=1,#t do
+ pcall(t[i])
end
+ end
} )
function luautilities.registerfinalizer(f)
- finalizers[#finalizers+1]=f
+ finalizers[#finalizers+1]=f
end
function luautilities.checkmemory(previous,threshold,trace)
- local current=collectgarbage("count")
- if previous then
- local checked=(threshold or 64)*1024
- local delta=current-previous
- if current-previous>checked then
- collectgarbage("collect")
- local afterwards=collectgarbage("count")
- if trace or tracememory then
- report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
- previous/1024,current/1024,delta/1024,threshold,afterwards)
- end
- return afterwards
- elseif trace or tracememory then
- report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
- previous/1024,current/1024,delta/1024,threshold)
- end
+ local current=collectgarbage("count")
+ if previous then
+ local checked=(threshold or 64)*1024
+ local delta=current-previous
+ if current-previous>checked then
+ collectgarbage("collect")
+ local afterwards=collectgarbage("count")
+ if trace or tracememory then
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB",
+ previous/1024,current/1024,delta/1024,threshold,afterwards)
+ end
+ return afterwards
+ elseif trace or tracememory then
+ report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB",
+ previous/1024,current/1024,delta/1024,threshold)
end
- return current
+ end
+ return current
end
@@ -13968,14 +13975,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-deb"] = package.loaded["util-deb"] or true
--- original size: 9955, stripped down to: 7311
+-- original size: 9955, stripped down to: 6693
if not modules then modules={} end modules ['util-deb']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber=type,next,tostring,tonumber
local format,find,sub,gsub=string.format,string.find,string.sub,string.gsub
@@ -13994,266 +14001,266 @@ local names={}
local initialize=false
if not (FFISUPPORTED and ffi) then
elseif os.type=="windows" then
- initialize=function()
- local kernel=ffilib("kernel32","system")
- if kernel then
- local tonumber=ffi.number or tonumber
- ffi.cdef[[
+ initialize=function()
+ local kernel=ffilib("kernel32","system")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ ffi.cdef[[
int QueryPerformanceFrequency(int64_t *lpFrequency);
int QueryPerformanceCounter(int64_t *lpPerformanceCount);
]]
- local target=ffi.new("__int64[1]")
- ticks=function()
- if kernel.QueryPerformanceCounter(target)==1 then
- return tonumber(target[0])
- else
- return 0
- end
- end
- local target=ffi.new("__int64[1]")
- seconds=function(ticks)
- if kernel.QueryPerformanceFrequency(target)==1 then
- return ticks/tonumber(target[0])
- else
- return 0
- end
- end
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
end
- initialize=false
+ end
end
+ initialize=false
+ end
elseif os.type=="unix" then
- initialize=function()
- local C=ffi.C
- local tonumber=ffi.number or tonumber
- ffi.cdef [[
+ initialize=function()
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ ffi.cdef [[
/* what a mess */
typedef int clk_id_t;
typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
typedef struct timespec { long sec; long nsec; } ctx_timespec;
int clock_gettime(clk_id_t timerid, struct timespec *t);
]]
- local target=ffi.new("ctx_timespec[?]",1)
- local clock=C.CLOCK_PROCESS_CPUTIME_ID
- ticks=function ()
- C.clock_gettime(clock,target)
- return tonumber(target[0].sec*1000000000+target[0].nsec)
- end
- seconds=function(ticks)
- return ticks/1000000000
- end
- initialize=false
+ local target=ffi.new("ctx_timespec[?]",1)
+ local clock=C.CLOCK_PROCESS_CPUTIME_ID
+ ticks=function ()
+ C.clock_gettime(clock,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
end
+ seconds=function(ticks)
+ return ticks/1000000000
+ end
+ initialize=false
+ end
end
setmetatableindex(names,function(t,name)
- local v=setmetatableindex(function(t,source)
- local v=setmetatableindex(function(t,line)
- local v={ total=0,count=0,nesting=0 }
- t[line]=v
- return v
- end)
- t[source]=v
- return v
+ local v=setmetatableindex(function(t,source)
+ local v=setmetatableindex(function(t,line)
+ local v={ total=0,count=0,nesting=0 }
+ t[line]=v
+ return v
end)
- t[name]=v
+ t[source]=v
return v
+ end)
+ t[name]=v
+ return v
end)
local getinfo=nil
local sethook=nil
local function hook(where)
- local f=getinfo(2,"nSl")
- if f then
- local source=f.short_src
- if not source then
- return
- end
- local line=f.linedefined or 0
- local name=f.name
- if not name then
- local what=f.what
- if what=="C" then
- name="<anonymous>"
- else
- name=f.namewhat or what or "<unknown>"
- end
- end
- local data=names[name][source][line]
- if where=="call" then
- local nesting=data.nesting
- if nesting==0 then
- data.count=data.count+1
- insert(data,ticks())
- data.nesting=1
- else
- data.nesting=nesting+1
- end
- elseif where=="return" then
- local nesting=data.nesting
- if nesting==1 then
- local t=remove(data)
- if t then
- data.total=data.total+ticks()-t
- end
- data.nesting=0
- else
- data.nesting=nesting-1
- end
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
+ end
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ local nesting=data.nesting
+ if nesting==0 then
+ data.count=data.count+1
+ insert(data,ticks())
+ data.nesting=1
+ else
+ data.nesting=nesting+1
+ end
+ elseif where=="return" then
+ local nesting=data.nesting
+ if nesting==1 then
+ local t=remove(data)
+ if t then
+ data.total=data.total+ticks()-t
end
+ data.nesting=0
+ else
+ data.nesting=nesting-1
+ end
end
+ end
end
function debugger.showstats(printer,threshold)
- local printer=printer or report
- local calls=0
- local functions=0
- local dataset={}
- local length=0
- local realtime=0
- local totaltime=0
- local threshold=threshold or 0
- for name,sources in next,names do
- for source,lines in next,sources do
- for line,data in next,lines do
- local count=data.count
- if count>threshold then
- if #name>length then
- length=#name
- end
- local total=data.total
- local real=total
- if real>0 then
- real=total-(count*overhead/dummycalls)
- if real<0 then
- real=0
- end
- realtime=realtime+real
- end
- totaltime=totaltime+total
- if line<0 then
- line=0
- end
- dataset[#dataset+1]={ real,total,count,name,source,line }
- end
- end
+ local printer=printer or report
+ local calls=0
+ local functions=0
+ local dataset={}
+ local length=0
+ local realtime=0
+ local totaltime=0
+ local threshold=threshold or 0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ local count=data.count
+ if count>threshold then
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ realtime=realtime+real
+ end
+ totaltime=totaltime+total
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
end
+ end
end
- sort(dataset,function(a,b)
- if a[1]==b[1] then
- if a[2]==b[2] then
- if a[3]==b[3] then
- if a[4]==b[4] then
- if a[5]==b[5] then
- return a[6]<b[6]
- else
- return a[5]<b[5]
- end
- else
- return a[4]<b[4]
- end
- else
- return b[3]<a[3]
- end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
else
- return b[2]<a[2]
+ return a[5]<b[5]
end
+ else
+ return a[4]<b[4]
+ end
else
- return b[1]<a[1]
+ return b[3]<a[3]
end
- end)
- if length>50 then
- length=50
- end
- local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
- for i=1,#dataset do
- local data=dataset[i]
- local real=data[1]
- local total=data[2]
- local count=data[3]
- local name=data[4]
- local source=data[5]
- local line=data[6]
- calls=calls+count
- functions=functions+1
- name=gsub(name,"%s+"," ")
- if #name>length then
- name=sub(name,1,length)
- end
- printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
- end
- printer("")
- printer(format("functions : %i",functions))
- printer(format("calls : %i",calls))
- printer(format("overhead : %f",seconds(overhead/1000)))
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
+ end
+ local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
+ for i=1,#dataset do
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ calls=calls+count
+ functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
+ end
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
end
local function getdebug()
- if sethook and getinfo then
- return
- end
- if not debug then
- local okay
- okay,debug=pcall(require,"debug")
- end
- if type(debug)~="table" then
- return
- end
- getinfo=debug.getinfo
- sethook=debug.sethook
- if type(getinfo)~="function" then
- getinfo=nil
- end
- if type(sethook)~="function" then
- sethook=nil
- end
+ if sethook and getinfo then
+ return
+ end
+ if not debug then
+ local okay
+ okay,debug=pcall(require,"debug")
+ end
+ if type(debug)~="table" then
+ return
+ end
+ getinfo=debug.getinfo
+ sethook=debug.sethook
+ if type(getinfo)~="function" then
+ getinfo=nil
+ end
+ if type(sethook)~="function" then
+ sethook=nil
+ end
end
function debugger.savestats(filename,threshold)
- local f=io.open(filename,'w')
- if f then
- debugger.showstats(function(str) f:write(str,"\n") end,threshold)
- f:close()
- end
+ local f=io.open(filename,'w')
+ if f then
+ debugger.showstats(function(str) f:write(str,"\n") end,threshold)
+ f:close()
+ end
end
function debugger.enable()
- getdebug()
- if sethook and getinfo and nesting==0 then
- running=true
- if initialize then
- initialize()
- end
- sethook(hook,"cr")
- local function dummy() end
- local t=ticks()
- for i=1,dummycalls do
- dummy()
- end
- overhead=ticks()-t
- end
- if nesting>0 then
- nesting=nesting+1
- end
+ getdebug()
+ if sethook and getinfo and nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
end
function debugger.disable()
- if nesting>0 then
- nesting=nesting-1
- end
- if sethook and getinfo and nesting==0 then
- sethook()
- end
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if sethook and getinfo and nesting==0 then
+ sethook()
+ end
end
local function showtraceback(rep)
- getdebug()
- if getinfo then
- local level=2
- local reporter=rep or report
- while true do
- local info=getinfo(level,"Sl")
- if not info then
- break
- elseif info.what=="C" then
- reporter("%2i : %s",level-1,"C function")
- else
- reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
- end
- level=level+1
- end
+ getdebug()
+ if getinfo then
+ local level=2
+ local reporter=rep or report
+ while true do
+ local info=getinfo(level,"Sl")
+ if not info then
+ break
+ elseif info.what=="C" then
+ reporter("%2i : %s",level-1,"C function")
+ else
+ reporter("%2i : %s : %s",level-1,info.short_src,info.currentline)
+ end
+ level=level+1
end
+ end
end
debugger.showtraceback=showtraceback
@@ -14264,91 +14271,91 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
--- original size: 7112, stripped down to: 3988
+-- original size: 7112, stripped down to: 3887
if not modules then modules={} end modules ['util-tpl']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities.templates=utilities.templates or {}
local templates=utilities.templates
-local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
+local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
local report_template=logs.reporter("template")
local tostring,next=tostring,next
local format,sub,byte=string.format,string.sub,string.byte
local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
local replacer
local function replacekey(k,t,how,recursive)
- local v=t[k]
- if not v then
- if trace_template then
- report_template("unknown key %a",k)
- end
- return ""
+ local v=t[k]
+ if not v then
+ if trace_template then
+ report_template("unknown key %a",k)
+ end
+ return ""
+ else
+ v=tostring(v)
+ if trace_template then
+ report_template("setting key %a to value %a",k,v)
+ end
+ if recursive then
+ return lpegmatch(replacer,v,1,t,how,recursive)
else
- v=tostring(v)
- if trace_template then
- report_template("setting key %a to value %a",k,v)
- end
- if recursive then
- return lpegmatch(replacer,v,1,t,how,recursive)
- else
- return v
- end
+ return v
end
+ end
end
local sqlescape=lpeg.replacer {
- { "'","''" },
- { "\\","\\\\" },
- { "\r\n","\\n" },
- { "\r","\\n" },
+ { "'","''" },
+ { "\\","\\\\" },
+ { "\r\n","\\n" },
+ { "\r","\\n" },
}
local sqlquoted=Cs(Cc("'")*sqlescape*Cc("'"))
lpegpatterns.sqlescape=sqlescape
lpegpatterns.sqlquoted=sqlquoted
local luaescape=lpegpatterns.luaescape
local escapers={
- lua=function(s)
- return lpegmatch(luaescape,s)
- end,
- sql=function(s)
- return lpegmatch(sqlescape,s)
- end,
+ lua=function(s)
+ return lpegmatch(luaescape,s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlescape,s)
+ end,
}
local quotedescapers={
- lua=function(s)
- return format("%q",s)
- end,
- sql=function(s)
- return lpegmatch(sqlquoted,s)
- end,
+ lua=function(s)
+ return format("%q",s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlquoted,s)
+ end,
}
local luaescaper=escapers.lua
local quotedluaescaper=quotedescapers.lua
local function replacekeyunquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and escapers[how] or luaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and escapers[how] or luaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replacekeyquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and quotedescapers[how] or quotedluaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and quotedescapers[how] or quotedluaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replaceoptional(l,m,r,t,how,recurse)
- local v=t[l]
- return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
+ local v=t[l]
+ return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
end
-local single=P("%")
+local single=P("%")
local double=P("%%")
local lquoted=P("%[")
local rquoted=P("]%")
@@ -14365,41 +14372,41 @@ local noloptional=P("%?")/''
local noroptional=P("?%")/''
local nomoptional=P(":")/''
local args=Carg(1)*Carg(2)*Carg(3)
-local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
-local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
-local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
+local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
+local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
+local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
local optional=noloptional*((C((1-nomoptional)^1)*nomoptional*C((1-noroptional)^1)*args)/replaceoptional)*noroptional
local any=P(1)
replacer=Cs((unquoted+quoted+escape+optional+key+any)^0)
local function replace(str,mapping,how,recurse)
- if mapping and str then
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
- return str
- end
+ if mapping and str then
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ else
+ return str
+ end
end
templates.replace=replace
function templates.replacer(str,how,recurse)
- return function(mapping)
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- end
+ return function(mapping)
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ end
end
function templates.load(filename,mapping,how,recurse)
- local data=io.loaddata(filename) or ""
- if mapping and next(mapping) then
- return replace(data,mapping,how,recurse)
- else
- return data
- end
+ local data=io.loaddata(filename) or ""
+ if mapping and next(mapping) then
+ return replace(data,mapping,how,recurse)
+ else
+ return data
+ end
end
function templates.resolve(t,mapping,how,recurse)
- if not mapping then
- mapping=t
- end
- for k,v in next,t do
- t[k]=replace(v,mapping,how,recurse)
- end
- return t
+ if not mapping then
+ mapping=t
+ end
+ for k,v in next,t do
+ t[k]=replace(v,mapping,how,recurse)
+ end
+ return t
end
@@ -14409,14 +14416,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sbx"] = package.loaded["util-sbx"] or true
--- original size: 20393, stripped down to: 13924
+-- original size: 20393, stripped down to: 13121
if not modules then modules={} end modules ['util-sbx']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not sandbox then require("l-sandbox") end
local next,type=next,type
@@ -14449,144 +14456,144 @@ local report=logs.reporter("sandbox")
trackers.register("sandbox",function(v) trace=v end)
sandbox.setreporter(report)
sandbox.finalizer {
- category="files",
- action=function()
- finalized=true
- end
+ category="files",
+ action=function()
+ finalized=true
+ end
}
local function registerroot(root,what)
- if finalized then
- report("roots are already finalized")
- else
- if type(root)=="table" then
- root,what=root[1],root[2]
- end
- if type(root)=="string" and root~="" then
- root=collapsepath(expandname(root))
- if what=="r" or what=="ro" or what=="readable" then
- what="read"
- elseif what=="w" or what=="wo" or what=="writable" then
- what="write"
- end
- validroots[root]=what=="write" or false
- end
+ if finalized then
+ report("roots are already finalized")
+ else
+ if type(root)=="table" then
+ root,what=root[1],root[2]
+ end
+ if type(root)=="string" and root~="" then
+ root=collapsepath(expandname(root))
+ if what=="r" or what=="ro" or what=="readable" then
+ what="read"
+ elseif what=="w" or what=="wo" or what=="writable" then
+ what="write"
+ end
+ validroots[root]=what=="write" or false
end
+ end
end
sandbox.finalizer {
- category="files",
- action=function()
+ category="files",
+ action=function()
+ if p_validroot then
+ report("roots are already initialized")
+ else
+ sandbox.registerroot(".","write")
+ for name in sortedhash(validroots) do
if p_validroot then
- report("roots are already initialized")
+ p_validroot=P(name)+p_validroot
else
- sandbox.registerroot(".","write")
- for name in sortedhash(validroots) do
- if p_validroot then
- p_validroot=P(name)+p_validroot
- else
- p_validroot=P(name)
- end
- end
- p_validroot=p_validroot/validroots
+ p_validroot=P(name)
end
+ end
+ p_validroot=p_validroot/validroots
end
+ end
}
local function registerbinary(name)
- if finalized then
- report("binaries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validbinaries then
- return
- end
- if validbinaries==true then
- validbinaries={ [name]=true }
- else
- validbinaries[name]=true
- end
- elseif name==true then
- validbinaries={}
+ if finalized then
+ report("binaries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validbinaries then
+ return
end
+ if validbinaries==true then
+ validbinaries={ [name]=true }
+ else
+ validbinaries[name]=true
+ end
+ elseif name==true then
+ validbinaries={}
+ end
end
local function registerlibrary(name)
- if finalized then
- report("libraries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validlibraries then
- return
- end
- if validlibraries==true then
- validlibraries={ [nameonly(name)]=true }
- else
- validlibraries[nameonly(name)]=true
- end
- elseif name==true then
- validlibraries={}
+ if finalized then
+ report("libraries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validlibraries then
+ return
end
+ if validlibraries==true then
+ validlibraries={ [nameonly(name)]=true }
+ else
+ validlibraries[nameonly(name)]=true
+ end
+ elseif name==true then
+ validlibraries={}
+ end
end
local p_write=S("wa") p_write=(1-p_write)^0*p_write
-local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
+local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
local function normalized(name)
- if platform=="windows" then
- name=gsub(name,"/","\\")
- end
- return name
+ if platform=="windows" then
+ name=gsub(name,"/","\\")
+ end
+ return name
end
function sandbox.possiblepath(name)
- return lpegmatch(p_path,name) and true or false
+ return lpegmatch(p_path,name) and true or false
end
local filenamelogger=false
function sandbox.setfilenamelogger(l)
- filenamelogger=type(l)=="function" and l or false
+ filenamelogger=type(l)=="function" and l or false
end
local function validfilename(name,what)
- if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
- local asked=collapsepath(expandname(name))
- local okay=lpegmatch(p_validroot,asked)
- if okay==true then
- if filenamelogger then
- filenamelogger(name,"w",asked,true)
- end
- return name
- elseif okay==false then
- if not what then
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- elseif lpegmatch(p_write,what) then
- if filenamelogger then
- filenamelogger(name,"w",asked,false)
- end
- return
- else
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- end
- elseif filenamelogger then
- filenamelogger(name,"*",name,false)
+ if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
+ local asked=collapsepath(expandname(name))
+ local okay=lpegmatch(p_validroot,asked)
+ if okay==true then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,true)
+ end
+ return name
+ elseif okay==false then
+ if not what then
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
+ end
+ return name
+ elseif lpegmatch(p_write,what) then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,false)
+ end
+ return
+ else
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
end
- else
return name
+ end
+ elseif filenamelogger then
+ filenamelogger(name,"*",name,false)
end
+ else
+ return name
+ end
end
local function readable(name,finalized)
- return validfilename(name,"r")
+ return validfilename(name,"r")
end
local function normalizedreadable(name,finalized)
- local valid=validfilename(name,"r")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"r")
+ if valid then
+ return normalized(valid)
+ end
end
local function writeable(name,finalized)
- return validfilename(name,"w")
+ return validfilename(name,"w")
end
local function normalizedwriteable(name,finalized)
- local valid=validfilename(name,"w")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"w")
+ if valid then
+ return normalized(valid)
+ end
end
validators.readable=readable
validators.writeable=normalizedwriteable
@@ -14594,316 +14601,316 @@ validators.normalizedreadable=normalizedreadable
validators.normalizedwriteable=writeable
validators.filename=readable
table.setmetatableindex(validators,function(t,k)
- if k then
- t[k]=readable
- end
- return readable
+ if k then
+ t[k]=readable
+ end
+ return readable
end)
function validators.string(s,finalized)
- if finalized and suspicious(s) then
- return ""
- else
- return s
- end
+ if finalized and suspicious(s) then
+ return ""
+ else
+ return s
+ end
end
function validators.cache(s)
- if finalized then
- return basename(s)
- else
- return s
- end
+ if finalized then
+ return basename(s)
+ else
+ return s
+ end
end
function validators.url(s)
- if finalized and find("^file:") then
- return ""
- else
- return s
- end
+ if finalized and find("^file:") then
+ return ""
+ else
+ return s
+ end
end
local function filehandlerone(action,one,...)
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
+ else
+ end
end
local function filehandlertwo(action,one,two,...)
- local checkedone=validfilename(one)
- if checkedone then
- local checkedtwo=validfilename(two)
- if checkedtwo then
- return action(one,two,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ local checkedtwo=validfilename(two)
+ if checkedtwo then
+ return action(one,two,...)
else
end
+ else
+ end
end
local function iohandler(action,one,...)
- if type(one)=="string" then
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- end
- elseif one then
- return action(one,...)
- else
- return action()
+ if type(one)=="string" then
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
end
+ elseif one then
+ return action(one,...)
+ else
+ return action()
+ end
end
local osexecute=sandbox.original(os.execute)
local iopopen=sandbox.original(io.popen)
local reported={}
local function validcommand(name,program,template,checkers,defaults,variables,reporter,strict)
- if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
- if variables then
- for variable,value in next,variables do
- local checker=validators[checkers[variable]]
- if checker then
- value=checker(unquoted(value),strict)
- if value then
- variables[variable]=optionalquoted(value)
- else
- report("variable %a with value %a fails the check",variable,value)
- return
- end
- else
- report("variable %a has no checker",variable)
- return
- end
- end
- for variable,default in next,defaults do
- local value=variables[variable]
- if not value or value=="" then
- local checker=validators[checkers[variable]]
- if checker then
- default=checker(unquoted(default),strict)
- if default then
- variables[variable]=optionalquoted(default)
- else
- report("variable %a with default %a fails the check",variable,default)
- return
- end
- end
- end
- end
- end
- local command=program.." "..replace(template,variables)
- if reporter then
- reporter("executing runner %a: %s",name,command)
- elseif trace then
- report("executing runner %a: %s",name,command)
- end
- return command
- elseif not reported[name] then
- report("executing program %a of runner %a is not permitted",program,name)
- reported[name]=true
- end
-end
-local runners={
- resultof=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("resultof: %s",command)
- end
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- end
- end
- end,
- execute=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("execute: %s",command)
- end
- return osexecute(command)
+ if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
+ if variables then
+ for variable,value in next,variables do
+ local checker=validators[checkers[variable]]
+ if checker then
+ value=checker(unquoted(value),strict)
+ if value then
+ variables[variable]=optionalquoted(value)
+ else
+ report("variable %a with value %a fails the check",variable,value)
+ return
+ end
+ else
+ report("variable %a has no checker",variable)
+ return
end
- end,
- pipeto=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("pipeto: %s",command)
+ end
+ for variable,default in next,defaults do
+ local value=variables[variable]
+ if not value or value=="" then
+ local checker=validators[checkers[variable]]
+ if checker then
+ default=checker(unquoted(default),strict)
+ if default then
+ variables[variable]=optionalquoted(default)
+ else
+ report("variable %a with default %a fails the check",variable,default)
+ return
end
- return iopopen(command,"w")
- end
- end,
-}
-function sandbox.registerrunner(specification)
- if type(specification)=="string" then
- local wrapped=validrunners[specification]
- inspect(table.sortedkeys(validrunners))
- if wrapped then
- return wrapped
- else
- report("unknown predefined runner %a",specification)
- return
+ end
end
+ end
end
- if type(specification)~="table" then
- report("specification should be a table (or string)")
- return
- end
- local name=specification.name
- if type(name)~="string" then
- report("invalid name, string expected",name)
- return
- end
- if validrunners[name] then
- report("invalid name, runner %a already defined")
- return
- end
- local program=specification.program
- if type(program)=="string" then
- elseif type(program)=="table" then
- program=program[platform] or program.default or program.unix
- end
- if type(program)~="string" or program=="" then
- report("invalid runner %a specified for platform %a",name,platform)
- return
+ local command=program.." "..replace(template,variables)
+ if reporter then
+ reporter("executing runner %a: %s",name,command)
+ elseif trace then
+ report("executing runner %a: %s",name,command)
end
- local template=specification.template
- if not template then
- report("missing template for runner %a",name)
- return
+ return command
+ elseif not reported[name] then
+ report("executing program %a of runner %a is not permitted",program,name)
+ reported[name]=true
+ end
+end
+local runners={
+ resultof=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("resultof: %s",command)
+ end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ end
end
- local method=specification.method or "execute"
- local checkers=specification.checkers or {}
- local defaults=specification.defaults or {}
- local runner=runners[method]
- if runner then
- local finalized=finalized
- local wrapped=function(variables)
- return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
- end
- validrunners[name]=wrapped
- return wrapped
- else
- validrunners[name]=nil
- report("invalid method for runner %a",name)
+ end,
+ execute=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("execute: %s",command)
+ end
+ return osexecute(command)
+ end
+ end,
+ pipeto=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("pipeto: %s",command)
+ end
+ return iopopen(command,"w")
end
+ end,
+}
+function sandbox.registerrunner(specification)
+ if type(specification)=="string" then
+ local wrapped=validrunners[specification]
+ inspect(table.sortedkeys(validrunners))
+ if wrapped then
+ return wrapped
+ else
+ report("unknown predefined runner %a",specification)
+ return
+ end
+ end
+ if type(specification)~="table" then
+ report("specification should be a table (or string)")
+ return
+ end
+ local name=specification.name
+ if type(name)~="string" then
+ report("invalid name, string expected",name)
+ return
+ end
+ if validrunners[name] then
+ report("invalid name, runner %a already defined")
+ return
+ end
+ local program=specification.program
+ if type(program)=="string" then
+ elseif type(program)=="table" then
+ program=program[platform] or program.default or program.unix
+ end
+ if type(program)~="string" or program=="" then
+ report("invalid runner %a specified for platform %a",name,platform)
+ return
+ end
+ local template=specification.template
+ if not template then
+ report("missing template for runner %a",name)
+ return
+ end
+ local method=specification.method or "execute"
+ local checkers=specification.checkers or {}
+ local defaults=specification.defaults or {}
+ local runner=runners[method]
+ if runner then
+ local finalized=finalized
+ local wrapped=function(variables)
+ return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
+ end
+ validrunners[name]=wrapped
+ return wrapped
+ else
+ validrunners[name]=nil
+ report("invalid method for runner %a",name)
+ end
end
function sandbox.getrunner(name)
- return name and validrunners[name]
+ return name and validrunners[name]
end
local function suspicious(str)
- return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
+ return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
end
local function binaryrunner(action,command,...)
- if validbinaries==false then
- report("no binaries permitted, ignoring command: %s",command)
- return
- end
- if type(command)~="string" then
- report("command should be a string")
- return
- end
- local program=lpegmatch(p_split,command)
- if not program or program=="" then
- report("unable to filter binary from command: %s",command)
- return
- end
- if validbinaries==true then
- elseif not validbinaries[program] then
- report("binary not permitted, ignoring command: %s",command)
- return
- elseif suspicious(command) then
- report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
- return
- end
- return action(command,...)
+ if validbinaries==false then
+ report("no binaries permitted, ignoring command: %s",command)
+ return
+ end
+ if type(command)~="string" then
+ report("command should be a string")
+ return
+ end
+ local program=lpegmatch(p_split,command)
+ if not program or program=="" then
+ report("unable to filter binary from command: %s",command)
+ return
+ end
+ if validbinaries==true then
+ elseif not validbinaries[program] then
+ report("binary not permitted, ignoring command: %s",command)
+ return
+ elseif suspicious(command) then
+ report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
+ return
+ end
+ return action(command,...)
end
local function dummyrunner(action,command,...)
- if type(command)=="table" then
- command=concat(command," ",command[0] and 0 or 1)
- end
- report("ignoring command: %s",command)
+ if type(command)=="table" then
+ command=concat(command," ",command[0] and 0 or 1)
+ end
+ report("ignoring command: %s",command)
end
sandbox.filehandlerone=filehandlerone
sandbox.filehandlertwo=filehandlertwo
sandbox.iohandler=iohandler
function sandbox.disablerunners()
- validbinaries=false
+ validbinaries=false
end
function sandbox.disablelibraries()
- validlibraries=false
+ validlibraries=false
end
if FFISUPPORTED and ffi then
- function sandbox.disablelibraries()
- validlibraries=false
- for k,v in next,ffi do
- if k~="gc" then
- ffi[k]=nil
- end
- end
+ function sandbox.disablelibraries()
+ validlibraries=false
+ for k,v in next,ffi do
+ if k~="gc" then
+ ffi[k]=nil
+ end
end
- local fiiload=ffi.load
- if fiiload then
- local reported={}
- function ffi.load(name,...)
- if validlibraries==false then
- elseif validlibraries==true then
- return fiiload(name,...)
- elseif validlibraries[nameonly(name)] then
- return fiiload(name,...)
- else
- end
- if not reported[name] then
- report("using library %a is not permitted",name)
- reported[name]=true
- end
- return nil
- end
+ end
+ local fiiload=ffi.load
+ if fiiload then
+ local reported={}
+ function ffi.load(name,...)
+ if validlibraries==false then
+ elseif validlibraries==true then
+ return fiiload(name,...)
+ elseif validlibraries[nameonly(name)] then
+ return fiiload(name,...)
+ else
+ end
+ if not reported[name] then
+ report("using library %a is not permitted",name)
+ reported[name]=true
+ end
+ return nil
end
+ end
end
local overload=sandbox.overload
local register=sandbox.register
- overload(loadfile,filehandlerone,"loadfile")
+ overload(loadfile,filehandlerone,"loadfile")
if io then
- overload(io.open,filehandlerone,"io.open")
- overload(io.popen,binaryrunner,"io.popen")
- overload(io.input,iohandler,"io.input")
- overload(io.output,iohandler,"io.output")
- overload(io.lines,filehandlerone,"io.lines")
+ overload(io.open,filehandlerone,"io.open")
+ overload(io.popen,binaryrunner,"io.popen")
+ overload(io.input,iohandler,"io.input")
+ overload(io.output,iohandler,"io.output")
+ overload(io.lines,filehandlerone,"io.lines")
end
if os then
- overload(os.execute,binaryrunner,"os.execute")
- overload(os.spawn,dummyrunner,"os.spawn")
- overload(os.exec,dummyrunner,"os.exec")
- overload(os.resultof,binaryrunner,"os.resultof")
- overload(os.pipeto,binaryrunner,"os.pipeto")
- overload(os.rename,filehandlertwo,"os.rename")
- overload(os.remove,filehandlerone,"os.remove")
+ overload(os.execute,binaryrunner,"os.execute")
+ overload(os.spawn,dummyrunner,"os.spawn")
+ overload(os.exec,dummyrunner,"os.exec")
+ overload(os.resultof,binaryrunner,"os.resultof")
+ overload(os.pipeto,binaryrunner,"os.pipeto")
+ overload(os.rename,filehandlertwo,"os.rename")
+ overload(os.remove,filehandlerone,"os.remove")
end
if lfs then
- overload(lfs.chdir,filehandlerone,"lfs.chdir")
- overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
- overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
- overload(lfs.isfile,filehandlerone,"lfs.isfile")
- overload(lfs.isdir,filehandlerone,"lfs.isdir")
- overload(lfs.attributes,filehandlerone,"lfs.attributes")
- overload(lfs.dir,filehandlerone,"lfs.dir")
- overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
- overload(lfs.touch,filehandlerone,"lfs.touch")
- overload(lfs.link,filehandlertwo,"lfs.link")
- overload(lfs.setmode,filehandlerone,"lfs.setmode")
- overload(lfs.readlink,filehandlerone,"lfs.readlink")
- overload(lfs.shortname,filehandlerone,"lfs.shortname")
- overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
+ overload(lfs.chdir,filehandlerone,"lfs.chdir")
+ overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
+ overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
+ overload(lfs.isfile,filehandlerone,"lfs.isfile")
+ overload(lfs.isdir,filehandlerone,"lfs.isdir")
+ overload(lfs.attributes,filehandlerone,"lfs.attributes")
+ overload(lfs.dir,filehandlerone,"lfs.dir")
+ overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
+ overload(lfs.touch,filehandlerone,"lfs.touch")
+ overload(lfs.link,filehandlertwo,"lfs.link")
+ overload(lfs.setmode,filehandlerone,"lfs.setmode")
+ overload(lfs.readlink,filehandlerone,"lfs.readlink")
+ overload(lfs.shortname,filehandlerone,"lfs.shortname")
+ overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
end
if zip then
- zip.open=register(zip.open,filehandlerone,"zip.open")
+ zip.open=register(zip.open,filehandlerone,"zip.open")
end
if fontloader then
- fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
- fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
+ fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
+ fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
end
if epdf then
- epdf.open=register(epdf.open,filehandlerone,"epdf.open")
+ epdf.open=register(epdf.open,filehandlerone,"epdf.open")
end
sandbox.registerroot=registerroot
sandbox.registerbinary=registerbinary
@@ -14917,14 +14924,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-mrg"] = package.loaded["util-mrg"] or true
--- original size: 7757, stripped down to: 6015
+-- original size: 7819, stripped down to: 5881
if not modules then modules={} end modules ['util-mrg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local gsub,format=string.gsub,string.format
local concat=table.concat
@@ -14952,19 +14959,19 @@ local m_report=[[
]]
local m_preloaded=[[package.loaded[%q] = package.loaded[%q] or true]]
local function self_fake()
- return m_faked
+ return m_faked
end
local function self_nothing()
- return ""
+ return ""
end
local function self_load(name)
- local data=io.loaddata(name) or ""
- if data=="" then
- report("unknown file %a",name)
- else
- report("inserting file %a",name)
- end
- return data or ""
+ local data=io.loaddata(name) or ""
+ if data=="" then
+ report("unknown file %a",name)
+ else
+ report("inserting file %a",name)
+ end
+ return data or ""
end
local space=patterns.space
local eol=patterns.newline
@@ -14993,98 +15000,99 @@ local mandatespacing=(eol+space)^1/""
local pack=digit*space^1*operator4*optionalspacing+optionalspacing*operator1*optionalspacing+optionalspacing*operator2*optionalspaces+mandatespacing*operator3*mandatespaces+optionalspaces*separator*optionalspaces
local lines=emptyline^2/"\n"
local spaces=(space*space)/" "
+local spaces=(space*space*space*space)/" "
local compact=Cs ((
- ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
+ ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
)^1 )
local strip=Cs((emptyline^2/"\n"+1)^0)
local stripreturn=Cs((1-P("return")*space^1*P(1-space-eol)^1*(space+eol)^0*P(-1))^1)
function merger.compact(data)
- return lpegmatch(strip,lpegmatch(compact,data))
+ return lpegmatch(strip,lpegmatch(compact,data))
end
local function self_compact(data)
- local delta=0
- if merger.strip_comment then
- local before=#data
- data=lpegmatch(compact,data)
- data=lpegmatch(strip,data)
- local after=#data
- delta=before-after
- report("original size %s, compacted to %s, stripped %s",before,after,delta)
- data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
- end
- return lpegmatch(stripreturn,data) or data,delta
+ local delta=0
+ if merger.strip_comment then
+ local before=#data
+ data=lpegmatch(compact,data)
+ data=lpegmatch(strip,data)
+ local after=#data
+ delta=before-after
+ report("original size %s, compacted to %s, stripped %s",before,after,delta)
+ data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
+ end
+ return lpegmatch(stripreturn,data) or data,delta
end
local function self_save(name,data)
- if data~="" then
- io.savedata(name,data)
- report("saving %s with size %s",name,#data)
- end
+ if data~="" then
+ io.savedata(name,data)
+ report("saving %s with size %s",name,#data)
+ end
end
local function self_swap(data,code)
- return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
+ return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
end
local function self_libs(libs,list)
- local result,f,frozen,foundpath={},nil,false,nil
- result[#result+1]="\n"
- if type(libs)=='string' then libs={ libs } end
- if type(list)=='string' then list={ list } end
+ local result,f,frozen,foundpath={},nil,false,nil
+ result[#result+1]="\n"
+ if type(libs)=='string' then libs={ libs } end
+ if type(list)=='string' then list={ list } end
+ for i=1,#libs do
+ local lib=libs[i]
+ for j=1,#list do
+ local pth=gsub(list[j],"\\","/")
+ report("checking library path %a",pth)
+ local name=pth.."/"..lib
+ if lfs.isfile(name) then
+ foundpath=pth
+ end
+ end
+ if foundpath then break end
+ end
+ if foundpath then
+ report("using library path %a",foundpath)
+ local right,wrong,original,stripped={},{},0,0
for i=1,#libs do
- local lib=libs[i]
- for j=1,#list do
- local pth=gsub(list[j],"\\","/")
- report("checking library path %a",pth)
- local name=pth.."/"..lib
- if lfs.isfile(name) then
- foundpath=pth
- end
- end
- if foundpath then break end
- end
- if foundpath then
- report("using library path %a",foundpath)
- local right,wrong,original,stripped={},{},0,0
- for i=1,#libs do
- local lib=libs[i]
- local fullname=foundpath.."/"..lib
- if lfs.isfile(fullname) then
- report("using library %a",fullname)
- local preloaded=file.nameonly(lib)
- local data=io.loaddata(fullname,true)
- original=original+#data
- local data,delta=self_compact(data)
- right[#right+1]=lib
- result[#result+1]=m_begin_closure
- result[#result+1]=format(m_preloaded,preloaded,preloaded)
- result[#result+1]=data
- result[#result+1]=m_end_closure
- stripped=stripped+delta
- else
- report("skipping library %a",fullname)
- wrong[#wrong+1]=lib
- end
- end
- right=#right>0 and concat(right," ") or "-"
- wrong=#wrong>0 and concat(wrong," ") or "-"
- report("used libraries: %a",right)
- report("skipped libraries: %a",wrong)
- report("original bytes: %a",original)
- report("stripped bytes: %a",stripped)
- result[#result+1]=format(m_report,right,wrong,original,stripped)
- else
- report("no valid library path found")
+ local lib=libs[i]
+ local fullname=foundpath.."/"..lib
+ if lfs.isfile(fullname) then
+ report("using library %a",fullname)
+ local preloaded=file.nameonly(lib)
+ local data=io.loaddata(fullname,true)
+ original=original+#data
+ local data,delta=self_compact(data)
+ right[#right+1]=lib
+ result[#result+1]=m_begin_closure
+ result[#result+1]=format(m_preloaded,preloaded,preloaded)
+ result[#result+1]=data
+ result[#result+1]=m_end_closure
+ stripped=stripped+delta
+ else
+ report("skipping library %a",fullname)
+ wrong[#wrong+1]=lib
+ end
end
- return concat(result,"\n\n")
+ right=#right>0 and concat(right," ") or "-"
+ wrong=#wrong>0 and concat(wrong," ") or "-"
+ report("used libraries: %a",right)
+ report("skipped libraries: %a",wrong)
+ report("original bytes: %a",original)
+ report("stripped bytes: %a",stripped)
+ result[#result+1]=format(m_report,right,wrong,original,stripped)
+ else
+ report("no valid library path found")
+ end
+ return concat(result,"\n\n")
end
function merger.selfcreate(libs,list,target)
- if target then
- self_save(target,self_swap(self_fake(),self_libs(libs,list)))
- end
+ if target then
+ self_save(target,self_swap(self_fake(),self_libs(libs,list)))
+ end
end
function merger.selfmerge(name,libs,list,target)
- self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
+ self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
end
function merger.selfclean(name)
- self_save(name,self_swap(self_load(name),self_nothing()))
+ self_save(name,self_swap(self_load(name),self_nothing()))
end
@@ -15094,14 +15102,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-env"] = package.loaded["util-env"] or true
--- original size: 9634, stripped down to: 5673
+-- original size: 9634, stripped down to: 5360
if not modules then modules={} end modules ['util-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate,mark=utilities.storage.allocate,utilities.storage.mark
local format,sub,match,gsub,find=string.format,string.sub,string.match,string.gsub,string.find
@@ -15113,185 +15121,185 @@ local setlocale=os.setlocale
setlocale(nil,nil)
local report=logs.reporter("system")
function os.setlocale(a,b)
- if a or b then
- if report then
- report()
- report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
- report("now on are on your own and without support. Crashes or unexpected side effects")
- report("can happen but don't bother the luatex and context developer team with it.")
- report()
- report=nil
- end
- setlocale(a,b)
- end
+ if a or b then
+ if report then
+ report()
+ report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
+ report("now on are on your own and without support. Crashes or unexpected side effects")
+ report("can happen but don't bother the luatex and context developer team with it.")
+ report()
+ report=nil
+ end
+ setlocale(a,b)
+ end
end
local validengines=allocate {
- ["luatex"]=true,
- ["luajittex"]=true,
+ ["luatex"]=true,
+ ["luajittex"]=true,
}
local basicengines=allocate {
- ["luatex"]="luatex",
- ["texlua"]="luatex",
- ["texluac"]="luatex",
- ["luajittex"]="luajittex",
- ["texluajit"]="luajittex",
+ ["luatex"]="luatex",
+ ["texlua"]="luatex",
+ ["texluac"]="luatex",
+ ["luajittex"]="luajittex",
+ ["texluajit"]="luajittex",
}
local luaengines=allocate {
- ["lua"]=true,
- ["luajit"]=true,
+ ["lua"]=true,
+ ["luajit"]=true,
}
environment.validengines=validengines
environment.basicengines=basicengines
if not arg then
- environment.used_as_library=true
+ environment.used_as_library=true
elseif luaengines[file.removesuffix(arg[-1])] then
elseif validengines[file.removesuffix(arg[0])] then
- if arg[1]=="--luaonly" then
- arg[-1]=arg[0]
- arg[ 0]=arg[2]
- for k=3,#arg do
- arg[k-2]=arg[k]
- end
- remove(arg)
- remove(arg)
- else
- end
- local originalzero=file.basename(arg[0])
- local specialmapping={ luatools=="base" }
- if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
+ if arg[1]=="--luaonly" then
+ arg[-1]=arg[0]
+ arg[ 0]=arg[2]
+ for k=3,#arg do
+ arg[k-2]=arg[k]
+ end
+ remove(arg)
+ remove(arg)
+ else
+ end
+ local originalzero=file.basename(arg[0])
+ local specialmapping={ luatools=="base" }
+ if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
arg[0]=specialmapping[originalzero] or originalzero
insert(arg,0,"--script")
insert(arg,0,"mtxrun")
- end
+ end
end
environment.arguments=allocate()
environment.files=allocate()
environment.sortedflags=nil
function environment.initializearguments(arg)
- local arguments,files={},{}
- environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
- for index=1,#arg do
- local argument=arg[index]
- if index>0 then
- local flag,value=match(argument,"^%-+(.-)=(.-)$")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=unquoted(value or "")
- else
- flag=match(argument,"^%-+(.+)")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=true
- else
- files[#files+1]=argument
- end
- end
+ local arguments,files={},{}
+ environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
+ for index=1,#arg do
+ local argument=arg[index]
+ if index>0 then
+ local flag,value=match(argument,"^%-+(.-)=(.-)$")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=unquoted(value or "")
+ else
+ flag=match(argument,"^%-+(.+)")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=true
+ else
+ files[#files+1]=argument
end
+ end
end
- environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
+ end
+ environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
end
function environment.setargument(name,value)
- environment.arguments[name]=value
+ environment.arguments[name]=value
end
function environment.getargument(name,partial)
- local arguments,sortedflags=environment.arguments,environment.sortedflags
- if arguments[name] then
- return arguments[name]
- elseif partial then
- if not sortedflags then
- sortedflags=allocate(table.sortedkeys(arguments))
- for k=1,#sortedflags do
- sortedflags[k]="^"..sortedflags[k]
- end
- environment.sortedflags=sortedflags
- end
- for k=1,#sortedflags do
- local v=sortedflags[k]
- if find(name,v) then
- return arguments[sub(v,2,#v)]
- end
- end
+ local arguments,sortedflags=environment.arguments,environment.sortedflags
+ if arguments[name] then
+ return arguments[name]
+ elseif partial then
+ if not sortedflags then
+ sortedflags=allocate(table.sortedkeys(arguments))
+ for k=1,#sortedflags do
+ sortedflags[k]="^"..sortedflags[k]
+ end
+ environment.sortedflags=sortedflags
end
- return nil
+ for k=1,#sortedflags do
+ local v=sortedflags[k]
+ if find(name,v) then
+ return arguments[sub(v,2,#v)]
+ end
+ end
+ end
+ return nil
end
environment.argument=environment.getargument
function environment.splitarguments(separator)
- local done,before,after=false,{},{}
- local originalarguments=environment.originalarguments
- for k=1,#originalarguments do
- local v=originalarguments[k]
- if not done and v==separator then
- done=true
- elseif done then
- after[#after+1]=v
- else
- before[#before+1]=v
- end
+ local done,before,after=false,{},{}
+ local originalarguments=environment.originalarguments
+ for k=1,#originalarguments do
+ local v=originalarguments[k]
+ if not done and v==separator then
+ done=true
+ elseif done then
+ after[#after+1]=v
+ else
+ before[#before+1]=v
end
- return before,after
+ end
+ return before,after
end
function environment.reconstructcommandline(arg,noquote)
- local resolveprefix=resolvers.resolve
- arg=arg or environment.originalarguments
- if noquote and #arg==1 then
- return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
- elseif #arg>0 then
- local result={}
- for i=1,#arg do
- result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
- end
- return concat(result," ")
- else
- return ""
+ local resolveprefix=resolvers.resolve
+ arg=arg or environment.originalarguments
+ if noquote and #arg==1 then
+ return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
+ elseif #arg>0 then
+ local result={}
+ for i=1,#arg do
+ result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
end
+ return concat(result," ")
+ else
+ return ""
+ end
end
function environment.relativepath(path,root)
- if not path then
- path=""
+ if not path then
+ path=""
+ end
+ if not file.is_rootbased_path(path) then
+ if not root then
+ root=file.pathpart(environment.ownscript or environment.ownname or ".")
end
- if not file.is_rootbased_path(path) then
- if not root then
- root=file.pathpart(environment.ownscript or environment.ownname or ".")
- end
- if root=="" then
- root="."
- end
- path=root.."/"..path
+ if root=="" then
+ root="."
end
- return file.collapsepath(path,true)
+ path=root.."/"..path
+ end
+ return file.collapsepath(path,true)
end
if arg then
- local newarg,instring={},false
- for index=1,#arg do
- local argument=arg[index]
- if find(argument,"^\"") then
- if find(argument,"\"$") then
- newarg[#newarg+1]=gsub(argument,"^\"(.-)\"$","%1")
- instring=false
- else
- newarg[#newarg+1]=gsub(argument,"^\"","")
- instring=true
- end
- elseif find(argument,"\"$") then
- if instring then
- newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
- instring=false
- else
- newarg[#newarg+1]=argument
- end
- elseif instring then
- newarg[#newarg]=newarg[#newarg].." "..argument
- else
- newarg[#newarg+1]=argument
- end
- end
- for i=1,-5,-1 do
- newarg[i]=arg[i]
+ local newarg,instring={},false
+ for index=1,#arg do
+ local argument=arg[index]
+ if find(argument,"^\"") then
+ if find(argument,"\"$") then
+ newarg[#newarg+1]=gsub(argument,"^\"(.-)\"$","%1")
+ instring=false
+ else
+ newarg[#newarg+1]=gsub(argument,"^\"","")
+ instring=true
+ end
+ elseif find(argument,"\"$") then
+ if instring then
+ newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
+ instring=false
+ else
+ newarg[#newarg+1]=argument
+ end
+ elseif instring then
+ newarg[#newarg]=newarg[#newarg].." "..argument
+ else
+ newarg[#newarg+1]=argument
end
- environment.initializearguments(newarg)
- environment.originalarguments=mark(newarg)
- environment.rawarguments=mark(arg)
- arg={}
+ end
+ for i=1,-5,-1 do
+ newarg[i]=arg[i]
+ end
+ environment.initializearguments(newarg)
+ environment.originalarguments=mark(newarg)
+ environment.rawarguments=mark(arg)
+ arg={}
end
@@ -15301,18 +15309,18 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-env"] = package.loaded["luat-env"] or true
--- original size: 6134, stripped down to: 4402
+-- original size: 6134, stripped down to: 4118
if not modules then modules={} end modules ['luat-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local rawset,rawget,loadfile=rawset,rawget,loadfile
local gsub=string.gsub
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_lua=logs.reporter("resolvers","lua")
local luautilities=utilities.lua
local luasuffixes=luautilities.suffixes
@@ -15320,145 +15328,145 @@ local texgettoks=tex and tex.gettoks
environment=environment or {}
local environment=environment
local mt={
- __index=function(_,k)
- if k=="version" then
- local version=texgettoks and texgettoks("contextversiontoks")
- if version and version~="" then
- rawset(environment,"version",version)
- return version
- else
- return "unknown"
- end
- elseif k=="kind" then
- local kind=texgettoks and texgettoks("contextkindtoks")
- if kind and kind~="" then
- rawset(environment,"kind",kind)
- return kind
- else
- return "unknown"
- end
- elseif k=="jobname" or k=="formatname" then
- local name=tex and tex[k]
- if name or name=="" then
- rawset(environment,k,name)
- return name
- else
- return "unknown"
- end
- elseif k=="outputfilename" then
- local name=environment.jobname
- rawset(environment,k,name)
- return name
- end
+ __index=function(_,k)
+ if k=="version" then
+ local version=texgettoks and texgettoks("contextversiontoks")
+ if version and version~="" then
+ rawset(environment,"version",version)
+ return version
+ else
+ return "unknown"
+ end
+ elseif k=="kind" then
+ local kind=texgettoks and texgettoks("contextkindtoks")
+ if kind and kind~="" then
+ rawset(environment,"kind",kind)
+ return kind
+ else
+ return "unknown"
+ end
+ elseif k=="jobname" or k=="formatname" then
+ local name=tex and tex[k]
+ if name or name=="" then
+ rawset(environment,k,name)
+ return name
+ else
+ return "unknown"
+ end
+ elseif k=="outputfilename" then
+ local name=environment.jobname
+ rawset(environment,k,name)
+ return name
end
+ end
}
setmetatable(environment,mt)
function environment.texfile(filename)
- return resolvers.findfile(filename,'tex')
+ return resolvers.findfile(filename,'tex')
end
function environment.luafile(filename)
- local resolved=resolvers.findfile(filename,'tex') or ""
- if resolved~="" then
- return resolved
- end
- resolved=resolvers.findfile(filename,'texmfscripts') or ""
- if resolved~="" then
- return resolved
- end
- return resolvers.findfile(filename,'luatexlibs') or ""
-end
-local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
+ local resolved=resolvers.findfile(filename,'tex') or ""
+ if resolved~="" then
+ return resolved
+ end
+ resolved=resolvers.findfile(filename,'texmfscripts') or ""
+ if resolved~="" then
+ return resolved
+ end
+ return resolvers.findfile(filename,'luatexlibs') or ""
+end
+local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
local function strippable(filename)
- if stripindeed then
- local modu=modules[file.nameonly(filename)]
- return modu and modu.dataonly
- else
- return false
- end
+ if stripindeed then
+ local modu=modules[file.nameonly(filename)]
+ return modu and modu.dataonly
+ else
+ return false
+ end
end
function environment.luafilechunk(filename,silent,macros)
- filename=file.replacesuffix(filename,"lua")
- local fullname=environment.luafile(filename)
- if fullname and fullname~="" then
- local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
- if not silent then
- report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
- end
- return data
- else
- if not silent then
- report_lua("unknown file %a",filename)
- end
- return nil
+ filename=file.replacesuffix(filename,"lua")
+ local fullname=environment.luafile(filename)
+ if fullname and fullname~="" then
+ local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
+ if not silent then
+ report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
+ end
+ return data
+ else
+ if not silent then
+ report_lua("unknown file %a",filename)
end
+ return nil
+ end
end
function environment.loadluafile(filename,version)
- local lucname,luaname,chunk
- local basename=file.removesuffix(filename)
- if basename==filename then
- luaname=file.addsuffix(basename,luasuffixes.lua)
- lucname=file.addsuffix(basename,luasuffixes.luc)
- else
- luaname=filename
- lucname=nil
- end
- local fullname=(lucname and environment.luafile(lucname)) or ""
- if fullname~="" then
+ local lucname,luaname,chunk
+ local basename=file.removesuffix(filename)
+ if basename==filename then
+ luaname=file.addsuffix(basename,luasuffixes.lua)
+ lucname=file.addsuffix(basename,luasuffixes.luc)
+ else
+ luaname=filename
+ lucname=nil
+ end
+ local fullname=(lucname and environment.luafile(lucname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
+ end
+ chunk=loadfile(fullname)
+ end
+ if chunk then
+ chunk()
+ if version then
+ local v=version
+ if modules and modules[filename] then
+ v=modules[filename].version
+ elseif versions and versions[filename] then
+ v=versions[filename]
+ end
+ if v==version then
+ return true
+ else
if trace_locating then
- report_lua("loading %a",fullname)
+ report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
end
- chunk=loadfile(fullname)
+ environment.loadluafile(filename)
+ end
+ else
+ return true
end
- if chunk then
- chunk()
- if version then
- local v=version
- if modules and modules[filename] then
- v=modules[filename].version
- elseif versions and versions[filename] then
- v=versions[filename]
- end
- if v==version then
- return true
- else
- if trace_locating then
- report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
- end
- environment.loadluafile(filename)
- end
- else
- return true
- end
+ end
+ fullname=(luaname and environment.luafile(luaname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
end
- fullname=(luaname and environment.luafile(luaname)) or ""
- if fullname~="" then
- if trace_locating then
- report_lua("loading %a",fullname)
- end
- chunk=loadfile(fullname)
- if not chunk then
- if trace_locating then
- report_lua("unknown file %a",filename)
- end
- else
- chunk()
- return true
- end
+ chunk=loadfile(fullname)
+ if not chunk then
+ if trace_locating then
+ report_lua("unknown file %a",filename)
+ end
+ else
+ chunk()
+ return true
end
- return false
+ end
+ return false
end
environment.filenames=setmetatable({},{
- __index=function(t,k)
- local v=environment.files[k]
- if v then
- return (gsub(v,"%.+$",""))
- end
- end,
- __newindex=function(t,k)
- end,
- __len=function(t)
- return #environment.files
- end,
+ __index=function(t,k)
+ local v=environment.files[k]
+ if v then
+ return (gsub(v,"%.+$",""))
+ end
+ end,
+ __newindex=function(t,k)
+ end,
+ __len=function(t)
+ return #environment.files
+ end,
} )
@@ -15468,16 +15476,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true
--- original size: 60383, stripped down to: 38562
+-- original size: 60383, stripped down to: 35698
if not modules then modules={} end modules ['lxml-tab']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
+local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end
if lpeg.setmaxstack then lpeg.setmaxstack(1000) end
xml=xml or {}
@@ -15495,17 +15503,17 @@ xml.xmlns=xml.xmlns or {}
local check=P(false)
local parse=check
function xml.registerns(namespace,pattern)
- check=check+C(P(lower(pattern)))/namespace
- parse=P { P(check)+1*V(1) }
+ check=check+C(P(lower(pattern)))/namespace
+ parse=P { P(check)+1*V(1) }
end
function xml.checkns(namespace,url)
- local ns=lpegmatch(parse,lower(url))
- if ns and namespace~=ns then
- xml.xmlns[namespace]=ns
- end
+ local ns=lpegmatch(parse,lower(url))
+ if ns and namespace~=ns then
+ xml.xmlns[namespace]=ns
+ end
end
function xml.resolvens(url)
- return lpegmatch(parse,lower(url)) or ""
+ return lpegmatch(parse,lower(url)) or ""
end
end
local nsremap,resolvens=xml.xmlns,xml.resolvens
@@ -15523,661 +15531,661 @@ local handle_dec_entity
local handle_any_entity_dtd
local handle_any_entity_text
local function preparexmlstate(settings)
- if settings then
- linenumbers=settings.linenumbers
- stack={}
- level=0
- top={}
- at={}
- mt={}
- dt={}
- nt=0
- xmlns={}
- errorstr=nil
- strip=settings.strip_cm_and_dt
- utfize=settings.utfize_entities
- resolve=settings.resolve_entities
- resolve_predefined=settings.resolve_predefined_entities
- unify_predefined=settings.unify_predefined_entities
- cleanup=settings.text_cleanup
- entities=settings.entities or {}
- currentfilename=settings.currentresource
- currentline=1
- parameters={}
- reported_at_errors={}
- dcache={}
- hcache={}
- acache={}
- if utfize==nil then
- settings.utfize_entities=true
- utfize=true
- end
- if resolve_predefined==nil then
- settings.resolve_predefined_entities=true
- resolve_predefined=true
- end
- else
- linenumbers=false
- stack=nil
- level=nil
- top=nil
- at=nil
- mt=nil
- dt=nil
- nt=nil
- xmlns=nil
- errorstr=nil
- strip=nil
- utfize=nil
- resolve=nil
- resolve_predefined=nil
- unify_predefined=nil
- cleanup=nil
- entities=nil
- parameters=nil
- reported_at_errors=nil
- dcache=nil
- hcache=nil
- acache=nil
- currentfilename=nil
- currentline=1
- end
+ if settings then
+ linenumbers=settings.linenumbers
+ stack={}
+ level=0
+ top={}
+ at={}
+ mt={}
+ dt={}
+ nt=0
+ xmlns={}
+ errorstr=nil
+ strip=settings.strip_cm_and_dt
+ utfize=settings.utfize_entities
+ resolve=settings.resolve_entities
+ resolve_predefined=settings.resolve_predefined_entities
+ unify_predefined=settings.unify_predefined_entities
+ cleanup=settings.text_cleanup
+ entities=settings.entities or {}
+ currentfilename=settings.currentresource
+ currentline=1
+ parameters={}
+ reported_at_errors={}
+ dcache={}
+ hcache={}
+ acache={}
+ if utfize==nil then
+ settings.utfize_entities=true
+ utfize=true
+ end
+ if resolve_predefined==nil then
+ settings.resolve_predefined_entities=true
+ resolve_predefined=true
+ end
+ else
+ linenumbers=false
+ stack=nil
+ level=nil
+ top=nil
+ at=nil
+ mt=nil
+ dt=nil
+ nt=nil
+ xmlns=nil
+ errorstr=nil
+ strip=nil
+ utfize=nil
+ resolve=nil
+ resolve_predefined=nil
+ unify_predefined=nil
+ cleanup=nil
+ entities=nil
+ parameters=nil
+ reported_at_errors=nil
+ dcache=nil
+ hcache=nil
+ acache=nil
+ currentfilename=nil
+ currentline=1
+ end
end
local function initialize_mt(root)
- mt={ __index=root }
+ mt={ __index=root }
end
function xml.setproperty(root,k,v)
- getmetatable(root).__index[k]=v
+ getmetatable(root).__index[k]=v
end
function xml.checkerror(top,toclose)
- return ""
+ return ""
end
local checkns=xml.checkns
local function add_attribute(namespace,tag,value)
- if cleanup and value~="" then
- value=cleanup(value)
- end
- if tag=="xmlns" then
- xmlns[#xmlns+1]=resolvens(value)
- at[tag]=value
- elseif namespace=="" then
- at[tag]=value
- elseif namespace=="xmlns" then
- checkns(tag,value)
- at["xmlns:"..tag]=value
- else
- at[namespace..":"..tag]=value
- end
+ if cleanup and value~="" then
+ value=cleanup(value)
+ end
+ if tag=="xmlns" then
+ xmlns[#xmlns+1]=resolvens(value)
+ at[tag]=value
+ elseif namespace=="" then
+ at[tag]=value
+ elseif namespace=="xmlns" then
+ checkns(tag,value)
+ at["xmlns:"..tag]=value
+ else
+ at[namespace..":"..tag]=value
+ end
end
local function add_empty(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- top=stack[level]
- dt=top.dt
- nt=#dt+1
- local t=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- cf=currentfilename,
- cl=currentline,
- __p__=top,
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- __p__=top,
- }
- dt[nt]=t
- setmetatable(t,mt)
- if at.xmlns then
- remove(xmlns)
- end
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ top=stack[level]
+ dt=top.dt
+ nt=#dt+1
+ local t=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=top,
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ __p__=top,
+ }
+ dt[nt]=t
+ setmetatable(t,mt)
+ if at.xmlns then
+ remove(xmlns)
+ end
+ at={}
end
local function add_begin(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- dt={}
- top=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- cf=currentfilename,
- cl=currentline,
- __p__=stack[level],
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- __p__=stack[level],
- }
- setmetatable(top,mt)
- nt=0
- level=level+1
- stack[level]=top
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ dt={}
+ top=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=stack[level],
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ __p__=stack[level],
+ }
+ setmetatable(top,mt)
+ nt=0
+ level=level+1
+ stack[level]=top
+ at={}
end
local function add_end(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local toclose=stack[level]
- level=level-1
- top=stack[level]
- if level<1 then
- errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- elseif toclose.tg~=tag then
- errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- end
- dt=top.dt
- nt=#dt+1
- dt[nt]=toclose
- toclose.ni=nt
- if toclose.at.xmlns then
- remove(xmlns)
- end
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local toclose=stack[level]
+ level=level-1
+ top=stack[level]
+ if level<1 then
+ errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ elseif toclose.tg~=tag then
+ errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ end
+ dt=top.dt
+ nt=#dt+1
+ dt[nt]=toclose
+ toclose.ni=nt
+ if toclose.at.xmlns then
+ remove(xmlns)
+ end
end
local function add_text(text)
- if text=="" then
- return
- end
- if cleanup then
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..cleanup(text)
- else
- nt=nt+1
- dt[nt]=cleanup(text)
- end
- else
- nt=1
- dt[1]=cleanup(text)
- end
+ if text=="" then
+ return
+ end
+ if cleanup then
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..cleanup(text)
+ else
+ nt=nt+1
+ dt[nt]=cleanup(text)
+ end
else
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..text
- else
- nt=nt+1
- dt[nt]=text
- end
- else
- nt=1
- dt[1]=text
- end
+ nt=1
+ dt[1]=cleanup(text)
end
-end
-local function add_special(what,spacing,text)
- if spacing~="" then
+ else
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..text
+ else
nt=nt+1
- dt[nt]=spacing
- end
- if strip and (what=="@cm@" or what=="@dt@") then
+ dt[nt]=text
+ end
else
- nt=nt+1
- dt[nt]=linenumbers and {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- cf=currentfilename,
- cl=currentline,
- } or {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- }
+ nt=1
+ dt[1]=text
end
+ end
+end
+local function add_special(what,spacing,text)
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ if strip and (what=="@cm@" or what=="@dt@") then
+ else
+ nt=nt+1
+ dt[nt]=linenumbers and {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ cf=currentfilename,
+ cl=currentline,
+ } or {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ }
+ end
end
local function set_message(txt)
- errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
+ errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
end
local function attribute_value_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute value %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute value %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
local function attribute_specification_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute specification %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute specification %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
do
- local badentity="&"
- xml.placeholders={
- unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
- unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
- unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
- }
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return utfchar(n)
- else
- return formatters["h:%s"](s),true
+ local badentity="&"
+ xml.placeholders={
+ unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
+ unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
+ unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
+ }
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local p_rest=(1-P(";"))^0
+ local p_many=P(1)^0
+ local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
+ xml.parsedentitylpeg=parsedentity
+ local predefined_unified={
+ [38]="&amp;",
+ [42]="&quot;",
+ [47]="&apos;",
+ [74]="&lt;",
+ [76]="&gt;",
+ }
+ local predefined_simplified={
+ [38]="&",amp="&",
+ [42]='"',quot='"',
+ [47]="'",apos="'",
+ [74]="<",lt="<",
+ [76]=">",gt=">",
+ }
+ local nofprivates=0xF0000
+ local privates_u={
+ [ [[&]] ]="&amp;",
+ [ [["]] ]="&quot;",
+ [ [[']] ]="&apos;",
+ [ [[<]] ]="&lt;",
+ [ [[>]] ]="&gt;",
+ }
+ local privates_p={
+ }
+ local privates_s={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[&]] ]="&U+26;",
+ [ [[']] ]="&U+27;",
+ [ [[<]] ]="&U+3C;",
+ [ [[>]] ]="&U+3E;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_x={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[']] ]="&U+27;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_n={
+ }
+ local escaped=utf.remapper(privates_u,"dynamic")
+ local unprivatized=utf.remapper(privates_p,"dynamic")
+ local unspecialized=utf.remapper(privates_s,"dynamic")
+ local despecialized=utf.remapper(privates_x,"dynamic")
+ xml.unprivatized=unprivatized
+ xml.unspecialized=unspecialized
+ xml.despecialized=despecialized
+ xml.escaped=escaped
+ local function unescaped(s)
+ local p=privates_n[s]
+ if not p then
+ nofprivates=nofprivates+1
+ p=utfchar(nofprivates)
+ privates_n[s]=p
+ s="&"..s..";"
+ privates_u[p]=s
+ privates_p[p]=s
+ privates_s[p]=s
+ end
+ return p
+ end
+ xml.privatetoken=unescaped
+ xml.privatecodes=privates_n
+ xml.specialcodes=privates_s
+ function xml.addspecialcode(key,value)
+ privates_s[key]=value or "&"..s..";"
+ end
+ handle_hex_entity=function(str)
+ local h=hcache[str]
+ if not h then
+ local n=tonumber(str,16)
+ h=unify_predefined and predefined_unified[n]
+ if h then
+ if trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+ end
+ elseif utfize then
+ h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring hex entity &#x%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
end
+ else
+ if trace_entities then
+ report_xml("found entity &#x%s;",str)
+ end
+ h="&#x"..str..";"
+ end
+ hcache[str]=h
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return utfchar(n)
- else
- return formatters["d:%s"](s),true
- end
- end
- local p_rest=(1-P(";"))^0
- local p_many=P(1)^0
- local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
- xml.parsedentitylpeg=parsedentity
- local predefined_unified={
- [38]="&amp;",
- [42]="&quot;",
- [47]="&apos;",
- [74]="&lt;",
- [76]="&gt;",
- }
- local predefined_simplified={
- [38]="&",amp="&",
- [42]='"',quot='"',
- [47]="'",apos="'",
- [74]="<",lt="<",
- [76]=">",gt=">",
- }
- local nofprivates=0xF0000
- local privates_u={
- [ [[&]] ]="&amp;",
- [ [["]] ]="&quot;",
- [ [[']] ]="&apos;",
- [ [[<]] ]="&lt;",
- [ [[>]] ]="&gt;",
- }
- local privates_p={
- }
- local privates_s={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[&]] ]="&U+26;",
- [ [[']] ]="&U+27;",
- [ [[<]] ]="&U+3C;",
- [ [[>]] ]="&U+3E;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_x={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[']] ]="&U+27;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_n={
- }
- local escaped=utf.remapper(privates_u,"dynamic")
- local unprivatized=utf.remapper(privates_p,"dynamic")
- local unspecialized=utf.remapper(privates_s,"dynamic")
- local despecialized=utf.remapper(privates_x,"dynamic")
- xml.unprivatized=unprivatized
- xml.unspecialized=unspecialized
- xml.despecialized=despecialized
- xml.escaped=escaped
- local function unescaped(s)
- local p=privates_n[s]
- if not p then
- nofprivates=nofprivates+1
- p=utfchar(nofprivates)
- privates_n[s]=p
- s="&"..s..";"
- privates_u[p]=s
- privates_p[p]=s
- privates_s[p]=s
- end
- return p
- end
- xml.privatetoken=unescaped
- xml.privatecodes=privates_n
- xml.specialcodes=privates_s
- function xml.addspecialcode(key,value)
- privates_s[key]=value or "&"..s..";"
- end
- handle_hex_entity=function(str)
- local h=hcache[str]
- if not h then
- local n=tonumber(str,16)
- h=unify_predefined and predefined_unified[n]
- if h then
- if trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- elseif utfize then
- h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring hex entity &#x%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- else
- if trace_entities then
- report_xml("found entity &#x%s;",str)
- end
- h="&#x"..str..";"
- end
- hcache[str]=h
- end
- return h
- end
- handle_dec_entity=function(str)
- local d=dcache[str]
- if not d then
- local n=tonumber(str)
- d=unify_predefined and predefined_unified[n]
- if d then
- if trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- elseif utfize then
- d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring dec entity &#%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- else
- if trace_entities then
- report_xml("found entity &#%s;",str)
- end
- d="&#"..str..";"
- end
- dcache[str]=d
+ return h
+ end
+ handle_dec_entity=function(str)
+ local d=dcache[str]
+ if not d then
+ local n=tonumber(str)
+ d=unify_predefined and predefined_unified[n]
+ if d then
+ if trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ elseif utfize then
+ d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring dec entity &#%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ else
+ if trace_entities then
+ report_xml("found entity &#%s;",str)
end
- return d
+ d="&#"..str..";"
+ end
+ dcache[str]=d
end
- handle_any_entity_dtd=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
- end
- return a
+ return d
+ end
+ handle_any_entity_dtd=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
- end
- return a
+ a=entities[str]
end
- end
- handle_any_entity_text=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(grammar_parsed_text_two,a) or a
- if type(a)=="number" then
- return ""
- else
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- end
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
end
- return a
+ a=a(str) or ""
+ end
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
end
- return a
- end
- end
- local p_rest=(1-P(";"))^1
- local spec={
- [0x23]="\\Ux{23}",
- [0x24]="\\Ux{24}",
- [0x25]="\\Ux{25}",
- [0x5C]="\\Ux{5C}",
- [0x7B]="\\Ux{7B}",
- [0x7C]="\\Ux{7C}",
- [0x7D]="\\Ux{7D}",
- [0x7E]="\\Ux{7E}",
- }
- local hash=table.setmetatableindex(spec,function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
- else
- return formatters["u:%s"](s),true
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
- end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
+ end
+ return a
+ end
+ end
+ handle_any_entity_text=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- return formatters["d:%s"](s),true
+ a=entities[str]
end
- end
- local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- local hash=table.setmetatableindex(function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
+ end
+ a=a(str) or ""
+ end
+ a=lpegmatch(grammar_parsed_text_two,a) or a
+ if type(a)=="number" then
+ return ""
+ else
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
+ end
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- return formatters["u:%s"](s),true
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
+ end
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
+ end
+ return a
+ end
+ end
+ local p_rest=(1-P(";"))^1
+ local spec={
+ [0x23]="\\Ux{23}",
+ [0x24]="\\Ux{24}",
+ [0x25]="\\Ux{25}",
+ [0x5C]="\\Ux{5C}",
+ [0x7B]="\\Ux{7B}",
+ [0x7C]="\\Ux{7C}",
+ [0x7D]="\\Ux{7D}",
+ [0x7E]="\\Ux{7E}",
+ }
+ local hash=table.setmetatableindex(spec,function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
- else
- return formatters["d:%s"](s),true
- end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ local hash=table.setmetatableindex(function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
+ end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
end
- local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- xml.reparsedentitylpeg=reparsedentity
- xml.unescapedentitylpeg=unescapedentity
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ xml.reparsedentitylpeg=reparsedentity
+ xml.unescapedentitylpeg=unescapedentity
end
local escaped=xml.escaped
local unescaped=xml.unescaped
local placeholders=xml.placeholders
local function handle_end_entity(str)
- report_xml("error in entity, %a found without ending %a",str,";")
- return str
+ report_xml("error in entity, %a found without ending %a",str,";")
+ return str
end
local function handle_crap_error(chr)
- report_xml("error in parsing, unexpected %a found ",chr)
- add_text(chr)
- return chr
+ report_xml("error in parsing, unexpected %a found ",chr)
+ add_text(chr)
+ return chr
end
local function handlenewline()
- currentline=currentline+1
+ currentline=currentline+1
end
local spacetab=S(' \t')
local space=S(' \r\n\t')
@@ -16202,141 +16210,141 @@ local space_nl=spacetab+newline
local spacing_nl=Cs((space_nl)^0)
local anything_nl=newline+P(1)
local function weirdentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","weird",k,v)
- end
- parameters[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","weird",k,v)
+ end
+ parameters[k]=v
end
local function normalentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","normal",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","normal",k,v)
+ end
+ entities[k]=v
end
local function systementity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","system",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","system",k,v)
+ end
+ entities[k]=v
end
local function publicentity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","public",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","public",k,v)
+ end
+ entities[k]=v
end
local function entityfile(pattern,k,v,n)
- if n then
- local okay,data
- if resolvers then
- okay,data=resolvers.loadbinfile(n)
- else
- data=io.loaddata(n)
- okay=data and data~=""
- end
- if okay then
- if trace_entities then
- report_xml("loading public entities %a as %a from %a",k,v,n)
- end
- lpegmatch(pattern,data)
- return
- end
+ if n then
+ local okay,data
+ if resolvers then
+ okay,data=resolvers.loadbinfile(n)
+ else
+ data=io.loaddata(n)
+ okay=data and data~=""
end
- report_xml("ignoring public entities %a as %a from %a",k,v,n)
+ if okay then
+ if trace_entities then
+ report_xml("loading public entities %a as %a from %a",k,v,n)
+ end
+ lpegmatch(pattern,data)
+ return
+ end
+ end
+ report_xml("ignoring public entities %a as %a from %a",k,v,n)
end
local function install(spacenewline,spacing,anything)
- local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
- local hexentitycontent=R("AF","af","09")^1
- local decentitycontent=R("09")^1
- local parsedentity=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_dtd)
- local parsedentity_text=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_text)
- local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local text_unparsed=Cs((anything-open)^1)
- local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
- local somespace=(spacenewline)^1
- local optionalspace=(spacenewline)^0
- local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
- local endofattributes=slash*close+close
- local whatever=space*name*optionalspace*equal
- local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
- local attributevalue=value+wrongvalue
- local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
- local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
- local parsedtext=text_parsed
- local unparsedtext=text_unparsed/add_text
- local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
- local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
- local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
- local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
- local begincomment=open*P("!--")
- local endcomment=P("--")*close
- local begininstruction=open*P("?")
- local endinstruction=P("?")*close
- local begincdata=open*P("![CDATA[")
- local endcdata=P("]]")*close
- local someinstruction=C((anything-endinstruction)^0)
- local somecomment=C((anything-endcomment )^0)
- local somecdata=C((anything-endcdata )^0)
- local begindoctype=open*P("!DOCTYPE")
- local enddoctype=close
- local beginset=P("[")
- local endset=P("]")
- local wrdtypename=C((anything-somespace-P(";"))^1)
- local doctypename=C((anything-somespace-close)^0)
- local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
- local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
- local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
- local normalentitytype=(doctypename*somespace*value)/normalentity
- local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
- local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
- local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
- local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
- entityfile(entitydoctype,...)
- end
- local function weirdresolve(s)
- lpegmatch(entitydoctype,parameters[s])
- end
- local function normalresolve(s)
- lpegmatch(entitydoctype,entities[s])
- end
- local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
- entitydoctype=entitydoctype+entityresolve
- local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
- local definitiondoctype=doctypename*somespace*doctypeset
- local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
- local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
- local simpledoctype=(anything-close)^1
- local somedoctype=C((somespace*(
+ local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
+ local hexentitycontent=R("AF","af","09")^1
+ local decentitycontent=R("09")^1
+ local parsedentity=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_dtd)
+ local parsedentity_text=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_text)
+ local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local text_unparsed=Cs((anything-open)^1)
+ local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
+ local somespace=(spacenewline)^1
+ local optionalspace=(spacenewline)^0
+ local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
+ local endofattributes=slash*close+close
+ local whatever=space*name*optionalspace*equal
+ local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
+ local attributevalue=value+wrongvalue
+ local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
+ local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
+ local parsedtext=text_parsed
+ local unparsedtext=text_unparsed/add_text
+ local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
+ local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
+ local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
+ local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
+ local begincomment=open*P("!--")
+ local endcomment=P("--")*close
+ local begininstruction=open*P("?")
+ local endinstruction=P("?")*close
+ local begincdata=open*P("![CDATA[")
+ local endcdata=P("]]")*close
+ local someinstruction=C((anything-endinstruction)^0)
+ local somecomment=C((anything-endcomment )^0)
+ local somecdata=C((anything-endcdata )^0)
+ local begindoctype=open*P("!DOCTYPE")
+ local enddoctype=close
+ local beginset=P("[")
+ local endset=P("]")
+ local wrdtypename=C((anything-somespace-P(";"))^1)
+ local doctypename=C((anything-somespace-close)^0)
+ local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
+ local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
+ local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
+ local normalentitytype=(doctypename*somespace*value)/normalentity
+ local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
+ local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
+ local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
+ local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
+ entityfile(entitydoctype,...)
+ end
+ local function weirdresolve(s)
+ lpegmatch(entitydoctype,parameters[s])
+ end
+ local function normalresolve(s)
+ lpegmatch(entitydoctype,entities[s])
+ end
+ local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
+ entitydoctype=entitydoctype+entityresolve
+ local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
+ local definitiondoctype=doctypename*somespace*doctypeset
+ local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
+ local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
+ local simpledoctype=(anything-close)^1
+ local somedoctype=C((somespace*(
publicentityfile+publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0)
- local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
- local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
- local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
- local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
- local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
- local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
- local trailer=space^0*(text_unparsed/set_message)^0
- local grammar_parsed_text_one=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
- }
- local grammar_parsed_text_two=P { "followup",
- followup=V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
- }
- local grammar_unparsed_text=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
- }
- return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
+ local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
+ local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
+ local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
+ local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
+ local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
+ local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
+ local trailer=space^0*(text_unparsed/set_message)^0
+ local grammar_parsed_text_one=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
+ }
+ local grammar_parsed_text_two=P { "followup",
+ followup=V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
+ }
+ local grammar_unparsed_text=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
+ }
+ return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
end
grammar_parsed_text_one_nop,
grammar_parsed_text_two_nop,
@@ -16345,576 +16353,576 @@ grammar_parsed_text_one_yes,
grammar_parsed_text_two_yes,
grammar_unparsed_text_yes=install(space_nl,spacing_nl,anything_nl)
local function _xmlconvert_(data,settings,detail)
- settings=settings or {}
- preparexmlstate(settings)
- if settings.linenumbers then
- grammar_parsed_text_one=grammar_parsed_text_one_yes
- grammar_parsed_text_two=grammar_parsed_text_two_yes
- grammar_unparsed_text=grammar_unparsed_text_yes
- else
- grammar_parsed_text_one=grammar_parsed_text_one_nop
- grammar_parsed_text_two=grammar_parsed_text_two_nop
- grammar_unparsed_text=grammar_unparsed_text_nop
- end
- local preprocessor=settings.preprocessor
- if data and data~="" and type(preprocessor)=="function" then
- data=preprocessor(data,settings) or data
+ settings=settings or {}
+ preparexmlstate(settings)
+ if settings.linenumbers then
+ grammar_parsed_text_one=grammar_parsed_text_one_yes
+ grammar_parsed_text_two=grammar_parsed_text_two_yes
+ grammar_unparsed_text=grammar_unparsed_text_yes
+ else
+ grammar_parsed_text_one=grammar_parsed_text_one_nop
+ grammar_parsed_text_two=grammar_parsed_text_two_nop
+ grammar_unparsed_text=grammar_unparsed_text_nop
+ end
+ local preprocessor=settings.preprocessor
+ if data and data~="" and type(preprocessor)=="function" then
+ data=preprocessor(data,settings) or data
+ end
+ if settings.parent_root then
+ mt=getmetatable(settings.parent_root)
+ else
+ initialize_mt(top)
+ end
+ level=level+1
+ stack[level]=top
+ top.dt={}
+ dt=top.dt
+ nt=0
+ if not data or data=="" then
+ errorstr="empty xml file"
+ elseif data==true then
+ errorstr=detail or "problematic xml file"
+ elseif utfize or resolve then
+ local m=lpegmatch(grammar_parsed_text_one,data)
+ if m then
+ m=lpegmatch(grammar_parsed_text_two,data,m)
end
- if settings.parent_root then
- mt=getmetatable(settings.parent_root)
- else
- initialize_mt(top)
- end
- level=level+1
- stack[level]=top
- top.dt={}
- dt=top.dt
- nt=0
- if not data or data=="" then
- errorstr="empty xml file"
- elseif data==true then
- errorstr=detail or "problematic xml file"
- elseif utfize or resolve then
- local m=lpegmatch(grammar_parsed_text_one,data)
- if m then
- m=lpegmatch(grammar_parsed_text_two,data,m)
- end
- if m then
- else
- errorstr="invalid xml file - parsed text"
- end
- elseif type(data)=="string" then
- if lpegmatch(grammar_unparsed_text,data) then
- errorstr=""
- else
- errorstr="invalid xml file - unparsed text"
- end
+ if m then
else
- errorstr="invalid xml file - no text at all"
- end
- local result
- if errorstr and errorstr~="" then
- result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
- setmetatable(result,mt)
- setmetatable(result.dt[1],mt)
- setmetatable(stack,mt)
- local errorhandler=settings.error_handler
- if errorhandler==false then
+ errorstr="invalid xml file - parsed text"
+ end
+ elseif type(data)=="string" then
+ if lpegmatch(grammar_unparsed_text,data) then
+ errorstr=""
+ else
+ errorstr="invalid xml file - unparsed text"
+ end
+ else
+ errorstr="invalid xml file - no text at all"
+ end
+ local result
+ if errorstr and errorstr~="" then
+ result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
+ setmetatable(result,mt)
+ setmetatable(result.dt[1],mt)
+ setmetatable(stack,mt)
+ local errorhandler=settings.error_handler
+ if errorhandler==false then
+ else
+ errorhandler=errorhandler or xml.errorhandler
+ if errorhandler then
+ local currentresource=settings.currentresource
+ if currentresource and currentresource~="" then
+ xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
else
- errorhandler=errorhandler or xml.errorhandler
- if errorhandler then
- local currentresource=settings.currentresource
- if currentresource and currentresource~="" then
- xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
- else
- xml.errorhandler(formatters["load error: %s"](errorstr))
- end
- end
- end
- else
- result=stack[1]
- end
- if not settings.no_root then
- result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
- setmetatable(result,mt)
- local rdt=result.dt
- for k=1,#rdt do
- local v=rdt[k]
- if type(v)=="table" and not v.special then
- result.ri=k
- v.__p__=result
- break
- end
+ xml.errorhandler(formatters["load error: %s"](errorstr))
end
+ end
end
- if errorstr and errorstr~="" then
- result.error=true
- else
- errorstr=nil
- end
- result.statistics={
- errormessage=errorstr,
- entities={
- decimals=dcache,
- hexadecimals=hcache,
- names=acache,
- intermediates=parameters,
- }
+ else
+ result=stack[1]
+ end
+ if not settings.no_root then
+ result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
+ setmetatable(result,mt)
+ local rdt=result.dt
+ for k=1,#rdt do
+ local v=rdt[k]
+ if type(v)=="table" and not v.special then
+ result.ri=k
+ v.__p__=result
+ break
+ end
+ end
+ end
+ if errorstr and errorstr~="" then
+ result.error=true
+ else
+ errorstr=nil
+ end
+ result.statistics={
+ errormessage=errorstr,
+ entities={
+ decimals=dcache,
+ hexadecimals=hcache,
+ names=acache,
+ intermediates=parameters,
}
- preparexmlstate()
- return result
+ }
+ preparexmlstate()
+ return result
end
local function xmlconvert(data,settings)
- local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
- if ok then
- return result
- elseif type(result)=="string" then
- return _xmlconvert_(true,settings,result)
- else
- return _xmlconvert_(true,settings)
- end
+ local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
+ if ok then
+ return result
+ elseif type(result)=="string" then
+ return _xmlconvert_(true,settings,result)
+ else
+ return _xmlconvert_(true,settings)
+ end
end
xml.convert=xmlconvert
function xml.inheritedconvert(data,xmldata)
- local settings=xmldata.settings
- if settings then
- settings.parent_root=xmldata
- end
- local xc=xmlconvert(data,settings)
- return xc
+ local settings=xmldata.settings
+ if settings then
+ settings.parent_root=xmldata
+ end
+ local xc=xmlconvert(data,settings)
+ return xc
end
function xml.is_valid(root)
- return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
+ return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
end
function xml.package(tag,attributes,data)
- local ns,tg=match(tag,"^(.-):?([^:]+)$")
- local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
- setmetatable(t,mt)
- return t
+ local ns,tg=match(tag,"^(.-):?([^:]+)$")
+ local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
+ setmetatable(t,mt)
+ return t
end
function xml.is_valid(root)
- return root and not root.error
+ return root and not root.error
end
xml.errorhandler=report_xml
function xml.load(filename,settings)
- local data=""
- if type(filename)=="string" then
- local f=io.open(filename,'r')
- if f then
- data=f:read("*all")
- f:close()
- end
- elseif filename then
- data=filename:read("*all")
- end
- if settings then
- settings.currentresource=filename
- local result=xmlconvert(data,settings)
- settings.currentresource=nil
- return result
- else
- return xmlconvert(data,{ currentresource=filename })
- end
+ local data=""
+ if type(filename)=="string" then
+ local f=io.open(filename,'r')
+ if f then
+ data=f:read("*all")
+ f:close()
+ end
+ elseif filename then
+ data=filename:read("*all")
+ end
+ if settings then
+ settings.currentresource=filename
+ local result=xmlconvert(data,settings)
+ settings.currentresource=nil
+ return result
+ else
+ return xmlconvert(data,{ currentresource=filename })
+ end
end
local no_root={ no_root=true }
function xml.toxml(data)
- if type(data)=="string" then
- local root={ xmlconvert(data,no_root) }
- return (#root>1 and root) or root[1]
- else
- return data
- end
+ if type(data)=="string" then
+ local root={ xmlconvert(data,no_root) }
+ return (#root>1 and root) or root[1]
+ else
+ return data
+ end
end
local function copy(old,p)
- if old then
- local new={}
- for k,v in next,old do
- local t=type(v)=="table"
- if k=="at" then
- local t={}
- for k,v in next,v do
- t[k]=v
- end
- new[k]=t
- elseif k=="dt" then
- v.__p__=nil
- v=copy(v,new)
- new[k]=v
- v.__p__=p
- else
- new[k]=v
- end
- end
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ local t=type(v)=="table"
+ if k=="at" then
+ local t={}
+ for k,v in next,v do
+ t[k]=v
+ end
+ new[k]=t
+ elseif k=="dt" then
+ v.__p__=nil
+ v=copy(v,new)
+ new[k]=v
+ v.__p__=p
+ else
+ new[k]=v
+ end
+ end
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
end
+ return new
+ else
+ return {}
+ end
end
xml.copy=copy
function xml.checkbom(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@" and find(v.dt[1],"xml.*version=") then
- return
- end
- end
- insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
- insert(dt,2,"\n" )
+ 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@" and find(v.dt[1],"xml.*version=") then
+ return
+ end
end
+ insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
+ insert(dt,2,"\n" )
+ end
end
local f_attribute=formatters['%s=%q']
local function verbose_element(e,handlers,escape)
- local handle=handlers.handle
- local serialize=handlers.serialize
- local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
- local ats=eat and next(eat) and {}
- if ats then
- local n=0
- for k in next,eat do
- n=n+1
- ats[n]=k
- end
- if n==1 then
- local k=ats[1]
- ats=f_attribute(k,escaped(eat[k]))
- else
- sort(ats)
- for i=1,n do
- local k=ats[i]
- ats[i]=f_attribute(k,escaped(eat[k]))
- end
- ats=concat(ats," ")
- end
- end
- if ern and trace_entities and ern~=ens then
- ens=ern
+ local handle=handlers.handle
+ local serialize=handlers.serialize
+ local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
+ local ats=eat and next(eat) and {}
+ if ats then
+ local n=0
+ for k in next,eat do
+ n=n+1
+ ats[n]=k
end
- local n=edt and #edt
- if ens~="" then
- if n and n>0 then
- if ats then
- handle("<",ens,":",etg," ",ats,">")
- else
- handle("<",ens,":",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",ens,":",etg,">")
+ if n==1 then
+ local k=ats[1]
+ ats=f_attribute(k,escaped(eat[k]))
+ else
+ sort(ats)
+ for i=1,n do
+ local k=ats[i]
+ ats[i]=f_attribute(k,escaped(eat[k]))
+ end
+ ats=concat(ats," ")
+ end
+ end
+ if ern and trace_entities and ern~=ens then
+ ens=ern
+ end
+ local n=edt and #edt
+ if ens~="" then
+ if n and n>0 then
+ if ats then
+ handle("<",ens,":",etg," ",ats,">")
+ else
+ handle("<",ens,":",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",ens,":",etg," ",ats,"/>")
- else
- handle("<",ens,":",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",ens,":",etg,">")
else
- if n and n>0 then
- if ats then
- handle("<",etg," ",ats,">")
- else
- handle("<",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",etg,">")
+ if ats then
+ handle("<",ens,":",etg," ",ats,"/>")
+ else
+ handle("<",ens,":",etg,"/>")
+ end
+ end
+ else
+ if n and n>0 then
+ if ats then
+ handle("<",etg," ",ats,">")
+ else
+ handle("<",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",etg," ",ats,"/>")
- else
- handle("<",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",etg,">")
+ else
+ if ats then
+ handle("<",etg," ",ats,"/>")
+ else
+ handle("<",etg,"/>")
+ end
end
+ end
end
local function verbose_pi(e,handlers)
- handlers.handle("<?",e.dt[1],"?>")
+ handlers.handle("<?",e.dt[1],"?>")
end
local function verbose_comment(e,handlers)
- handlers.handle("<!--",e.dt[1],"-->")
+ handlers.handle("<!--",e.dt[1],"-->")
end
local function verbose_cdata(e,handlers)
- handlers.handle("<![CDATA[",e.dt[1],"]]>")
+ handlers.handle("<![CDATA[",e.dt[1],"]]>")
end
local function verbose_doctype(e,handlers)
- handlers.handle("<!DOCTYPE",e.dt[1],">")
+ handlers.handle("<!DOCTYPE",e.dt[1],">")
end
local function verbose_root(e,handlers)
- handlers.serialize(e.dt,handlers)
+ handlers.serialize(e.dt,handlers)
end
local function verbose_text(e,handlers)
- handlers.handle(escaped(e))
+ handlers.handle(escaped(e))
end
local function verbose_document(e,handlers)
- local serialize=handlers.serialize
- local functions=handlers.functions
- for i=1,#e do
- local ei=e[i]
- if type(ei)=="string" then
- functions["@tx@"](ei,handlers)
- else
- serialize(ei,handlers)
- end
+ local serialize=handlers.serialize
+ local functions=handlers.functions
+ for i=1,#e do
+ local ei=e[i]
+ if type(ei)=="string" then
+ functions["@tx@"](ei,handlers)
+ else
+ serialize(ei,handlers)
end
+ end
end
local function serialize(e,handlers,...)
- if e then
- local initialize=handlers.initialize
- local finalize=handlers.finalize
- local functions=handlers.functions
- if initialize then
- local state=initialize(...)
- if not state==true then
- return state
- end
- end
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
- if finalize then
- return finalize()
- end
+ if e then
+ local initialize=handlers.initialize
+ local finalize=handlers.finalize
+ local functions=handlers.functions
+ if initialize then
+ local state=initialize(...)
+ if not state==true then
+ return state
+ end
+ end
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
end
+ if finalize then
+ return finalize()
+ end
+ end
end
local function xserialize(e,handlers)
- if e then
- local functions=handlers.functions
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
+ if e then
+ local functions=handlers.functions
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
end
+ end
end
local handlers={}
local function newhandlers(settings)
- local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
- if settings then
- for k,v in next,settings do
- if type(v)=="table" then
- local tk=t[k] if not tk then tk={} t[k]=tk end
- for kk,vv in next,v do
- tk[kk]=vv
- end
- else
- t[k]=v
- end
- end
- if settings.name then
- handlers[settings.name]=t
- end
+ local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
+ if settings then
+ for k,v in next,settings do
+ if type(v)=="table" then
+ local tk=t[k] if not tk then tk={} t[k]=tk end
+ for kk,vv in next,v do
+ tk[kk]=vv
+ end
+ else
+ t[k]=v
+ end
end
- utilities.storage.mark(t)
- return t
+ if settings.name then
+ handlers[settings.name]=t
+ end
+ end
+ utilities.storage.mark(t)
+ return t
end
local nofunction=function() end
function xml.sethandlersfunction(handler,name,fnc)
- handler.functions[name]=fnc or nofunction
+ handler.functions[name]=fnc or nofunction
end
function xml.gethandlersfunction(handler,name)
- return handler.functions[name]
+ return handler.functions[name]
end
function xml.gethandlers(name)
- return handlers[name]
+ return handlers[name]
end
newhandlers {
- name="verbose",
- initialize=false,
- finalize=false,
- serialize=xserialize,
- handle=print,
- functions={
- ["@dc@"]=verbose_document,
- ["@dt@"]=verbose_doctype,
- ["@rt@"]=verbose_root,
- ["@el@"]=verbose_element,
- ["@pi@"]=verbose_pi,
- ["@cm@"]=verbose_comment,
- ["@cd@"]=verbose_cdata,
- ["@tx@"]=verbose_text,
- }
+ name="verbose",
+ initialize=false,
+ finalize=false,
+ serialize=xserialize,
+ handle=print,
+ functions={
+ ["@dc@"]=verbose_document,
+ ["@dt@"]=verbose_doctype,
+ ["@rt@"]=verbose_root,
+ ["@el@"]=verbose_element,
+ ["@pi@"]=verbose_pi,
+ ["@cm@"]=verbose_comment,
+ ["@cd@"]=verbose_cdata,
+ ["@tx@"]=verbose_text,
+ }
}
local result
local xmlfilehandler=newhandlers {
- name="file",
- initialize=function(name)
- result=io.open(name,"wb")
- return result
- end,
- finalize=function()
- result:close()
- return true
- end,
- handle=function(...)
- result:write(...)
- end,
+ name="file",
+ initialize=function(name)
+ result=io.open(name,"wb")
+ return result
+ end,
+ finalize=function()
+ result:close()
+ return true
+ end,
+ handle=function(...)
+ result:write(...)
+ end,
}
function xml.save(root,name)
- serialize(root,xmlfilehandler,name)
+ serialize(root,xmlfilehandler,name)
end
local result,r,threshold={},0,512
local xmlstringhandler=newhandlers {
- name="string",
- initialize=function()
- r=0
- return result
- end,
- finalize=function()
- local done=concat(result,"",1,r)
- r=0
- if r>threshold then
- result={}
- end
- return done
- end,
- handle=function(...)
- for i=1,select("#",...) do
- r=r+1
- result[r]=select(i,...)
- end
- end,
+ name="string",
+ initialize=function()
+ r=0
+ return result
+ end,
+ finalize=function()
+ local done=concat(result,"",1,r)
+ r=0
+ if r>threshold then
+ result={}
+ end
+ return done
+ end,
+ handle=function(...)
+ for i=1,select("#",...) do
+ r=r+1
+ result[r]=select(i,...)
+ end
+ end,
}
local function xmltostring(root)
- if not root then
- return ""
- elseif type(root)=="string" then
- return root
- else
- return serialize(root,xmlstringhandler) or ""
- end
+ if not root then
+ return ""
+ elseif type(root)=="string" then
+ return root
+ else
+ return serialize(root,xmlstringhandler) or ""
+ end
end
local function __tostring(root)
- return (root and xmltostring(root)) or ""
+ return (root and xmltostring(root)) or ""
end
initialize_mt=function(root)
- mt={ __tostring=__tostring,__index=root }
+ mt={ __tostring=__tostring,__index=root }
end
xml.defaulthandlers=handlers
xml.newhandlers=newhandlers
xml.serialize=serialize
xml.tostring=xmltostring
local function xmlstring(e,handle)
- if not handle or (e.special and e.tg~="@rt@") then
- elseif e.tg then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- xmlstring(edt[i],handle)
- end
- end
- else
- handle(e)
+ if not handle or (e.special and e.tg~="@rt@") then
+ elseif e.tg then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ xmlstring(edt[i],handle)
+ end
end
+ else
+ handle(e)
+ end
end
xml.string=xmlstring
function xml.settings(e)
- while e do
- local s=e.settings
- if s then
- return s
- else
- e=e.__p__
- end
+ while e do
+ local s=e.settings
+ if s then
+ return s
+ else
+ e=e.__p__
end
- return nil
+ end
+ return nil
end
function xml.root(e)
- local r=e
- while e do
- e=e.__p__
- if e then
- r=e
- end
+ local r=e
+ while e do
+ e=e.__p__
+ if e then
+ r=e
end
- return r
+ end
+ return r
end
function xml.parent(root)
- return root.__p__
+ return root.__p__
end
function xml.body(root)
- return root.ri and root.dt[root.ri] or root
+ return root.ri and root.dt[root.ri] or root
end
function xml.name(root)
- if not root then
- return ""
- end
- local ns=root.ns
- local tg=root.tg
- if ns=="" then
- return tg
- else
- return ns..":"..tg
- end
+ if not root then
+ return ""
+ end
+ local ns=root.ns
+ local tg=root.tg
+ if ns=="" then
+ return tg
+ else
+ return ns..":"..tg
+ end
end
function xml.erase(dt,k)
- if dt then
- if k then
- dt[k]=""
- else for k=1,#dt do
- dt[1]={ "" }
- end end
- end
+ if dt then
+ if k then
+ dt[k]=""
+ else for k=1,#dt do
+ dt[1]={ "" }
+ end end
+ end
end
function xml.assign(dt,k,root)
- if dt and k then
- dt[k]=type(root)=="table" and xml.body(root) or root
- return dt[k]
- else
- return xml.body(root)
- end
+ if dt and k then
+ dt[k]=type(root)=="table" and xml.body(root) or root
+ return dt[k]
+ else
+ return xml.body(root)
+ end
end
function xml.tocdata(e,wrapper)
- local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
- if wrapper then
- whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
- end
- local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
- setmetatable(t,getmetatable(e))
- e.dt={ t }
+ local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
+ if wrapper then
+ whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
+ end
+ local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
+ setmetatable(t,getmetatable(e))
+ 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
+ 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
- return root
+ end
+ return root
end
function xml.kind(e)
- local dt=e and e.dt
- if dt then
- local n=#dt
- if n==1 then
- local d=dt[1]
- if d.special then
- local tg=d.tg
- if tg=="@cd@" then
- return "cdata"
- elseif tg=="@cm" then
- return "comment"
- elseif tg=="@pi@" then
- return "instruction"
- elseif tg=="@dt@" then
- return "declaration"
- end
- elseif type(d)=="string" then
- return "text"
- end
- return "element"
- elseif n>0 then
- return "mixed"
- end
+ local dt=e and e.dt
+ if dt then
+ local n=#dt
+ if n==1 then
+ local d=dt[1]
+ if d.special then
+ local tg=d.tg
+ if tg=="@cd@" then
+ return "cdata"
+ elseif tg=="@cm" then
+ return "comment"
+ elseif tg=="@pi@" then
+ return "instruction"
+ elseif tg=="@dt@" then
+ return "declaration"
+ end
+ elseif type(d)=="string" then
+ return "text"
+ end
+ return "element"
+ elseif n>0 then
+ return "mixed"
end
- return "empty"
+ end
+ return "empty"
end
@@ -16924,14 +16932,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true
--- original size: 54551, stripped down to: 33353
+-- original size: 54551, stripped down to: 30745
if not modules then modules={} end modules ['lxml-lpt']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local concat,remove,insert=table.concat,table.remove,table.insert
local type,next,tonumber,tostring,setmetatable,load,select=type,next,tonumber,tostring,setmetatable,load,select
@@ -16944,21 +16952,21 @@ local trace_lparse=false
local trace_lprofile=false
local report_lpath=logs.reporter("xml","lpath")
if trackers then
- trackers.register("xml.path",function(v)
- trace_lpath=v
- end)
- trackers.register("xml.parse",function(v)
- trace_lparse=v
- end)
- trackers.register("xml.profile",function(v)
- trace_lpath=v
- trace_lparse=v
- trace_lprofile=v
- end)
+ trackers.register("xml.path",function(v)
+ trace_lpath=v
+ end)
+ trackers.register("xml.parse",function(v)
+ trace_lparse=v
+ end)
+ trackers.register("xml.profile",function(v)
+ trace_lpath=v
+ trace_lparse=v
+ trace_lprofile=v
+ end)
end
local xml=xml
-local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
-local lpathcached=0 function xml.lpathcached() return lpathcached end
+local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
+local lpathcached=0 function xml.lpathcached() return lpathcached end
xml.functions=xml.functions or {}
local functions=xml.functions
xml.expressions=xml.expressions or {}
@@ -16972,262 +16980,262 @@ local xmlpatterns=lpegpatterns.xml
finalizers.xml=finalizers.xml or {}
finalizers.tex=finalizers.tex or {}
local function fallback (t,name)
- local fn=finalizers[name]
- if fn then
- t[name]=fn
- else
- report_lpath("unknown sub finalizer %a",name)
- fn=function() end
- end
- return fn
+ local fn=finalizers[name]
+ if fn then
+ t[name]=fn
+ else
+ report_lpath("unknown sub finalizer %a",name)
+ fn=function() end
+ end
+ return fn
end
setmetatableindex(finalizers.xml,fallback)
setmetatableindex(finalizers.tex,fallback)
xml.defaultprotocol="xml"
local apply_axis={}
apply_axis['root']=function(list)
- local collected={}
- for l=1,#list do
- local ll=list[l]
- local rt=ll
- while ll do
- ll=ll.__p__
- if ll then
- rt=ll
- end
- end
- collected[l]=rt
+ local collected={}
+ for l=1,#list do
+ local ll=list[l]
+ local rt=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
+ rt=ll
+ end
end
- return collected
+ collected[l]=rt
+ end
+ return collected
end
apply_axis['self']=function(list)
- return list
+ return list
end
apply_axis['child']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local dt=ll.dt
- if dt then
- local n=#dt
- if n==0 then
- ll.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- ll.en=1
- end
- else
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- end
- end
- ll.en=en
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local dt=ll.dt
+ if dt then
+ local n=#dt
+ if n==0 then
+ ll.en=0
+ elseif n==1 then
+ local dk=dt[1]
+ if dk.tg then
+ c=c+1
+ collected[c]=dk
+ dk.ni=1
+ dk.ei=1
+ ll.en=1
+ end
+ else
+ local en=0
+ for k=1,#dt do
+ local dk=dt[k]
+ if dk.tg then
+ c=c+1
+ en=en+1
+ collected[c]=dk
+ dk.ni=k
+ dk.ei=en
+ end
end
+ ll.en=en
+ end
end
- return collected
+ end
+ return collected
end
local function collect(list,collected,c)
- local dt=list.dt
- if dt then
- local n=#dt
- if n==0 then
- list.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- c=collect(dk,collected,c)
- list.en=1
- else
- list.en=0
- end
- else
- local en=0
- for k=1,n do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- c=collect(dk,collected,c)
- end
- end
- list.en=en
+ local dt=list.dt
+ if dt then
+ local n=#dt
+ if n==0 then
+ list.en=0
+ elseif n==1 then
+ local dk=dt[1]
+ if dk.tg then
+ c=c+1
+ collected[c]=dk
+ dk.ni=1
+ dk.ei=1
+ c=collect(dk,collected,c)
+ list.en=1
+ else
+ list.en=0
+ end
+ else
+ local en=0
+ for k=1,n do
+ local dk=dt[k]
+ if dk.tg then
+ c=c+1
+ en=en+1
+ collected[c]=dk
+ dk.ni=k
+ dk.ei=en
+ c=collect(dk,collected,c)
end
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant']=function(list)
- local collected,c={},0
- for l=1,#list do
- c=collect(list[l],collected,c)
- end
- return collected
+ local collected,c={},0
+ for l=1,#list do
+ c=collect(list[l],collected,c)
+ end
+ return collected
end
local function collect(list,collected,c)
- local dt=list.dt
- if dt then
- local n=#dt
- if n==0 then
- list.en=0
- elseif n==1 then
- local dk=dt[1]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=1
- dk.ei=1
- c=collect(dk,collected,c)
- list.en=1
- end
- else
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- en=en+1
- collected[c]=dk
- dk.ni=k
- dk.ei=en
- c=collect(dk,collected,c)
- end
- end
- list.en=en
+ local dt=list.dt
+ if dt then
+ local n=#dt
+ if n==0 then
+ list.en=0
+ elseif n==1 then
+ local dk=dt[1]
+ if dk.tg then
+ c=c+1
+ collected[c]=dk
+ dk.ni=1
+ dk.ei=1
+ c=collect(dk,collected,c)
+ list.en=1
+ end
+ else
+ local en=0
+ for k=1,#dt do
+ local dk=dt[k]
+ if dk.tg then
+ c=c+1
+ en=en+1
+ collected[c]=dk
+ dk.ni=k
+ dk.ei=en
+ c=collect(dk,collected,c)
end
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- if ll.special~=true then
- c=c+1
- collected[c]=ll
- end
- c=collect(ll,collected,c)
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ if ll.special~=true then
+ c=c+1
+ collected[c]=ll
end
- return collected
+ c=collect(ll,collected,c)
+ end
+ return collected
end
apply_axis['ancestor']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ while ll do
+ ll=ll.__p__
+ if ll then
+ c=c+1
+ collected[c]=ll
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['ancestor-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ c=c+1
+ collected[c]=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
c=c+1
collected[c]=ll
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['parent']=function(list)
- local collected,c={},0
- for l=1,#list do
- local pl=list[l].__p__
- if pl then
- c=c+1
- collected[c]=pl
- end
+ local collected,c={},0
+ for l=1,#list do
+ local pl=list[l].__p__
+ if pl then
+ c=c+1
+ collected[c]=pl
end
- return collected
+ end
+ return collected
end
apply_axis['attribute']=function(list)
- return {}
+ return {}
end
apply_axis['namespace']=function(list)
- return {}
+ return {}
end
apply_axis['following']=function(list)
- return {}
+ return {}
end
apply_axis['preceding']=function(list)
- return {}
+ return {}
end
apply_axis['following-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=ll.ni+1,#d do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=ll.ni+1,#d do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['preceding-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=1,ll.ni-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=1,ll.ni-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['reverse-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=ll.ni-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected,c={},0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=ll.ni-1,1,-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['auto-descendant-or-self']=apply_axis['descendant-or-self']
apply_axis['auto-descendant']=apply_axis['descendant']
@@ -17235,130 +17243,130 @@ apply_axis['auto-child']=apply_axis['child']
apply_axis['auto-self']=apply_axis['self']
apply_axis['initial-child']=apply_axis['child']
local function apply_nodes(list,directive,nodes)
- local maxn=#nodes
- if maxn==3 then
- local nns,ntg=nodes[2],nodes[3]
- if not nns and not ntg then
+ local maxn=#nodes
+ if maxn==3 then
+ local nns,ntg=nodes[2],nodes[3]
+ if not nns and not ntg then
+ if directive then
+ return list
+ else
+ return {}
+ end
+ else
+ local collected,c,m,p={},0,0,nil
+ if not nns then
+ for l=1,#list do
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
if directive then
- return list
- else
- return {}
+ if ntg==ltg then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif ntg~=ltg then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
end
- else
- local collected,c,m,p={},0,0,nil
- if not nns then
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- if directive then
- if ntg==ltg then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif ntg~=ltg then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- elseif not ntg then
- for l=1,#list do
- local ll=list[l]
- local lns=ll.rn or ll.ns
- if lns then
- if directive then
- if lns==nns then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif lns~=nns then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- else
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=ltg==ntg and lns==nns
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
+ end
+ end
+ elseif not ntg then
+ for l=1,#list do
+ local ll=list[l]
+ local lns=ll.rn or ll.ns
+ if lns then
+ if directive then
+ if lns==nns then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif lns~=nns then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
end
- return collected
+ end
end
- else
- local collected,c,m,p={},0,0,nil
+ else
for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=false
- for n=1,maxn,3 do
- local nns,ntg=nodes[n+1],nodes[n+2]
- ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
- if ok then
- break
- end
- end
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=ltg==ntg and lns==nns
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
end
+ end
end
- return collected
+ end
+ return collected
end
-end
-local quit_expression=false
-local function apply_expression(list,expression,order)
- local collected,c={},0
- quit_expression=false
+ else
+ local collected,c,m,p={},0,0,nil
for l=1,#list do
- local ll=list[l]
- if expression(list,ll,l,order) then
- c=c+1
- collected[c]=ll
- end
- if quit_expression then
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=false
+ for n=1,maxn,3 do
+ local nns,ntg=nodes[n+1],nodes[n+2]
+ ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
+ if ok then
break
+ end
end
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
+ c=c+1
+ collected[c],ll.mi=ll,m
+ end
+ end
end
return collected
+ end
end
-local function apply_selector(list,specification)
- if xml.applyselector then
- apply_selector=xml.applyselector
- return apply_selector(list,specification)
- else
- return list
+local quit_expression=false
+local function apply_expression(list,expression,order)
+ local collected,c={},0
+ quit_expression=false
+ for l=1,#list do
+ local ll=list[l]
+ if expression(list,ll,l,order) then
+ c=c+1
+ collected[c]=ll
+ end
+ if quit_expression then
+ break
end
+ end
+ return collected
+end
+local function apply_selector(list,specification)
+ if xml.applyselector then
+ apply_selector=xml.applyselector
+ return apply_selector(list,specification)
+ else
+ return list
+ end
end
local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb
local spaces=S(" \n\r\t\f")^0
@@ -17369,24 +17377,24 @@ local lp_doequal=P("=")/"=="
local lp_or=P("|")/" or "
local lp_and=P("&")/" and "
local builtin={
- text="(ll.dt[1] or '')",
- content="ll.dt",
- name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
- tag="ll.tg",
- position="l",
- firstindex="1",
- firstelement="1",
- first="1",
- lastindex="(#ll.__p__.dt or 1)",
- lastelement="(ll.__p__.en or 1)",
- last="#list",
- rootposition="order",
- order="order",
- element="(ll.ei or 1)",
- index="(ll.ni or 1)",
- match="(ll.mi or 1)",
- namespace="ll.ns",
- ns="ll.ns",
+ text="(ll.dt[1] or '')",
+ content="ll.dt",
+ name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
+ tag="ll.tg",
+ position="l",
+ firstindex="1",
+ firstelement="1",
+ first="1",
+ lastindex="(#ll.__p__.dt or 1)",
+ lastelement="(ll.__p__.en or 1)",
+ last="#list",
+ rootposition="order",
+ order="order",
+ element="(ll.ei or 1)",
+ index="(ll.ni or 1)",
+ match="(ll.mi or 1)",
+ namespace="ll.ns",
+ ns="ll.ns",
}
local lp_builtin=lpeg.utfchartabletopattern(builtin)/builtin*((spaces*P("(")*spaces*P(")"))/"")
local lp_attribute=(P("@")+P("attribute::"))/""*Cc("(ll.at and ll.at['")*((R("az","AZ")+S("-_:"))^1)*Cc("'])")
@@ -17396,11 +17404,11 @@ local lp_fastpos=lp_fastpos_n+lp_fastpos_p
local lp_reserved=C("and")+C("or")+C("not")+C("div")+C("mod")+C("true")+C("false")
local lp_lua_function=Cs((R("az","AZ","__")^1*(P(".")*R("az","AZ","__")^1)^1)*("("))/"%0"
local lp_function=C(R("az","AZ","__")^1)*P("(")/function(t)
- if expressions[t] then
- return "expr."..t.."("
- else
- return "expr.error("
- end
+ if expressions[t] then
+ return "expr."..t.."("
+ else
+ return "expr.error("
+ end
end
local lparent=P("(")
local rparent=P(")")
@@ -17413,24 +17421,24 @@ local lp_string=Cc("'")*R("az","AZ","--","__")^1*Cc("'")
local lp_content=(P("'")*(1-P("'"))^0*P("'")+P('"')*(1-P('"'))^0*P('"'))
local cleaner
local lp_special=(C(P("name")+P("text")+P("tag")+P("count")+P("child")))*value/function(t,s)
- if expressions[t] then
- s=s and s~="" and lpegmatch(cleaner,s)
- if s and s~="" then
- return "expr."..t.."(ll,"..s..")"
- else
- return "expr."..t.."(ll)"
- end
+ if expressions[t] then
+ s=s and s~="" and lpegmatch(cleaner,s)
+ if s and s~="" then
+ return "expr."..t.."(ll,"..s..")"
else
- return "expr.error("..t..")"
+ return "expr."..t.."(ll)"
end
+ else
+ return "expr.error("..t..")"
+ end
end
local content=lp_builtin+lp_attribute+lp_special+lp_noequal+lp_doequal+lp_or+lp_and+lp_reserved+lp_lua_function+lp_function+lp_content+
- lp_child+lp_any
+ lp_child+lp_any
local converter=Cs (
- lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
+ lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
)
cleaner=Cs ((
- lp_reserved+lp_number+lp_string+1 )^1 )
+ lp_reserved+lp_number+lp_string+1 )^1 )
local template_e=[[
local expr = xml.expressions
return function(list,ll,l,order)
@@ -17446,75 +17454,75 @@ local template_f_y=[[
local template_f_n=[[
return xml.finalizers['%s']['%s']
]]
-local register_last_match={ kind="axis",axis="last-match" }
-local register_self={ kind="axis",axis="self" }
-local register_parent={ kind="axis",axis="parent" }
-local register_descendant={ kind="axis",axis="descendant" }
-local register_child={ kind="axis",axis="child" }
+local register_last_match={ kind="axis",axis="last-match" }
+local register_self={ kind="axis",axis="self" }
+local register_parent={ kind="axis",axis="parent" }
+local register_descendant={ kind="axis",axis="descendant" }
+local register_child={ kind="axis",axis="child" }
local register_descendant_or_self={ kind="axis",axis="descendant-or-self" }
-local register_root={ kind="axis",axis="root" }
-local register_ancestor={ kind="axis",axis="ancestor" }
-local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
-local register_attribute={ kind="axis",axis="attribute" }
-local register_namespace={ kind="axis",axis="namespace" }
-local register_following={ kind="axis",axis="following" }
+local register_root={ kind="axis",axis="root" }
+local register_ancestor={ kind="axis",axis="ancestor" }
+local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
+local register_attribute={ kind="axis",axis="attribute" }
+local register_namespace={ kind="axis",axis="namespace" }
+local register_following={ kind="axis",axis="following" }
local register_following_sibling={ kind="axis",axis="following-sibling" }
-local register_preceding={ kind="axis",axis="preceding" }
+local register_preceding={ kind="axis",axis="preceding" }
local register_preceding_sibling={ kind="axis",axis="preceding-sibling" }
-local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
+local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
local register_auto_descendant_or_self={ kind="axis",axis="auto-descendant-or-self" }
-local register_auto_descendant={ kind="axis",axis="auto-descendant" }
-local register_auto_self={ kind="axis",axis="auto-self" }
-local register_auto_child={ kind="axis",axis="auto-child" }
-local register_initial_child={ kind="axis",axis="initial-child" }
+local register_auto_descendant={ kind="axis",axis="auto-descendant" }
+local register_auto_self={ kind="axis",axis="auto-self" }
+local register_auto_child={ kind="axis",axis="auto-child" }
+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)
- if not skip[str] then
- report_lpath("error in expression: %s => %s",str,cnv)
- skip[str]=cnv or str
- end
- return false
+ if not skip[str] then
+ report_lpath("error in expression: %s => %s",str,cnv)
+ skip[str]=cnv or str
+ end
+ return false
end
local function errorrunner_f(str,arg)
- report_lpath("error in finalizer: %s(%s)",str,arg or "")
- return false
+ report_lpath("error in finalizer: %s(%s)",str,arg or "")
+ return false
end
local function register_nodes(nodetest,nodes)
- return { kind="nodes",nodetest=nodetest,nodes=nodes }
+ return { kind="nodes",nodetest=nodetest,nodes=nodes }
end
local function register_selector(specification)
- return { kind="selector",specification=specification }
+ return { kind="selector",specification=specification }
end
local function register_expression(expression)
- local converted=lpegmatch(converter,expression)
- local runner=load(format(template_e,converted))
- runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
- return { kind="expression",expression=expression,converted=converted,evaluator=runner }
+ local converted=lpegmatch(converter,expression)
+ local runner=load(format(template_e,converted))
+ runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
+ return { kind="expression",expression=expression,converted=converted,evaluator=runner }
end
local function register_finalizer(protocol,name,arguments)
- local runner
- if arguments and arguments~="" then
- runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
- else
- runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
- end
- runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
- return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
+ local runner
+ if arguments and arguments~="" then
+ runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
+ else
+ runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
+ end
+ runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
+ return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
end
local expression=P { "ex",
- ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
- sq="'"*(1-S("'"))^0*"'",
- dq='"'*(1-S('"'))^0*'"',
+ ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
+ sq="'"*(1-S("'"))^0*"'",
+ dq='"'*(1-S('"'))^0*'"',
}
local arguments=P { "ar",
- ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
- nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
- sq=P("'")*(1-P("'"))^0*P("'"),
- dq=P('"')*(1-P('"'))^0*P('"'),
+ ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
+ nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
+ sq=P("'")*(1-P("'"))^0*P("'"),
+ dq=P('"')*(1-P('"'))^0*P('"'),
}
local function register_error(str)
- return { kind="error",error=format("unparsed: %s",str) }
+ return { kind="error",error=format("unparsed: %s",str) }
end
local special_1=P("*")*Cc(register_auto_descendant)*Cc(register_all_nodes)
local special_2=P("/")*Cc(register_auto_self)
@@ -17522,367 +17530,367 @@ local special_3=P("")*Cc(register_auto_self)
local no_nextcolon=P(-1)+#(1-P(":"))
local no_nextlparent=P(-1)+#(1-P("("))
local pathparser=Ct { "patterns",
- patterns=spaces*V("protocol")*spaces*(
- (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
- ),
- protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
- step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
- axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
- special=special_1+special_2+special_3,
- initial=(P("/")*spaces*Cc(register_initial_child))^-1,
- error=(P(1)^1)/register_error,
- shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
- shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
- s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
- s_descendant=P("**")*Cc(register_descendant),
- s_child=P("*")*no_nextcolon*Cc(register_child),
- s_parent=P("..")*Cc(register_parent),
- s_self=P("." )*Cc(register_self),
- s_root=P("^^")*Cc(register_root),
- s_ancestor=P("^")*Cc(register_ancestor),
- s_lastmatch=P("=")*Cc(register_last_match),
- descendant=P("descendant::")*Cc(register_descendant),
- child=P("child::")*Cc(register_child),
- parent=P("parent::")*Cc(register_parent),
- self=P("self::")*Cc(register_self),
- root=P('root::')*Cc(register_root),
- ancestor=P('ancestor::')*Cc(register_ancestor),
- descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
- ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
- following=P('following::')*Cc(register_following),
- following_sibling=P('following-sibling::')*Cc(register_following_sibling),
- preceding=P('preceding::')*Cc(register_preceding),
- preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
- reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
- last_match=P('last-match::')*Cc(register_last_match),
- selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
- nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
- expressions=expression/register_expression,
- letters=R("az")^1,
- name=(1-S("/[]()|:*!"))^1,
- negate=P("!")*Cc(false),
- nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
- nodetest=V("negate")+Cc(true),
- nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
- wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
- nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
- finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
+ patterns=spaces*V("protocol")*spaces*(
+ (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
+ ),
+ protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
+ step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
+ axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
+ special=special_1+special_2+special_3,
+ initial=(P("/")*spaces*Cc(register_initial_child))^-1,
+ error=(P(1)^1)/register_error,
+ shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
+ shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
+ s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
+ s_descendant=P("**")*Cc(register_descendant),
+ s_child=P("*")*no_nextcolon*Cc(register_child),
+ s_parent=P("..")*Cc(register_parent),
+ s_self=P("." )*Cc(register_self),
+ s_root=P("^^")*Cc(register_root),
+ s_ancestor=P("^")*Cc(register_ancestor),
+ s_lastmatch=P("=")*Cc(register_last_match),
+ descendant=P("descendant::")*Cc(register_descendant),
+ child=P("child::")*Cc(register_child),
+ parent=P("parent::")*Cc(register_parent),
+ self=P("self::")*Cc(register_self),
+ root=P('root::')*Cc(register_root),
+ ancestor=P('ancestor::')*Cc(register_ancestor),
+ descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
+ ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
+ following=P('following::')*Cc(register_following),
+ following_sibling=P('following-sibling::')*Cc(register_following_sibling),
+ preceding=P('preceding::')*Cc(register_preceding),
+ preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
+ reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
+ last_match=P('last-match::')*Cc(register_last_match),
+ selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
+ nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
+ expressions=expression/register_expression,
+ letters=R("az")^1,
+ name=(1-S("/[]()|:*!"))^1,
+ negate=P("!")*Cc(false),
+ nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
+ nodetest=V("negate")+Cc(true),
+ nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
+ wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
+ nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
+ finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
}
xmlpatterns.pathparser=pathparser
local cache={}
local function nodesettostring(set,nodetest)
- local t={}
- for i=1,#set,3 do
- local directive,ns,tg=set[i],set[i+1],set[i+2]
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- t[#t+1]=(directive and tg) or format("not(%s)",tg)
- end
- if nodetest==false then
- return format("not(%s)",concat(t,"|"))
- else
- return concat(t,"|")
- end
+ local t={}
+ for i=1,#set,3 do
+ local directive,ns,tg=set[i],set[i+1],set[i+2]
+ if not ns or ns=="" then ns="*" end
+ if not tg or tg=="" then tg="*" end
+ tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
+ t[#t+1]=(directive and tg) or format("not(%s)",tg)
+ end
+ if nodetest==false then
+ return format("not(%s)",concat(t,"|"))
+ else
+ return concat(t,"|")
+ end
end
local function tagstostring(list)
- if #list==0 then
- return "no elements"
- else
- local t={}
- for i=1,#list do
- local li=list[i]
- local ns,tg=li.ns,li.tg
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- t[i]=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- end
- return concat(t," ")
+ if #list==0 then
+ return "no elements"
+ else
+ local t={}
+ for i=1,#list do
+ local li=list[i]
+ local ns,tg=li.ns,li.tg
+ if not ns or ns=="" then ns="*" end
+ if not tg or tg=="" then tg="*" end
+ t[i]=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
end
+ return concat(t," ")
+ end
end
xml.nodesettostring=nodesettostring
local lpath
local function lshow(parsed)
- if type(parsed)=="string" then
- parsed=lpath(parsed)
- end
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
- table.serialize(parsed,false))
+ if type(parsed)=="string" then
+ parsed=lpath(parsed)
+ end
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
+ table.serialize(parsed,false))
end
xml.lshow=lshow
local function add_comment(p,str)
- local pc=p.comment
- if not pc then
- p.comment={ str }
- else
- pc[#pc+1]=str
- end
+ local pc=p.comment
+ if not pc then
+ p.comment={ str }
+ else
+ pc[#pc+1]=str
+ end
end
lpath=function (pattern)
- lpathcalls=lpathcalls+1
- if type(pattern)=="table" then
- return pattern
- else
- local parsed=cache[pattern]
- if parsed then
- lpathcached=lpathcached+1
+ lpathcalls=lpathcalls+1
+ if type(pattern)=="table" then
+ return pattern
+ else
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcached=lpathcached+1
+ else
+ parsed=lpegmatch(pathparser,pattern)
+ if parsed then
+ parsed.pattern=pattern
+ local np=#parsed
+ if np==0 then
+ parsed={ pattern=pattern,register_self,state="parsing error" }
+ report_lpath("parsing error in pattern: %s",pattern)
+ lshow(parsed)
else
- parsed=lpegmatch(pathparser,pattern)
- if parsed then
- parsed.pattern=pattern
- local np=#parsed
- if np==0 then
- parsed={ pattern=pattern,register_self,state="parsing error" }
- report_lpath("parsing error in pattern: %s",pattern)
- lshow(parsed)
- else
- local pi=parsed[1]
- if pi.axis=="auto-child" then
- if false then
- add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
- parsed[1]=register_auto_descendant_or_self
- else
- add_comment(parsed,"auto-child replaced by auto-descendant")
- parsed[1]=register_auto_descendant
- end
- elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
- add_comment(parsed,"initial-child removed")
- remove(parsed,1)
- end
- local np=#parsed
- if np>1 then
- local pnp=parsed[np]
- if pnp.kind=="nodes" and pnp.nodetest==true then
- local nodes=pnp.nodes
- if nodes[1]==true and nodes[2]==false and nodes[3]==false then
- add_comment(parsed,"redundant final wildcard filter removed")
- remove(parsed,np)
- end
- end
- end
- end
+ local pi=parsed[1]
+ if pi.axis=="auto-child" then
+ if false then
+ add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
+ parsed[1]=register_auto_descendant_or_self
else
- parsed={ pattern=pattern }
+ add_comment(parsed,"auto-child replaced by auto-descendant")
+ parsed[1]=register_auto_descendant
end
- cache[pattern]=parsed
- if trace_lparse and not trace_lprofile then
- lshow(parsed)
+ elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
+ add_comment(parsed,"initial-child removed")
+ remove(parsed,1)
+ end
+ local np=#parsed
+ if np>1 then
+ local pnp=parsed[np]
+ if pnp.kind=="nodes" and pnp.nodetest==true then
+ local nodes=pnp.nodes
+ if nodes[1]==true and nodes[2]==false and nodes[3]==false then
+ add_comment(parsed,"redundant final wildcard filter removed")
+ remove(parsed,np)
+ end
end
+ end
end
- return parsed
+ else
+ parsed={ pattern=pattern }
+ end
+ cache[pattern]=parsed
+ if trace_lparse and not trace_lprofile then
+ lshow(parsed)
+ end
end
+ return parsed
+ end
end
xml.lpath=lpath
do
- local profiled={}
- xml.profiled=profiled
- local lastmatch=nil
- local keepmatch=nil
- if directives then
- directives.register("xml.path.keeplastmatch",function(v)
- keepmatch=v
- lastmatch=nil
- end)
- end
- apply_axis["last-match"]=function()
- return lastmatch or {}
- end
- local function profiled_apply(list,parsed,nofparsed,order)
- local p=profiled[parsed.pattern]
- if p then
- p.tested=p.tested+1
- else
- p={ tested=1,matched=0,finalized=0 }
- profiled[parsed.pattern]=p
- end
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- p.matched=p.matched+1
- p.finalized=p.finalized+1
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- p.finalized=p.finalized+1
- return collected
- end
- return nil
- end
- end
- if collected then
- p.matched=p.matched+1
- end
- return collected
- end
- local function traced_apply(list,parsed,nofparsed,order)
- if trace_lparse then
- lshow(parsed)
- end
- report_lpath("collecting: %s",parsed.pattern)
- report_lpath("root tags : %s",tagstostring(list))
- report_lpath("order : %s",order or "unset")
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
- return collected
- end
- return nil
- end
- end
+ local profiled={}
+ xml.profiled=profiled
+ local lastmatch=nil
+ local keepmatch=nil
+ if directives then
+ directives.register("xml.path.keeplastmatch",function(v)
+ keepmatch=v
+ lastmatch=nil
+ end)
+ end
+ apply_axis["last-match"]=function()
+ return lastmatch or {}
+ end
+ local function profiled_apply(list,parsed,nofparsed,order)
+ local p=profiled[parsed.pattern]
+ if p then
+ p.tested=p.tested+1
+ else
+ p={ tested=1,matched=0,finalized=0 }
+ profiled[parsed.pattern]=p
+ end
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ p.matched=p.matched+1
+ p.finalized=p.finalized+1
return collected
- end
- local function normal_apply(list,parsed,nofparsed,order)
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- local axis=pi.axis
- if axis~="self" then
- collected=apply_axis[axis](collected)
- end
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- return pi.finalizer(collected)
- end
- if not collected or #collected==0 then
- local pf=i<nofparsed and parsed[nofparsed].finalizer
- if pf then
- return pf(collected)
- end
- return nil
- end
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ p.finalized=p.finalized+1
+ return collected
end
- return collected
+ return nil
+ end
end
- local apply=normal_apply
- if trackers then
- trackers.register("xml.path,xml.parse,xml.profile",function()
- if trace_lprofile then
- apply=profiled_apply
- elseif trace_lpath then
- apply=traced_apply
- else
- apply=normal_apply
- end
- end)
+ if collected then
+ p.matched=p.matched+1
end
- function xml.applylpath(list,pattern)
- if not list then
- lastmatch=nil
- return
- end
- local parsed=cache[pattern]
- if parsed then
- lpathcalls=lpathcalls+1
- lpathcached=lpathcached+1
- elseif type(pattern)=="table" then
- lpathcalls=lpathcalls+1
- parsed=pattern
- else
- parsed=lpath(pattern) or pattern
- end
- if not parsed then
- lastmatch=nil
- return
- end
- local nofparsed=#parsed
- if nofparsed==0 then
- lastmatch=nil
- return
- end
- local collected=apply({ list },parsed,nofparsed,list.mi)
- lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ local function traced_apply(list,parsed,nofparsed,order)
+ if trace_lparse then
+ lshow(parsed)
+ end
+ report_lpath("collecting: %s",parsed.pattern)
+ report_lpath("root tags : %s",tagstostring(list))
+ report_lpath("order : %s",order or "unset")
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
return collected
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
+ return collected
+ end
+ return nil
+ end
end
- function xml.lastmatch()
- return lastmatch
- end
- local stack={}
- function xml.pushmatch()
- insert(stack,lastmatch)
- end
- function xml.popmatch()
- lastmatch=remove(stack)
+ return collected
+ end
+ local function normal_apply(list,parsed,nofparsed,order)
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ local axis=pi.axis
+ if axis~="self" then
+ collected=apply_axis[axis](collected)
+ end
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ return pi.finalizer(collected)
+ end
+ if not collected or #collected==0 then
+ local pf=i<nofparsed and parsed[nofparsed].finalizer
+ if pf then
+ return pf(collected)
+ end
+ return nil
+ end
end
+ return collected
+ end
+ local apply=normal_apply
+ if trackers then
+ trackers.register("xml.path,xml.parse,xml.profile",function()
+ if trace_lprofile then
+ apply=profiled_apply
+ elseif trace_lpath then
+ apply=traced_apply
+ else
+ apply=normal_apply
+ end
+ end)
+ end
+ function xml.applylpath(list,pattern)
+ if not list then
+ lastmatch=nil
+ return
+ end
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcalls=lpathcalls+1
+ lpathcached=lpathcached+1
+ elseif type(pattern)=="table" then
+ lpathcalls=lpathcalls+1
+ parsed=pattern
+ else
+ parsed=lpath(pattern) or pattern
+ end
+ if not parsed then
+ lastmatch=nil
+ return
+ end
+ local nofparsed=#parsed
+ if nofparsed==0 then
+ lastmatch=nil
+ return
+ end
+ local collected=apply({ list },parsed,nofparsed,list.mi)
+ lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ function xml.lastmatch()
+ return lastmatch
+ end
+ local stack={}
+ function xml.pushmatch()
+ insert(stack,lastmatch)
+ end
+ function xml.popmatch()
+ lastmatch=remove(stack)
+ end
end
local applylpath=xml.applylpath
function xml.filter(root,pattern)
- return applylpath(root,pattern)
+ return applylpath(root,pattern)
end
expressions.child=function(e,pattern)
- return applylpath(e,pattern)
+ return applylpath(e,pattern)
end
expressions.count=function(e,pattern)
- local collected=applylpath(e,pattern)
- return pattern and (collected and #collected) or 0
+ local collected=applylpath(e,pattern)
+ return pattern and (collected and #collected) or 0
end
expressions.oneof=function(s,...)
- for i=1,select("#",...) do
- if s==select(i,...) then
- return true
- end
+ for i=1,select("#",...) do
+ if s==select(i,...) then
+ return true
end
- return false
+ end
+ return false
end
expressions.error=function(str)
- xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
- return false
+ xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
+ return false
end
expressions.undefined=function(s)
- return s==nil
+ return s==nil
end
expressions.quit=function(s)
- if s or s==nil then
- quit_expression=true
- end
- return true
+ if s or s==nil then
+ quit_expression=true
+ end
+ return true
end
expressions.print=function(...)
- print(...)
- return true
+ print(...)
+ return true
end
expressions.find=find
expressions.upper=upper
@@ -17890,233 +17898,233 @@ expressions.lower=lower
expressions.number=tonumber
expressions.boolean=toboolean
function expressions.contains(str,pattern)
- local t=type(str)
- if t=="string" then
- if find(str,pattern) then
- return true
- end
- elseif t=="table" then
- for i=1,#str do
- local d=str[i]
- if type(d)=="string" and find(d,pattern) then
- return true
- end
- end
+ local t=type(str)
+ if t=="string" then
+ if find(str,pattern) then
+ return true
end
- return false
+ elseif t=="table" then
+ for i=1,#str do
+ local d=str[i]
+ if type(d)=="string" and find(d,pattern) then
+ return true
+ end
+ end
+ end
+ return false
end
function xml.expressions.idstring(str)
- return type(str)=="string" and gsub(str,"^#","") or ""
+ return type(str)=="string" and gsub(str,"^#","") or ""
end
local function traverse(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local r=e.__p__
- handle(r,r.dt,e.ni)
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local r=e.__p__
+ handle(r,r.dt,e.ni)
end
+ end
end
local function selection(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- if handle then
- for c=1,#collected do
- handle(collected[c])
- end
- else
- return collected
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ if handle then
+ for c=1,#collected do
+ handle(collected[c])
+ end
+ else
+ return collected
end
+ end
end
-xml.traverse=traverse
+xml.traverse=traverse
xml.selection=selection
local function dofunction(collected,fnc,...)
- if collected then
- local f=functions[fnc]
- if f then
- for c=1,#collected do
- f(collected[c],...)
- end
- else
- report_lpath("unknown function %a",fnc)
- end
+ if collected then
+ local f=functions[fnc]
+ if f then
+ for c=1,#collected do
+ f(collected[c],...)
+ end
+ else
+ report_lpath("unknown function %a",fnc)
end
+ end
end
finalizers.xml["function"]=dofunction
finalizers.tex["function"]=dofunction
expressions.text=function(e,n)
- local rdt=e.__p__.dt
- return rdt and rdt[n] or ""
+ local rdt=e.__p__.dt
+ return rdt and rdt[n] or ""
end
expressions.name=function(e,n)
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=type(e)=="table" and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=type(e)=="table" and e
+ elseif n<0 then
+ local d,k=e.__p__.dt,e.ni
+ for i=k-1,1,-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
end
+ end
end
- if found then
- local ns,tg=found.rn or found.ns or "",found.tg
- if ns~="" then
- return ns..":"..tg
+ else
+ local d,k=e.__p__.dt,e.ni
+ for i=k+1,#d,1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==1 then
+ found=di
+ break
else
- return tg
+ n=n-1
end
+ end
+ end
+ end
+ if found then
+ local ns,tg=found.rn or found.ns or "",found.tg
+ if ns~="" then
+ return ns..":"..tg
else
- return ""
+ return tg
end
+ else
+ return ""
+ end
end
expressions.tag=function(e,n)
- if not e then
- return ""
+ if not e then
+ return ""
+ else
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=(type(e)=="table") and e
+ elseif n<0 then
+ local d,k=e.__p__.dt,e.ni
+ for i=k-1,1,-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
+ end
+ end
+ end
else
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=(type(e)=="table") and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
- end
+ local d,k=e.__p__.dt,e.ni
+ for i=k+1,#d,1 do
+ local di=d[i]
+ if type(di)=="table" then
+ if n==1 then
+ found=di
+ break
+ else
+ n=n-1
+ end
end
- return (found and found.tg) or ""
+ end
end
+ return (found and found.tg) or ""
+ end
end
local dummy=function() end
function xml.elements(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
+ end
end
function xml.collected(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ return collected[c]
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- return collected[c]
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- return collected[c]
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ return collected[c]
+ end
end
+ end
end
function xml.inspect(collection,pattern)
- pattern=pattern or "."
- for e in xml.collected(collection,pattern or ".") do
- report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
- end
+ pattern=pattern or "."
+ for e in xml.collected(collection,pattern or ".") do
+ report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
+ end
end
local function split(e)
- local dt=e.dt
- if dt then
- for i=1,#dt do
- local dti=dt[i]
- if type(dti)=="string" then
- dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
- dti=gsub(dti,"[\n\r]+","\n\n")
- dt[i]=dti
- else
- split(dti)
- end
- end
+ local dt=e.dt
+ if dt then
+ for i=1,#dt do
+ local dti=dt[i]
+ if type(dti)=="string" then
+ dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
+ dti=gsub(dti,"[\n\r]+","\n\n")
+ dt[i]=dti
+ else
+ split(dti)
+ end
end
- return e
+ end
+ return e
end
function xml.finalizers.paragraphs(c)
- for i=1,#c do
- split(c[i])
- end
- return c
+ for i=1,#c do
+ split(c[i])
+ end
+ return c
end
@@ -18126,14 +18134,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-mis"] = package.loaded["lxml-mis"] or true
--- original size: 3574, stripped down to: 1863
+-- original size: 3574, stripped down to: 1808
if not modules then modules={} end modules ['lxml-mis']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local xml,lpeg,string=xml,lpeg,string
local type=type
@@ -18144,26 +18152,26 @@ local P,S,R,C,V,Cc,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.Cc,lpeg.Cs
lpegpatterns.xml=lpegpatterns.xml or {}
local xmlpatterns=lpegpatterns.xml
local function xmlgsub(t,old,new)
- local dt=t.dt
- if dt then
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="string" then
- dt[k]=gsub(v,old,new)
- else
- xmlgsub(v,old,new)
- end
- end
+ local dt=t.dt
+ if dt then
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="string" then
+ dt[k]=gsub(v,old,new)
+ else
+ xmlgsub(v,old,new)
+ end
end
+ end
end
function xml.stripleadingspaces(dk,d,k)
- if d and k then
- local dkm=d[k-1]
- if dkm and type(dkm)=="string" then
- local s=match(dkm,"\n(%s+)")
- xmlgsub(dk,"\n"..rep(" ",#s),"\n")
- end
+ if d and k then
+ local dkm=d[k-1]
+ if dkm and type(dkm)=="string" then
+ local s=match(dkm,"\n(%s+)")
+ xmlgsub(dk,"\n"..rep(" ",#s),"\n")
end
+ end
end
local normal=(1-S("<&>"))^0
local special=P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"
@@ -18175,17 +18183,17 @@ local cleansed=Cs(((P("<")*(1-P(">"))^0*P(">"))/""+1)^0)
xmlpatterns.escaped=escaped
xmlpatterns.unescaped=unescaped
xmlpatterns.cleansed=cleansed
-function xml.escaped (str) return lpegmatch(escaped,str) end
+function xml.escaped (str) return lpegmatch(escaped,str) end
function xml.unescaped(str) return lpegmatch(unescaped,str) end
-function xml.cleansed (str) return lpegmatch(cleansed,str) end
+function xml.cleansed (str) return lpegmatch(cleansed,str) end
function xml.fillin(root,pattern,str,check)
- local e=xml.first(root,pattern)
- if e then
- local n=#e.dt
- if not check or n==0 or (n==1 and e.dt[1]=="") then
- e.dt={ str }
- end
+ local e=xml.first(root,pattern)
+ if e then
+ local n=#e.dt
+ if not check or n==0 or (n==1 and e.dt[1]=="") then
+ e.dt={ str }
end
+ end
end
@@ -18195,17 +18203,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-aux"] = package.loaded["lxml-aux"] or true
--- original size: 30650, stripped down to: 21793
+-- original size: 30650, stripped down to: 19621
if not modules then modules={} end modules ['lxml-aux']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
-local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
+local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
+local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
local report_xml=logs.reporter("xml")
local xml=xml
local xmlcopy,xmlname=xml.copy,xml.name
@@ -18218,308 +18226,308 @@ local utfbyte=utf.byte
local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
local striplinepatterns=utilities.strings.striplinepatterns
local function report(what,pattern,c,e)
- report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
+ report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
end
local function withelements(e,handle,depth)
- if e and handle then
- local edt=e.dt
- if edt then
- depth=depth or 0
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- handle(e,depth)
- withelements(e,handle,depth+1)
- end
- end
+ if e and handle then
+ local edt=e.dt
+ if edt then
+ depth=depth or 0
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ handle(e,depth)
+ withelements(e,handle,depth+1)
end
+ end
end
+ end
end
xml.withelements=withelements
function xml.withelement(e,n,handle)
- if e and n~=0 and handle then
- local edt=e.dt
- if edt then
- if n>0 then
- for i=1,#edt do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==1 then
- handle(ei)
- return
- else
- n=n-1
- end
- end
- end
- elseif n<0 then
- for i=#edt,1,-1 do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==-1 then
- handle(ei)
- return
- else
- n=n+1
- end
- end
- end
+ if e and n~=0 and handle then
+ local edt=e.dt
+ if edt then
+ if n>0 then
+ for i=1,#edt do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==1 then
+ handle(ei)
+ return
+ else
+ n=n-1
end
+ end
end
- end
-end
-function xml.each(root,pattern,handle,reverse)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- if handle then
- if reverse then
- for c=#collected,1,-1 do
- handle(collected[c])
- end
+ elseif n<0 then
+ for i=#edt,1,-1 do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==-1 then
+ handle(ei)
+ return
else
- for c=1,#collected do
- handle(collected[c])
- end
+ n=n+1
end
+ end
end
- return collected
+ end
end
+ end
end
-function xml.processattributes(root,pattern,handle)
- local collected=xmlapplylpath(root,pattern)
- if collected and handle then
+function xml.each(root,pattern,handle,reverse)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ if handle then
+ if reverse then
+ for c=#collected,1,-1 do
+ handle(collected[c])
+ end
+ else
for c=1,#collected do
- handle(collected[c].at)
+ handle(collected[c])
end
+ end
end
return collected
+ end
+end
+function xml.processattributes(root,pattern,handle)
+ local collected=xmlapplylpath(root,pattern)
+ if collected and handle then
+ for c=1,#collected do
+ handle(collected[c].at)
+ end
+ end
+ return collected
end
function xml.collect(root,pattern)
- return xmlapplylpath(root,pattern)
+ return xmlapplylpath(root,pattern)
end
function xml.collecttexts(root,pattern,flatten)
- local collected=xmlapplylpath(root,pattern)
- if collected and flatten then
- local xmltostring=xml.tostring
- for c=1,#collected do
- collected[c]=xmltostring(collected[c].dt)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected and flatten then
+ local xmltostring=xml.tostring
+ for c=1,#collected do
+ collected[c]=xmltostring(collected[c].dt)
end
- return collected or {}
+ end
+ return collected or {}
end
function xml.collect_tags(root,pattern,nonamespace)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- local t,n={},0
- for c=1,#collected do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace then
- t[n]=tg
- elseif ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
- end
- return t
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ local t,n={},0
+ for c=1,#collected do
+ local e=collected[c]
+ local ns,tg=e.ns,e.tg
+ n=n+1
+ if nonamespace then
+ t[n]=tg
+ elseif ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
+ end
end
+ return t
+ end
end
local no_root={ no_root=true }
local function redo_ni(d)
- for k=1,#d do
- local dk=d[k]
- if type(dk)=="table" then
- dk.ni=k
- end
+ for k=1,#d do
+ local dk=d[k]
+ if type(dk)=="table" then
+ dk.ni=k
end
+ end
end
xml.reindex=redo_ni
local function xmltoelement(whatever,root)
- if not whatever then
- return nil
- end
- local element
- if type(whatever)=="string" then
- element=xmlinheritedconvert(whatever,root)
- else
- element=whatever
- end
- if element.error then
- return whatever
- end
- if element then
- end
- return element
+ if not whatever then
+ return nil
+ end
+ local element
+ if type(whatever)=="string" then
+ element=xmlinheritedconvert(whatever,root)
+ else
+ element=whatever
+ end
+ if element.error then
+ return whatever
+ end
+ if element then
+ end
+ return element
end
xml.toelement=xmltoelement
local function copiedelement(element,newparent)
- if type(element)=="string" then
- return element
- else
- element=xmlcopy(element).dt
- if newparent and type(element)=="table" then
- element.__p__=newparent
- end
- return element
+ if type(element)=="string" then
+ return element
+ else
+ element=xmlcopy(element).dt
+ if newparent and type(element)=="table" then
+ element.__p__=newparent
end
+ return element
+ end
end
function xml.delete(root,pattern)
- if not pattern or pattern=="" then
- local p=root.__p__
+ if not pattern or pattern=="" then
+ local p=root.__p__
+ if p then
+ if trace_manipulations then
+ report('deleting',"--",c,root)
+ end
+ local d=p.dt
+ remove(d,root.ni)
+ redo_ni(d)
+ end
+ else
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
if p then
- if trace_manipulations then
- report('deleting',"--",c,root)
- end
- local d=p.dt
- remove(d,root.ni)
- redo_ni(d)
- end
- else
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('deleting',pattern,c,e)
- end
- local d=p.dt
- local ni=e.ni
- if ni<=#d then
- if false then
- p.dt[ni]=""
- else
- remove(d,ni)
- redo_ni(d)
- end
- else
- end
- end
+ if trace_manipulations then
+ report('deleting',pattern,c,e)
+ end
+ local d=p.dt
+ local ni=e.ni
+ if ni<=#d then
+ if false then
+ p.dt[ni]=""
+ else
+ remove(d,ni)
+ redo_ni(d)
end
+ else
+ end
end
+ end
end
+ end
end
function xml.replace(root,pattern,whatever)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('replacing',pattern,c,e)
- end
- local d=p.dt
- local n=e.ni
- local t=copiedelement(element,p)
- if type(t)=="table" then
- d[n]=t[1]
- for i=2,#t do
- n=n+1
- insert(d,n,t[i])
- end
- else
- d[n]=t
- end
- redo_ni(d)
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
+ if p then
+ if trace_manipulations then
+ report('replacing',pattern,c,e)
end
+ local d=p.dt
+ local n=e.ni
+ local t=copiedelement(element,p)
+ if type(t)=="table" then
+ d[n]=t[1]
+ for i=2,#t do
+ n=n+1
+ insert(d,n,t[i])
+ end
+ else
+ d[n]=t
+ end
+ redo_ni(d)
+ end
end
+ end
end
local function wrap(e,wrapper)
- local t={
- rn=e.rn,
- tg=e.tg,
- ns=e.ns,
- at=e.at,
- dt=e.dt,
- __p__=e,
- }
- setmetatable(t,getmetatable(e))
- e.rn=wrapper.rn or e.rn or ""
- e.tg=wrapper.tg or e.tg or ""
- e.ns=wrapper.ns or e.ns or ""
- e.at=fastcopy(wrapper.at)
- e.dt={ t }
+ local t={
+ rn=e.rn,
+ tg=e.tg,
+ ns=e.ns,
+ at=e.at,
+ dt=e.dt,
+ __p__=e,
+ }
+ setmetatable(t,getmetatable(e))
+ e.rn=wrapper.rn or e.rn or ""
+ e.tg=wrapper.tg or e.tg or ""
+ e.ns=wrapper.ns or e.ns or ""
+ e.at=fastcopy(wrapper.at)
+ e.dt={ t }
end
function xml.wrap(root,pattern,whatever)
- if whatever then
- local wrapper=xmltoelement(whatever,root)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if trace_manipulations then
- report('wrapping',pattern,c,e)
- end
- wrap(e,wrapper)
- end
+ if whatever then
+ local wrapper=xmltoelement(whatever,root)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if trace_manipulations then
+ report('wrapping',pattern,c,e)
end
- else
- wrap(root,xmltoelement(pattern))
+ wrap(e,wrapper)
+ end
end
+ else
+ wrap(root,xmltoelement(pattern))
+ end
end
local function inject_element(root,pattern,whatever,prepend)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function inject_e(e)
- local r=e.__p__
- local d,k,rri=r.dt,e.ni,r.ri
- local edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
- if edt then
- local be,af
- local cp=copiedelement(element,e)
- if prepend then
- be,af=cp,edt
- else
- be,af=edt,cp
- end
- local bn=#be
- for i=1,#af do
- bn=bn+1
- be[bn]=af[i]
- end
- if rri then
- r.dt[rri].dt=be
- else
- d[k].dt=be
- end
- redo_ni(d)
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ local function inject_e(e)
+ local r=e.__p__
+ local d,k,rri=r.dt,e.ni,r.ri
+ local edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
+ if edt then
+ local be,af
+ local cp=copiedelement(element,e)
+ if prepend then
+ be,af=cp,edt
+ else
+ be,af=edt,cp
+ end
+ local bn=#be
+ for i=1,#af do
+ bn=bn+1
+ be[bn]=af[i]
+ end
+ if rri then
+ r.dt[rri].dt=be
+ else
+ d[k].dt=be
+ end
+ redo_ni(d)
end
- if not collected then
- elseif collected.tg then
- inject_e(collected)
- else
- for c=1,#collected do
- inject_e(collected[c])
- end
+ end
+ if not collected then
+ elseif collected.tg then
+ inject_e(collected)
+ else
+ for c=1,#collected do
+ inject_e(collected[c])
end
+ end
end
local function insert_element(root,pattern,whatever,before)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function insert_e(e)
- local r=e.__p__
- local d,k=r.dt,e.ni
- if not before then
- k=k+1
- end
- insert(d,k,copiedelement(element,r))
- redo_ni(d)
- end
- if not collected then
- elseif collected.tg then
- insert_e(collected)
- else
- for c=1,#collected do
- insert_e(collected[c])
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ local function insert_e(e)
+ local r=e.__p__
+ local d,k=r.dt,e.ni
+ if not before then
+ k=k+1
+ end
+ insert(d,k,copiedelement(element,r))
+ redo_ni(d)
+ end
+ if not collected then
+ elseif collected.tg then
+ insert_e(collected)
+ else
+ for c=1,#collected do
+ insert_e(collected[c])
end
+ end
end
xml.insert_element=insert_element
xml.insertafter=insert_element
@@ -18527,124 +18535,124 @@ xml.insertbefore=function(r,p,e) insert_element(r,p,e,true) end
xml.injectafter=inject_element
xml.injectbefore=function(r,p,e) inject_element(r,p,e,true) end
local function include(xmldata,pattern,attribute,recursive,loaddata,level)
- pattern=pattern or 'include'
- loaddata=loaddata or io.loaddata
- local collected=xmlapplylpath(xmldata,pattern)
- if collected then
- if not level then
- level=1
- end
- for c=1,#collected do
- local ek=collected[c]
- local name=nil
- local ekdt=ek.dt
- if ekdt then
- local ekat=ek.at
- local ekrt=ek.__p__
- if ekrt then
- local epdt=ekrt.dt
- if not attribute or attribute=="" then
- name=(type(ekdt)=="table" and ekdt[1]) or ekdt
- end
- if not name then
- for a in gmatch(attribute or "href","([^|]+)") do
- name=ekat[a]
- if name then
- break
- end
- end
- end
- local data=nil
- if name and name~="" then
- local d,n=loaddata(name)
- data=d or ""
- name=n or name
- if trace_inclusions then
- report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
- end
- end
- if not data or data=="" then
- epdt[ek.ni]=""
- elseif ekat["parse"]=="text" then
- epdt[ek.ni]=xml.escaped(data)
- else
+ pattern=pattern or 'include'
+ loaddata=loaddata or io.loaddata
+ local collected=xmlapplylpath(xmldata,pattern)
+ if collected then
+ if not level then
+ level=1
+ end
+ for c=1,#collected do
+ local ek=collected[c]
+ local name=nil
+ local ekdt=ek.dt
+ if ekdt then
+ local ekat=ek.at
+ local ekrt=ek.__p__
+ if ekrt then
+ local epdt=ekrt.dt
+ if not attribute or attribute=="" then
+ name=(type(ekdt)=="table" and ekdt[1]) or ekdt
+ end
+ if not name then
+ for a in gmatch(attribute or "href","([^|]+)") do
+ name=ekat[a]
+ if name then
+ break
+ end
+ end
+ end
+ local data=nil
+ if name and name~="" then
+ local d,n=loaddata(name)
+ data=d or ""
+ name=n or name
+ if trace_inclusions then
+ report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
+ end
+ end
+ if not data or data=="" then
+ epdt[ek.ni]=""
+ elseif ekat["parse"]=="text" then
+ epdt[ek.ni]=xml.escaped(data)
+ else
local settings=xmldata.settings
local savedresource=settings.currentresource
settings.currentresource=name
- local xi=xmlinheritedconvert(data,xmldata)
- if not xi then
- epdt[ek.ni]=""
- else
- if recursive then
- include(xi,pattern,attribute,recursive,loaddata,level+1)
- end
- local child=xml.body(xi)
- child.__p__=ekrt
- child.__f__=name
+ local xi=xmlinheritedconvert(data,xmldata)
+ if not xi then
+ epdt[ek.ni]=""
+ else
+ if recursive then
+ include(xi,pattern,attribute,recursive,loaddata,level+1)
+ end
+ local child=xml.body(xi)
+ child.__p__=ekrt
+ child.__f__=name
child.cf=name
- epdt[ek.ni]=child
- local settings=xmldata.settings
- local inclusions=settings and settings.inclusions
- if inclusions then
- inclusions[#inclusions+1]=name
- elseif settings then
- settings.inclusions={ name }
- else
- settings={ inclusions={ name } }
- xmldata.settings=settings
- end
- if child.er then
- local badinclusions=settings.badinclusions
- if badinclusions then
- badinclusions[#badinclusions+1]=name
- else
- settings.badinclusions={ name }
- end
- end
- end
-settings.currentresource=savedresource
- end
+ epdt[ek.ni]=child
+ local settings=xmldata.settings
+ local inclusions=settings and settings.inclusions
+ if inclusions then
+ inclusions[#inclusions+1]=name
+ elseif settings then
+ settings.inclusions={ name }
+ else
+ settings={ inclusions={ name } }
+ xmldata.settings=settings
+ end
+ if child.er then
+ local badinclusions=settings.badinclusions
+ if badinclusions then
+ badinclusions[#badinclusions+1]=name
+ else
+ settings.badinclusions={ name }
end
+ end
end
+settings.currentresource=savedresource
+ end
end
+ end
end
+ end
end
xml.include=include
function xml.inclusion(e,default)
- while e do
- local f=e.__f__
- if f then
- return f
- else
- e=e.__p__
- end
+ while e do
+ local f=e.__f__
+ if f then
+ return f
+ else
+ e=e.__p__
end
- return default
+ end
+ return default
end
local function getinclusions(key,e,sorted)
- while e do
- local settings=e.settings
- if settings then
- local inclusions=settings[key]
- if inclusions then
- inclusions=table.unique(inclusions)
- if sorted then
- table.sort(inclusions)
- end
- return inclusions
- else
- e=e.__p__
- end
- else
- e=e.__p__
- end
+ while e do
+ local settings=e.settings
+ if settings then
+ local inclusions=settings[key]
+ if inclusions then
+ inclusions=table.unique(inclusions)
+ if sorted then
+ table.sort(inclusions)
+ end
+ return inclusions
+ else
+ e=e.__p__
+ end
+ else
+ e=e.__p__
end
+ end
end
function xml.inclusions(e,sorted)
- return getinclusions("inclusions",e,sorted)
+ return getinclusions("inclusions",e,sorted)
end
function xml.badinclusions(e,sorted)
- return getinclusions("badinclusions",e,sorted)
+ return getinclusions("badinclusions",e,sorted)
end
local b_collapser=lpegpatterns.b_collapser
local m_collapser=lpegpatterns.m_collapser
@@ -18653,194 +18661,194 @@ local b_stripper=lpegpatterns.b_stripper
local m_stripper=lpegpatterns.m_stripper
local e_stripper=lpegpatterns.e_stripper
local function stripelement(e,nolines,anywhere)
- local edt=e.dt
- if edt then
- local n=#edt
- if n==0 then
- return e
- elseif anywhere then
- local t={}
- local m=0
- for e=1,n do
- local str=edt[e]
- if type(str)~="string" then
- m=m+1
- t[m]=str
- elseif str~="" then
- if nolines then
- str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
- else
- str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
- end
- if str~="" then
- m=m+1
- t[m]=str
- end
- end
- end
- e.dt=t
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==0 then
+ return e
+ elseif anywhere then
+ local t={}
+ local m=0
+ for e=1,n do
+ local str=edt[e]
+ if type(str)~="string" then
+ m=m+1
+ t[m]=str
+ elseif str~="" then
+ if nolines then
+ str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
+ else
+ str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
+ end
+ if str~="" then
+ m=m+1
+ t[m]=str
+ end
+ end
+ end
+ e.dt=t
+ else
+ local str=edt[1]
+ if type(str)=="string" then
+ if str~="" then
+ str=lpegmatch(nolines and b_collapser or b_stripper,str)
+ end
+ if str=="" then
+ remove(edt,1)
+ n=n-1
else
- local str=edt[1]
- if type(str)=="string" then
- if str~="" then
- str=lpegmatch(nolines and b_collapser or b_stripper,str)
- end
- if str=="" then
- remove(edt,1)
- n=n-1
- else
- edt[1]=str
- end
- end
- if n>0 then
- str=edt[n]
- if type(str)=="string" then
- if str=="" then
- remove(edt)
- else
- str=lpegmatch(nolines and e_collapser or e_stripper,str)
- if str=="" then
- remove(edt)
- else
- edt[n]=str
- end
- end
- end
+ edt[1]=str
+ end
+ end
+ if n>0 then
+ str=edt[n]
+ if type(str)=="string" then
+ if str=="" then
+ remove(edt)
+ else
+ str=lpegmatch(nolines and e_collapser or e_stripper,str)
+ if str=="" then
+ remove(edt)
+ else
+ edt[n]=str
end
+ end
end
+ end
end
- return e
+ end
+ return e
end
xml.stripelement=stripelement
function xml.strip(root,pattern,nolines,anywhere)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for i=1,#collected do
- stripelement(collected[i],nolines,anywhere)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for i=1,#collected do
+ stripelement(collected[i],nolines,anywhere)
end
+ end
end
local function renamespace(root,oldspace,newspace)
- local ndt=#root.dt
- for i=1,ndt or 0 do
- local e=root[i]
- if type(e)=="table" then
- if e.ns==oldspace then
- e.ns=newspace
- if e.rn then
- e.rn=newspace
- end
- end
- local edt=e.dt
- if edt then
- renamespace(edt,oldspace,newspace)
- end
+ local ndt=#root.dt
+ for i=1,ndt or 0 do
+ local e=root[i]
+ if type(e)=="table" then
+ if e.ns==oldspace then
+ e.ns=newspace
+ if e.rn then
+ e.rn=newspace
end
+ end
+ local edt=e.dt
+ if edt then
+ renamespace(edt,oldspace,newspace)
+ end
end
+ end
end
xml.renamespace=renamespace
function xml.remaptag(root,pattern,newtg)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].tg=newtg
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].tg=newtg
end
+ end
end
function xml.remapnamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].ns=newns
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].ns=newns
end
+ end
end
function xml.checknamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if (not e.rn or e.rn=="") and e.ns=="" then
- e.rn=newns
- end
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if (not e.rn or e.rn=="") and e.ns=="" then
+ e.rn=newns
+ end
end
+ end
end
function xml.remapname(root,pattern,newtg,newns,newrn)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- e.tg,e.ns,e.rn=newtg,newns,newrn
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ e.tg,e.ns,e.rn=newtg,newns,newrn
end
+ end
end
function xml.cdatatotext(e)
- local dt=e.dt
- if #dt==1 then
- local first=dt[1]
- if first.tg=="@cd@" then
- e.dt=first.dt
- end
- else
+ local dt=e.dt
+ if #dt==1 then
+ local first=dt[1]
+ if first.tg=="@cd@" then
+ e.dt=first.dt
end
+ else
+ end
end
function xml.texttocdata(e)
- local dt=e.dt
- local s=xml.tostring(dt)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(dt)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
function xml.elementtocdata(e)
- local dt=e.dt
- local s=xml.tostring(e)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(e)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
xml.builtinentities=table.tohash { "amp","quot","apos","lt","gt" }
local entities=characters and characters.entities or nil
local builtinentities=xml.builtinentities
function xml.addentitiesdoctype(root,option)
- if not entities then
- require("char-ent")
- entities=characters.entities
- end
- if entities and root and root.tg=="@rt@" and root.statistics then
- local list={}
- local hexify=option=="hexadecimal"
- for k,v in table.sortedhash(root.statistics.entities.names) do
- if not builtinentities[k] then
- local e=entities[k]
- if not e then
- e=format("[%s]",k)
- elseif hexify then
- e=format("&#%05X;",utfbyte(k))
- end
- list[#list+1]=format(" <!ENTITY %s %q >",k,e)
- end
- end
- local dt=root.dt
- local n=dt[1].tg=="@pi@" and 2 or 1
- if #list>0 then
- insert(dt,n,{ "\n" })
- insert(dt,n,{
- tg="@dt@",
- dt={ format("Something [\n%s\n] ",concat(list)) },
- ns="",
- special=true,
- })
- insert(dt,n,{ "\n\n" })
- else
- end
+ if not entities then
+ require("char-ent")
+ entities=characters.entities
+ end
+ if entities and root and root.tg=="@rt@" and root.statistics then
+ local list={}
+ local hexify=option=="hexadecimal"
+ for k,v in table.sortedhash(root.statistics.entities.names) do
+ if not builtinentities[k] then
+ local e=entities[k]
+ if not e then
+ e=format("[%s]",k)
+ elseif hexify then
+ e=format("&#%05X;",utfbyte(k))
+ end
+ list[#list+1]=format(" <!ENTITY %s %q >",k,e)
+ end
end
+ local dt=root.dt
+ local n=dt[1].tg=="@pi@" and 2 or 1
+ if #list>0 then
+ insert(dt,n,{ "\n" })
+ insert(dt,n,{
+ tg="@dt@",
+ dt={ format("Something [\n%s\n] ",concat(list)) },
+ ns="",
+ special=true,
+ })
+ insert(dt,n,{ "\n\n" })
+ else
+ end
+ end
end
xml.all=xml.each
xml.insert=xml.insertafter
@@ -18850,239 +18858,239 @@ xml.before=xml.insertbefore
xml.process=xml.each
xml.obsolete=xml.obsolete or {}
local obsolete=xml.obsolete
-xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
-xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
-xml.delete_element=xml.delete obsolete.delete_element=xml.delete
-xml.replace_element=xml.replace obsolete.replace_element=xml.replace
-xml.each_element=xml.each obsolete.each_element=xml.each
-xml.process_elements=xml.process obsolete.process_elements=xml.process
-xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
-xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
-xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
-xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
-xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
-xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
-xml.inject_element=xml.inject obsolete.inject_element=xml.inject
-xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
-xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
-xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
+xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
+xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
+xml.delete_element=xml.delete obsolete.delete_element=xml.delete
+xml.replace_element=xml.replace obsolete.replace_element=xml.replace
+xml.each_element=xml.each obsolete.each_element=xml.each
+xml.process_elements=xml.process obsolete.process_elements=xml.process
+xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
+xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
+xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
+xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
+xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
+xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
+xml.inject_element=xml.inject obsolete.inject_element=xml.inject
+xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
+xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
+xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
function xml.cdata(e)
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
end
- return ""
+ end
+ return ""
end
function xml.finalizers.xml.cdata(collected)
- if collected then
- local e=collected[1]
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
- end
+ if collected then
+ local e=collected[1]
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
+ end
end
- return ""
+ end
+ return ""
end
function xml.insertcomment(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.insertcdata(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.setcomment(e,str,n)
- e.dt={ {
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.setcdata(e,str)
- e.dt={ {
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.separate(x,pattern)
- local collected=xmlapplylpath(x,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local d=e.dt
- if d==x then
- report_xml("warning: xml.separate changes root")
- x=d
- end
- local t,n={ "\n" },1
- local i,nd=1,#d
- while i<=nd do
- while i<=nd do
- local di=d[i]
- if type(di)=="string" then
- if di=="\n" or find(di,"^%s+$") then
- i=i+1
- else
- d[i]=strip(di)
- break
- end
- else
- break
- end
- end
- if i>nd then
- break
- end
- t[n+1]="\n"
- t[n+2]=d[i]
- t[n+3]="\n"
- n=n+3
- i=i+1
+ local collected=xmlapplylpath(x,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local d=e.dt
+ if d==x then
+ report_xml("warning: xml.separate changes root")
+ x=d
+ end
+ local t,n={ "\n" },1
+ local i,nd=1,#d
+ while i<=nd do
+ while i<=nd do
+ local di=d[i]
+ if type(di)=="string" then
+ if di=="\n" or find(di,"^%s+$") then
+ i=i+1
+ else
+ d[i]=strip(di)
+ break
end
- t[n+1]="\n"
- setmetatable(t,getmetatable(d))
- e.dt=t
+ else
+ break
+ end
end
+ if i>nd then
+ break
+ end
+ t[n+1]="\n"
+ t[n+2]=d[i]
+ t[n+3]="\n"
+ n=n+3
+ i=i+1
+ end
+ t[n+1]="\n"
+ setmetatable(t,getmetatable(d))
+ e.dt=t
end
- return x
+ end
+ return x
end
local helpers=xml.helpers or {}
xml.helpers=helpers
local function normal(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)=="string" and str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)=="string" and str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
local function recurse(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)~="string" then
- recurse(str,action)
- elseif str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)~="string" then
+ recurse(str,action)
+ elseif str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
function helpers.recursetext(collected,action,recursive)
- if recursive then
- for i=1,#collected do
- recurse(collected[i],action)
- end
- else
- for i=1,#collected do
- normal(collected[i],action)
- end
+ if recursive then
+ for i=1,#collected do
+ recurse(collected[i],action)
+ end
+ else
+ for i=1,#collected do
+ normal(collected[i],action)
end
+ end
end
local specials={
- ["@rt@"]="root",
- ["@pi@"]="instruction",
- ["@cm@"]="comment",
- ["@dt@"]="declaration",
- ["@cd@"]="cdata",
+ ["@rt@"]="root",
+ ["@pi@"]="instruction",
+ ["@cm@"]="comment",
+ ["@dt@"]="declaration",
+ ["@cd@"]="cdata",
}
local function convert(x,strip,flat)
- local ns=x.ns
- local tg=x.tg
- local at=x.at
- local dt=x.dt
- local node=flat and {
- [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
- } or {
- _namespace=ns~="" and ns or nil,
- _tag=not x.special and tg or nil,
- _type=specials[tg] or "_element",
- }
- if at then
- for k,v in next,at do
- node[k]=v
+ local ns=x.ns
+ local tg=x.tg
+ local at=x.at
+ local dt=x.dt
+ local node=flat and {
+ [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
+ } or {
+ _namespace=ns~="" and ns or nil,
+ _tag=not x.special and tg or nil,
+ _type=specials[tg] or "_element",
+ }
+ if at then
+ for k,v in next,at do
+ node[k]=v
+ end
+ end
+ local n=0
+ for i=1,#dt do
+ local di=dt[i]
+ if type(di)=="table" then
+ if flat and di.special then
+ else
+ di=convert(di,strip,flat)
+ if di then
+ n=n+1
+ node[n]=di
end
+ end
+ elseif strip then
+ di=lpegmatch(strip,di)
+ if di~="" then
+ n=n+1
+ node[n]=di
+ end
+ else
+ n=n+1
+ node[n]=di
end
- local n=0
- for i=1,#dt do
- local di=dt[i]
- if type(di)=="table" then
- if flat and di.special then
- else
- di=convert(di,strip,flat)
- if di then
- n=n+1
- node[n]=di
- end
- end
- elseif strip then
- di=lpegmatch(strip,di)
- if di~="" then
- n=n+1
- node[n]=di
- end
- else
- n=n+1
- node[n]=di
- end
- end
- if next(node) then
- return node
- end
+ end
+ if next(node) then
+ return node
+ end
end
function xml.totable(x,strip,flat)
- if type(x)=="table" then
- if strip then
- strip=striplinepatterns[strip]
- end
- return convert(x,strip,flat)
+ if type(x)=="table" then
+ if strip then
+ strip=striplinepatterns[strip]
end
+ return convert(x,strip,flat)
+ end
end
function xml.rename(e,namespace,name,attributes)
- if type(e)~="table" or not e.tg then
- return
- end
- if type(name)=="table" then
- attributes=name
- name=namespace
- namespace=""
- elseif type(name)~="string" then
- attributes={}
- name=namespace
- namespace=""
- end
- if type(attributes)~="table" then
- attributes={}
- end
- e.ns=namespace
- e.rn=namespace
- e.tg=name
- e.at=attributes
+ if type(e)~="table" or not e.tg then
+ return
+ end
+ if type(name)=="table" then
+ attributes=name
+ name=namespace
+ namespace=""
+ elseif type(name)~="string" then
+ attributes={}
+ name=namespace
+ namespace=""
+ end
+ if type(attributes)~="table" then
+ attributes={}
+ end
+ e.ns=namespace
+ e.rn=namespace
+ e.tg=name
+ e.at=attributes
end
@@ -19092,14 +19100,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
--- original size: 11096, stripped down to: 8243
+-- original size: 11096, stripped down to: 7702
if not modules then modules={} end modules ['lxml-xml']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber,next=tonumber,next
local concat=table.concat
@@ -19111,241 +19119,241 @@ local xmltostring=xml.tostring
local xmlserialize=xml.serialize
local xmlcollected=xml.collected
local xmlnewhandlers=xml.newhandlers
-local reparsedentity=xml.reparsedentitylpeg
+local reparsedentity=xml.reparsedentitylpeg
local unescapedentity=xml.unescapedentitylpeg
local parsedentity=reparsedentity
local function first(collected)
- return collected and collected[1]
+ return collected and collected[1]
end
local function last(collected)
- return collected and collected[#collected]
+ return collected and collected[#collected]
end
local function all(collected)
- return collected
+ return collected
end
local reverse=table.reversed
local function attribute(collected,name)
- if collected and #collected>0 then
- local at=collected[1].at
- return at and at[name]
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ return at and at[name]
+ end
end
local function att(id,name)
- local at=id.at
- return at and at[name]
+ local at=id.at
+ return at and at[name]
end
local function count(collected)
- return collected and #collected or 0
+ return collected and #collected or 0
end
local function position(collected,n)
- if not collected then
- return 0
- end
- local nc=#collected
- if nc==0 then
- return 0
- end
- n=tonumber(n) or 0
- if n<0 then
- return collected[nc+n+1]
- elseif n>0 then
- return collected[n]
- else
- return collected[1].mi or 0
- end
+ if not collected then
+ return 0
+ end
+ local nc=#collected
+ if nc==0 then
+ return 0
+ end
+ n=tonumber(n) or 0
+ if n<0 then
+ return collected[nc+n+1]
+ elseif n>0 then
+ return collected[n]
+ else
+ return collected[1].mi or 0
+ end
end
local function match(collected)
- return collected and #collected>0 and collected[1].mi or 0
+ return collected and #collected>0 and collected[1].mi or 0
end
local function index(collected)
- return collected and #collected>0 and collected[1].ni or 0
+ return collected and #collected>0 and collected[1].ni or 0
end
local function attributes(collected,arguments)
- if collected and #collected>0 then
- local at=collected[1].at
- if arguments then
- return at[arguments]
- elseif next(at) then
- return at
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ if arguments then
+ return at[arguments]
+ elseif next(at) then
+ return at
end
+ end
end
local function chainattribute(collected,arguments)
- if collected and #collected>0 then
- local e=collected[1]
- while e do
- local at=e.at
- if at then
- local a=at[arguments]
- if a then
- return a
- end
- else
- break
- end
- e=e.__p__
+ if collected and #collected>0 then
+ local e=collected[1]
+ while e do
+ local at=e.at
+ if at then
+ local a=at[arguments]
+ if a then
+ return a
end
+ else
+ break
+ end
+ e=e.__p__
end
- return ""
+ end
+ return ""
end
local function raw(collected)
- if collected and #collected>0 then
- local e=collected[1] or collected
- return e and xmltostring(e) or ""
- else
- return ""
- end
+ if collected and #collected>0 then
+ local e=collected[1] or collected
+ return e and xmltostring(e) or ""
+ else
+ return ""
+ end
end
local xmltexthandler=xmlnewhandlers {
- name="string",
- initialize=function()
- result={}
- return result
- end,
- finalize=function()
- return concat(result)
- end,
- handle=function(...)
- result[#result+1]=concat {... }
- end,
- escape=false,
+ name="string",
+ initialize=function()
+ result={}
+ return result
+ end,
+ finalize=function()
+ return concat(result)
+ end,
+ handle=function(...)
+ result[#result+1]=concat {... }
+ end,
+ escape=false,
}
local function xmltotext(root)
- local dt=root.dt
- if not dt then
- return ""
- end
- local nt=#dt
- if nt==0 then
- return ""
- elseif nt==1 and type(dt[1])=="string" then
- return dt[1]
- else
- return xmlserialize(root,xmltexthandler) or ""
- end
+ local dt=root.dt
+ if not dt then
+ return ""
+ end
+ local nt=#dt
+ if nt==0 then
+ return ""
+ elseif nt==1 and type(dt[1])=="string" then
+ return dt[1]
+ else
+ return xmlserialize(root,xmltexthandler) or ""
+ end
end
function xml.serializetotext(root)
- return root and xmlserialize(root,xmltexthandler) or ""
+ return root and xmlserialize(root,xmltexthandler) or ""
end
local function text(collected)
- if collected then
- local e=collected[1] or collected
- return e and xmltotext(e) or ""
- else
- return ""
- end
+ if collected then
+ local e=collected[1] or collected
+ return e and xmltotext(e) or ""
+ else
+ return ""
+ end
end
local function texts(collected)
- if not collected then
- return {}
- end
- local nc=#collected
- if nc==0 then
- return {}
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- if e and e.dt then
- n=n+1
- t[n]=e.dt
- end
- end
- return t
+ if not collected then
+ return {}
+ end
+ local nc=#collected
+ if nc==0 then
+ return {}
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ if e and e.dt then
+ n=n+1
+ t[n]=e.dt
+ end
+ end
+ return t
end
local function tag(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- return c and c.tg
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ return c and c.tg
end
local function name(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- if not c then
- elseif c.ns=="" then
- return c.tg
- else
- return c.ns..":"..c.tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ if not c then
+ elseif c.ns=="" then
+ return c.tg
+ else
+ return c.ns..":"..c.tg
+ end
end
local function tags(collected,nonamespace)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace or ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ local ns,tg=e.ns,e.tg
+ n=n+1
+ if nonamespace or ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
end
- return t
+ end
+ return t
end
local function empty(collected,spacesonly)
- if not collected then
- return true
- end
- local nc=#collected
- if nc==0 then
- return true
- end
- for c=1,nc do
- local e=collected[c]
- if e then
- local edt=e.dt
- if edt then
- local n=#edt
- if n==1 then
- local edk=edt[1]
- local typ=type(edk)
- if typ=="table" then
- return false
- elseif edk~="" then
- return false
- elseif spacesonly and not find(edk,"%S") then
- return false
- end
- elseif n>1 then
- return false
- end
- end
+ if not collected then
+ return true
+ end
+ local nc=#collected
+ if nc==0 then
+ return true
+ end
+ for c=1,nc do
+ local e=collected[c]
+ if e then
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==1 then
+ local edk=edt[1]
+ local typ=type(edk)
+ if typ=="table" then
+ return false
+ elseif edk~="" then
+ return false
+ elseif spacesonly and not find(edk,"%S") then
+ return false
+ end
+ elseif n>1 then
+ return false
end
+ end
end
- return true
+ end
+ return true
end
finalizers.first=first
finalizers.last=last
@@ -19368,124 +19376,124 @@ finalizers.name=name
finalizers.tags=tags
finalizers.empty=empty
function xml.first(id,pattern)
- return first(xmlfilter(id,pattern))
+ return first(xmlfilter(id,pattern))
end
function xml.last(id,pattern)
- return last(xmlfilter(id,pattern))
+ return last(xmlfilter(id,pattern))
end
function xml.count(id,pattern)
- return count(xmlfilter(id,pattern))
+ return count(xmlfilter(id,pattern))
end
function xml.attribute(id,pattern,a,default)
- return attribute(xmlfilter(id,pattern),a,default)
+ return attribute(xmlfilter(id,pattern),a,default)
end
function xml.raw(id,pattern)
- if pattern then
- return raw(xmlfilter(id,pattern))
- else
- return raw(id)
- end
+ if pattern then
+ return raw(xmlfilter(id,pattern))
+ else
+ return raw(id)
+ end
end
function xml.text(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- return collected and #collected>0 and xmltotext(collected[1]) or ""
- elseif id then
- return xmltotext(id) or ""
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ return collected and #collected>0 and xmltotext(collected[1]) or ""
+ elseif id then
+ return xmltotext(id) or ""
+ else
+ return ""
+ end
end
function xml.pure(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- if collected and #collected>0 then
- parsedentity=unescapedentity
- local s=collected and #collected>0 and xmltotext(collected[1]) or ""
- parsedentity=reparsedentity
- return s
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ if collected and #collected>0 then
+ parsedentity=unescapedentity
+ local s=collected and #collected>0 and xmltotext(collected[1]) or ""
+ parsedentity=reparsedentity
+ return s
else
- parsedentity=unescapedentity
- local s=xmltotext(id) or ""
- parsedentity=reparsedentity
- return s
+ return ""
end
+ else
+ parsedentity=unescapedentity
+ local s=xmltotext(id) or ""
+ parsedentity=reparsedentity
+ return s
+ end
end
xml.content=text
function xml.position(id,pattern,n)
- return position(xmlfilter(id,pattern),n)
+ return position(xmlfilter(id,pattern),n)
end
function xml.match(id,pattern)
- return match(xmlfilter(id,pattern))
+ return match(xmlfilter(id,pattern))
end
function xml.empty(id,pattern,spacesonly)
- return empty(xmlfilter(id,pattern),spacesonly)
+ return empty(xmlfilter(id,pattern),spacesonly)
end
xml.all=xml.filter
xml.index=xml.position
xml.found=xml.filter
local function totable(x)
- local t={}
- for e in xmlcollected(x[1] or x,"/*") do
- t[e.tg]=xmltostring(e.dt) or ""
- end
- return next(t) and t or nil
+ local t={}
+ for e in xmlcollected(x[1] or x,"/*") do
+ t[e.tg]=xmltostring(e.dt) or ""
+ end
+ return next(t) and t or nil
end
xml.table=totable
finalizers.table=totable
local function textonly(e,t)
- if e then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- textonly(e,t)
- else
- t[#t+1]=e
- end
- end
+ if e then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ textonly(e,t)
+ else
+ t[#t+1]=e
end
+ end
end
- return t
+ end
+ return t
end
function xml.textonly(e)
- return concat(textonly(e,{}))
+ return concat(textonly(e,{}))
end
function finalizers.lowerall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=lower(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[lower(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=lower(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[lower(k)]=v
end
+ e.at=t
+ end
end
+ end
end
function finalizers.upperall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=upper(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[upper(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=upper(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[upper(k)]=v
end
+ e.at=t
+ end
end
+ end
end
@@ -19495,14 +19503,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-xml"] = package.loaded["trac-xml"] or true
--- original size: 6407, stripped down to: 4965
+-- original size: 6407, stripped down to: 4640
if not modules then modules={} end modules ['trac-xml']={
- version=1.001,
- comment="companion to trac-log.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local formatters=string.formatters
local reporters=logs.reporters
@@ -19511,152 +19519,152 @@ local xmlcollected=xml.collected
local xmltext=xml.text
local xmlfirst=xml.first
local function showhelp(specification,...)
- local root=xml.convert(specification.helpinfo or "")
- if not root then
- return
- end
- local xs=xml.gethandlers("string")
- xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
- xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
- local wantedcategories=select("#",...)==0 and true or table.tohash {... }
- local nofcategories=xml.count(root,"/application/flags/category")
- local report=specification.report
- for category in xmlcollected(root,"/application/flags/category") do
- local categoryname=category.at.name or ""
- if wantedcategories==true or wantedcategories[categoryname] then
- if nofcategories>1 then
- report("%s options:",categoryname)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for flag in xmlcollected(subcategory,"/flag") do
- local name=flag.at.name
- local value=flag.at.value
- local short=xmltext(xmlfirst(flag,"/short"))
- if value then
- report("--%-20s %s",formatters["%s=%s"](name,value),short)
- else
- report("--%-20s %s",name,short)
- end
- end
- report()
- end
- end
- end
- for category in xmlcollected(root,"/application/examples/category") do
- local title=xmltext(xmlfirst(category,"/title"))
- if title and title~="" then
- report()
- report(title)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for example in xmlcollected(subcategory,"/example") do
- local command=xmltext(xmlfirst(example,"/command"))
- local comment=xmltext(xmlfirst(example,"/comment"))
- report(command)
- end
- report()
- end
- end
- for comment in xmlcollected(root,"/application/comments/comment") do
- local comment=xmltext(comment)
+ local root=xml.convert(specification.helpinfo or "")
+ if not root then
+ return
+ end
+ local xs=xml.gethandlers("string")
+ xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
+ xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
+ local wantedcategories=select("#",...)==0 and true or table.tohash {... }
+ local nofcategories=xml.count(root,"/application/flags/category")
+ local report=specification.report
+ for category in xmlcollected(root,"/application/flags/category") do
+ local categoryname=category.at.name or ""
+ if wantedcategories==true or wantedcategories[categoryname] then
+ if nofcategories>1 then
+ report("%s options:",categoryname)
report()
- report(comment)
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for flag in xmlcollected(subcategory,"/flag") do
+ local name=flag.at.name
+ local value=flag.at.value
+ local short=xmltext(xmlfirst(flag,"/short"))
+ if value then
+ report("--%-20s %s",formatters["%s=%s"](name,value),short)
+ else
+ report("--%-20s %s",name,short)
+ end
+ end
report()
+ end
+ end
+ end
+ for category in xmlcollected(root,"/application/examples/category") do
+ local title=xmltext(xmlfirst(category,"/title"))
+ if title and title~="" then
+ report()
+ report(title)
+ report()
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for example in xmlcollected(subcategory,"/example") do
+ local command=xmltext(xmlfirst(example,"/command"))
+ local comment=xmltext(xmlfirst(example,"/comment"))
+ report(command)
+ end
+ report()
end
+ end
+ for comment in xmlcollected(root,"/application/comments/comment") do
+ local comment=xmltext(comment)
+ report()
+ report(comment)
+ report()
+ end
end
local reporthelp=reporters.help
local exporthelp=reporters.export
local function xmlfound(t)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="table" then
- return false
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="table" then
+ return false
+ end
+ if type(helpinfo)~="string" then
+ helpinfo="Warning: no helpinfo found."
+ t.helpinfo=helpinfo
+ return false
+ end
+ if string.find(helpinfo,".xml$") then
+ local ownscript=environment.ownscript
+ local helpdata=false
+ if ownscript then
+ local helpfile=file.join(file.pathpart(ownscript),helpinfo)
+ helpdata=io.loaddata(helpfile)
+ if helpdata=="" then
+ helpdata=false
+ end
end
- if type(helpinfo)~="string" then
- helpinfo="Warning: no helpinfo found."
- t.helpinfo=helpinfo
- return false
+ if not helpdata then
+ local helpfile=resolvers.findfile(helpinfo,"tex")
+ helpdata=helpfile and io.loaddata(helpfile)
end
- if string.find(helpinfo,".xml$") then
- local ownscript=environment.ownscript
- local helpdata=false
- if ownscript then
- local helpfile=file.join(file.pathpart(ownscript),helpinfo)
- helpdata=io.loaddata(helpfile)
- if helpdata=="" then
- helpdata=false
- end
- end
- if not helpdata then
- local helpfile=resolvers.findfile(helpinfo,"tex")
- helpdata=helpfile and io.loaddata(helpfile)
- end
- if helpdata and helpdata~="" then
- helpinfo=helpdata
- else
- helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
- end
+ if helpdata and helpdata~="" then
+ helpinfo=helpdata
+ else
+ helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
end
- t.helpinfo=helpinfo
- return string.find(t.helpinfo,"^<%?xml") and true or false
+ end
+ t.helpinfo=helpinfo
+ return string.find(t.helpinfo,"^<%?xml") and true or false
end
function reporters.help(t,...)
- if xmlfound(t) then
- showhelp(t,...)
- else
- reporthelp(t,...)
- end
+ if xmlfound(t) then
+ showhelp(t,...)
+ else
+ reporthelp(t,...)
+ end
end
function reporters.export(t,methods,filename)
- if not xmlfound(t) then
- return exporthelp(t)
- end
- if not methods or methods=="" then
- methods=environment.arguments["exporthelp"]
- end
- if not filename or filename=="" then
- filename=environment.files[1]
- end
- dofile(resolvers.findfile("trac-exp.lua","tex"))
- local exporters=logs.exporters
- if not exporters or not methods then
- return exporthelp(t)
- end
- if methods=="all" then
- methods=table.keys(exporters)
- elseif type(methods)=="string" then
- methods=utilities.parsers.settings_to_array(methods)
- else
- return exporthelp(t)
- end
- if type(filename)~="string" or filename=="" then
- filename=false
- elseif file.pathpart(filename)=="" then
- t.report("export file %a will not be saved on the current path (safeguard)",filename)
- return
- end
- for i=1,#methods do
- local method=methods[i]
- local exporter=exporters[method]
- if exporter then
- local result=exporter(t,method)
- if result and result~="" then
- if filename then
- local fullname=file.replacesuffix(filename,method)
- t.report("saving export in %a",fullname)
- dir.mkdirs(file.pathpart(fullname))
- io.savedata(fullname,result)
- else
- reporters.lines(t,result)
- end
- else
- t.report("no output from exporter %a",method)
- end
+ if not xmlfound(t) then
+ return exporthelp(t)
+ end
+ if not methods or methods=="" then
+ methods=environment.arguments["exporthelp"]
+ end
+ if not filename or filename=="" then
+ filename=environment.files[1]
+ end
+ dofile(resolvers.findfile("trac-exp.lua","tex"))
+ local exporters=logs.exporters
+ if not exporters or not methods then
+ return exporthelp(t)
+ end
+ if methods=="all" then
+ methods=table.keys(exporters)
+ elseif type(methods)=="string" then
+ methods=utilities.parsers.settings_to_array(methods)
+ else
+ return exporthelp(t)
+ end
+ if type(filename)~="string" or filename=="" then
+ filename=false
+ elseif file.pathpart(filename)=="" then
+ t.report("export file %a will not be saved on the current path (safeguard)",filename)
+ return
+ end
+ for i=1,#methods do
+ local method=methods[i]
+ local exporter=exporters[method]
+ if exporter then
+ local result=exporter(t,method)
+ if result and result~="" then
+ if filename then
+ local fullname=file.replacesuffix(filename,method)
+ t.report("saving export in %a",fullname)
+ dir.mkdirs(file.pathpart(fullname))
+ io.savedata(fullname,result)
else
- t.report("unknown exporter %a",method)
+ reporters.lines(t,result)
end
+ else
+ t.report("no output from exporter %a",method)
+ end
+ else
+ t.report("unknown exporter %a",method)
end
+ end
end
@@ -19666,149 +19674,149 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-ini"] = package.loaded["data-ini"] or true
--- original size: 11099, stripped down to: 7516
+-- original size: 11099, stripped down to: 7152
if not modules then modules={} end modules ['data-ini']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local next,type,getmetatable,rawset=next,type,getmetatable,rawset
local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char
local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join
local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv
local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
local report_initialization=logs.reporter("resolvers","initialization")
resolvers=resolvers or {}
local resolvers=resolvers
texconfig.kpse_init=false
texconfig.shell_escape='t'
if not (environment and environment.default_texmfcnf) and kpse and kpse.default_texmfcnf then
- local default_texmfcnf=kpse.default_texmfcnf()
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
- default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
- environment.default_texmfcnf=default_texmfcnf
+ local default_texmfcnf=kpse.default_texmfcnf()
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
+ default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
+ environment.default_texmfcnf=default_texmfcnf
end
kpse={ original=kpse }
setmetatable(kpse,{
- __index=function(kp,name)
- report_initialization("fatal error: kpse library is accessed (key: %s)",name)
- os.exit()
- end
+ __index=function(kp,name)
+ report_initialization("fatal error: kpse library is accessed (key: %s)",name)
+ os.exit()
+ end
} )
do
- local osfontdir=osgetenv("OSFONTDIR")
- if osfontdir and osfontdir~="" then
- elseif osname=="windows" then
- ossetenv("OSFONTDIR","c:/windows/fonts//")
- elseif osname=="macosx" then
- ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
- end
+ local osfontdir=osgetenv("OSFONTDIR")
+ if osfontdir and osfontdir~="" then
+ elseif osname=="windows" then
+ ossetenv("OSFONTDIR","c:/windows/fonts//")
+ elseif osname=="macosx" then
+ ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
+ end
end
do
- local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
- if not homedir or homedir=="" then
- homedir=char(127)
- end
- homedir=file.collapsepath(homedir)
- ossetenv("HOME",homedir)
- ossetenv("USERPROFILE",homedir)
- environment.homedir=homedir
+ local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
+ if not homedir or homedir=="" then
+ homedir=char(127)
+ end
+ homedir=file.collapsepath(homedir)
+ ossetenv("HOME",homedir)
+ ossetenv("USERPROFILE",homedir)
+ environment.homedir=homedir
end
do
- local args=environment.originalarguments or arg
- if not environment.ownmain then
- environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
- end
- local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
- local ownpath=environment.ownpath or os.selfdir
- ownbin=file.collapsepath(ownbin)
- ownpath=file.collapsepath(ownpath)
- if not ownpath or ownpath=="" or ownpath=="unset" then
- ownpath=args[-1] or arg[-1]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- if not ownpath or ownpath=="" then
- ownpath=args[-0] or arg[-0]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- end
- local binary=ownbin
- if not ownpath or ownpath=="" then
- ownpath=ownpath and filedirname(binary)
- end
- if not ownpath or ownpath=="" then
- if os.binsuffix~="" then
- binary=file.replacesuffix(binary,os.binsuffix)
- end
- local path=osgetenv("PATH")
- if path then
- for p in gmatch(path,"[^"..io.pathseparator.."]+") do
- local b=filejoin(p,binary)
- if lfs.isfile(b) then
- local olddir=lfs.currentdir()
- if lfs.chdir(p) then
- local pp=lfs.currentdir()
- if trace_locating and p~=pp then
- report_initialization("following symlink %a to %a",p,pp)
- end
- ownpath=pp
- lfs.chdir(olddir)
- else
- if trace_locating then
- report_initialization("unable to check path %a",p)
- end
- ownpath=p
- end
- break
- end
- end
+ local args=environment.originalarguments or arg
+ if not environment.ownmain then
+ environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
+ end
+ local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
+ local ownpath=environment.ownpath or os.selfdir
+ ownbin=file.collapsepath(ownbin)
+ ownpath=file.collapsepath(ownpath)
+ if not ownpath or ownpath=="" or ownpath=="unset" then
+ ownpath=args[-1] or arg[-1]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ if not ownpath or ownpath=="" then
+ ownpath=args[-0] or arg[-0]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ end
+ local binary=ownbin
+ if not ownpath or ownpath=="" then
+ ownpath=ownpath and filedirname(binary)
+ end
+ if not ownpath or ownpath=="" then
+ if os.binsuffix~="" then
+ binary=file.replacesuffix(binary,os.binsuffix)
+ end
+ local path=osgetenv("PATH")
+ if path then
+ for p in gmatch(path,"[^"..io.pathseparator.."]+") do
+ local b=filejoin(p,binary)
+ if lfs.isfile(b) then
+ local olddir=lfs.currentdir()
+ if lfs.chdir(p) then
+ local pp=lfs.currentdir()
+ if trace_locating and p~=pp then
+ report_initialization("following symlink %a to %a",p,pp)
+ end
+ ownpath=pp
+ lfs.chdir(olddir)
+ else
+ if trace_locating then
+ report_initialization("unable to check path %a",p)
+ end
+ ownpath=p
end
+ break
+ end
end
- if not ownpath or ownpath=="" then
- ownpath="."
- report_initialization("forcing fallback to ownpath %a",ownpath)
- elseif trace_locating then
- report_initialization("using ownpath %a",ownpath)
- end
+ end
end
- environment.ownbin=ownbin
- environment.ownpath=ownpath
+ if not ownpath or ownpath=="" then
+ ownpath="."
+ report_initialization("forcing fallback to ownpath %a",ownpath)
+ elseif trace_locating then
+ report_initialization("using ownpath %a",ownpath)
+ end
+ end
+ environment.ownbin=ownbin
+ environment.ownpath=ownpath
end
resolvers.ownpath=environment.ownpath
function resolvers.getownpath()
- return environment.ownpath
+ return environment.ownpath
end
do
- local ownpath=environment.ownpath or dir.current()
- if ownpath then
- ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
- ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
- ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
- else
- report_initialization("error: unable to locate ownpath")
- os.exit()
- end
-end
-local texos=environment.texos or osgetenv("TEXOS")
+ local ownpath=environment.ownpath or dir.current()
+ if ownpath then
+ ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
+ ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
+ ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
+ else
+ report_initialization("error: unable to locate ownpath")
+ os.exit()
+ end
+end
+local texos=environment.texos or osgetenv("TEXOS")
local texmfos=environment.texmfos or osgetenv('SELFAUTODIR')
if not texos or texos=="" then
- texos=file.basename(texmfos)
+ texos=file.basename(texmfos)
end
ossetenv('TEXMFOS',texmfos)
-ossetenv('TEXOS',texos)
-ossetenv('SELFAUTOSYSTEM',os.platform)
+ossetenv('TEXOS',texos)
+ossetenv('SELFAUTOSYSTEM',os.platform)
environment.texos=texos
environment.texmfos=texmfos
local texroot=environment.texroot or osgetenv("TEXROOT")
if not texroot or texroot=="" then
- texroot=osgetenv('SELFAUTOPARENT')
- ossetenv('TEXROOT',texroot)
+ texroot=osgetenv('SELFAUTOPARENT')
+ ossetenv('TEXROOT',texroot)
end
environment.texroot=file.collapsepath(texroot)
local prefixes=utilities.storage.allocate()
@@ -19817,30 +19825,30 @@ local resolved={}
local abstract={}
local dynamic={}
function resolvers.resetresolve(str)
- resolved,abstract={},{}
+ resolved,abstract={},{}
end
function resolvers.allprefixes(separator)
- local all=table.sortedkeys(prefixes)
- if separator then
- for i=1,#all do
- all[i]=all[i]..":"
- end
+ local all=table.sortedkeys(prefixes)
+ if separator then
+ for i=1,#all do
+ all[i]=all[i]..":"
end
- return all
+ end
+ return all
end
local function _resolve_(method,target)
- local action=prefixes[method]
- if action then
- return action(target)
- else
- return method..":"..target
- end
+ local action=prefixes[method]
+ if action then
+ return action(target)
+ else
+ return method..":"..target
+ end
end
function resolvers.unresolve(str)
- return abstract[str] or str
+ return abstract[str] or str
end
function resolvers.setdynamic(str)
- dynamic[str]=true
+ dynamic[str]=true
end
local pattern=Cs((C(R("az")^2)*P(":")*C((1-S(" \"\';,"))^1)/_resolve_+P(1))^0)
local prefix=C(R("az")^2)*P(":")
@@ -19849,65 +19857,65 @@ local notarget=(#S(";,")+P(-1))*Cc("")
local p_resolve=Cs(((prefix*(target+notarget))/_resolve_+P(1))^0)
local p_simple=prefix*P(-1)
local function resolve(str)
- if type(str)=="table" then
- local res={}
- for i=1,#str do
- res[i]=resolve(str[i])
- end
- return res
- end
- local res=resolved[str]
- if res then
- return res
+ if type(str)=="table" then
+ local res={}
+ for i=1,#str do
+ res[i]=resolve(str[i])
end
- local simple=lpegmatch(p_simple,str)
- local action=prefixes[simple]
- if action then
- local res=action(res)
- if not dynamic[simple] then
- resolved[simple]=res
- abstract[res]=simple
- end
- return res
+ return res
+ end
+ local res=resolved[str]
+ if res then
+ return res
+ end
+ local simple=lpegmatch(p_simple,str)
+ local action=prefixes[simple]
+ if action then
+ local res=action(res)
+ if not dynamic[simple] then
+ resolved[simple]=res
+ abstract[res]=simple
end
- res=lpegmatch(p_resolve,str)
- resolved[str]=res
- abstract[res]=str
return res
+ end
+ res=lpegmatch(p_resolve,str)
+ resolved[str]=res
+ abstract[res]=str
+ return res
end
resolvers.resolve=resolve
if type(osuname)=="function" then
- for k,v in next,osuname() do
- if not prefixes[k] then
- prefixes[k]=function() return v end
- end
+ for k,v in next,osuname() do
+ if not prefixes[k] then
+ prefixes[k]=function() return v end
end
+ end
end
if ostype=="unix" then
- local pattern
- local function makepattern(t,k,v)
- if t then
- rawset(t,k,v)
- end
- local colon=P(":")
- for k,v in table.sortedpairs(prefixes) do
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- pattern=Cs((p*colon+colon/";"+P(1))^0)
- end
- makepattern()
- table.setmetatablenewindex(prefixes,makepattern)
- function resolvers.repath(str)
- return lpegmatch(pattern,str)
+ local pattern
+ local function makepattern(t,k,v)
+ if t then
+ rawset(t,k,v)
+ end
+ local colon=P(":")
+ for k,v in table.sortedpairs(prefixes) do
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
end
+ pattern=Cs((p*colon+colon/";"+P(1))^0)
+ end
+ makepattern()
+ table.setmetatablenewindex(prefixes,makepattern)
+ function resolvers.repath(str)
+ return lpegmatch(pattern,str)
+ end
else
- function resolvers.repath(str)
- return str
- end
+ function resolvers.repath(str)
+ return str
+ end
end
@@ -19917,14 +19925,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-exp"] = package.loaded["data-exp"] or true
--- original size: 18105, stripped down to: 11207
+-- original size: 18105, stripped down to: 10389
if not modules then modules={} end modules ['data-exp']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub
local concat,sort=table.concat,table.sort
@@ -19934,21 +19942,21 @@ local Ct,Cs,Cc,Carg,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.P,lpeg.C,lpeg.S
local type,next=type,next
local isdir=lfs.isdir
local collapsepath,joinpath,basename=file.collapsepath,file.join,file.basename
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
local report_expansions=logs.reporter("resolvers","expansions")
local report_globbing=logs.reporter("resolvers","globbing")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
local function f_both(a,b)
- local t,n={},0
- for sb in gmatch(b,"[^,]+") do
- for sa in gmatch(a,"[^,]+") do
- n=n+1;t[n]=sa..sb
- end
+ local t,n={},0
+ for sb in gmatch(b,"[^,]+") do
+ for sa in gmatch(a,"[^,]+") do
+ n=n+1;t[n]=sa..sb
end
- return concat(t,",")
+ end
+ return concat(t,",")
end
local comma=P(",")
local nocomma=(1-comma)^1
@@ -19958,7 +19966,7 @@ local after=Cs((Carg(1)*nocomma+docomma)^0)
local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0)
local function f_first (a,b) return lpegmatch(after,b,1,a) end
local function f_second(a,b) return lpegmatch(before,a,1,b) end
-local function f_both (a,b) return lpegmatch(both,b,1,a) end
+local function f_both (a,b) return lpegmatch(both,b,1,a) end
local left=P("{")
local right=P("}")
local var=P((1-S("{}" ))^0)
@@ -19971,141 +19979,141 @@ local l_rest=Cs((left*var*(left/"")*var*(right/"")*var*right+other )^0 )
local stripper_1=lpeg.stripper ("{}@")
local replacer_1=lpeg.replacer { { ",}",",@}" },{ "{,","{@," },}
local function splitpathexpr(str,newlist,validate)
- if trace_expansions then
- report_expansions("expanding variable %a",str)
- end
- local t,ok,done=newlist or {},false,false
- local n=#t
- str=lpegmatch(replacer_1,str)
+ if trace_expansions then
+ report_expansions("expanding variable %a",str)
+ end
+ local t,ok,done=newlist or {},false,false
+ local n=#t
+ str=lpegmatch(replacer_1,str)
+ repeat
+ local old=str
repeat
- local old=str
- repeat
- local old=str
- str=lpegmatch(l_first,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_second,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_both,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_rest,str)
- until old==str
- until old==str
- str=lpegmatch(stripper_1,str)
- if validate then
- for s in gmatch(str,"[^,]+") do
- s=validate(s)
- if s then
- n=n+1
- t[n]=s
- end
- end
- else
- for s in gmatch(str,"[^,]+") do
- n=n+1
- t[n]=s
- end
+ local old=str
+ str=lpegmatch(l_first,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_second,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_both,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_rest,str)
+ until old==str
+ until old==str
+ str=lpegmatch(stripper_1,str)
+ if validate then
+ for s in gmatch(str,"[^,]+") do
+ s=validate(s)
+ if s then
+ n=n+1
+ t[n]=s
+ end
end
- if trace_expansions then
- for k=1,#t do
- report_expansions("% 4i: %s",k,t[k])
- end
+ else
+ for s in gmatch(str,"[^,]+") do
+ n=n+1
+ t[n]=s
end
- return t
+ end
+ if trace_expansions then
+ for k=1,#t do
+ report_expansions("% 4i: %s",k,t[k])
+ end
+ end
+ return t
end
local function validate(s)
- s=collapsepath(s)
- return s~="" and not find(s,"^!*unset/*$") and s
+ s=collapsepath(s)
+ return s~="" and not find(s,"^!*unset/*$") and s
end
resolvers.validatedpath=validate
function resolvers.expandedpathfromlist(pathlist)
- local newlist={}
- for k=1,#pathlist do
- splitpathexpr(pathlist[k],newlist,validate)
- end
- return newlist
+ local newlist={}
+ for k=1,#pathlist do
+ splitpathexpr(pathlist[k],newlist,validate)
+ end
+ return newlist
end
local usedhomedir=nil
-local donegation=(P("!")/"" )^0
+local donegation=(P("!")/"" )^0
local doslashes=(P("\\")/"/"+1)^0
local function expandedhome()
- if not usedhomedir then
- usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
- if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
- if trace_expansions then
- report_expansions("no home dir set, ignoring dependent path using current path")
- end
- usedhomedir="."
- end
+ if not usedhomedir then
+ usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
+ if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
+ if trace_expansions then
+ report_expansions("no home dir set, ignoring dependent path using current path")
+ end
+ usedhomedir="."
end
- return usedhomedir
+ end
+ return usedhomedir
end
local dohome=((P("~")+P("$HOME")+P("%HOME%"))/expandedhome)^0
local cleanup=Cs(donegation*dohome*doslashes)
resolvers.cleanpath=function(str)
- return str and lpegmatch(cleanup,str) or ""
+ return str and lpegmatch(cleanup,str) or ""
end
local expandhome=P("~")/"$HOME"
local dodouble=P('"')/""*(expandhome+(1-P('"')))^0*P('"')/""
local dosingle=P("'")/""*(expandhome+(1-P("'")))^0*P("'")/""
-local dostring=(expandhome+1 )^0
+local dostring=(expandhome+1 )^0
local stripper=Cs(
- lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
+ lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
)
function resolvers.checkedvariable(str)
- return type(str)=="string" and lpegmatch(stripper,str) or str
+ return type(str)=="string" and lpegmatch(stripper,str) or str
end
local cache={}
local splitter=lpeg.tsplitat(";")
local backslashswapper=lpeg.replacer("\\","/")
local function splitconfigurationpath(str)
- if str then
- local found=cache[str]
- if not found then
- if str=="" then
- found={}
- else
- local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
- found={}
- local noffound=0
- for i=1,#split do
- local s=split[i]
- if not find(s,"^{*unset}*") then
- noffound=noffound+1
- found[noffound]=s
- end
- end
- if trace_expansions then
- report_expansions("splitting path specification %a",str)
- for k=1,noffound do
- report_expansions("% 4i: %s",k,found[k])
- end
- end
- cache[str]=found
- end
+ if str then
+ local found=cache[str]
+ if not found then
+ if str=="" then
+ found={}
+ else
+ local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
+ found={}
+ local noffound=0
+ for i=1,#split do
+ local s=split[i]
+ if not find(s,"^{*unset}*") then
+ noffound=noffound+1
+ found[noffound]=s
+ end
end
- return found
+ if trace_expansions then
+ report_expansions("splitting path specification %a",str)
+ for k=1,noffound do
+ report_expansions("% 4i: %s",k,found[k])
+ end
+ end
+ cache[str]=found
+ end
end
+ return found
+ end
end
resolvers.splitconfigurationpath=splitconfigurationpath
function resolvers.splitpath(str)
- if type(str)=='table' then
- return str
- else
- return splitconfigurationpath(str)
- end
+ if type(str)=='table' then
+ return str
+ else
+ return splitconfigurationpath(str)
+ end
end
function resolvers.joinpath(str)
- if type(str)=='table' then
- return joinpath(str)
- else
- return str
- end
+ if type(str)=='table' then
+ return joinpath(str)
+ else
+ return str
+ end
end
local attributes,directory=lfs.attributes,lfs.dir
local weird=P(".")^1+lpeg.anywhere(S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t"))
@@ -20118,201 +20126,201 @@ local fullcache={}
local nofsharedscans=0
local addcasecraptoo=true
local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant)
- local full=path=="" and spec or (spec..path..'/')
- local dirlist={}
- local nofdirs=0
- local pattern=tolerant and lessweird or weird
- local filelist={}
- local noffiles=0
- for name in directory(full) do
- if not lpegmatch(pattern,name) then
- local mode=attributes(full..name,"mode")
- if mode=="file" then
- n=n+1
- noffiles=noffiles+1
- filelist[noffiles]=name
- elseif mode=="directory" then
- m=m+1
- nofdirs=nofdirs+1
- if path~="" then
- dirlist[nofdirs]=path.."/"..name
- else
- dirlist[nofdirs]=name
- end
- end
+ local full=path=="" and spec or (spec..path..'/')
+ local dirlist={}
+ local nofdirs=0
+ local pattern=tolerant and lessweird or weird
+ local filelist={}
+ local noffiles=0
+ for name in directory(full) do
+ if not lpegmatch(pattern,name) then
+ local mode=attributes(full..name,"mode")
+ if mode=="file" then
+ n=n+1
+ noffiles=noffiles+1
+ filelist[noffiles]=name
+ elseif mode=="directory" then
+ m=m+1
+ nofdirs=nofdirs+1
+ if path~="" then
+ dirlist[nofdirs]=path.."/"..name
+ else
+ dirlist[nofdirs]=name
end
+ end
end
- if noffiles>0 then
- sort(filelist)
- for i=1,noffiles do
- local name=filelist[i]
- local lower=lower(name)
- local paths=files[lower]
- if paths then
- if onlyone then
- else
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- if addcasecraptoo then
- local paths=files[name]
- if not paths then
- files[name]=path
- elseif type(paths)=="string" then
- files[name]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- end
- if type(paths)=="string" then
- files[lower]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- else
- files[lower]=path
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- end
+ end
+ if noffiles>0 then
+ sort(filelist)
+ for i=1,noffiles do
+ local name=filelist[i]
+ local lower=lower(name)
+ local paths=files[lower]
+ if paths then
+ if onlyone then
+ else
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
+ if addcasecraptoo then
+ local paths=files[name]
+ if not paths then
+ files[name]=path
+ elseif type(paths)=="string" then
+ files[name]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
+ end
+ if type(paths)=="string" then
+ files[lower]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
- end
- if nofdirs>0 then
- sort(dirlist)
- for i=1,nofdirs do
- files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
+ else
+ files[lower]=path
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
end
+ end
+ end
+ end
+ if nofdirs>0 then
+ sort(dirlist)
+ for i=1,nofdirs do
+ files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
end
- scancache[sub(full,1,-2)]=files
- return files,remap,n,m,r
+ end
+ scancache[sub(full,1,-2)]=files
+ return files,remap,n,m,r
end
function resolvers.scanfiles(path,branch,usecache,onlyonce,tolerant)
- local realpath=resolveprefix(path)
- if usecache then
- local content=fullcache[realpath]
- if content then
- if trace_locating then
- report_expansions("using cached scan of path %a, branch %a",path,branch or path)
- end
- nofsharedscans=nofsharedscans+1
- return content
- end
- end
- statistics.starttiming(timer)
+ local realpath=resolveprefix(path)
+ if usecache then
+ local content=fullcache[realpath]
+ if content then
+ if trace_locating then
+ report_expansions("using cached scan of path %a, branch %a",path,branch or path)
+ end
+ nofsharedscans=nofsharedscans+1
+ return content
+ end
+ end
+ statistics.starttiming(timer)
+ if trace_locating then
+ report_expansions("scanning path %a, branch %a",path,branch or path)
+ end
+ local content
+ if isdir(realpath) then
+ local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
+ content={
+ metadata={
+ path=path,
+ files=n,
+ directories=m,
+ remappings=r,
+ },
+ files=files,
+ remap=remap,
+ }
if trace_locating then
- report_expansions("scanning path %a, branch %a",path,branch or path)
+ report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
end
- local content
- if isdir(realpath) then
- local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
- content={
- metadata={
- path=path,
- files=n,
- directories=m,
- remappings=r,
- },
- files=files,
- remap=remap,
- }
- if trace_locating then
- report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
- end
- else
- content={
- metadata={
- path=path,
- files=0,
- directories=0,
- remappings=0,
- },
- files={},
- remap={},
- }
- if trace_locating then
- report_expansions("invalid path %a",realpath)
- end
- end
- if usecache then
- scanned[#scanned+1]=realpath
- fullcache[realpath]=content
+ else
+ content={
+ metadata={
+ path=path,
+ files=0,
+ directories=0,
+ remappings=0,
+ },
+ files={},
+ remap={},
+ }
+ if trace_locating then
+ report_expansions("invalid path %a",realpath)
end
- nofscans=nofscans+1
- statistics.stoptiming(timer)
- return content
+ end
+ if usecache then
+ scanned[#scanned+1]=realpath
+ fullcache[realpath]=content
+ end
+ nofscans=nofscans+1
+ statistics.stoptiming(timer)
+ return content
end
function resolvers.simplescanfiles(path,branch,usecache)
- return resolvers.scanfiles(path,branch,usecache,true,true)
+ return resolvers.scanfiles(path,branch,usecache,true,true)
end
function resolvers.scandata()
- table.sort(scanned)
- return {
- n=nofscans,
- shared=nofsharedscans,
- time=statistics.elapsedtime(timer),
- paths=scanned,
- }
+ table.sort(scanned)
+ return {
+ n=nofscans,
+ shared=nofsharedscans,
+ time=statistics.elapsedtime(timer),
+ paths=scanned,
+ }
end
function resolvers.get_from_content(content,path,name)
- if not content then
- return
- end
- local files=content.files
- if not files then
- return
- end
- local remap=content.remap
- if not remap then
- return
- end
- if name then
- local used=lower(name)
- return path,remap[used] or used
- else
- local name=path
- local used=lower(name)
- local path=files[used]
- if path then
- return path,remap[used] or used
- end
- end
+ if not content then
+ return
+ end
+ local files=content.files
+ if not files then
+ return
+ end
+ local remap=content.remap
+ if not remap then
+ return
+ end
+ if name then
+ local used=lower(name)
+ return path,remap[used] or used
+ else
+ local name=path
+ local used=lower(name)
+ local path=files[used]
+ if path then
+ return path,remap[used] or used
+ end
+ end
end
local nothing=function() end
function resolvers.filtered_from_content(content,pattern)
- if content and type(pattern)=="string" then
- local pattern=lower(pattern)
- local files=content.files
- local remap=content.remap
- if files and remap then
- local f=sortedkeys(files)
- local n=#f
- local i=0
- local function iterator()
- while i<n do
- i=i+1
- local k=f[i]
- if find(k,pattern) then
- return files[k],remap and remap[k] or k
- end
- end
- end
- return iterator
+ if content and type(pattern)=="string" then
+ local pattern=lower(pattern)
+ local files=content.files
+ local remap=content.remap
+ if files and remap then
+ local f=sortedkeys(files)
+ local n=#f
+ local i=0
+ local function iterator()
+ while i<n do
+ i=i+1
+ local k=f[i]
+ if find(k,pattern) then
+ return files[k],remap and remap[k] or k
+ end
end
+ end
+ return iterator
end
- return nothing
+ end
+ return nothing
end
@@ -20322,14 +20330,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-env"] = package.loaded["data-env"] or true
--- original size: 9360, stripped down to: 6903
+-- original size: 9360, stripped down to: 6312
if not modules then modules={} end modules ['data-env']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local lower,gsub=string.lower,string.gsub
local next=next
@@ -20349,255 +20357,255 @@ resolvers.suffixmap=suffixmap
resolvers.usertypes=usertypes
local luasuffixes=utilities.lua.suffixes
local relations=allocate {
- core={
- ofm={
- names={ "ofm","omega font metric","omega font metrics" },
- variable='OFMFONTS',
- suffixes={ 'ofm','tfm' },
- },
- ovf={
- names={ "ovf","omega virtual font","omega virtual fonts" },
- variable='OVFFONTS',
- suffixes={ 'ovf','vf' },
- },
- tfm={
- names={ "tfm","tex font metric","tex font metrics" },
- variable='TFMFONTS',
- suffixes={ 'tfm' },
- },
- vf={
- names={ "vf","virtual font","virtual fonts" },
- variable='VFFONTS',
- suffixes={ 'vf' },
- },
- otf={
- names={ "otf","opentype","opentype font","opentype fonts"},
- variable='OPENTYPEFONTS',
- suffixes={ 'otf' },
- },
- ttf={
- names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
- variable='TTFONTS',
- suffixes={ 'ttf','ttc','dfont' },
- },
- afm={
- names={ "afm","adobe font metric","adobe font metrics" },
- variable="AFMFONTS",
- suffixes={ "afm" },
- },
- pfb={
- names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
- variable='T1FONTS',
- suffixes={ 'pfb','pfa' },
- },
- fea={
- names={ "fea","font feature","font features","font feature file","font feature files" },
- variable='FONTFEATURES',
- suffixes={ 'fea' },
- },
- cid={
- names={ "cid","cid map","cid maps","cid file","cid files" },
- variable='FONTCIDMAPS',
- suffixes={ 'cid','cidmap' },
- },
- fmt={
- names={ "fmt","format","tex format" },
- variable='TEXFORMATS',
- suffixes={ 'fmt' },
- },
- mem={
- names={ 'mem',"metapost format" },
- variable='MPMEMS',
- suffixes={ 'mem' },
- },
- mp={
- names={ "mp" },
- variable='MPINPUTS',
- suffixes={ 'mp','mpvi','mpiv','mpii' },
- usertype=true,
- },
- tex={
- names={ "tex" },
- variable='TEXINPUTS',
- suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
- usertype=true,
- },
- icc={
- names={ "icc","icc profile","icc profiles" },
- variable='ICCPROFILES',
- suffixes={ 'icc' },
- },
- texmfscripts={
- names={ "texmfscript","texmfscripts","script","scripts" },
- variable='TEXMFSCRIPTS',
- suffixes={ 'lua','rb','pl','py' },
- },
- lua={
- names={ "lua" },
- variable='LUAINPUTS',
- suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
- usertype=true,
- },
- lib={
- names={ "lib" },
- variable='CLUAINPUTS',
- suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
- },
- bib={
- names={ 'bib' },
- variable='BIBINPUTS',
- suffixes={ 'bib' },
- usertype=true,
- },
- bst={
- names={ 'bst' },
- variable='BSTINPUTS',
- suffixes={ 'bst' },
- usertype=true,
- },
- fontconfig={
- names={ 'fontconfig','fontconfig file','fontconfig files' },
- variable='FONTCONFIG_PATH',
- },
- pk={
- names={ "pk" },
- variable='PKFONTS',
- suffixes={ 'pk' },
- },
+ core={
+ ofm={
+ names={ "ofm","omega font metric","omega font metrics" },
+ variable='OFMFONTS',
+ suffixes={ 'ofm','tfm' },
+ },
+ ovf={
+ names={ "ovf","omega virtual font","omega virtual fonts" },
+ variable='OVFFONTS',
+ suffixes={ 'ovf','vf' },
+ },
+ tfm={
+ names={ "tfm","tex font metric","tex font metrics" },
+ variable='TFMFONTS',
+ suffixes={ 'tfm' },
},
- obsolete={
- enc={
- names={ "enc","enc files","enc file","encoding files","encoding file" },
- variable='ENCFONTS',
- suffixes={ 'enc' },
- },
- map={
- names={ "map","map files","map file" },
- variable='TEXFONTMAPS',
- suffixes={ 'map' },
- },
- lig={
- names={ "lig files","lig file","ligature file","ligature files" },
- variable='LIGFONTS',
- suffixes={ 'lig' },
- },
- opl={
- names={ "opl" },
- variable='OPLFONTS',
- suffixes={ 'opl' },
- },
- ovp={
- names={ "ovp" },
- variable='OVPFONTS',
- suffixes={ 'ovp' },
- },
+ vf={
+ names={ "vf","virtual font","virtual fonts" },
+ variable='VFFONTS',
+ suffixes={ 'vf' },
},
- kpse={
- base={
- names={ 'base',"metafont format" },
- variable='MFBASES',
- suffixes={ 'base','bas' },
- },
- cmap={
- names={ 'cmap','cmap files','cmap file' },
- variable='CMAPFONTS',
- suffixes={ 'cmap' },
- },
- cnf={
- names={ 'cnf' },
- suffixes={ 'cnf' },
- },
- web={
- names={ 'web' },
- suffixes={ 'web','ch' }
- },
- cweb={
- names={ 'cweb' },
- suffixes={ 'w','web','ch' },
- },
- gf={
- names={ 'gf' },
- suffixes={ '<resolution>gf' },
- },
- mf={
- names={ 'mf' },
- variable='MFINPUTS',
- suffixes={ 'mf' },
- },
- mft={
- names={ 'mft' },
- suffixes={ 'mft' },
- },
- pk={
- names={ 'pk' },
- suffixes={ '<resolution>pk' },
- },
+ otf={
+ names={ "otf","opentype","opentype font","opentype fonts"},
+ variable='OPENTYPEFONTS',
+ suffixes={ 'otf' },
},
+ ttf={
+ names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
+ variable='TTFONTS',
+ suffixes={ 'ttf','ttc','dfont' },
+ },
+ afm={
+ names={ "afm","adobe font metric","adobe font metrics" },
+ variable="AFMFONTS",
+ suffixes={ "afm" },
+ },
+ pfb={
+ names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
+ variable='T1FONTS',
+ suffixes={ 'pfb','pfa' },
+ },
+ fea={
+ names={ "fea","font feature","font features","font feature file","font feature files" },
+ variable='FONTFEATURES',
+ suffixes={ 'fea' },
+ },
+ cid={
+ names={ "cid","cid map","cid maps","cid file","cid files" },
+ variable='FONTCIDMAPS',
+ suffixes={ 'cid','cidmap' },
+ },
+ fmt={
+ names={ "fmt","format","tex format" },
+ variable='TEXFORMATS',
+ suffixes={ 'fmt' },
+ },
+ mem={
+ names={ 'mem',"metapost format" },
+ variable='MPMEMS',
+ suffixes={ 'mem' },
+ },
+ mp={
+ names={ "mp" },
+ variable='MPINPUTS',
+ suffixes={ 'mp','mpvi','mpiv','mpii' },
+ usertype=true,
+ },
+ tex={
+ names={ "tex" },
+ variable='TEXINPUTS',
+ suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
+ usertype=true,
+ },
+ icc={
+ names={ "icc","icc profile","icc profiles" },
+ variable='ICCPROFILES',
+ suffixes={ 'icc' },
+ },
+ texmfscripts={
+ names={ "texmfscript","texmfscripts","script","scripts" },
+ variable='TEXMFSCRIPTS',
+ suffixes={ 'lua','rb','pl','py' },
+ },
+ lua={
+ names={ "lua" },
+ variable='LUAINPUTS',
+ suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
+ usertype=true,
+ },
+ lib={
+ names={ "lib" },
+ variable='CLUAINPUTS',
+ suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
+ },
+ bib={
+ names={ 'bib' },
+ variable='BIBINPUTS',
+ suffixes={ 'bib' },
+ usertype=true,
+ },
+ bst={
+ names={ 'bst' },
+ variable='BSTINPUTS',
+ suffixes={ 'bst' },
+ usertype=true,
+ },
+ fontconfig={
+ names={ 'fontconfig','fontconfig file','fontconfig files' },
+ variable='FONTCONFIG_PATH',
+ },
+ pk={
+ names={ "pk" },
+ variable='PKFONTS',
+ suffixes={ 'pk' },
+ },
+ },
+ obsolete={
+ enc={
+ names={ "enc","enc files","enc file","encoding files","encoding file" },
+ variable='ENCFONTS',
+ suffixes={ 'enc' },
+ },
+ map={
+ names={ "map","map files","map file" },
+ variable='TEXFONTMAPS',
+ suffixes={ 'map' },
+ },
+ lig={
+ names={ "lig files","lig file","ligature file","ligature files" },
+ variable='LIGFONTS',
+ suffixes={ 'lig' },
+ },
+ opl={
+ names={ "opl" },
+ variable='OPLFONTS',
+ suffixes={ 'opl' },
+ },
+ ovp={
+ names={ "ovp" },
+ variable='OVPFONTS',
+ suffixes={ 'ovp' },
+ },
+ },
+ kpse={
+ base={
+ names={ 'base',"metafont format" },
+ variable='MFBASES',
+ suffixes={ 'base','bas' },
+ },
+ cmap={
+ names={ 'cmap','cmap files','cmap file' },
+ variable='CMAPFONTS',
+ suffixes={ 'cmap' },
+ },
+ cnf={
+ names={ 'cnf' },
+ suffixes={ 'cnf' },
+ },
+ web={
+ names={ 'web' },
+ suffixes={ 'web','ch' }
+ },
+ cweb={
+ names={ 'cweb' },
+ suffixes={ 'w','web','ch' },
+ },
+ gf={
+ names={ 'gf' },
+ suffixes={ '<resolution>gf' },
+ },
+ mf={
+ names={ 'mf' },
+ variable='MFINPUTS',
+ suffixes={ 'mf' },
+ },
+ mft={
+ names={ 'mft' },
+ suffixes={ 'mft' },
+ },
+ pk={
+ names={ 'pk' },
+ suffixes={ '<resolution>pk' },
+ },
+ },
}
resolvers.relations=relations
function resolvers.updaterelations()
- for category,categories in next,relations do
- for name,relation in next,categories do
- local rn=relation.names
- local rv=relation.variable
- if rn and rv then
- local rs=relation.suffixes
- local ru=relation.usertype
- for i=1,#rn do
- local rni=lower(gsub(rn[i]," ",""))
- formats[rni]=rv
- if rs then
- suffixes[rni]=rs
- for i=1,#rs do
- local rsi=rs[i]
- suffixmap[rsi]=rni
- end
- end
- end
- if ru then
- usertypes[name]=true
- end
+ for category,categories in next,relations do
+ for name,relation in next,categories do
+ local rn=relation.names
+ local rv=relation.variable
+ if rn and rv then
+ local rs=relation.suffixes
+ local ru=relation.usertype
+ for i=1,#rn do
+ local rni=lower(gsub(rn[i]," ",""))
+ formats[rni]=rv
+ if rs then
+ suffixes[rni]=rs
+ for i=1,#rs do
+ local rsi=rs[i]
+ suffixmap[rsi]=rni
end
+ end
+ end
+ if ru then
+ usertypes[name]=true
end
+ end
end
+ end
end
resolvers.updaterelations()
local function simplified(t,k)
- return k and rawget(t,lower(gsub(k," ",""))) or nil
+ return k and rawget(t,lower(gsub(k," ",""))) or nil
end
setmetatableindex(formats,simplified)
setmetatableindex(suffixes,simplified)
setmetatableindex(suffixmap,simplified)
function resolvers.suffixofformat(str)
- local s=suffixes[str]
- return s and s[1] or ""
+ local s=suffixes[str]
+ return s and s[1] or ""
end
function resolvers.suffixofformat(str)
- return suffixes[str] or {}
+ return suffixes[str] or {}
end
for name,format in next,formats do
- dangerous[name]=true
+ dangerous[name]=true
end
dangerous.tex=nil
function resolvers.formatofvariable(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.formatofsuffix(str)
- return suffixmap[suffixonly(str)] or 'tex'
+ return suffixmap[suffixonly(str)] or 'tex'
end
function resolvers.variableofformat(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.variableofformatorsuffix(str)
- local v=formats[str]
- if v then
- return v
- end
- v=suffixmap[suffixonly(str)]
- if v then
- return formats[v]
- end
- return ''
+ local v=formats[str]
+ if v then
+ return v
+ end
+ v=suffixmap[suffixonly(str)]
+ if v then
+ return formats[v]
+ end
+ return ''
end
@@ -20607,14 +20615,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16116, stripped down to: 11459
+-- original size: 16116, stripped down to: 10782
if not modules then modules={} end modules ['data-tmp']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub,concat=string.format,string.lower,string.gsub,table.concat
local concat=table.concat
@@ -20622,19 +20630,19 @@ local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile
local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
local formatters=string.formatters
local next,type=next,type
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
local report_caches=logs.reporter("resolvers","caches")
local report_resolvers=logs.reporter("resolvers","caching")
local resolvers=resolvers
local cleanpath=resolvers.cleanpath
-local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
-local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
+local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
+local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
local compile=utilities.lua.compile
function utilities.lua.compile(luafile,lucfile,cleanup,strip)
- if cleanup==nil then cleanup=directive_cleanup end
- if strip==nil then strip=directive_strip end
- return compile(luafile,lucfile,cleanup,strip)
+ if cleanup==nil then cleanup=directive_cleanup end
+ if strip==nil then strip=directive_strip end
+ return compile(luafile,lucfile,cleanup,strip)
end
caches=caches or {}
local caches=caches
@@ -20649,324 +20657,324 @@ caches.relocate=false
caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
local writable,readables,usedreadables=nil,{},{}
local function identify()
- local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- cachepath=file.collapsepath(cachepath)
- local valid=isdir(cachepath)
- if valid then
- if is_readable(cachepath) then
- readables[#readables+1]=cachepath
- if not writable and is_writable(cachepath) then
- writable=cachepath
- end
- end
- elseif not writable and caches.force then
- local cacheparent=file.dirname(cachepath)
- if is_writable(cacheparent) and true then
- if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
- mkdirs(cachepath)
- if isdir(cachepath) and is_writable(cachepath) then
- report_caches("path %a created",cachepath)
- writable=cachepath
- readables[#readables+1]=cachepath
- end
- end
- end
- end
+ local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ cachepath=file.collapsepath(cachepath)
+ local valid=isdir(cachepath)
+ if valid then
+ if is_readable(cachepath) then
+ readables[#readables+1]=cachepath
+ if not writable and is_writable(cachepath) then
+ writable=cachepath
end
- end
- end
- local texmfcaches=caches.defaults
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- cachepath=resolvers.expansion(cachepath)
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- local valid=isdir(cachepath)
- if valid and is_readable(cachepath) then
- if not writable and is_writable(cachepath) then
- readables[#readables+1]=cachepath
- writable=cachepath
- break
- end
- end
+ end
+ elseif not writable and caches.force then
+ local cacheparent=file.dirname(cachepath)
+ if is_writable(cacheparent) and true then
+ if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
+ mkdirs(cachepath)
+ if isdir(cachepath) and is_writable(cachepath) then
+ report_caches("path %a created",cachepath)
+ writable=cachepath
+ readables[#readables+1]=cachepath
+ end
end
+ end
end
+ end
end
- if not writable then
- report_caches("fatal error: there is no valid writable cache path defined")
- os.exit()
- elseif #readables==0 then
- report_caches("fatal error: there is no valid readable cache path defined")
- os.exit()
- end
- writable=dir.expandname(resolvers.cleanpath(writable))
- local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
- if tree then
- caches.tree=tree
- writable=mkdirs(writable,base,more,tree)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more,tree)
- end
- else
- writable=mkdirs(writable,base,more)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more)
+ end
+ local texmfcaches=caches.defaults
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ cachepath=resolvers.expansion(cachepath)
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ local valid=isdir(cachepath)
+ if valid and is_readable(cachepath) then
+ if not writable and is_writable(cachepath) then
+ readables[#readables+1]=cachepath
+ writable=cachepath
+ break
+ end
end
+ end
end
- if trace_cache then
- for i=1,#readables do
- report_caches("using readable path %a (order %s)",readables[i],i)
- end
- report_caches("using writable path %a",writable)
+ end
+ if not writable then
+ report_caches("fatal error: there is no valid writable cache path defined")
+ os.exit()
+ elseif #readables==0 then
+ report_caches("fatal error: there is no valid readable cache path defined")
+ os.exit()
+ end
+ writable=dir.expandname(resolvers.cleanpath(writable))
+ local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
+ if tree then
+ caches.tree=tree
+ writable=mkdirs(writable,base,more,tree)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more,tree)
end
- identify=function()
- return writable,readables
+ else
+ writable=mkdirs(writable,base,more)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more)
+ end
+ end
+ if trace_cache then
+ for i=1,#readables do
+ report_caches("using readable path %a (order %s)",readables[i],i)
end
+ report_caches("using writable path %a",writable)
+ end
+ identify=function()
return writable,readables
+ end
+ return writable,readables
end
function caches.usedpaths(separator)
- local writable,readables=identify()
- if #readables>1 then
- local result={}
- local done={}
- for i=1,#readables do
- local readable=readables[i]
- if readable==writable then
- done[readable]=true
- result[#result+1]=formatters["readable+writable: %a"](readable)
- elseif usedreadables[i] then
- done[readable]=true
- result[#result+1]=formatters["readable: %a"](readable)
- end
- end
- if not done[writable] then
- result[#result+1]=formatters["writable: %a"](writable)
- end
- return concat(result,separator or " | ")
- else
- return writable or "?"
+ local writable,readables=identify()
+ if #readables>1 then
+ local result={}
+ local done={}
+ for i=1,#readables do
+ local readable=readables[i]
+ if readable==writable then
+ done[readable]=true
+ result[#result+1]=formatters["readable+writable: %a"](readable)
+ elseif usedreadables[i] then
+ done[readable]=true
+ result[#result+1]=formatters["readable: %a"](readable)
+ end
+ end
+ if not done[writable] then
+ result[#result+1]=formatters["writable: %a"](writable)
end
+ return concat(result,separator or " | ")
+ else
+ return writable or "?"
+ end
end
function caches.configfiles()
- return concat(resolvers.configurationfiles(),";")
+ return concat(resolvers.configurationfiles(),";")
end
function caches.hashed(tree)
- tree=gsub(tree,"[\\/]+$","")
- tree=lower(tree)
- local hash=md5.hex(tree)
- if trace_cache or trace_locating then
- report_caches("hashing tree %a, hash %a",tree,hash)
- end
- return hash
+ tree=gsub(tree,"[\\/]+$","")
+ tree=lower(tree)
+ local hash=md5.hex(tree)
+ if trace_cache or trace_locating then
+ report_caches("hashing tree %a, hash %a",tree,hash)
+ end
+ return hash
end
function caches.treehash()
- local tree=caches.configfiles()
- if not tree or tree=="" then
- return false
- else
- return caches.hashed(tree)
- end
+ local tree=caches.configfiles()
+ if not tree or tree=="" then
+ return false
+ else
+ return caches.hashed(tree)
+ end
end
local r_cache,w_cache={},{}
local function getreadablepaths(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=r_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done={}
- for i=1,#readables do
- done[i]=file.join(readables[i],...)
- end
- else
- done=readables
- end
- r_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=r_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done={}
+ for i=1,#readables do
+ done[i]=file.join(readables[i],...)
+ end
+ else
+ done=readables
end
- return done
+ r_cache[hash]=done
+ end
+ return done
end
local function getwritablepath(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=w_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done=mkdirs(writable,...)
- else
- done=writable
- end
- w_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=w_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done=mkdirs(writable,...)
+ else
+ done=writable
end
- return done
+ w_cache[hash]=done
+ end
+ return done
end
caches.getreadablepaths=getreadablepaths
caches.getwritablepath=getwritablepath
function caches.getfirstreadablefile(filename,...)
- local fullname,path=caches.setfirstwritablefile(filename,...)
+ local fullname,path=caches.setfirstwritablefile(filename,...)
+ if is_readable(fullname) then
+ return fullname,path
+ end
+ local rd=getreadablepaths(...)
+ for i=1,#rd do
+ local path=rd[i]
+ local fullname=file.join(path,filename)
if is_readable(fullname) then
- return fullname,path
- end
- local rd=getreadablepaths(...)
- for i=1,#rd do
- local path=rd[i]
- local fullname=file.join(path,filename)
- if is_readable(fullname) then
- usedreadables[i]=true
- return fullname,path
- end
+ usedreadables[i]=true
+ return fullname,path
end
- return fullname,path
+ end
+ return fullname,path
end
function caches.setfirstwritablefile(filename,...)
- local wr=getwritablepath(...)
- local fullname=file.join(wr,filename)
- return fullname,wr
+ local wr=getwritablepath(...)
+ local fullname=file.join(wr,filename)
+ return fullname,wr
end
function caches.define(category,subcategory)
- return function()
- return getwritablepath(category,subcategory)
- end
+ return function()
+ return getwritablepath(category,subcategory)
+ end
end
function caches.setluanames(path,name)
- return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
+ return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
end
function caches.loaddata(readables,name,writable)
- if type(readables)=="string" then
- readables={ readables }
+ if type(readables)=="string" then
+ readables={ readables }
+ end
+ for i=1,#readables do
+ local path=readables[i]
+ local loader=false
+ local tmaname,tmcname=caches.setluanames(path,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader and isfile(tmaname) then
+ local tmacrap,tmcname=caches.setluanames(writable,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ utilities.lua.compile(tmaname,tmcname)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader then
+ loader=loadfile(tmaname)
+ end
end
- for i=1,#readables do
- local path=readables[i]
- local loader=false
- local tmaname,tmcname=caches.setluanames(path,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader and isfile(tmaname) then
- local tmacrap,tmcname=caches.setluanames(writable,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- utilities.lua.compile(tmaname,tmcname)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader then
- loader=loadfile(tmaname)
- end
- end
- if loader then
- loader=loader()
- collectgarbage("step")
- return loader
- end
+ if loader then
+ loader=loader()
+ collectgarbage("step")
+ return loader
end
- return false
+ end
+ return false
end
function caches.is_writable(filepath,filename)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- return is_writable(tmaname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ return is_writable(tmaname)
end
local saveoptions={ compact=true }
function caches.savedata(filepath,filename,data,raw)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- data.cache_uuid=os.uuid()
- if caches.direct then
- file.savedata(tmaname,table.serialize(data,true,saveoptions))
- else
- table.tofile(tmaname,data,true,saveoptions)
- end
- utilities.lua.compile(tmaname,tmcname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ data.cache_uuid=os.uuid()
+ if caches.direct then
+ file.savedata(tmaname,table.serialize(data,true,saveoptions))
+ else
+ table.tofile(tmaname,data,true,saveoptions)
+ end
+ utilities.lua.compile(tmaname,tmcname)
end
local content_state={}
function caches.contentstate()
- return content_state or {}
+ return content_state or {}
end
function caches.loadcontent(cachename,dataname,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
- if blob then
- local data=blob()
- if data and data.content then
- if data.type==dataname then
- if data.version==resolvers.cacheversion then
- content_state[#content_state+1]=data.uuid
- if trace_locating then
- report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
- end
- return data.content
- else
- report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
- end
- else
- report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
- end
- elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
+ if blob then
+ local data=blob()
+ if data and data.content then
+ if data.type==dataname then
+ if data.version==resolvers.cacheversion then
+ content_state[#content_state+1]=data.uuid
+ if trace_locating then
+ report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
+ end
+ return data.content
+ else
+ report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
end
+ else
+ report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
+ end
elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
end
+ elseif trace_locating then
+ report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ end
end
function caches.collapsecontent(content)
- for k,v in next,content do
- if type(v)=="table" and #v==1 then
- content[k]=v[1]
- end
+ for k,v in next,content do
+ if type(v)=="table" and #v==1 then
+ content[k]=v[1]
end
+ end
end
function caches.savecontent(cachename,dataname,content,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local luaname=addsuffix(filename,luasuffixes.lua)
- local lucname=addsuffix(filename,luasuffixes.luc)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local luaname=addsuffix(filename,luasuffixes.lua)
+ local lucname=addsuffix(filename,luasuffixes.luc)
+ if trace_locating then
+ report_resolvers("preparing %a for %a",dataname,cachename)
+ end
+ local data={
+ type=dataname,
+ root=cachename,
+ version=resolvers.cacheversion,
+ date=os.date("%Y-%m-%d"),
+ time=os.date("%H:%M:%S"),
+ content=content,
+ uuid=os.uuid(),
+ }
+ local ok=io.savedata(luaname,table.serialize(data,true))
+ if ok then
if trace_locating then
- report_resolvers("preparing %a for %a",dataname,cachename)
- end
- local data={
- type=dataname,
- root=cachename,
- version=resolvers.cacheversion,
- date=os.date("%Y-%m-%d"),
- time=os.date("%H:%M:%S"),
- content=content,
- uuid=os.uuid(),
- }
- local ok=io.savedata(luaname,table.serialize(data,true))
- if ok then
- if trace_locating then
- report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
- end
- if utilities.lua.compile(luaname,lucname) then
- if trace_locating then
- report_resolvers("%a compiled to %a",dataname,lucname)
- end
- return true
- else
- if trace_locating then
- report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
- end
- os.remove(lucname)
- end
- elseif trace_locating then
- report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
end
+ if utilities.lua.compile(luaname,lucname) then
+ if trace_locating then
+ report_resolvers("%a compiled to %a",dataname,lucname)
+ end
+ return true
+ else
+ if trace_locating then
+ report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
+ end
+ os.remove(lucname)
+ end
+ elseif trace_locating then
+ report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ end
end
@@ -20976,14 +20984,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-met"] = package.loaded["data-met"] or true
--- original size: 5310, stripped down to: 3980
+-- original size: 5310, stripped down to: 3784
if not modules then modules={} end modules ['data-met']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local find,format=string.find,string.format
local sequenced=table.sequenced
@@ -20997,86 +21005,86 @@ local allocate=utilities.storage.allocate
local resolvers=resolvers
local registered={}
local function splitmethod(filename)
- if not filename then
- return { scheme="unknown",original=filename }
- end
- if type(filename)=="table" then
- return filename
- end
- filename=file.collapsepath(filename,".")
- if not find(filename,"://",1,true) then
- return { scheme="file",path=filename,original=filename,filename=filename }
- end
- local specification=url.hashed(filename)
- if not specification.scheme or specification.scheme=="" then
- return { scheme="file",path=filename,original=filename,filename=filename }
- else
- return specification
- end
+ if not filename then
+ return { scheme="unknown",original=filename }
+ end
+ if type(filename)=="table" then
+ return filename
+ end
+ filename=file.collapsepath(filename,".")
+ if not find(filename,"://",1,true) then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ end
+ local specification=url.hashed(filename)
+ if not specification.scheme or specification.scheme=="" then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ else
+ return specification
+ end
end
resolvers.splitmethod=splitmethod
local function methodhandler(what,first,...)
- local method=registered[what]
- if method then
- local how,namespace=method.how,method.namespace
- if how=="uri" or how=="url" then
- local specification=splitmethod(first)
- local scheme=specification.scheme
- local resolver=namespace and namespace[scheme]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
- end
- return resolver(specification,...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
- end
- return resolver(specification,...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
- end
- end
- elseif how=="tag" then
- local resolver=namespace and namespace[first]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,first)
- end
- return resolver(...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
- end
- return resolver(...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
- end
- end
+ local method=registered[what]
+ if method then
+ local how,namespace=method.how,method.namespace
+ if how=="uri" or how=="url" then
+ local specification=splitmethod(first)
+ local scheme=specification.scheme
+ local resolver=namespace and namespace[scheme]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
+ end
+ return resolver(specification,...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
+ end
+ return resolver(specification,...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
end
- else
- report_methods("resolving, invalid method %a")
+ end
+ elseif how=="tag" then
+ local resolver=namespace and namespace[first]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,first)
+ end
+ return resolver(...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
+ end
+ return resolver(...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
+ end
+ end
end
+ else
+ report_methods("resolving, invalid method %a")
+ end
end
resolvers.methodhandler=methodhandler
function resolvers.registermethod(name,namespace,how)
- registered[name]={ how=how or "tag",namespace=namespace }
- namespace["byscheme"]=function(scheme,filename,...)
- if scheme=="file" then
- return methodhandler(name,filename,...)
- else
- return methodhandler(name,addurlscheme(filename,scheme),...)
- end
+ registered[name]={ how=how or "tag",namespace=namespace }
+ namespace["byscheme"]=function(scheme,filename,...)
+ if scheme=="file" then
+ return methodhandler(name,filename,...)
+ else
+ return methodhandler(name,addurlscheme(filename,scheme),...)
end
+ end
end
-local concatinators=allocate { notfound=file.join }
-local locators=allocate { notfound=function() end }
-local hashers=allocate { notfound=function() end }
-local generators=allocate { notfound=function() end }
+local concatinators=allocate { notfound=file.join }
+local locators=allocate { notfound=function() end }
+local hashers=allocate { notfound=function() end }
+local generators=allocate { notfound=function() end }
resolvers.concatinators=concatinators
resolvers.locators=locators
resolvers.hashers=hashers
@@ -21094,14 +21102,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-res"] = package.loaded["data-res"] or true
--- original size: 68195, stripped down to: 47727
+-- original size: 68195, stripped down to: 43680
if not modules then modules={} end modules ['data-res']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local gsub,find,lower,upper,match,gmatch=string.gsub,string.find,string.lower,string.upper,string.match,string.gmatch
local concat,insert,remove=table.concat,table.insert,table.remove
@@ -21126,11 +21134,11 @@ local isfile=lfs.isfile
local isdir=lfs.isdir
local setmetatableindex=table.setmetatableindex
local luasuffixes=utilities.lua.suffixes
-local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
-local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
+local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
+local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
local report_resolving=logs.reporter("resolvers","resolving")
local resolvers=resolvers
local expandedpathfromlist=resolvers.expandedpathfromlist
@@ -21151,15 +21159,15 @@ resolvers.luacnfname="texmfcnf.lua"
resolvers.luacnffallback="contextcnf.lua"
resolvers.luacnfstate="unknown"
if environment.default_texmfcnf then
- resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
+ resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
else
- resolvers.luacnfspec=concat ({
- "home:texmf/web2c",
- "selfautoparent:/texmf-local/web2c",
- "selfautoparent:/texmf-context/web2c",
- "selfautoparent:/texmf-dist/web2c",
- "selfautoparent:/texmf/web2c",
- },";")
+ resolvers.luacnfspec=concat ({
+ "home:texmf/web2c",
+ "selfautoparent:/texmf-local/web2c",
+ "selfautoparent:/texmf-context/web2c",
+ "selfautoparent:/texmf-dist/web2c",
+ "selfautoparent:/texmf/web2c",
+ },";")
end
local unset_variable="unset"
local formats=resolvers.formats
@@ -21170,24 +21178,24 @@ local suffixmap=resolvers.suffixmap
resolvers.defaultsuffixes={ "tex" }
local instance=nil
function resolvers.setenv(key,value,raw)
- if instance then
- instance.environment[key]=value
- ossetenv(key,raw and value or resolveprefix(value))
- end
+ if instance then
+ instance.environment[key]=value
+ ossetenv(key,raw and value or resolveprefix(value))
+ end
end
local function getenv(key)
- local value=rawget(instance.environment,key)
- if value and value~="" then
- return value
- else
- local e=osgetenv(key)
- return e~=nil and e~="" and checkedvariable(e) or ""
- end
+ local value=rawget(instance.environment,key)
+ if value and value~="" then
+ return value
+ else
+ local e=osgetenv(key)
+ return e~=nil and e~="" and checkedvariable(e) or ""
+ end
end
resolvers.getenv=getenv
resolvers.env=getenv
local function resolvevariable(k)
- return instance.expansions[k]
+ return instance.expansions[k]
end
local dollarstripper=lpeg.stripper("$")
local inhibitstripper=P("!")^0*Cs(P(1)^0)
@@ -21201,1506 +21209,1506 @@ local somevariable=R("az","AZ","09","__","--")^1/resolvevariable
local variable=(P("$")/"")*(somevariable+(P("{")/"")*somevariable*(P("}")/""))
local variableresolver=Cs((variable+P(1))^0)
local function expandedvariable(var)
- return lpegmatch(variableexpander,var) or var
+ return lpegmatch(variableexpander,var) or var
end
function resolvers.reset()
- if trace_locating then
- report_resolving("creating instance")
- end
- local environment={}
- local variables={}
- local expansions={}
- local order={}
- instance={
- environment=environment,
- variables=variables,
- expansions=expansions,
- order=order,
- files={},
- setups={},
- found={},
- foundintrees={},
- hashes={},
- hashed={},
- pathlists=false,
- specification={},
- lists={},
- data={},
- fakepaths={},
- remember=true,
- diskcache=true,
- renewcache=false,
- renewtree=false,
- loaderror=false,
- savelists=true,
- pattern=nil,
- force_suffixes=true,
- pathstack={},
- }
- setmetatableindex(variables,function(t,k)
- local v
- for i=1,#order do
- v=order[i][k]
- if v~=nil then
- t[k]=v
- return v
- end
- end
- if v==nil then
- v=""
- end
+ if trace_locating then
+ report_resolving("creating instance")
+ end
+ local environment={}
+ local variables={}
+ local expansions={}
+ local order={}
+ instance={
+ environment=environment,
+ variables=variables,
+ expansions=expansions,
+ order=order,
+ files={},
+ setups={},
+ found={},
+ foundintrees={},
+ hashes={},
+ hashed={},
+ pathlists=false,
+ specification={},
+ lists={},
+ data={},
+ fakepaths={},
+ remember=true,
+ diskcache=true,
+ renewcache=false,
+ renewtree=false,
+ loaderror=false,
+ savelists=true,
+ pattern=nil,
+ force_suffixes=true,
+ pathstack={},
+ }
+ setmetatableindex(variables,function(t,k)
+ local v
+ for i=1,#order do
+ v=order[i][k]
+ if v~=nil then
t[k]=v
return v
- end)
- setmetatableindex(environment,function(t,k)
- local v=osgetenv(k)
- if v==nil then
- v=variables[k]
- end
- if v~=nil then
- v=checkedvariable(v) or ""
- end
- v=resolvers.repath(v)
- t[k]=v
- return v
- end)
- setmetatableindex(expansions,function(t,k)
- local v=environment[k]
- if type(v)=="string" then
- v=lpegmatch(variableresolver,v)
- v=lpegmatch(variablecleaner,v)
- end
- t[k]=v
- return v
- end)
+ end
+ end
+ if v==nil then
+ v=""
+ end
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(environment,function(t,k)
+ local v=osgetenv(k)
+ if v==nil then
+ v=variables[k]
+ end
+ if v~=nil then
+ v=checkedvariable(v) or ""
+ end
+ v=resolvers.repath(v)
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(expansions,function(t,k)
+ local v=environment[k]
+ if type(v)=="string" then
+ v=lpegmatch(variableresolver,v)
+ v=lpegmatch(variablecleaner,v)
+ end
+ t[k]=v
+ return v
+ end)
end
function resolvers.initialized()
- return instance~=nil
+ return instance~=nil
end
local function reset_hashes()
- instance.lists={}
- instance.pathlists=false
- instance.found={}
+ instance.lists={}
+ instance.pathlists=false
+ instance.found={}
end
local function reset_caches()
- instance.lists={}
- instance.pathlists=false
+ instance.lists={}
+ instance.pathlists=false
end
local slash=P("/")
local pathexpressionpattern=Cs (
- Cc("^")*(
- Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+ Cc("^")*(
+ Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+slash^2/"/"+(1-slash)*P(-1)*Cc("/")+P(1)
- )^1*Cc("$")
+ )^1*Cc("$")
)
local cache={}
local function makepathexpression(str)
- if str=="." then
- return "^%./$"
- else
- local c=cache[str]
- if not c then
- c=lpegmatch(pathexpressionpattern,str)
- cache[str]=c
- end
- return c
+ if str=="." then
+ return "^%./$"
+ else
+ local c=cache[str]
+ if not c then
+ c=lpegmatch(pathexpressionpattern,str)
+ cache[str]=c
end
+ return c
+ end
end
local function reportcriticalvariables(cnfspec)
- if trace_locating then
- for i=1,#resolvers.criticalvars do
- local k=resolvers.criticalvars[i]
- local v=resolvers.getenv(k) or "unknown"
- report_resolving("variable %a set to %a",k,v)
- end
- report_resolving()
- if cnfspec then
- report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
- end
- report_resolving()
+ if trace_locating then
+ for i=1,#resolvers.criticalvars do
+ local k=resolvers.criticalvars[i]
+ local v=resolvers.getenv(k) or "unknown"
+ report_resolving("variable %a set to %a",k,v)
+ end
+ report_resolving()
+ if cnfspec then
+ report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
end
- reportcriticalvariables=function() end
+ report_resolving()
+ end
+ reportcriticalvariables=function() end
end
local function identify_configuration_files()
- local specification=instance.specification
- if #specification==0 then
- local cnfspec=getenv("TEXMFCNF")
- if cnfspec=="" then
- cnfspec=resolvers.luacnfspec
- resolvers.luacnfstate="default"
- else
- resolvers.luacnfstate="environment"
- end
- reportcriticalvariables(cnfspec)
- local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
- local function locatecnf(luacnfname,kind)
- for i=1,#cnfpaths do
- local filepath=cnfpaths[i]
- local filename=collapsepath(filejoin(filepath,luacnfname))
- local realname=resolveprefix(filename)
- if trace_locating then
- local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
- local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
- report_resolving("looking for %s %a on %s path %a from specification %a",
- kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
- end
- if isfile(realname) then
- specification[#specification+1]=filename
- if trace_locating then
- report_resolving("found %s configuration file %a",kind,realname)
- end
- end
- end
- end
- locatecnf(resolvers.luacnfname,"regular")
- if #specification==0 then
- locatecnf(resolvers.luacnffallback,"fallback")
- end
+ local specification=instance.specification
+ if #specification==0 then
+ local cnfspec=getenv("TEXMFCNF")
+ if cnfspec=="" then
+ cnfspec=resolvers.luacnfspec
+ resolvers.luacnfstate="default"
+ else
+ resolvers.luacnfstate="environment"
+ end
+ reportcriticalvariables(cnfspec)
+ local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
+ local function locatecnf(luacnfname,kind)
+ for i=1,#cnfpaths do
+ local filepath=cnfpaths[i]
+ local filename=collapsepath(filejoin(filepath,luacnfname))
+ local realname=resolveprefix(filename)
if trace_locating then
- report_resolving()
+ local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
+ local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
+ report_resolving("looking for %s %a on %s path %a from specification %a",
+ kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
+ end
+ if isfile(realname) then
+ specification[#specification+1]=filename
+ if trace_locating then
+ report_resolving("found %s configuration file %a",kind,realname)
+ end
end
- elseif trace_locating then
- report_resolving("configuration files already identified")
+ end
end
+ locatecnf(resolvers.luacnfname,"regular")
+ if #specification==0 then
+ locatecnf(resolvers.luacnffallback,"fallback")
+ end
+ if trace_locating then
+ report_resolving()
+ end
+ elseif trace_locating then
+ report_resolving("configuration files already identified")
+ end
end
local function load_configuration_files()
- local specification=instance.specification
- if #specification>0 then
- local luacnfname=resolvers.luacnfname
- for i=1,#specification do
- local filename=specification[i]
- local pathname=filedirname(filename)
- local filename=filejoin(pathname,luacnfname)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local setups=instance.setups
- local data=blob()
- local parent=data and data.parent
- if parent then
- local filename=filejoin(pathname,parent)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local parentdata=blob()
- if parentdata then
- report_resolving("loading configuration file %a",filename)
- data=table.merged(parentdata,data)
- end
- end
- end
- data=data and data.content
- if data then
- if trace_locating then
- report_resolving("loading configuration file %a",filename)
- report_resolving()
- end
- local variables=data.variables or {}
- local warning=false
- for k,v in next,data do
- local variant=type(v)
- if variant=="table" then
- initializesetter(filename,k,v)
- elseif variables[k]==nil then
- if trace_locating and not warning then
- report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
- k,resolveprefix(filename))
- warning=true
- end
- variables[k]=v
- end
- end
- setups[pathname]=variables
- if resolvers.luacnfstate=="default" then
- local cnfspec=variables["TEXMFCNF"]
- if cnfspec then
- if trace_locating then
- report_resolving("reloading configuration due to TEXMF redefinition")
- end
- resolvers.setenv("TEXMFCNF",cnfspec)
- instance.specification={}
- identify_configuration_files()
- load_configuration_files()
- resolvers.luacnfstate="configuration"
- break
- end
- end
- else
- if trace_locating then
- report_resolving("skipping configuration file %a (no content)",filename)
- end
- setups[pathname]={}
- instance.loaderror=true
- end
- elseif trace_locating then
- report_resolving("skipping configuration file %a (no valid format)",filename)
+ local specification=instance.specification
+ if #specification>0 then
+ local luacnfname=resolvers.luacnfname
+ for i=1,#specification do
+ local filename=specification[i]
+ local pathname=filedirname(filename)
+ local filename=filejoin(pathname,luacnfname)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local setups=instance.setups
+ local data=blob()
+ local parent=data and data.parent
+ if parent then
+ local filename=filejoin(pathname,parent)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local parentdata=blob()
+ if parentdata then
+ report_resolving("loading configuration file %a",filename)
+ data=table.merged(parentdata,data)
end
- instance.order[#instance.order+1]=instance.setups[pathname]
- if instance.loaderror then
- break
+ end
+ end
+ data=data and data.content
+ if data then
+ if trace_locating then
+ report_resolving("loading configuration file %a",filename)
+ report_resolving()
+ end
+ local variables=data.variables or {}
+ local warning=false
+ for k,v in next,data do
+ local variant=type(v)
+ if variant=="table" then
+ initializesetter(filename,k,v)
+ elseif variables[k]==nil then
+ if trace_locating and not warning then
+ report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
+ k,resolveprefix(filename))
+ warning=true
+ end
+ variables[k]=v
+ end
+ end
+ setups[pathname]=variables
+ if resolvers.luacnfstate=="default" then
+ local cnfspec=variables["TEXMFCNF"]
+ if cnfspec then
+ if trace_locating then
+ report_resolving("reloading configuration due to TEXMF redefinition")
+ end
+ resolvers.setenv("TEXMFCNF",cnfspec)
+ instance.specification={}
+ identify_configuration_files()
+ load_configuration_files()
+ resolvers.luacnfstate="configuration"
+ break
end
+ end
+ else
+ if trace_locating then
+ report_resolving("skipping configuration file %a (no content)",filename)
+ end
+ setups[pathname]={}
+ instance.loaderror=true
end
- elseif trace_locating then
- report_resolving("warning: no lua configuration files found")
+ elseif trace_locating then
+ report_resolving("skipping configuration file %a (no valid format)",filename)
+ end
+ instance.order[#instance.order+1]=instance.setups[pathname]
+ if instance.loaderror then
+ break
+ end
end
+ elseif trace_locating then
+ report_resolving("warning: no lua configuration files found")
+ end
end
function resolvers.configurationfiles()
- return instance.specification or {}
+ return instance.specification or {}
end
local function load_file_databases()
- instance.loaderror=false
- instance.files={}
- if not instance.renewcache then
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- resolvers.hashers.byscheme(hash.type,hash.name)
- if instance.loaderror then break end
- end
+ instance.loaderror=false
+ instance.files={}
+ if not instance.renewcache then
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ resolvers.hashers.byscheme(hash.type,hash.name)
+ if instance.loaderror then break end
end
+ end
end
local function locate_file_databases()
- local texmfpaths=resolvers.expandedpathlist("TEXMF")
- if #texmfpaths>0 then
- for i=1,#texmfpaths do
- local path=collapsepath(texmfpaths[i])
- path=gsub(path,"/+$","")
- local stripped=lpegmatch(inhibitstripper,path)
- if stripped~="" then
- local runtime=stripped==path
- path=cleanpath(path)
- local spec=resolvers.splitmethod(stripped)
- if runtime and (spec.noscheme or spec.scheme=="file") then
- stripped="tree:///"..stripped
- elseif spec.scheme=="cache" or spec.scheme=="file" then
- stripped=spec.path
- end
- if trace_locating then
- if runtime then
- report_resolving("locating list of %a (runtime) (%s)",path,stripped)
- else
- report_resolving("locating list of %a (cached)",path)
- end
- end
- methodhandler('locators',stripped)
- end
+ local texmfpaths=resolvers.expandedpathlist("TEXMF")
+ if #texmfpaths>0 then
+ for i=1,#texmfpaths do
+ local path=collapsepath(texmfpaths[i])
+ path=gsub(path,"/+$","")
+ local stripped=lpegmatch(inhibitstripper,path)
+ if stripped~="" then
+ local runtime=stripped==path
+ path=cleanpath(path)
+ local spec=resolvers.splitmethod(stripped)
+ if runtime and (spec.noscheme or spec.scheme=="file") then
+ stripped="tree:///"..stripped
+ elseif spec.scheme=="cache" or spec.scheme=="file" then
+ stripped=spec.path
end
if trace_locating then
- report_resolving()
+ if runtime then
+ report_resolving("locating list of %a (runtime) (%s)",path,stripped)
+ else
+ report_resolving("locating list of %a (cached)",path)
+ end
end
- elseif trace_locating then
- report_resolving("no texmf paths are defined (using TEXMF)")
- end
-end
-local function generate_file_databases()
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- methodhandler('generators',hash.name)
+ methodhandler('locators',stripped)
+ end
end
if trace_locating then
- report_resolving()
+ report_resolving()
end
+ elseif trace_locating then
+ report_resolving("no texmf paths are defined (using TEXMF)")
+ end
+end
+local function generate_file_databases()
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ methodhandler('generators',hash.name)
+ end
+ if trace_locating then
+ report_resolving()
+ end
end
local function save_file_databases()
- for i=1,#instance.hashes do
- local hash=instance.hashes[i]
- local cachename=hash.name
- if hash.cache then
- local content=instance.files[cachename]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",cachename)
- end
- caches.savecontent(cachename,"files",content)
- elseif trace_locating then
- report_resolving("not saving runtime tree %a",cachename)
- end
+ for i=1,#instance.hashes do
+ local hash=instance.hashes[i]
+ local cachename=hash.name
+ if hash.cache then
+ local content=instance.files[cachename]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",cachename)
+ end
+ caches.savecontent(cachename,"files",content)
+ elseif trace_locating then
+ report_resolving("not saving runtime tree %a",cachename)
end
+ end
end
function resolvers.renew(hashname)
- if hashname and hashname~="" then
- local expanded=resolvers.expansion(hashname) or ""
- if expanded~="" then
- if trace_locating then
- report_resolving("identifying tree %a from %a",expanded,hashname)
- end
- hashname=expanded
- else
- if trace_locating then
- report_resolving("identifying tree %a",hashname)
- end
- end
- local realpath=resolveprefix(hashname)
- if isdir(realpath) then
- if trace_locating then
- report_resolving("using path %a",realpath)
- end
- methodhandler('generators',hashname)
- local content=instance.files[hashname]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",hashname)
- end
- caches.savecontent(hashname,"files",content)
- else
- report_resolving("invalid path %a",realpath)
- end
+ if hashname and hashname~="" then
+ local expanded=resolvers.expansion(hashname) or ""
+ if expanded~="" then
+ if trace_locating then
+ report_resolving("identifying tree %a from %a",expanded,hashname)
+ end
+ hashname=expanded
+ else
+ if trace_locating then
+ report_resolving("identifying tree %a",hashname)
+ end
end
+ local realpath=resolveprefix(hashname)
+ if isdir(realpath) then
+ if trace_locating then
+ report_resolving("using path %a",realpath)
+ end
+ methodhandler('generators',hashname)
+ local content=instance.files[hashname]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",hashname)
+ end
+ caches.savecontent(hashname,"files",content)
+ else
+ report_resolving("invalid path %a",realpath)
+ end
+ end
end
local function load_databases()
- locate_file_databases()
- if instance.diskcache and not instance.renewcache then
- load_file_databases()
- if instance.loaderror then
- generate_file_databases()
- save_file_databases()
- end
- else
- generate_file_databases()
- if instance.renewcache then
- save_file_databases()
- end
+ locate_file_databases()
+ if instance.diskcache and not instance.renewcache then
+ load_file_databases()
+ if instance.loaderror then
+ generate_file_databases()
+ save_file_databases()
+ end
+ else
+ generate_file_databases()
+ if instance.renewcache then
+ save_file_databases()
end
+ end
end
function resolvers.appendhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a appended",name)
- end
- insert(instance.hashes,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a appended",name)
end
+ insert(instance.hashes,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.prependhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a prepended",name)
- end
- insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a prepended",name)
end
+ insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.extendtexmfvariable(specification)
- local t=resolvers.splitpath(getenv("TEXMF"))
- insert(t,1,specification)
- local newspec=concat(t,",")
- if instance.environment["TEXMF"] then
- instance.environment["TEXMF"]=newspec
- elseif instance.variables["TEXMF"] then
- instance.variables["TEXMF"]=newspec
- else
- end
- reset_hashes()
+ local t=resolvers.splitpath(getenv("TEXMF"))
+ insert(t,1,specification)
+ local newspec=concat(t,",")
+ if instance.environment["TEXMF"] then
+ instance.environment["TEXMF"]=newspec
+ elseif instance.variables["TEXMF"] then
+ instance.variables["TEXMF"]=newspec
+ else
+ end
+ reset_hashes()
end
function resolvers.splitexpansions()
- local ie=instance.expansions
- for k,v in next,ie do
- local t,tn,h,p={},0,{},splitconfigurationpath(v)
- for kk=1,#p do
- local vv=p[kk]
- if vv~="" and not h[vv] then
- tn=tn+1
- t[tn]=vv
- h[vv]=true
- end
- end
- if #t>1 then
- ie[k]=t
- else
- ie[k]=t[1]
- end
+ local ie=instance.expansions
+ for k,v in next,ie do
+ local t,tn,h,p={},0,{},splitconfigurationpath(v)
+ for kk=1,#p do
+ local vv=p[kk]
+ if vv~="" and not h[vv] then
+ tn=tn+1
+ t[tn]=vv
+ h[vv]=true
+ end
end
+ if #t>1 then
+ ie[k]=t
+ else
+ ie[k]=t[1]
+ end
+ end
end
function resolvers.datastate()
- return caches.contentstate()
+ return caches.contentstate()
end
function resolvers.variable(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.variables[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.variables[name]
+ return result~=nil and result or ""
end
function resolvers.expansion(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.expansions[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.expansions[name]
+ return result~=nil and result or ""
end
function resolvers.unexpandedpathlist(str)
- local pth=resolvers.variable(str)
- local lst=resolvers.splitpath(pth)
- return expandedpathfromlist(lst)
+ local pth=resolvers.variable(str)
+ local lst=resolvers.splitpath(pth)
+ return expandedpathfromlist(lst)
end
function resolvers.unexpandedpath(str)
- return joinpath(resolvers.unexpandedpathlist(str))
+ return joinpath(resolvers.unexpandedpathlist(str))
end
function resolvers.pushpath(name)
- local pathstack=instance.pathstack
- local lastpath=pathstack[#pathstack]
- local pluspath=filedirname(name)
- if lastpath then
- lastpath=collapsepath(filejoin(lastpath,pluspath))
- else
- lastpath=collapsepath(pluspath)
- end
- insert(pathstack,lastpath)
- if trace_paths then
- report_resolving("pushing path %a",lastpath)
- end
+ local pathstack=instance.pathstack
+ local lastpath=pathstack[#pathstack]
+ local pluspath=filedirname(name)
+ if lastpath then
+ lastpath=collapsepath(filejoin(lastpath,pluspath))
+ else
+ lastpath=collapsepath(pluspath)
+ end
+ insert(pathstack,lastpath)
+ if trace_paths then
+ report_resolving("pushing path %a",lastpath)
+ end
end
function resolvers.poppath()
- local pathstack=instance.pathstack
- if trace_paths and #pathstack>0 then
- report_resolving("popping path %a",pathstack[#pathstack])
- end
- remove(pathstack)
+ local pathstack=instance.pathstack
+ if trace_paths and #pathstack>0 then
+ report_resolving("popping path %a",pathstack[#pathstack])
+ end
+ remove(pathstack)
end
function resolvers.stackpath()
- local pathstack=instance.pathstack
- local currentpath=pathstack[#pathstack]
- return currentpath~="" and currentpath or nil
+ local pathstack=instance.pathstack
+ local currentpath=pathstack[#pathstack]
+ return currentpath~="" and currentpath or nil
end
local done={}
function resolvers.resetextrapaths()
- local ep=instance.extra_paths
- if not ep then
- done={}
- instance.extra_paths={}
- elseif #ep>0 then
- done={}
- reset_caches()
- end
+ local ep=instance.extra_paths
+ if not ep then
+ done={}
+ instance.extra_paths={}
+ elseif #ep>0 then
+ done={}
+ reset_caches()
+ end
end
function resolvers.getextrapaths()
- return instance.extra_paths or {}
+ return instance.extra_paths or {}
end
function resolvers.registerextrapath(paths,subpaths)
- if not subpaths or subpaths=="" then
- if not paths or path=="" then
- return
- elseif done[paths] then
- return
- end
- end
- local paths=settings_to_array(paths)
- local subpaths=settings_to_array(subpaths)
- local ep=instance.extra_paths or {}
- local oldn=#ep
- local newn=oldn
- local nofpaths=#paths
- local nofsubpaths=#subpaths
- if nofpaths>0 then
- if nofsubpaths>0 then
- for i=1,nofpaths do
- local p=paths[i]
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=p.."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
- end
- else
- for i=1,nofpaths do
- local p=paths[i]
- if not done[p] then
- newn=newn+1
- ep[newn]=cleanpath(p)
- done[p]=true
- end
- end
+ if not subpaths or subpaths=="" then
+ if not paths or path=="" then
+ return
+ elseif done[paths] then
+ return
+ end
+ end
+ local paths=settings_to_array(paths)
+ local subpaths=settings_to_array(subpaths)
+ local ep=instance.extra_paths or {}
+ local oldn=#ep
+ local newn=oldn
+ local nofpaths=#paths
+ local nofsubpaths=#subpaths
+ if nofpaths>0 then
+ if nofsubpaths>0 then
+ for i=1,nofpaths do
+ local p=paths[i]
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=p.."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
end
- elseif nofsubpaths>0 then
- for i=1,oldn do
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=ep[i].."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
+ end
+ else
+ for i=1,nofpaths do
+ local p=paths[i]
+ if not done[p] then
+ newn=newn+1
+ ep[newn]=cleanpath(p)
+ done[p]=true
end
+ end
end
- if newn>0 then
- instance.extra_paths=ep
- end
- if newn~=oldn then
- reset_caches()
+ elseif nofsubpaths>0 then
+ for i=1,oldn do
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=ep[i].."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
+ end
end
+ end
+ if newn>0 then
+ instance.extra_paths=ep
+ end
+ if newn~=oldn then
+ reset_caches()
+ end
end
function resolvers.pushextrapath(path)
- local paths=settings_to_array(path)
- if instance.extra_stack then
- insert(instance.extra_stack,1,paths)
- else
- instance.extra_stack={ paths }
- end
- reset_caches()
+ local paths=settings_to_array(path)
+ if instance.extra_stack then
+ insert(instance.extra_stack,1,paths)
+ else
+ instance.extra_stack={ paths }
+ end
+ reset_caches()
end
function resolvers.popextrapath()
- if instance.extra_stack then
- reset_caches()
- return remove(instance.extra_stack,1)
- end
+ if instance.extra_stack then
+ reset_caches()
+ return remove(instance.extra_stack,1)
+ end
end
local function made_list(instance,list,extra_too)
- local done={}
- local new={}
- local newn=0
- local function add(p)
- for k=1,#p do
- local v=p[k]
- if not done[v] then
- done[v]=true
- newn=newn+1
- new[newn]=v
- end
- end
+ local done={}
+ local new={}
+ local newn=0
+ local function add(p)
+ for k=1,#p do
+ local v=p[k]
+ if not done[v] then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ end
end
- for k=1,#list do
- local v=list[k]
- if done[v] then
- elseif find(v,"^[%.%/]$") then
- done[v]=true
- newn=newn+1
- new[newn]=v
- else
- break
- end
+ end
+ for k=1,#list do
+ local v=list[k]
+ if done[v] then
+ elseif find(v,"^[%.%/]$") then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ else
+ break
+ end
+ end
+ if extra_too then
+ local es=instance.extra_stack
+ if es and #es>0 then
+ for k=1,#es do
+ add(es[k])
+ end
end
- if extra_too then
- local es=instance.extra_stack
- if es and #es>0 then
- for k=1,#es do
- add(es[k])
- end
- end
- local ep=instance.extra_paths
- if ep and #ep>0 then
- add(ep)
- end
+ local ep=instance.extra_paths
+ if ep and #ep>0 then
+ add(ep)
end
- add(list)
- return new
+ end
+ add(list)
+ return new
end
function resolvers.cleanpathlist(str)
- local t=resolvers.expandedpathlist(str)
- if t then
- for i=1,#t do
- t[i]=collapsepath(cleanpath(t[i]))
- end
+ local t=resolvers.expandedpathlist(str)
+ if t then
+ for i=1,#t do
+ t[i]=collapsepath(cleanpath(t[i]))
end
- return t
+ end
+ return t
end
function resolvers.expandpath(str)
- return joinpath(resolvers.expandedpathlist(str))
+ return joinpath(resolvers.expandedpathlist(str))
end
function resolvers.expandedpathlist(str,extra_too)
- if not str then
- return {}
- elseif instance.savelists then
- str=lpegmatch(dollarstripper,str)
- local lists=instance.lists
- local lst=lists[str]
- if not lst then
- local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
- lst=expandedpathfromlist(l)
- lists[str]=lst
- end
- return lst
- else
- local lst=resolvers.splitpath(resolvers.expansion(str))
- return made_list(instance,expandedpathfromlist(lst),extra_too)
+ if not str then
+ return {}
+ elseif instance.savelists then
+ str=lpegmatch(dollarstripper,str)
+ local lists=instance.lists
+ local lst=lists[str]
+ if not lst then
+ local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
+ lst=expandedpathfromlist(l)
+ lists[str]=lst
end
+ return lst
+ else
+ local lst=resolvers.splitpath(resolvers.expansion(str))
+ return made_list(instance,expandedpathfromlist(lst),extra_too)
+ end
end
function resolvers.expandedpathlistfromvariable(str)
- str=lpegmatch(dollarstripper,str)
- local tmp=resolvers.variableofformatorsuffix(str)
- return resolvers.expandedpathlist(tmp~="" and tmp or str)
+ str=lpegmatch(dollarstripper,str)
+ local tmp=resolvers.variableofformatorsuffix(str)
+ return resolvers.expandedpathlist(tmp~="" and tmp or str)
end
function resolvers.expandpathfromvariable(str)
- return joinpath(resolvers.expandedpathlistfromvariable(str))
+ return joinpath(resolvers.expandedpathlistfromvariable(str))
end
function resolvers.cleanedpathlist(v)
- local t=resolvers.expandedpathlist(v)
- for i=1,#t do
- t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
- end
- return t
+ local t=resolvers.expandedpathlist(v)
+ for i=1,#t do
+ t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
+ end
+ return t
end
function resolvers.expandbraces(str)
- local pth=expandedpathfromlist(resolvers.splitpath(str))
- return joinpath(pth)
+ local pth=expandedpathfromlist(resolvers.splitpath(str))
+ return joinpath(pth)
end
function resolvers.registerfilehash(name,content,someerror)
- if content then
- instance.files[name]=content
- else
- instance.files[name]={}
- if somerror==true then
- instance.loaderror=someerror
- end
+ if content then
+ instance.files[name]=content
+ else
+ instance.files[name]={}
+ if somerror==true then
+ instance.loaderror=someerror
end
+ end
end
function resolvers.getfilehashes()
- return instance and instance.files or {}
+ return instance and instance.files or {}
end
function resolvers.gethashes()
- return instance and instance.hashes or {}
+ return instance and instance.hashes or {}
end
function resolvers.renewcache()
- if instance then
- instance.renewcache=true
- end
+ if instance then
+ instance.renewcache=true
+ end
end
local function isreadable(name)
- local readable=isfile(name)
- if trace_detail then
- if readable then
- report_resolving("file %a is readable",name)
- else
- report_resolving("file %a is not readable",name)
- end
+ local readable=isfile(name)
+ if trace_detail then
+ if readable then
+ report_resolving("file %a is readable",name)
+ else
+ report_resolving("file %a is not readable",name)
end
- return readable
+ end
+ return readable
end
local function collect_files(names)
- local filelist={}
- local noffiles=0
- local function check(hash,root,pathname,path,basename,name)
- if not pathname or find(path,pathname) then
- local variant=hash.type
- local search=filejoin(root,path,name)
- local result=methodhandler('concatinators',variant,root,path,name)
- if trace_detail then
- report_resolving("match: variant %a, search %a, result %a",variant,search,result)
- end
- noffiles=noffiles+1
- filelist[noffiles]={ variant,search,result }
- end
+ local filelist={}
+ local noffiles=0
+ local function check(hash,root,pathname,path,basename,name)
+ if not pathname or find(path,pathname) then
+ local variant=hash.type
+ local search=filejoin(root,path,name)
+ local result=methodhandler('concatinators',variant,root,path,name)
+ if trace_detail then
+ report_resolving("match: variant %a, search %a, result %a",variant,search,result)
+ end
+ noffiles=noffiles+1
+ filelist[noffiles]={ variant,search,result }
end
- for k=1,#names do
- local filename=names[k]
+ end
+ for k=1,#names do
+ local filename=names[k]
+ if trace_detail then
+ report_resolving("checking name %a",filename)
+ end
+ local basename=filebasename(filename)
+ local pathname=filedirname(filename)
+ if pathname=="" or find(pathname,"^%.") then
+ pathname=false
+ else
+ pathname=gsub(pathname,"%*",".*")
+ pathname="/"..pathname.."$"
+ end
+ local hashes=instance.hashes
+ for h=1,#hashes do
+ local hash=hashes[h]
+ local hashname=hash.name
+ local content=hashname and instance.files[hashname]
+ if content then
if trace_detail then
- report_resolving("checking name %a",filename)
+ report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
end
- local basename=filebasename(filename)
- local pathname=filedirname(filename)
- if pathname=="" or find(pathname,"^%.") then
- pathname=false
- else
- pathname=gsub(pathname,"%*",".*")
- pathname="/"..pathname.."$"
- end
- local hashes=instance.hashes
- for h=1,#hashes do
- local hash=hashes[h]
- local hashname=hash.name
- local content=hashname and instance.files[hashname]
- if content then
- if trace_detail then
- report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
- end
- local path,name=lookup(content,basename)
- if path then
- local metadata=content.metadata
- local realroot=metadata and metadata.path or hashname
- if type(path)=="string" then
- check(hash,realroot,pathname,path,basename,name)
- else
- for i=1,#path do
- check(hash,realroot,pathname,path[i],basename,name)
- end
- end
- end
- elseif trace_locating then
- report_resolving("no match in %a (%s)",hashname,basename)
+ local path,name=lookup(content,basename)
+ if path then
+ local metadata=content.metadata
+ local realroot=metadata and metadata.path or hashname
+ if type(path)=="string" then
+ check(hash,realroot,pathname,path,basename,name)
+ else
+ for i=1,#path do
+ check(hash,realroot,pathname,path[i],basename,name)
end
+ end
end
+ elseif trace_locating then
+ report_resolving("no match in %a (%s)",hashname,basename)
+ end
end
- return noffiles>0 and filelist or nil
+ end
+ return noffiles>0 and filelist or nil
end
local fit={}
function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname)
- local foundintrees=instance.foundintrees
- if usedmethod=="direct" and filename==foundname and fit[foundname] then
- else
- local collapsed=collapsepath(foundname,true)
- local t={
- filename=filename,
- format=format~="" and format or nil,
- filetype=filetype~="" and filetype or nil,
- usedmethod=usedmethod,
- foundname=foundname,
- fullname=collapsed,
- }
- fit[foundname]=t
- foundintrees[#foundintrees+1]=t
- end
+ local foundintrees=instance.foundintrees
+ if usedmethod=="direct" and filename==foundname and fit[foundname] then
+ else
+ local collapsed=collapsepath(foundname,true)
+ local t={
+ filename=filename,
+ format=format~="" and format or nil,
+ filetype=filetype~="" and filetype or nil,
+ usedmethod=usedmethod,
+ foundname=foundname,
+ fullname=collapsed,
+ }
+ fit[foundname]=t
+ foundintrees[#foundintrees+1]=t
+ end
end
function resolvers.foundintrees()
- return instance.foundintrees or {}
+ return instance.foundintrees or {}
end
function resolvers.foundintree(fullname)
- local f=fit[fullname]
- return f and f.usedmethod=="database"
+ local f=fit[fullname]
+ return f and f.usedmethod=="database"
end
local function can_be_dir(name)
- local fakepaths=instance.fakepaths
- if not fakepaths[name] then
- if isdir(name) then
- fakepaths[name]=1
- else
- fakepaths[name]=2
- end
+ local fakepaths=instance.fakepaths
+ if not fakepaths[name] then
+ if isdir(name) then
+ fakepaths[name]=1
+ else
+ fakepaths[name]=2
end
- return fakepaths[name]==1
+ end
+ return fakepaths[name]==1
end
local preparetreepattern=Cs((P(".")/"%%."+P("-")/"%%-"+P(1))^0*Cc("$"))
local collect_instance_files
local function find_analyze(filename,askedformat,allresults)
- local filetype=''
- local filesuffix=suffixonly(filename)
- local wantedfiles={}
- wantedfiles[#wantedfiles+1]=filename
- if askedformat=="" then
- if filesuffix=="" or not suffixmap[filesuffix] then
- local defaultsuffixes=resolvers.defaultsuffixes
- local formatofsuffix=resolvers.formatofsuffix
- for i=1,#defaultsuffixes do
- local forcedname=filename..'.'..defaultsuffixes[i]
- wantedfiles[#wantedfiles+1]=forcedname
- filetype=formatofsuffix(forcedname)
- if trace_locating then
- report_resolving("forcing filetype %a",filetype)
- end
- end
- else
- filetype=resolvers.formatofsuffix(filename)
- if trace_locating then
- report_resolving("using suffix based filetype %a",filetype)
- end
+ local filetype=''
+ local filesuffix=suffixonly(filename)
+ local wantedfiles={}
+ wantedfiles[#wantedfiles+1]=filename
+ if askedformat=="" then
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local defaultsuffixes=resolvers.defaultsuffixes
+ local formatofsuffix=resolvers.formatofsuffix
+ for i=1,#defaultsuffixes do
+ local forcedname=filename..'.'..defaultsuffixes[i]
+ wantedfiles[#wantedfiles+1]=forcedname
+ filetype=formatofsuffix(forcedname)
+ if trace_locating then
+ report_resolving("forcing filetype %a",filetype)
end
+ end
else
- if filesuffix=="" or not suffixmap[filesuffix] then
- local format_suffixes=suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
- end
- end
- end
- filetype=askedformat
- if trace_locating then
- report_resolving("using given filetype %a",filetype)
+ filetype=resolvers.formatofsuffix(filename)
+ if trace_locating then
+ report_resolving("using suffix based filetype %a",filetype)
+ end
+ end
+ else
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local format_suffixes=suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
end
+ end
end
- return filetype,wantedfiles
+ filetype=askedformat
+ if trace_locating then
+ report_resolving("using given filetype %a",filetype)
+ end
+ end
+ return filetype,wantedfiles
end
local function find_direct(filename,allresults)
- if not dangerous[askedformat] and isreadable(filename) then
- if trace_detail then
- report_resolving("file %a found directly",filename)
- end
- return "direct",{ filename }
+ if not dangerous[askedformat] and isreadable(filename) then
+ if trace_detail then
+ report_resolving("file %a found directly",filename)
end
+ return "direct",{ filename }
+ end
end
local function find_wildcard(filename,allresults)
- if find(filename,'*',1,true) then
- if trace_locating then
- report_resolving("checking wildcard %a",filename)
- end
- local result=resolvers.findwildcardfiles(filename)
- if result then
- return "wildcard",result
- end
- end
-end
-local function find_qualified(filename,allresults,askedformat,alsostripped)
- if not is_qualified_path(filename) then
- return
- end
+ if find(filename,'*',1,true) then
if trace_locating then
- report_resolving("checking qualified name %a",filename)
+ report_resolving("checking wildcard %a",filename)
end
- if isreadable(filename) then
- if trace_detail then
- report_resolving("qualified file %a found",filename)
- end
- return "qualified",{ filename }
+ local result=resolvers.findwildcardfiles(filename)
+ if result then
+ return "wildcard",result
end
+ end
+end
+local function find_qualified(filename,allresults,askedformat,alsostripped)
+ if not is_qualified_path(filename) then
+ return
+ end
+ if trace_locating then
+ report_resolving("checking qualified name %a",filename)
+ end
+ if isreadable(filename) then
if trace_detail then
- report_resolving("locating qualified file %a",filename)
- end
- local forcedname,suffix="",suffixonly(filename)
- if suffix=="" then
- local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- local s=format_suffixes[i]
- forcedname=filename.."."..s
- if isreadable(forcedname) then
- if trace_locating then
- report_resolving("no suffix, forcing format filetype %a",s)
- end
- return "qualified",{ forcedname }
- end
- end
+ report_resolving("qualified file %a found",filename)
+ end
+ return "qualified",{ filename }
+ end
+ if trace_detail then
+ report_resolving("locating qualified file %a",filename)
+ end
+ local forcedname,suffix="",suffixonly(filename)
+ if suffix=="" then
+ local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ local s=format_suffixes[i]
+ forcedname=filename.."."..s
+ if isreadable(forcedname) then
+ if trace_locating then
+ report_resolving("no suffix, forcing format filetype %a",s)
+ end
+ return "qualified",{ forcedname }
end
+ end
end
- if alsostripped and suffix and suffix~="" then
- local basename=filebasename(filename)
- local pattern=lpegmatch(preparetreepattern,filename)
- local savedformat=askedformat
- local format=savedformat or ""
- if format=="" then
- askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if alsostripped and suffix and suffix~="" then
+ local basename=filebasename(filename)
+ local pattern=lpegmatch(preparetreepattern,filename)
+ local savedformat=askedformat
+ local format=savedformat or ""
+ if format=="" then
+ askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if not format then
+ askedformat="othertextfiles"
+ end
+ if basename~=filename then
+ local resolved=collect_instance_files(basename,askedformat,allresults)
+ if #resolved==0 then
+ local lowered=lower(basename)
+ if filename~=lowered then
+ resolved=collect_instance_files(lowered,askedformat,allresults)
end
- if not format then
- askedformat="othertextfiles"
+ end
+ resolvers.format=savedformat
+ if #resolved>0 then
+ local result={}
+ for r=1,#resolved do
+ local rr=resolved[r]
+ if find(rr,pattern) then
+ result[#result+1]=rr
+ end
end
- if basename~=filename then
- local resolved=collect_instance_files(basename,askedformat,allresults)
- if #resolved==0 then
- local lowered=lower(basename)
- if filename~=lowered then
- resolved=collect_instance_files(lowered,askedformat,allresults)
- end
- end
- resolvers.format=savedformat
- if #resolved>0 then
- local result={}
- for r=1,#resolved do
- local rr=resolved[r]
- if find(rr,pattern) then
- result[#result+1]=rr
- end
- end
- if #result>0 then
- return "qualified",result
- end
- end
+ if #result>0 then
+ return "qualified",result
end
+ end
end
+ end
end
local function check_subpath(fname)
- if isreadable(fname) then
- if trace_detail then
- report_resolving("found %a by deep scanning",fname)
- end
- return fname
+ if isreadable(fname) then
+ if trace_detail then
+ report_resolving("found %a by deep scanning",fname)
end
+ return fname
+ end
end
local function makepathlist(list,filetype)
- local typespec=resolvers.variableofformat(filetype)
- local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
- local entry={}
- if pathlist and #pathlist>0 then
- for k=1,#pathlist do
- local path=pathlist[k]
- local prescanned=find(path,'^!!')
- local resursive=find(path,'//$')
- local pathname=lpegmatch(inhibitstripper,path)
- local expression=makepathexpression(pathname)
- local barename=gsub(pathname,"/+$","")
- barename=resolveprefix(barename)
- local scheme=url.hasscheme(barename)
- local schemename=gsub(barename,"%.%*$",'')
- entry[k]={
- path=path,
- pathname=pathname,
- prescanned=prescanned,
- recursive=recursive,
- expression=expression,
- barename=barename,
- scheme=scheme,
- schemename=schemename,
- }
- end
- entry.typespec=typespec
- list[filetype]=entry
- else
- list[filetype]=false
- end
- return entry
+ local typespec=resolvers.variableofformat(filetype)
+ local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
+ local entry={}
+ if pathlist and #pathlist>0 then
+ for k=1,#pathlist do
+ local path=pathlist[k]
+ local prescanned=find(path,'^!!')
+ local resursive=find(path,'//$')
+ local pathname=lpegmatch(inhibitstripper,path)
+ local expression=makepathexpression(pathname)
+ local barename=gsub(pathname,"/+$","")
+ barename=resolveprefix(barename)
+ local scheme=url.hasscheme(barename)
+ local schemename=gsub(barename,"%.%*$",'')
+ entry[k]={
+ path=path,
+ pathname=pathname,
+ prescanned=prescanned,
+ recursive=recursive,
+ expression=expression,
+ barename=barename,
+ scheme=scheme,
+ schemename=schemename,
+ }
+ end
+ entry.typespec=typespec
+ list[filetype]=entry
+ else
+ list[filetype]=false
+ end
+ return entry
end
local function find_intree(filename,filetype,wantedfiles,allresults)
- local pathlists=instance.pathlists
- if not pathlists then
- pathlists=setmetatableindex({},makepathlist)
- instance.pathlists=pathlists
- end
- local pathlist=pathlists[filetype]
- if pathlist then
- local method="intree"
- local filelist=collect_files(wantedfiles)
- local dirlist={}
- local result={}
- if filelist then
- for i=1,#filelist do
- dirlist[i]=filedirname(filelist[i][3]).."/"
+ local pathlists=instance.pathlists
+ if not pathlists then
+ pathlists=setmetatableindex({},makepathlist)
+ instance.pathlists=pathlists
+ end
+ local pathlist=pathlists[filetype]
+ if pathlist then
+ local method="intree"
+ local filelist=collect_files(wantedfiles)
+ local dirlist={}
+ local result={}
+ if filelist then
+ for i=1,#filelist do
+ dirlist[i]=filedirname(filelist[i][3]).."/"
+ end
+ end
+ if trace_detail then
+ report_resolving("checking filename %a in tree",filename)
+ end
+ for k=1,#pathlist do
+ local entry=pathlist[k]
+ local path=entry.path
+ local pathname=entry.pathname
+ local done=false
+ if filelist then
+ local expression=entry.expression
+ if trace_detail then
+ report_resolving("using pattern %a for path %a",expression,pathname)
+ end
+ for k=1,#filelist do
+ local fl=filelist[k]
+ local f=fl[2]
+ local d=dirlist[k]
+ if find(d,expression) or find(resolveprefix(d),expression) then
+ result[#result+1]=resolveprefix(fl[3])
+ done=true
+ if allresults then
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
+ end
+ else
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
+ end
+ break
end
+ elseif trace_detail then
+ report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ end
end
- if trace_detail then
- report_resolving("checking filename %a in tree",filename)
- end
- for k=1,#pathlist do
- local entry=pathlist[k]
- local path=entry.path
- local pathname=entry.pathname
- local done=false
- if filelist then
- local expression=entry.expression
+ end
+ if done then
+ method="database"
+ else
+ method="filesystem"
+ local scheme=entry.scheme
+ if not scheme or scheme=="file" then
+ local pname=entry.schemename
+ if not find(pname,"*",1,true) then
+ if can_be_dir(pname) then
+ if not done and not entry.prescanned then
if trace_detail then
- report_resolving("using pattern %a for path %a",expression,pathname)
+ report_resolving("quick root scan for %a",pname)
end
- for k=1,#filelist do
- local fl=filelist[k]
- local f=fl[2]
- local d=dirlist[k]
- if find(d,expression) or find(resolveprefix(d),expression) then
- result[#result+1]=resolveprefix(fl[3])
- done=true
- if allresults then
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
- end
- else
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
- end
- break
- end
- elseif trace_detail then
- report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local fname=check_subpath(filejoin(pname,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
- end
- end
- if done then
- method="database"
- else
- method="filesystem"
- local scheme=entry.scheme
- if not scheme or scheme=="file" then
- local pname=entry.schemename
- if not find(pname,"*",1,true) then
- if can_be_dir(pname) then
- if not done and not entry.prescanned then
- if trace_detail then
- report_resolving("quick root scan for %a",pname)
- end
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local fname=check_subpath(filejoin(pname,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- if not done and entry.recursive then
- if trace_detail then
- report_resolving("scanning filesystem for %a",pname)
- end
- local files=resolvers.simplescanfiles(pname,false,true)
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local subpath=files[w]
- if not subpath or subpath=="" then
- elseif type(subpath)=="string" then
- local fname=check_subpath(filejoin(pname,subpath,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- else
- for i=1,#subpath do
- local sp=subpath[i]
- if sp=="" then
- else
- local fname=check_subpath(filejoin(pname,sp,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- end
- if done and not allresults then
- break
- end
- end
- end
- end
- end
+ end
+ end
+ if not done and entry.recursive then
+ if trace_detail then
+ report_resolving("scanning filesystem for %a",pname)
+ end
+ local files=resolvers.simplescanfiles(pname,false,true)
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local subpath=files[w]
+ if not subpath or subpath=="" then
+ elseif type(subpath)=="string" then
+ local fname=check_subpath(filejoin(pname,subpath,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
+ end
else
- end
- else
- for k=1,#wantedfiles do
- local pname=entry.barename
- local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
- if fname then
+ for i=1,#subpath do
+ local sp=subpath[i]
+ if sp=="" then
+ else
+ local fname=check_subpath(filejoin(pname,sp,w))
+ if fname then
result[#result+1]=fname
done=true
if not allresults then
- break
+ break
end
+ end
end
+ end
+ if done and not allresults then
+ break
+ end
end
+ end
end
+ end
end
- if done and not allresults then
+ else
+ end
+ else
+ for k=1,#wantedfiles do
+ local pname=entry.barename
+ local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
break
+ end
end
+ end
end
- if #result>0 then
- return method,result
- end
+ end
+ if done and not allresults then
+ break
+ end
end
+ if #result>0 then
+ return method,result
+ end
+ end
end
local function find_onpath(filename,filetype,wantedfiles,allresults)
- if trace_detail then
- report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
- end
- local result={}
- for k=1,#wantedfiles do
- local fname=wantedfiles[k]
- if fname and isreadable(fname) then
- filename=fname
- result[#result+1]=filejoin('.',fname)
- if not allresults then
- break
- end
- end
- end
- if #result>0 then
- return "onpath",result
+ if trace_detail then
+ report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
+ end
+ local result={}
+ for k=1,#wantedfiles do
+ local fname=wantedfiles[k]
+ if fname and isreadable(fname) then
+ filename=fname
+ result[#result+1]=filejoin('.',fname)
+ if not allresults then
+ break
+ end
end
+ end
+ if #result>0 then
+ return "onpath",result
+ end
end
local function find_otherwise(filename,filetype,wantedfiles,allresults)
- local filelist=collect_files(wantedfiles)
- local fl=filelist and filelist[1]
- if fl then
- return "otherwise",{ resolveprefix(fl[3]) }
- end
+ local filelist=collect_files(wantedfiles)
+ local fl=filelist and filelist[1]
+ if fl then
+ return "otherwise",{ resolveprefix(fl[3]) }
+ end
end
collect_instance_files=function(filename,askedformat,allresults)
- if not filename or filename=="" then
- return {}
- end
- askedformat=askedformat or ""
- filename=collapsepath(filename,".")
- filename=gsub(filename,"^%./",getcurrentdir().."/")
- if allresults then
- local filetype,wantedfiles=find_analyze(filename,askedformat)
- local results={
- { find_direct (filename,true) },
- { find_wildcard (filename,true) },
- { find_qualified(filename,true,askedformat) },
- { find_intree (filename,filetype,wantedfiles,true) },
- { find_onpath (filename,filetype,wantedfiles,true) },
- { find_otherwise(filename,filetype,wantedfiles,true) },
- }
- local result,status,done={},{},{}
- for k,r in next,results do
- local method,list=r[1],r[2]
- if method and list then
- for i=1,#list do
- local c=collapsepath(list[i])
- if not done[c] then
- result[#result+1]=c
- done[c]=true
- end
- status[#status+1]=formatters["%-10s: %s"](method,c)
- end
- end
- end
- if trace_detail then
- report_resolving("lookup status: %s",table.serialize(status,filename))
+ if not filename or filename=="" then
+ return {}
+ end
+ askedformat=askedformat or ""
+ filename=collapsepath(filename,".")
+ filename=gsub(filename,"^%./",getcurrentdir().."/")
+ if allresults then
+ local filetype,wantedfiles=find_analyze(filename,askedformat)
+ local results={
+ { find_direct (filename,true) },
+ { find_wildcard (filename,true) },
+ { find_qualified(filename,true,askedformat) },
+ { find_intree (filename,filetype,wantedfiles,true) },
+ { find_onpath (filename,filetype,wantedfiles,true) },
+ { find_otherwise(filename,filetype,wantedfiles,true) },
+ }
+ local result,status,done={},{},{}
+ for k,r in next,results do
+ local method,list=r[1],r[2]
+ if method and list then
+ for i=1,#list do
+ local c=collapsepath(list[i])
+ if not done[c] then
+ result[#result+1]=c
+ done[c]=true
+ end
+ status[#status+1]=formatters["%-10s: %s"](method,c)
end
- return result,status
- else
- local method,result,stamp,filetype,wantedfiles
- if instance.remember then
- if askedformat=="" then
- stamp=formatters["%s::%s"](suffixonly(filename),filename)
- else
- stamp=formatters["%s::%s"](askedformat,filename)
- end
- result=stamp and instance.found[stamp]
- if result then
- if trace_locating then
- report_resolving("remembered file %a",filename)
- end
- return result
- end
+ end
+ end
+ if trace_detail then
+ report_resolving("lookup status: %s",table.serialize(status,filename))
+ end
+ return result,status
+ else
+ local method,result,stamp,filetype,wantedfiles
+ if instance.remember then
+ if askedformat=="" then
+ stamp=formatters["%s::%s"](suffixonly(filename),filename)
+ else
+ stamp=formatters["%s::%s"](askedformat,filename)
+ end
+ result=stamp and instance.found[stamp]
+ if result then
+ if trace_locating then
+ report_resolving("remembered file %a",filename)
end
- method,result=find_direct(filename)
+ return result
+ end
+ end
+ method,result=find_direct(filename)
+ if not result then
+ method,result=find_wildcard(filename)
+ if not result then
+ method,result=find_qualified(filename,false,askedformat)
if not result then
- method,result=find_wildcard(filename)
- if not result then
- method,result=find_qualified(filename,false,askedformat)
- if not result then
- filetype,wantedfiles=find_analyze(filename,askedformat)
- method,result=find_intree(filename,filetype,wantedfiles)
- if not result then
- method,result=find_onpath(filename,filetype,wantedfiles)
- if resolve_otherwise and not result then
- method,result=find_otherwise(filename,filetype,wantedfiles)
- end
- end
- end
- end
- end
- if result and #result>0 then
- local foundname=collapsepath(result[1])
- resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
- result={ foundname }
- else
- result={}
- end
- if stamp then
- if trace_locating then
- report_resolving("remembering file %a using hash %a",filename,stamp)
+ filetype,wantedfiles=find_analyze(filename,askedformat)
+ method,result=find_intree(filename,filetype,wantedfiles)
+ if not result then
+ method,result=find_onpath(filename,filetype,wantedfiles)
+ if resolve_otherwise and not result then
+ method,result=find_otherwise(filename,filetype,wantedfiles)
end
- instance.found[stamp]=result
+ end
end
- return result
+ end
+ end
+ if result and #result>0 then
+ local foundname=collapsepath(result[1])
+ resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
+ result={ foundname }
+ else
+ result={}
end
+ if stamp then
+ if trace_locating then
+ report_resolving("remembering file %a using hash %a",filename,stamp)
+ end
+ instance.found[stamp]=result
+ end
+ return result
+ end
end
local function findfiles(filename,filetype,allresults)
- if not filename or filename=="" then
- return {}
- end
- local result,status=collect_instance_files(filename,filetype or "",allresults)
- if not result or #result==0 then
- local lowered=lower(filename)
- if filename~=lowered then
- result,status=collect_instance_files(lowered,filetype or "",allresults)
- end
+ if not filename or filename=="" then
+ return {}
+ end
+ local result,status=collect_instance_files(filename,filetype or "",allresults)
+ if not result or #result==0 then
+ local lowered=lower(filename)
+ if filename~=lowered then
+ result,status=collect_instance_files(lowered,filetype or "",allresults)
end
- return result or {},status
+ end
+ return result or {},status
end
function resolvers.findfiles(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,true)
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,true)
+ end
end
function resolvers.findfile(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,false)[1] or ""
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,false)[1] or ""
+ end
end
function resolvers.findpath(filename,filetype)
- return filedirname(findfiles(filename,filetype,false)[1] or "")
+ return filedirname(findfiles(filename,filetype,false)[1] or "")
end
local function findgivenfiles(filename,allresults)
- local base=filebasename(filename)
- local result={}
- local hashes=instance.hashes
- local function okay(hash,path,name)
- local found=methodhandler('concatinators',hash.type,hash.name,path,name)
- if found and found~="" then
- result[#result+1]=resolveprefix(found)
- return not allresults
- end
- end
- for k=1,#hashes do
- local hash=hashes[k]
- local content=instance.files[hash.name]
- if content then
- local path,name=lookup(content,base)
- if not path then
- elseif type(path)=="string" then
- if okay(hash,path,name) then
- return result
- end
- else
- for i=1,#path do
- if okay(hash,path[i],name) then
- return result
- end
- end
- end
+ local base=filebasename(filename)
+ local result={}
+ local hashes=instance.hashes
+ local function okay(hash,path,name)
+ local found=methodhandler('concatinators',hash.type,hash.name,path,name)
+ if found and found~="" then
+ result[#result+1]=resolveprefix(found)
+ return not allresults
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local content=instance.files[hash.name]
+ if content then
+ local path,name=lookup(content,base)
+ if not path then
+ elseif type(path)=="string" then
+ if okay(hash,path,name) then
+ return result
+ end
+ else
+ for i=1,#path do
+ if okay(hash,path[i],name) then
+ return result
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findgivenfiles(filename)
- return findgivenfiles(filename,true)
+ return findgivenfiles(filename,true)
end
function resolvers.findgivenfile(filename)
- return findgivenfiles(filename,false)[1] or ""
+ return findgivenfiles(filename,false)[1] or ""
end
local makewildcard=Cs(
- (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
+ (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
)
function resolvers.wildcardpattern(pattern)
- return lpegmatch(makewildcard,pattern) or pattern
+ return lpegmatch(makewildcard,pattern) or pattern
end
local function findwildcardfiles(filename,allresults,result)
- local result=result or {}
- local base=filebasename(filename)
- local dirn=filedirname(filename)
- local path=lower(lpegmatch(makewildcard,dirn) or dirn)
- local name=lower(lpegmatch(makewildcard,base) or base)
- local files=instance.files
- if find(name,"*",1,true) then
- local hashes=instance.hashes
- local function okay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
- end
+ local result=result or {}
+ local base=filebasename(filename)
+ local dirn=filedirname(filename)
+ local path=lower(lpegmatch(makewildcard,dirn) or dirn)
+ local name=lower(lpegmatch(makewildcard,base) or base)
+ local files=instance.files
+ if find(name,"*",1,true) then
+ local hashes=instance.hashes
+ local function okay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
end
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- for found,base in filtered(files[hashname],name) do
- if type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
- end
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ for found,base in filtered(files[hashname],name) do
+ if type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
end
- end
- else
- local function okayokay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
+ end
end
+ end
end
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- local found,base=lookup(content,base)
- if not found then
- elseif type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
+ end
+ end
+ else
+ local function okayokay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
+ end
+ end
+ end
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ local found,base=lookup(content,base)
+ if not found then
+ elseif type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
+ end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
end
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findwildcardfiles(filename,result)
- return findwildcardfiles(filename,true,result)
+ return findwildcardfiles(filename,true,result)
end
function resolvers.findwildcardfile(filename)
- return findwildcardfiles(filename,false)[1] or ""
+ return findwildcardfiles(filename,false)[1] or ""
end
function resolvers.automount()
end
function resolvers.starttiming()
- statistics.starttiming(instance)
+ statistics.starttiming(instance)
end
function resolvers.stoptiming()
- statistics.stoptiming(instance)
+ statistics.stoptiming(instance)
end
function resolvers.load(option)
- resolvers.starttiming()
- identify_configuration_files()
- load_configuration_files()
- if option~="nofiles" then
- load_databases()
- resolvers.automount()
- end
- resolvers.stoptiming()
- local files=instance.files
- return files and next(files) and true
+ resolvers.starttiming()
+ identify_configuration_files()
+ load_configuration_files()
+ if option~="nofiles" then
+ load_databases()
+ resolvers.automount()
+ end
+ resolvers.stoptiming()
+ local files=instance.files
+ return files and next(files) and true
end
function resolvers.loadtime()
- return statistics.elapsedtime(instance)
+ return statistics.elapsedtime(instance)
end
local function report(str)
- if trace_locating then
- report_resolving(str)
- else
- print(str)
- end
+ if trace_locating then
+ report_resolving(str)
+ else
+ print(str)
+ end
end
function resolvers.dowithfilesandreport(command,files,...)
- if files and #files>0 then
- if trace_locating then
- report('')
- end
- if type(files)=="string" then
- files={ files }
- end
- for f=1,#files do
- local file=files[f]
- local result=command(file,...)
- if type(result)=='string' then
- report(result)
- else
- for i=1,#result do
- report(result[i])
- end
- end
+ if files and #files>0 then
+ if trace_locating then
+ report('')
+ end
+ if type(files)=="string" then
+ files={ files }
+ end
+ for f=1,#files do
+ local file=files[f]
+ local result=command(file,...)
+ if type(result)=='string' then
+ report(result)
+ else
+ for i=1,#result do
+ report(result[i])
end
+ end
end
+ end
end
-function resolvers.showpath(str)
- return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
+function resolvers.showpath(str)
+ return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
end
function resolvers.registerfile(files,name,path)
- if files[name] then
- if type(files[name])=='string' then
- files[name]={ files[name],path }
- else
- files[name]=path
- end
+ if files[name] then
+ if type(files[name])=='string' then
+ files[name]={ files[name],path }
else
- files[name]=path
+ files[name]=path
end
+ else
+ files[name]=path
+ end
end
function resolvers.dowithpath(name,func)
- local pathlist=resolvers.expandedpathlist(name)
- for i=1,#pathlist do
- func("^"..cleanpath(pathlist[i]))
- end
+ local pathlist=resolvers.expandedpathlist(name)
+ for i=1,#pathlist do
+ func("^"..cleanpath(pathlist[i]))
+ end
end
function resolvers.dowithvariable(name,func)
- func(expandedvariable(name))
+ func(expandedvariable(name))
end
function resolvers.locateformat(name)
- local engine=environment.ownmain or "luatex"
- local barename=removesuffix(name)
- local fullname=addsuffix(barename,"fmt")
- local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
- if fmtname=="" then
- fmtname=resolvers.findfile(fullname)
- fmtname=cleanpath(fmtname)
- end
- if fmtname~="" then
- local barename=removesuffix(fmtname)
- local luaname=addsuffix(barename,luasuffixes.lua)
- local lucname=addsuffix(barename,luasuffixes.luc)
- local luiname=addsuffix(barename,luasuffixes.lui)
- if isfile(luiname) then
- return barename,luiname
- elseif isfile(lucname) then
- return barename,lucname
- elseif isfile(luaname) then
- return barename,luaname
- end
- end
- return nil,nil
+ local engine=environment.ownmain or "luatex"
+ local barename=removesuffix(name)
+ local fullname=addsuffix(barename,"fmt")
+ local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
+ if fmtname=="" then
+ fmtname=resolvers.findfile(fullname)
+ fmtname=cleanpath(fmtname)
+ end
+ if fmtname~="" then
+ local barename=removesuffix(fmtname)
+ local luaname=addsuffix(barename,luasuffixes.lua)
+ local lucname=addsuffix(barename,luasuffixes.luc)
+ local luiname=addsuffix(barename,luasuffixes.lui)
+ if isfile(luiname) then
+ return barename,luiname
+ elseif isfile(lucname) then
+ return barename,lucname
+ elseif isfile(luaname) then
+ return barename,luaname
+ end
+ end
+ return nil,nil
end
function resolvers.booleanvariable(str,default)
- local b=resolvers.expansion(str)
- if b=="" then
- return default
- else
- b=toboolean(b)
- return (b==nil and default) or b
- end
+ local b=resolvers.expansion(str)
+ if b=="" then
+ return default
+ else
+ b=toboolean(b)
+ return (b==nil and default) or b
+ end
end
function resolvers.dowithfilesintree(pattern,handle,before,after)
- local hashes=instance.hashes
- for i=1,#hashes do
- local hash=hashes[i]
- local blobtype=hash.type
- local blobpath=hash.name
- if blobtype and blobpath then
- local total=0
- local checked=0
- local done=0
- if before then
- before(blobtype,blobpath,pattern)
- end
- for path,name in filtered(instance.files[blobpath],pattern) do
- if type(path)=="string" then
- checked=checked+1
- if handle(blobtype,blobpath,path,name) then
- done=done+1
- end
- else
- checked=checked+#path
- for i=1,#path do
- if handle(blobtype,blobpath,path[i],name) then
- done=done+1
- end
- end
- end
- end
- if after then
- after(blobtype,blobpath,pattern,checked,done)
+ local hashes=instance.hashes
+ for i=1,#hashes do
+ local hash=hashes[i]
+ local blobtype=hash.type
+ local blobpath=hash.name
+ if blobtype and blobpath then
+ local total=0
+ local checked=0
+ local done=0
+ if before then
+ before(blobtype,blobpath,pattern)
+ end
+ for path,name in filtered(instance.files[blobpath],pattern) do
+ if type(path)=="string" then
+ checked=checked+1
+ if handle(blobtype,blobpath,path,name) then
+ done=done+1
+ end
+ else
+ checked=checked+#path
+ for i=1,#path do
+ if handle(blobtype,blobpath,path[i],name) then
+ done=done+1
end
+ end
end
+ end
+ if after then
+ after(blobtype,blobpath,pattern,checked,done)
+ end
end
+ end
end
local obsolete=resolvers.obsolete or {}
resolvers.obsolete=obsolete
-resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
-resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
+resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
+resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
function resolvers.knownvariables(pattern)
- if instance then
- local environment=instance.environment
- local variables=instance.variables
- local expansions=instance.expansions
- local order=instance.order
- local pattern=upper(pattern or "")
- local result={}
- for i=1,#order do
- for key in next,order[i] do
- if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
- result[key]={
- environment=rawget(environment,key),
- variable=key,
- expansion=expansions[key],
- resolved=resolveprefix(expansions[key]),
- }
- end
- end
+ if instance then
+ local environment=instance.environment
+ local variables=instance.variables
+ local expansions=instance.expansions
+ local order=instance.order
+ local pattern=upper(pattern or "")
+ local result={}
+ for i=1,#order do
+ for key in next,order[i] do
+ if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
+ result[key]={
+ environment=rawget(environment,key),
+ variable=key,
+ expansion=expansions[key],
+ resolved=resolveprefix(expansions[key]),
+ }
end
- return result
- else
- return {}
+ end
end
+ return result
+ else
+ return {}
+ end
end
@@ -22710,14 +22718,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-pre"] = package.loaded["data-pre"] or true
--- original size: 4854, stripped down to: 2993
+-- original size: 4854, stripped down to: 2889
if not modules then modules={} end modules ['data-pre']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local resolvers=resolvers
local prefixes=resolvers.prefixes
@@ -22730,64 +22738,64 @@ local dirname=file.dirname
local joinpath=file.join
local isfile=lfs.isfile
prefixes.environment=function(str)
- return cleanpath(expansion(str))
+ return cleanpath(expansion(str))
end
local function relative(str,n)
- if not isfile(str) then
- local pstr="./"..str
+ if not isfile(str) then
+ local pstr="./"..str
+ if isfile(pstr) then
+ str=pstr
+ else
+ local p="../"
+ for i=1,n or 2 do
+ local pstr=p..str
if isfile(pstr) then
- str=pstr
+ str=pstr
+ break
else
- local p="../"
- for i=1,n or 2 do
- local pstr=p..str
- if isfile(pstr) then
- str=pstr
- break
- else
- p=p.."../"
- end
- end
+ p=p.."../"
end
+ end
end
- return cleanpath(str)
+ end
+ return cleanpath(str)
end
local function locate(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(fullname~="" and fullname or str)
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(fullname~="" and fullname or str)
end
prefixes.relative=relative
prefixes.locate=locate
prefixes.auto=function(str)
- local fullname=relative(str)
- if not isfile(fullname) then
- fullname=locate(str)
- end
- return fullname
+ local fullname=relative(str)
+ if not isfile(fullname) then
+ fullname=locate(str)
+ end
+ return fullname
end
prefixes.filename=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(basename((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(basename((fullname~="" and fullname) or str))
end
prefixes.pathname=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(dirname((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(dirname((fullname~="" and fullname) or str))
end
prefixes.selfautoloc=function(str)
- local pth=getenv('SELFAUTOLOC')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOLOC')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautoparent=function(str)
- local pth=getenv('SELFAUTOPARENT')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOPARENT')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautodir=function(str)
- local pth=getenv('SELFAUTODIR')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTODIR')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.home=function(str)
- local pth=getenv('HOME')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('HOME')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.env=prefixes.environment
prefixes.rel=prefixes.relative
@@ -22797,24 +22805,24 @@ prefixes.full=prefixes.locate
prefixes.file=prefixes.filename
prefixes.path=prefixes.pathname
local function toppath()
- local inputstack=resolvers.inputstack
- if not inputstack then
- return "."
- end
- local pathname=dirname(inputstack[#inputstack] or "")
- if pathname=="" then
- return "."
- else
- return pathname
- end
+ local inputstack=resolvers.inputstack
+ if not inputstack then
+ return "."
+ end
+ local pathname=dirname(inputstack[#inputstack] or "")
+ if pathname=="" then
+ return "."
+ else
+ return pathname
+ end
end
local function jobpath()
- local path=resolvers.stackpath()
- if not path or path=="" then
- return "."
- else
- return path
- end
+ local path=resolvers.stackpath()
+ if not path or path=="" then
+ return "."
+ else
+ return path
+ end
end
resolvers.toppath=toppath
resolvers.jobpath=jobpath
@@ -22830,14 +22838,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-inp"] = package.loaded["data-inp"] or true
--- original size: 910, stripped down to: 823
+-- original size: 910, stripped down to: 818
if not modules then modules={} end modules ['data-inp']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -22860,14 +22868,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-out"] = package.loaded["data-out"] or true
--- original size: 530, stripped down to: 475
+-- original size: 530, stripped down to: 470
if not modules then modules={} end modules ['data-out']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -22883,16 +22891,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-fil"] = package.loaded["data-fil"] or true
--- original size: 3863, stripped down to: 3310
+-- original size: 3863, stripped down to: 3170
if not modules then modules={} end modules ['data-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_files=logs.reporter("resolvers","files")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -22900,88 +22908,88 @@ local finders,openers,loaders,savers=resolvers.finders,resolvers.openers,resolve
local locators,hashers,generators,concatinators=resolvers.locators,resolvers.hashers,resolvers.generators,resolvers.concatinators
local checkgarbage=utilities.garbagecollector and utilities.garbagecollector.check
function locators.file(specification)
- local filename=specification.filename
- local realname=resolveprefix(filename)
- if realname and realname~='' and lfs.isdir(realname) then
- if trace_locating then
- report_files("file locator %a found as %a",filename,realname)
- end
- resolvers.appendhash('file',filename,true)
- elseif trace_locating then
- report_files("file locator %a not found",filename)
+ local filename=specification.filename
+ local realname=resolveprefix(filename)
+ if realname and realname~='' and lfs.isdir(realname) then
+ if trace_locating then
+ report_files("file locator %a found as %a",filename,realname)
end
+ resolvers.appendhash('file',filename,true)
+ elseif trace_locating then
+ report_files("file locator %a not found",filename)
+ end
end
function hashers.file(specification)
- local pathname=specification.filename
- local content=caches.loadcontent(pathname,'files')
- resolvers.registerfilehash(pathname,content,content==nil)
+ local pathname=specification.filename
+ local content=caches.loadcontent(pathname,'files')
+ resolvers.registerfilehash(pathname,content,content==nil)
end
function generators.file(specification)
- local pathname=specification.filename
- local content=resolvers.scanfiles(pathname,false,true)
- resolvers.registerfilehash(pathname,content,true)
+ local pathname=specification.filename
+ local content=resolvers.scanfiles(pathname,false,true)
+ resolvers.registerfilehash(pathname,content,true)
end
concatinators.file=file.join
function finders.file(specification,filetype)
- local filename=specification.filename
- local foundname=resolvers.findfile(filename,filetype)
- if foundname and foundname~="" then
- if trace_locating then
- report_files("file finder: %a found",filename)
- end
- return foundname
- else
- if trace_locating then
- report_files("file finder: %a not found",filename)
- end
- return finders.notfound()
+ local filename=specification.filename
+ local foundname=resolvers.findfile(filename,filetype)
+ if foundname and foundname~="" then
+ if trace_locating then
+ report_files("file finder: %a found",filename)
+ end
+ return foundname
+ else
+ if trace_locating then
+ report_files("file finder: %a not found",filename)
end
+ return finders.notfound()
+ end
end
function openers.helpers.textopener(tag,filename,f)
- return {
- reader=function() return f:read () end,
- close=function() logs.show_close(filename) return f:close() end,
- }
+ return {
+ reader=function() return f:read () end,
+ close=function() logs.show_close(filename) return f:close() end,
+ }
end
function openers.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"r")
- if f then
- if trace_locating then
- report_files("file opener: %a opened",filename)
- end
- return openers.helpers.textopener("file",filename,f)
- end
- end
- if trace_locating then
- report_files("file opener: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"r")
+ if f then
+ if trace_locating then
+ report_files("file opener: %a opened",filename)
+ end
+ return openers.helpers.textopener("file",filename,f)
end
- return openers.notfound()
+ end
+ if trace_locating then
+ report_files("file opener: %a not found",filename)
+ end
+ return openers.notfound()
end
function loaders.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"rb")
- if f then
- logs.show_load(filename)
- if trace_locating then
- report_files("file loader: %a loaded",filename)
- end
- local s=f:read("*a")
- if checkgarbage then
- checkgarbage(#s)
- end
- f:close()
- if s then
- return true,s,#s
- end
- end
- end
- if trace_locating then
- report_files("file loader: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"rb")
+ if f then
+ logs.show_load(filename)
+ if trace_locating then
+ report_files("file loader: %a loaded",filename)
+ end
+ local s=f:read("*a")
+ if checkgarbage then
+ checkgarbage(#s)
+ end
+ f:close()
+ if s then
+ return true,s,#s
+ end
end
- return loaders.notfound()
+ end
+ if trace_locating then
+ report_files("file loader: %a not found",filename)
+ end
+ return loaders.notfound()
end
@@ -22991,116 +22999,116 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-con"] = package.loaded["data-con"] or true
--- original size: 5029, stripped down to: 3607
+-- original size: 5029, stripped down to: 3432
if not modules then modules={} end modules ['data-con']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub=string.format,string.lower,string.gsub
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
-local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
-local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
+local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
containers=containers or {}
local containers=containers
containers.usecache=true
local report_containers=logs.reporter("resolvers","containers")
local allocated={}
local mt={
- __index=function(t,k)
- if k=="writable" then
- local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
- t.writable=writable
- return writable
- elseif k=="readables" then
- local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
- t.readables=readables
- return readables
- end
- end,
- __storage__=true
+ __index=function(t,k)
+ if k=="writable" then
+ local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
+ t.writable=writable
+ return writable
+ elseif k=="readables" then
+ local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
+ t.readables=readables
+ return readables
+ end
+ end,
+ __storage__=true
}
function containers.define(category,subcategory,version,enabled)
- if category and subcategory then
- local c=allocated[category]
- if not c then
- c={}
- allocated[category]=c
- end
- local s=c[subcategory]
- if not s then
- s={
- category=category,
- subcategory=subcategory,
- storage={},
- enabled=enabled,
- version=version or math.pi,
- trace=false,
- }
- setmetatable(s,mt)
- c[subcategory]=s
- end
- return s
+ if category and subcategory then
+ local c=allocated[category]
+ if not c then
+ c={}
+ allocated[category]=c
+ end
+ local s=c[subcategory]
+ if not s then
+ s={
+ category=category,
+ subcategory=subcategory,
+ storage={},
+ enabled=enabled,
+ version=version or math.pi,
+ trace=false,
+ }
+ setmetatable(s,mt)
+ c[subcategory]=s
end
+ return s
+ end
end
function containers.is_usable(container,name)
- return container.enabled and caches and caches.is_writable(container.writable,name)
+ return container.enabled and caches and caches.is_writable(container.writable,name)
end
function containers.is_valid(container,name)
- if name and name~="" then
- local storage=container.storage[name]
- return storage and storage.cache_version==container.version
- else
- return false
- end
+ if name and name~="" then
+ local storage=container.storage[name]
+ return storage and storage.cache_version==container.version
+ else
+ return false
+ end
end
function containers.read(container,name)
- local storage=container.storage
- local stored=storage[name]
- if not stored and container.enabled and caches and containers.usecache then
- stored=caches.loaddata(container.readables,name,container.writable)
- if stored and stored.cache_version==container.version then
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","load",container.subcategory,name)
- end
- else
- stored=nil
- end
- storage[name]=stored
- elseif stored then
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
- end
+ local storage=container.storage
+ local stored=storage[name]
+ if not stored and container.enabled and caches and containers.usecache then
+ stored=caches.loaddata(container.readables,name,container.writable)
+ if stored and stored.cache_version==container.version then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","load",container.subcategory,name)
+ end
+ else
+ stored=nil
end
- return stored
+ storage[name]=stored
+ elseif stored then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
+ end
+ end
+ return stored
end
function containers.write(container,name,data)
- if data then
- data.cache_version=container.version
- if container.enabled and caches then
- local unique,shared=data.unique,data.shared
- data.unique,data.shared=nil,nil
- caches.savedata(container.writable,name,data)
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","save",container.subcategory,name)
- end
- data.unique,data.shared=unique,shared
- end
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","store",container.subcategory,name)
- end
- container.storage[name]=data
+ if data then
+ data.cache_version=container.version
+ if container.enabled and caches then
+ local unique,shared=data.unique,data.shared
+ data.unique,data.shared=nil,nil
+ caches.savedata(container.writable,name,data)
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","save",container.subcategory,name)
+ end
+ data.unique,data.shared=unique,shared
end
- return data
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","store",container.subcategory,name)
+ end
+ container.storage[name]=data
+ end
+ return data
end
function containers.content(container,name)
- return container.storage[name]
+ return container.storage[name]
end
function containers.cleanname(name)
- return (gsub(lower(name),"[^%w\128-\255]+","-"))
+ return (gsub(lower(name),"[^%w\128-\255]+","-"))
end
@@ -23110,97 +23118,97 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-use"] = package.loaded["data-use"] or true
--- original size: 4272, stripped down to: 3289
+-- original size: 4272, stripped down to: 3060
if not modules then modules={} end modules ['data-use']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub,find=string.format,string.lower,string.gsub,string.find
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_mounts=logs.reporter("resolvers","mounts")
local resolvers=resolvers
resolvers.automounted=resolvers.automounted or {}
function resolvers.automount(usecache)
- local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
- if (not mountpaths or #mountpaths==0) and usecache then
- mountpaths=caches.getreadablepaths("mount")
- end
- if mountpaths and #mountpaths>0 then
- resolvers.starttiming()
- for k=1,#mountpaths do
- local root=mountpaths[k]
- local f=io.open(root.."/url.tmi")
- if f then
- for line in f:lines() do
- if line then
- if find(line,"^[%%#%-]") then
- elseif find(line,"^zip://") then
- if trace_locating then
- report_mounts("mounting %a",line)
- end
- table.insert(resolvers.automounted,line)
- resolvers.usezipfile(line)
- end
- end
- end
- f:close()
+ local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
+ if (not mountpaths or #mountpaths==0) and usecache then
+ mountpaths=caches.getreadablepaths("mount")
+ end
+ if mountpaths and #mountpaths>0 then
+ resolvers.starttiming()
+ for k=1,#mountpaths do
+ local root=mountpaths[k]
+ local f=io.open(root.."/url.tmi")
+ if f then
+ for line in f:lines() do
+ if line then
+ if find(line,"^[%%#%-]") then
+ elseif find(line,"^zip://") then
+ if trace_locating then
+ report_mounts("mounting %a",line)
+ end
+ table.insert(resolvers.automounted,line)
+ resolvers.usezipfile(line)
end
+ end
end
- resolvers.stoptiming()
+ f:close()
+ end
end
+ resolvers.stoptiming()
+ end
end
statistics.register("used config file",function() return caches.configfiles() end)
statistics.register("used cache path",function() return caches.usedpaths() end)
function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner)
- local enginebanner=status.banner
- if formatbanner and enginebanner and sourcefile then
- local luvname=file.replacesuffix(texname,"luv")
- local luvdata={
- enginebanner=enginebanner,
- formatbanner=formatbanner,
- sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
- sourcefile=sourcefile,
- luaversion=LUAVERSION,
- }
- io.savedata(luvname,table.serialize(luvdata,true))
- lua.registerfinalizer(function()
- logs.report("format banner","%s",banner)
- logs.newline()
- end)
- end
+ local enginebanner=status.banner
+ if formatbanner and enginebanner and sourcefile then
+ local luvname=file.replacesuffix(texname,"luv")
+ local luvdata={
+ enginebanner=enginebanner,
+ formatbanner=formatbanner,
+ sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
+ sourcefile=sourcefile,
+ luaversion=LUAVERSION,
+ }
+ io.savedata(luvname,table.serialize(luvdata,true))
+ lua.registerfinalizer(function()
+ logs.report("format banner","%s",banner)
+ logs.newline()
+ end)
+ end
end
function statistics.checkfmtstatus(texname)
- local enginebanner=status.banner
- if enginebanner and texname then
- local luvname=file.replacesuffix(texname,"luv")
- if lfs.isfile(luvname) then
- local luv=dofile(luvname)
- if luv and luv.sourcefile then
- local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
- local luvbanner=luv.enginebanner or "?"
- if luvbanner~=enginebanner then
- return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
- end
- local luvhash=luv.sourcehash or "?"
- if luvhash~=sourcehash then
- return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
- end
- local luvluaversion=luv.luaversion or 0
- if luvluaversion~=LUAVERSION then
- return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
- end
- else
- return "invalid status file"
- end
- else
- return "missing status file"
- end
+ local enginebanner=status.banner
+ if enginebanner and texname then
+ local luvname=file.replacesuffix(texname,"luv")
+ if lfs.isfile(luvname) then
+ local luv=dofile(luvname)
+ if luv and luv.sourcefile then
+ local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
+ local luvbanner=luv.enginebanner or "?"
+ if luvbanner~=enginebanner then
+ return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
+ end
+ local luvhash=luv.sourcehash or "?"
+ if luvhash~=sourcehash then
+ return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
+ end
+ local luvluaversion=luv.luaversion or 0
+ if luvluaversion~=LUAVERSION then
+ return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
+ end
+ else
+ return "invalid status file"
+ end
+ else
+ return "missing status file"
end
- return true
+ end
+ return true
end
@@ -23210,17 +23218,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-zip"] = package.loaded["data-zip"] or true
--- original size: 8700, stripped down to: 6781
+-- original size: 8700, stripped down to: 6313
if not modules then modules={} end modules ['data-zip']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,find,match=string.format,string.find,string.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_zip=logs.reporter("resolvers","zip")
local resolvers=resolvers
zip=zip or {}
@@ -23230,213 +23238,213 @@ zip.archives=archives
local registeredfiles=zip.registeredfiles or {}
zip.registeredfiles=registeredfiles
local function validzip(str)
- if not find(str,"^zip://") then
- return "zip:///"..str
- else
- return str
- end
+ if not find(str,"^zip://") then
+ return "zip:///"..str
+ else
+ return str
+ end
end
function zip.openarchive(name)
- if not name or name=="" then
- return nil
- else
- local arch=archives[name]
- if not arch then
- local full=resolvers.findfile(name) or ""
- arch=full~="" and zip.open(full) or false
- archives[name]=arch
- end
- return arch
+ if not name or name=="" then
+ return nil
+ else
+ local arch=archives[name]
+ if not arch then
+ local full=resolvers.findfile(name) or ""
+ arch=full~="" and zip.open(full) or false
+ archives[name]=arch
end
+ return arch
+ end
end
function zip.closearchive(name)
- if not name or (name=="" and archives[name]) then
- zip.close(archives[name])
- archives[name]=nil
- end
+ if not name or (name=="" and archives[name]) then
+ zip.close(archives[name])
+ archives[name]=nil
+ end
end
function resolvers.locators.zip(specification)
- local archive=specification.filename
- local zipfile=archive and archive~="" and zip.openarchive(archive)
- if trace_locating then
- if zipfile then
- report_zip("locator: archive %a found",archive)
- else
- report_zip("locator: archive %a not found",archive)
- end
+ local archive=specification.filename
+ local zipfile=archive and archive~="" and zip.openarchive(archive)
+ if trace_locating then
+ if zipfile then
+ report_zip("locator: archive %a found",archive)
+ else
+ report_zip("locator: archive %a not found",archive)
end
+ end
end
function resolvers.hashers.zip(specification)
- local archive=specification.filename
- if trace_locating then
- report_zip("loading file %a",archive)
- end
- resolvers.usezipfile(specification.original)
+ local archive=specification.filename
+ if trace_locating then
+ report_zip("loading file %a",archive)
+ end
+ resolvers.usezipfile(specification.original)
end
function resolvers.concatinators.zip(zipfile,path,name)
- if not path or path=="" then
- return format('%s?name=%s',zipfile,name)
- else
- return format('%s?name=%s/%s',zipfile,path,name)
- end
+ if not path or path=="" then
+ return format('%s?name=%s',zipfile,name)
+ else
+ return format('%s?name=%s/%s',zipfile,path,name)
+ end
end
function resolvers.finders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("finder: archive %a found",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- dfile:close()
- if trace_locating then
- report_zip("finder: file %a found",queryname)
- end
- return specification.original
- elseif trace_locating then
- report_zip("finder: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("finder: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("finder: archive %a found",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ dfile:close()
+ if trace_locating then
+ report_zip("finder: file %a found",queryname)
+ end
+ return specification.original
+ elseif trace_locating then
+ report_zip("finder: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("finder: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("finder: %a not found",original)
- end
- return resolvers.finders.notfound()
+ end
+ if trace_locating then
+ report_zip("finder: %a not found",original)
+ end
+ return resolvers.finders.notfound()
end
function resolvers.openers.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("opener; archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- if trace_locating then
- report_zip("opener: file %a found",queryname)
- end
- return resolvers.openers.helpers.textopener('zip',original,dfile)
- elseif trace_locating then
- report_zip("opener: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("opener: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("opener; archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ if trace_locating then
+ report_zip("opener: file %a found",queryname)
+ end
+ return resolvers.openers.helpers.textopener('zip',original,dfile)
+ elseif trace_locating then
+ report_zip("opener: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("opener: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("opener: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("opener: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.loaders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("loader: archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- logs.show_load(original)
- if trace_locating then
- report_zip("loader; file %a loaded",original)
- end
- local s=dfile:read("*all")
- dfile:close()
- return true,s,#s
- elseif trace_locating then
- report_zip("loader: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("loader; unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("loader: archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ logs.show_load(original)
+ if trace_locating then
+ report_zip("loader; file %a loaded",original)
+ end
+ local s=dfile:read("*all")
+ dfile:close()
+ return true,s,#s
+ elseif trace_locating then
+ report_zip("loader: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("loader; unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("loader: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("loader: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.usezipfile(archive)
- local specification=resolvers.splitmethod(archive)
- local archive=specification.filename
- if archive and not registeredfiles[archive] then
- local z=zip.openarchive(archive)
- if z then
- local tree=url.query(specification.query).tree or ""
- if trace_locating then
- report_zip("registering: archive %a",archive)
- end
- resolvers.starttiming()
- resolvers.prependhash('zip',archive)
- resolvers.extendtexmfvariable(archive)
- registeredfiles[archive]=z
- resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
- resolvers.stoptiming()
- elseif trace_locating then
- report_zip("registering: unknown archive %a",archive)
- end
+ local specification=resolvers.splitmethod(archive)
+ local archive=specification.filename
+ if archive and not registeredfiles[archive] then
+ local z=zip.openarchive(archive)
+ if z then
+ local tree=url.query(specification.query).tree or ""
+ if trace_locating then
+ report_zip("registering: archive %a",archive)
+ end
+ resolvers.starttiming()
+ resolvers.prependhash('zip',archive)
+ resolvers.extendtexmfvariable(archive)
+ registeredfiles[archive]=z
+ resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
+ resolvers.stoptiming()
elseif trace_locating then
- report_zip("registering: archive %a not found",archive)
+ report_zip("registering: unknown archive %a",archive)
end
+ elseif trace_locating then
+ report_zip("registering: archive %a not found",archive)
+ end
end
function resolvers.registerzipfile(z,tree)
- local names={}
- local files={}
- local remap={}
- local n=0
- local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
- local register=resolvers.registerfile
- if trace_locating then
- report_zip("registering: using filter %a",filter)
- end
- for i in z:files() do
- local filename=i.filename
- local path,name=match(filename,filter)
- if not path then
- n=n+1
- register(names,filename,"")
- local usedname=lower(filename)
- files[usedname]=""
- if usedname~=filename then
- remap[usedname]=filename
- end
- elseif name and name~="" then
- n=n+1
- register(names,name,path)
- local usedname=lower(name)
- files[usedname]=path
- if usedname~=name then
- remap[usedname]=name
- end
- else
- end
+ local names={}
+ local files={}
+ local remap={}
+ local n=0
+ local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
+ local register=resolvers.registerfile
+ if trace_locating then
+ report_zip("registering: using filter %a",filter)
+ end
+ for i in z:files() do
+ local filename=i.filename
+ local path,name=match(filename,filter)
+ if not path then
+ n=n+1
+ register(names,filename,"")
+ local usedname=lower(filename)
+ files[usedname]=""
+ if usedname~=filename then
+ remap[usedname]=filename
+ end
+ elseif name and name~="" then
+ n=n+1
+ register(names,name,path)
+ local usedname=lower(name)
+ files[usedname]=path
+ if usedname~=name then
+ remap[usedname]=name
+ end
+ else
end
- report_zip("registering: %s files registered",n)
- return {
- files=files,
- remap=remap,
- }
+ end
+ report_zip("registering: %s files registered",n)
+ return {
+ files=files,
+ remap=remap,
+ }
end
@@ -23446,20 +23454,20 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tre"] = package.loaded["data-tre"] or true
--- original size: 8478, stripped down to: 5611
+-- original size: 8478, stripped down to: 5223
if not modules then modules={} end modules ['data-tre']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local find,gsub,lower=string.find,string.gsub,string.lower
-local basename,dirname,joinname=file.basename,file.dirname,file .join
+local basename,dirname,joinname=file.basename,file.dirname,file .join
local globdir,isdir,isfile=dir.glob,lfs.isdir,lfs.isfile
local P,lpegmatch=lpeg.P,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_trees=logs.reporter("resolvers","trees")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -23468,167 +23476,167 @@ local lookup=resolvers.get_from_content
local collectors={}
local found={}
function resolvers.finders.tree(specification)
- local spec=specification.filename
- local okay=found[spec]
- if okay==nil then
- if spec~="" then
- local path=dirname(spec)
- local name=basename(spec)
- if path=="" then
- path="."
- end
- local names=collectors[path]
- if not names then
- local pattern=find(path,"/%*+$") and path or (path.."/*")
- names=globdir(pattern)
- collectors[path]=names
- end
- local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
- for i=1,#names do
- local fullname=names[i]
- if find(fullname,pattern) then
- found[spec]=fullname
- return fullname
- end
- end
- local pattern=lower(pattern)
- for i=1,#names do
- local fullname=lower(names[i])
- if find(fullname,pattern) then
- if isfile(fullname) then
- found[spec]=fullname
- return fullname
- else
- break
- end
- end
- end
+ local spec=specification.filename
+ local okay=found[spec]
+ if okay==nil then
+ if spec~="" then
+ local path=dirname(spec)
+ local name=basename(spec)
+ if path=="" then
+ path="."
+ end
+ local names=collectors[path]
+ if not names then
+ local pattern=find(path,"/%*+$") and path or (path.."/*")
+ names=globdir(pattern)
+ collectors[path]=names
+ end
+ local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
+ for i=1,#names do
+ local fullname=names[i]
+ if find(fullname,pattern) then
+ found[spec]=fullname
+ return fullname
+ end
+ end
+ local pattern=lower(pattern)
+ for i=1,#names do
+ local fullname=lower(names[i])
+ if find(fullname,pattern) then
+ if isfile(fullname) then
+ found[spec]=fullname
+ return fullname
+ else
+ break
+ end
end
- okay=notfound()
- found[spec]=okay
+ end
end
- return okay
+ okay=notfound()
+ found[spec]=okay
+ end
+ return okay
end
function resolvers.locators.tree(specification)
- local name=specification.filename
- local realname=resolveprefix(name)
- if realname and realname~='' and isdir(realname) then
- if trace_locating then
- report_trees("locator %a found",realname)
- end
- resolvers.appendhash('tree',name,false)
- elseif trace_locating then
- report_trees("locator %a not found",name)
+ local name=specification.filename
+ local realname=resolveprefix(name)
+ if realname and realname~='' and isdir(realname) then
+ if trace_locating then
+ report_trees("locator %a found",realname)
end
+ resolvers.appendhash('tree',name,false)
+ elseif trace_locating then
+ report_trees("locator %a not found",name)
+ end
end
function resolvers.hashers.tree(specification)
- local name=specification.filename
- if trace_locating then
- report_trees("analyzing %a",name)
- end
- resolvers.methodhandler("hashers",name)
- resolvers.generators.file(specification)
+ local name=specification.filename
+ if trace_locating then
+ report_trees("analyzing %a",name)
+ end
+ resolvers.methodhandler("hashers",name)
+ resolvers.generators.file(specification)
end
local collectors={}
local splitter=lpeg.splitat("/**/")
local stripper=lpeg.replacer { [P("/")*P("*")^1*P(-1)]="" }
table.setmetatableindex(collectors,function(t,k)
- local rootname=lpegmatch(stripper,k)
- local dataname=joinname(rootname,"dirlist")
- local content=caches.loadcontent(dataname,"files",dataname)
- if not content then
- content=resolvers.scanfiles(rootname,nil,nil,false,true)
- caches.savecontent(dataname,"files",content,dataname)
- end
- t[k]=content
- return content
+ local rootname=lpegmatch(stripper,k)
+ local dataname=joinname(rootname,"dirlist")
+ local content=caches.loadcontent(dataname,"files",dataname)
+ if not content then
+ content=resolvers.scanfiles(rootname,nil,nil,false,true)
+ caches.savecontent(dataname,"files",content,dataname)
+ end
+ t[k]=content
+ return content
end)
local function checked(root,p,n)
- if p then
- if type(p)=="table" then
- for i=1,#p do
- local fullname=joinname(root,p[i],n)
- if isfile(fullname) then
- return fullname
- end
- end
- else
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
+ if p then
+ if type(p)=="table" then
+ for i=1,#p do
+ local fullname=joinname(root,p[i],n)
+ if isfile(fullname) then
+ return fullname
end
+ end
+ else
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- return notfound()
+ end
+ return notfound()
end
local function resolve(specification)
- local filename=specification.filename
- if filename~="" then
- local root,rest=lpegmatch(splitter,filename)
- if root and rest then
- local path,name=dirname(rest),basename(rest)
- if name~=rest then
- local content=collectors[root]
- local p,n=lookup(content,name)
- if not p then
- return notfound()
- end
- local pattern=".*/"..path.."$"
- local istable=type(p)=="table"
- if istable then
- for i=1,#p do
- local pi=p[i]
- if pi==path or find(pi,pattern) then
- local fullname=joinname(root,pi,n)
- if isfile(fullname) then
- return fullname
- end
- end
- end
- elseif p==path or find(p,pattern) then
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
- end
- local queries=specification.queries
- if queries and queries.option=="fileonly" then
- return checked(root,p,n)
- else
- return notfound()
- end
+ local filename=specification.filename
+ if filename~="" then
+ local root,rest=lpegmatch(splitter,filename)
+ if root and rest then
+ local path,name=dirname(rest),basename(rest)
+ if name~=rest then
+ local content=collectors[root]
+ local p,n=lookup(content,name)
+ if not p then
+ return notfound()
+ end
+ local pattern=".*/"..path.."$"
+ local istable=type(p)=="table"
+ if istable then
+ for i=1,#p do
+ local pi=p[i]
+ if pi==path or find(pi,pattern) then
+ local fullname=joinname(root,pi,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
+ end
+ elseif p==path or find(p,pattern) then
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- local path,name=dirname(filename),basename(filename)
- local root=lpegmatch(stripper,path)
- local content=collectors[path]
- local p,n=lookup(content,name)
- if p then
- return checked(root,p,n)
+ local queries=specification.queries
+ if queries and queries.option=="fileonly" then
+ return checked(root,p,n)
+ else
+ return notfound()
end
+ end
+ end
+ local path,name=dirname(filename),basename(filename)
+ local root=lpegmatch(stripper,path)
+ local content=collectors[path]
+ local p,n=lookup(content,name)
+ if p then
+ return checked(root,p,n)
end
- return notfound()
+ end
+ return notfound()
end
-resolvers.finders .dirlist=resolve
-resolvers.locators .dirlist=resolvers.locators .tree
-resolvers.hashers .dirlist=resolvers.hashers .tree
+resolvers.finders .dirlist=resolve
+resolvers.locators .dirlist=resolvers.locators .tree
+resolvers.hashers .dirlist=resolvers.hashers .tree
resolvers.generators.dirlist=resolvers.generators.file
-resolvers.openers .dirlist=resolvers.openers .file
-resolvers.loaders .dirlist=resolvers.loaders .file
+resolvers.openers .dirlist=resolvers.openers .file
+resolvers.loaders .dirlist=resolvers.loaders .file
function resolvers.finders.dirfile(specification)
- local queries=specification.queries
- if queries then
- queries.option="fileonly"
- else
- specification.queries={ option="fileonly" }
- end
- return resolve(specification)
-end
-resolvers.locators .dirfile=resolvers.locators .dirlist
-resolvers.hashers .dirfile=resolvers.hashers .dirlist
+ local queries=specification.queries
+ if queries then
+ queries.option="fileonly"
+ else
+ specification.queries={ option="fileonly" }
+ end
+ return resolve(specification)
+end
+resolvers.locators .dirfile=resolvers.locators .dirlist
+resolvers.hashers .dirfile=resolvers.hashers .dirlist
resolvers.generators.dirfile=resolvers.generators.dirlist
-resolvers.openers .dirfile=resolvers.openers .dirlist
-resolvers.loaders .dirfile=resolvers.loaders .dirlist
+resolvers.openers .dirfile=resolvers.openers .dirlist
+resolvers.loaders .dirfile=resolvers.loaders .dirlist
end -- of closure
@@ -23637,19 +23645,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-sch"] = package.loaded["data-sch"] or true
--- original size: 6753, stripped down to: 5511
+-- original size: 6753, stripped down to: 5268
if not modules then modules={} end modules ['data-sch']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local load,tonumber=load,tonumber
local gsub,concat,format=string.gsub,table.concat,string.format
local finders,openers,loaders=resolvers.finders,resolvers.openers,resolvers.loaders
-local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
+local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
local report_schemes=logs.reporter("resolvers","schemes")
local http=require("socket.http")
local ltn12=require("ltn12")
@@ -23662,27 +23670,27 @@ schemes.cleaners=cleaners
local threshold=24*60*60
directives.register("schemes.threshold",function(v) threshold=tonumber(v) or threshold end)
function cleaners.none(specification)
- return specification.original
+ return specification.original
end
function cleaners.strip(specification)
- local path,name=file.splitbase(specification.original)
- if path=="" then
- return (gsub(name,"[^%a%d%.]+","-"))
- else
- return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
- end
+ local path,name=file.splitbase(specification.original)
+ if path=="" then
+ return (gsub(name,"[^%a%d%.]+","-"))
+ else
+ return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
+ end
end
function cleaners.md5(specification)
- return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
+ return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
end
local cleaner=cleaners.strip
directives.register("schemes.cleanmethod",function(v) cleaner=cleaners[v] or cleaners.strip end)
function resolvers.schemes.cleanname(specification)
- local hash=cleaner(specification)
- if trace_schemes then
- report_schemes("hashing %a to %a",specification.original,hash)
- end
- return hash
+ local hash=cleaner(specification)
+ if trace_schemes then
+ report_schemes("hashing %a to %a",specification.original,hash)
+ end
+ return hash
end
local cached={}
local loaded={}
@@ -23690,139 +23698,139 @@ local reused={}
local thresholds={}
local handlers={}
local runner=sandbox.registerrunner {
- name="curl resolver",
- method="execute",
- program="curl",
- template="--silent --insecure --create-dirs --output %cachename% %original%",
- checkers={
- cachename="cache",
- original="url",
- }
+ name="curl resolver",
+ method="execute",
+ program="curl",
+ template="--silent --insecure --create-dirs --output %cachename% %original%",
+ checkers={
+ cachename="cache",
+ original="url",
+ }
}
local function fetch(specification)
- local original=specification.original
- local scheme=specification.scheme
- local cleanname=schemes.cleanname(specification)
- local cachename=caches.setfirstwritablefile(cleanname,"schemes")
- if not cached[original] then
- statistics.starttiming(schemes)
- if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
- cached[original]=cachename
- local handler=handlers[scheme]
- if handler then
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
- end
- logs.flush()
- handler(specification,cachename)
- else
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
- end
- logs.flush()
- runner {
- original=original,
- cachename=cachename,
- }
- end
- end
- if io.exists(cachename) then
- cached[original]=cachename
- if trace_schemes then
- report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
- end
- else
- cached[original]=""
- if trace_schemes then
- report_schemes("using missing %a, protocol %a",original,scheme)
- end
+ local original=specification.original
+ local scheme=specification.scheme
+ local cleanname=schemes.cleanname(specification)
+ local cachename=caches.setfirstwritablefile(cleanname,"schemes")
+ if not cached[original] then
+ statistics.starttiming(schemes)
+ if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
+ cached[original]=cachename
+ local handler=handlers[scheme]
+ if handler then
+ if trace_schemes then
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
end
- loaded[scheme]=loaded[scheme]+1
- statistics.stoptiming(schemes)
- else
+ logs.flush()
+ handler(specification,cachename)
+ else
if trace_schemes then
- report_schemes("reusing %a, protocol %a",original,scheme)
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
end
- reused[scheme]=reused[scheme]+1
+ logs.flush()
+ runner {
+ original=original,
+ cachename=cachename,
+ }
+ end
end
- return cached[original]
+ if io.exists(cachename) then
+ cached[original]=cachename
+ if trace_schemes then
+ report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
+ end
+ else
+ cached[original]=""
+ if trace_schemes then
+ report_schemes("using missing %a, protocol %a",original,scheme)
+ end
+ end
+ loaded[scheme]=loaded[scheme]+1
+ statistics.stoptiming(schemes)
+ else
+ if trace_schemes then
+ report_schemes("reusing %a, protocol %a",original,scheme)
+ end
+ reused[scheme]=reused[scheme]+1
+ end
+ return cached[original]
end
local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
+ return resolvers.methodhandler("finders",fetch(specification),filetype)
end
local opener=openers.file
local loader=loaders.file
local function install(scheme,handler,newthreshold)
- handlers [scheme]=handler
- loaded [scheme]=0
- reused [scheme]=0
- finders [scheme]=finder
- openers [scheme]=opener
- loaders [scheme]=loader
- thresholds[scheme]=newthreshold or threshold
+ handlers [scheme]=handler
+ loaded [scheme]=0
+ reused [scheme]=0
+ finders [scheme]=finder
+ openers [scheme]=opener
+ loaders [scheme]=loader
+ thresholds[scheme]=newthreshold or threshold
end
schemes.install=install
local function http_handler(specification,cachename)
- local tempname=cachename..".tmp"
- local f=io.open(tempname,"wb")
- local status,message=http.request {
- url=specification.original,
- sink=ltn12.sink.file(f)
- }
- if not status then
- os.remove(tempname)
- else
- os.remove(cachename)
- os.rename(tempname,cachename)
- end
- return cachename
+ local tempname=cachename..".tmp"
+ local f=io.open(tempname,"wb")
+ local status,message=http.request {
+ url=specification.original,
+ sink=ltn12.sink.file(f)
+ }
+ if not status then
+ os.remove(tempname)
+ else
+ os.remove(cachename)
+ os.rename(tempname,cachename)
+ end
+ return cachename
end
install('http',http_handler)
install('https')
install('ftp')
statistics.register("scheme handling time",function()
- local l,r,nl,nr={},{},0,0
- for k,v in table.sortedhash(loaded) do
- if v>0 then
- nl=nl+1
- l[nl]=k..":"..v
- end
- end
- for k,v in table.sortedhash(reused) do
- if v>0 then
- nr=nr+1
- r[nr]=k..":"..v
- end
- end
- local n=nl+nr
- if n>0 then
- l=nl>0 and concat(l) or "none"
- r=nr>0 and concat(r) or "none"
- return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
- statistics.elapsedtime(schemes),n,threshold,l,r)
- else
- return nil
- end
+ local l,r,nl,nr={},{},0,0
+ for k,v in table.sortedhash(loaded) do
+ if v>0 then
+ nl=nl+1
+ l[nl]=k..":"..v
+ end
+ end
+ for k,v in table.sortedhash(reused) do
+ if v>0 then
+ nr=nr+1
+ r[nr]=k..":"..v
+ end
+ end
+ local n=nl+nr
+ if n>0 then
+ l=nl>0 and concat(l) or "none"
+ r=nr>0 and concat(r) or "none"
+ return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
+ statistics.elapsedtime(schemes),n,threshold,l,r)
+ else
+ return nil
+ end
end)
local httprequest=http.request
local toquery=url.toquery
local function fetchstring(url,data)
- local q=data and toquery(data)
- if q then
- url=url.."?"..q
- end
- local reply=httprequest(url)
- return reply
+ local q=data and toquery(data)
+ if q then
+ url=url.."?"..q
+ end
+ local reply=httprequest(url)
+ return reply
end
schemes.fetchstring=fetchstring
function schemes.fetchtable(url,data)
- local reply=fetchstring(url,data)
- if reply then
- local s=load("return "..reply)
- if s then
- return s()
- end
+ local reply=fetchstring(url,data)
+ if reply then
+ local s=load("return "..reply)
+ if s then
+ return s()
end
+ end
end
@@ -23832,14 +23840,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lua"] = package.loaded["data-lua"] or true
--- original size: 4207, stripped down to: 3137
+-- original size: 4207, stripped down to: 3041
if not modules then modules={} end modules ['data-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local package,lpeg=package,lpeg
local gsub=string.gsub
@@ -23858,20 +23866,20 @@ helpers.report=logs.reporter("resolvers","libraries")
trackers.register("resolvers.libraries",function(v) helpers.trace=v end)
trackers.register("resolvers.locating",function(v) helpers.trace=v end)
helpers.sequence={
- "already loaded",
- "preload table",
- "lua variable format",
- "lib variable format",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
+ "already loaded",
+ "preload table",
+ "lua variable format",
+ "lib variable format",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
}
local pattern=Cs(P("!")^0/""*(P("/")*P(-1)/"/"+P("/")^1/"/"+1)^0)
function helpers.cleanpath(path)
- return resolveprefix(lpegmatch(pattern,path))
+ return resolveprefix(lpegmatch(pattern,path))
end
local loadedaslib=helpers.loadedaslib
local registerpath=helpers.registerpath
@@ -23879,56 +23887,56 @@ local lualibfile=helpers.lualibfile
local luaformatpaths
local libformatpaths
local function getluaformatpaths()
- if not luaformatpaths then
- luaformatpaths={}
- for i=1,#luaformats do
- registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
- end
+ if not luaformatpaths then
+ luaformatpaths={}
+ for i=1,#luaformats do
+ registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
end
- return luaformatpaths
+ end
+ return luaformatpaths
end
local function getlibformatpaths()
- if not libformatpaths then
- libformatpaths={}
- for i=1,#libformats do
- registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
- end
+ if not libformatpaths then
+ libformatpaths={}
+ for i=1,#libformats do
+ registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
end
- return libformatpaths
+ end
+ return libformatpaths
end
local function loadedbyformat(name,rawname,suffixes,islib,what)
- local trace=helpers.trace
- local report=helpers.report
- for i=1,#suffixes do
- local format=suffixes[i]
- local resolved=resolvers.findfile(name,format) or ""
- if trace then
- report("%s format, identifying %a using format %a",what,name,format)
- end
- if resolved~="" then
- if trace then
- report("%s format, %a found on %a",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ local report=helpers.report
+ for i=1,#suffixes do
+ local format=suffixes[i]
+ local resolved=resolvers.findfile(name,format) or ""
+ if trace then
+ report("%s format, identifying %a using format %a",what,name,format)
end
+ if resolved~="" then
+ if trace then
+ report("%s format, %a found on %a",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
+ end
+ end
end
helpers.loadedbyformat=loadedbyformat
methods["lua variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
end
methods["lib variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
end
resolvers.loadlualib=require
@@ -23939,64 +23947,64 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-aux"] = package.loaded["data-aux"] or true
--- original size: 2438, stripped down to: 2003
+-- original size: 2438, stripped down to: 1863
if not modules then modules={} end modules ['data-aux']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local find=string.find
local type,next=type,next
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local resolvers=resolvers
local report_scripts=logs.reporter("resolvers","scripts")
function resolvers.updatescript(oldname,newname)
- local scriptpath="context/lua"
- newname=file.addsuffix(newname,"lua")
- local oldscript=resolvers.cleanpath(oldname)
+ local scriptpath="context/lua"
+ newname=file.addsuffix(newname,"lua")
+ local oldscript=resolvers.cleanpath(oldname)
+ if trace_locating then
+ report_scripts("to be replaced old script %a",oldscript)
+ end
+ local newscripts=resolvers.findfiles(newname) or {}
+ if #newscripts==0 then
if trace_locating then
- report_scripts("to be replaced old script %a",oldscript)
+ report_scripts("unable to locate new script")
end
- local newscripts=resolvers.findfiles(newname) or {}
- if #newscripts==0 then
+ else
+ for i=1,#newscripts do
+ local newscript=resolvers.cleanpath(newscripts[i])
+ if trace_locating then
+ report_scripts("checking new script %a",newscript)
+ end
+ if oldscript==newscript then
if trace_locating then
- report_scripts("unable to locate new script")
+ report_scripts("old and new script are the same")
end
- else
- for i=1,#newscripts do
- local newscript=resolvers.cleanpath(newscripts[i])
- if trace_locating then
- report_scripts("checking new script %a",newscript)
- end
- if oldscript==newscript then
- if trace_locating then
- report_scripts("old and new script are the same")
- end
- elseif not find(newscript,scriptpath,1,true) then
- if trace_locating then
- report_scripts("new script should come from %a",scriptpath)
- end
- elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
- if trace_locating then
- report_scripts("invalid new script name")
- end
- else
- local newdata=io.loaddata(newscript)
- if newdata then
- if trace_locating then
- report_scripts("old script content replaced by new content")
- end
- io.savedata(oldscript,newdata)
- break
- elseif trace_locating then
- report_scripts("unable to load new script")
- end
- end
+ elseif not find(newscript,scriptpath,1,true) then
+ if trace_locating then
+ report_scripts("new script should come from %a",scriptpath)
+ end
+ elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
+ if trace_locating then
+ report_scripts("invalid new script name")
end
+ else
+ local newdata=io.loaddata(newscript)
+ if newdata then
+ if trace_locating then
+ report_scripts("old script content replaced by new content")
+ end
+ io.savedata(oldscript,newdata)
+ break
+ elseif trace_locating then
+ report_scripts("unable to load new script")
+ end
+ end
end
+ end
end
@@ -24006,53 +24014,53 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmf"] = package.loaded["data-tmf"] or true
--- original size: 2601, stripped down to: 1627
+-- original size: 2601, stripped down to: 1549
if not modules then modules={} end modules ['data-tmf']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local resolvers=resolvers
local report_tds=logs.reporter("resolvers","tds")
function resolvers.load_tree(tree,resolve)
- if type(tree)=="string" and tree~="" then
- local getenv,setenv=resolvers.getenv,resolvers.setenv
- local texos="texmf-"..os.platform
- local oldroot=environment.texroot
- local newroot=file.collapsepath(tree)
- local newtree=file.join(newroot,texos)
- local newpath=file.join(newtree,"bin")
- if not lfs.isdir(newtree) then
- report_tds("no %a under tree %a",texos,tree)
- os.exit()
- end
- if not lfs.isdir(newpath) then
- report_tds("no '%s/bin' under tree %a",texos,tree)
- os.exit()
- end
- local texmfos=newtree
- environment.texroot=newroot
- environment.texos=texos
- environment.texmfos=texmfos
- if resolve then
- resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
- end
- setenv('SELFAUTOPARENT',newroot)
- setenv('SELFAUTODIR',newtree)
- setenv('SELFAUTOLOC',newpath)
- setenv('TEXROOT',newroot)
- setenv('TEXOS',texos)
- setenv('TEXMFOS',texmfos)
- setenv('TEXMFCNF',resolvers.luacnfspec,true)
- setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
- report_tds("changing from root %a to %a",oldroot,newroot)
- report_tds("prepending %a to PATH",newpath)
- report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
- report_tds()
- end
+ if type(tree)=="string" and tree~="" then
+ local getenv,setenv=resolvers.getenv,resolvers.setenv
+ local texos="texmf-"..os.platform
+ local oldroot=environment.texroot
+ local newroot=file.collapsepath(tree)
+ local newtree=file.join(newroot,texos)
+ local newpath=file.join(newtree,"bin")
+ if not lfs.isdir(newtree) then
+ report_tds("no %a under tree %a",texos,tree)
+ os.exit()
+ end
+ if not lfs.isdir(newpath) then
+ report_tds("no '%s/bin' under tree %a",texos,tree)
+ os.exit()
+ end
+ local texmfos=newtree
+ environment.texroot=newroot
+ environment.texos=texos
+ environment.texmfos=texmfos
+ if resolve then
+ resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
+ end
+ setenv('SELFAUTOPARENT',newroot)
+ setenv('SELFAUTODIR',newtree)
+ setenv('SELFAUTOLOC',newpath)
+ setenv('TEXROOT',newroot)
+ setenv('TEXOS',texos)
+ setenv('TEXMFOS',texmfos)
+ setenv('TEXMFCNF',resolvers.luacnfspec,true)
+ setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
+ report_tds("changing from root %a to %a",oldroot,newroot)
+ report_tds("prepending %a to PATH",newpath)
+ report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
+ report_tds()
+ end
end
@@ -24062,14 +24070,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lst"] = package.loaded["data-lst"] or true
--- original size: 1823, stripped down to: 1591
+-- original size: 1823, stripped down to: 1542
if not modules then modules={} end modules ['data-lst']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type=type
local concat,sortedhash=table.concat,table.sortedhash
@@ -24080,37 +24088,37 @@ local resolveprefix=resolvers.resolve
local report_lists=logs.reporter("resolvers","lists")
local report_resolved=logs.reporter("system","resolved")
local function tabstr(str)
- if type(str)=='table' then
- return concat(str," | ")
- else
- return str
- end
+ if type(str)=='table' then
+ return concat(str," | ")
+ else
+ return str
+ end
end
function listers.variables(pattern)
- local result=resolvers.knownvariables(pattern)
- for key,value in sortedhash(result) do
- report_lists(key)
- report_lists(" env: %s",tabstr(value.environment or "unset"))
- report_lists(" var: %s",tabstr(value.variable or "unset"))
- report_lists(" exp: %s",tabstr(value.expansion or "unset"))
- report_lists(" res: %s",tabstr(value.resolved or "unset"))
- end
+ local result=resolvers.knownvariables(pattern)
+ for key,value in sortedhash(result) do
+ report_lists(key)
+ report_lists(" env: %s",tabstr(value.environment or "unset"))
+ report_lists(" var: %s",tabstr(value.variable or "unset"))
+ report_lists(" exp: %s",tabstr(value.expansion or "unset"))
+ report_lists(" res: %s",tabstr(value.resolved or "unset"))
+ end
end
function listers.configurations()
- local configurations=resolvers.configurationfiles()
- for i=1,#configurations do
- report_resolved("file : %s",resolveprefix(configurations[i]))
- end
- report_resolved("")
- local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
- for i=1,#list do
- local li=resolveprefix(list[i])
- if lfs.isdir(li) then
- report_resolved("path - %s",li)
- else
- report_resolved("path + %s",li)
- end
+ local configurations=resolvers.configurationfiles()
+ for i=1,#configurations do
+ report_resolved("file : %s",resolveprefix(configurations[i]))
+ end
+ report_resolved("")
+ local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
+ for i=1,#list do
+ local li=resolveprefix(list[i])
+ if lfs.isdir(li) then
+ report_resolved("path - %s",li)
+ else
+ report_resolved("path + %s",li)
end
+ end
end
@@ -24120,14 +24128,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lib"] = package.loaded["util-lib"] or true
--- original size: 16094, stripped down to: 9206
+-- original size: 16094, stripped down to: 8443
if not modules then modules={} end modules ['util-lib']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local type=type
local next=next
@@ -24147,291 +24155,291 @@ local qualifiedpath=file.is_qualified_path
local isfile=lfs.isfile
local done=false
local function locate(required,version,trace,report,action)
- if type(required)~="string" then
- report("provide a proper library name")
- return
- end
- if trace then
- report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/")
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
- if isfile(addsuffix(required,os.libsuffix)) then
- if trace then
- report("qualified name %a found",required)
- end
- found_library=required
- else
- if trace then
- report("qualified name %a not found",required)
- end
- end
+ if type(required)~="string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library=nil
+ local required_full=gsub(required,"%.","/")
+ local required_path=pathpart(required_full)
+ local required_base=nameonly(required_full)
+ if qualifiedpath(required) then
+ if isfile(addsuffix(required,os.libsuffix)) then
+ if trace then
+ report("qualified name %a found",required)
+ end
+ found_library=required
else
- local required_name=required_base.."."..os.libsuffix
- local version=type(version)=="string" and version~="" and version or false
- local engine="luatex"
- if trace and not done then
- local list=expandpaths("lib")
- for i=1,#list do
- report("tds path %i: %s",i,list[i])
- end
+ if trace then
+ report("qualified name %a not found",required)
+ end
+ end
+ else
+ local required_name=required_base.."."..os.libsuffix
+ local version=type(version)=="string" and version~="" and version or false
+ local engine="luatex"
+ if trace and not done then
+ local list=expandpaths("lib")
+ for i=1,#list do
+ report("tds path %i: %s",i,list[i])
+ end
+ end
+ local function found(locate,asked_library,how,...)
+ if trace then
+ report("checking %s: %a",how,asked_library)
+ end
+ return locate(asked_library,...)
+ end
+ local function check(locate,...)
+ local found=nil
+ if version then
+ local asked_library=joinfile(required_path,version,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function found(locate,asked_library,how,...)
- if trace then
- report("checking %s: %a",how,asked_library)
- end
- return locate(asked_library,...)
- end
- local function check(locate,...)
- local found=nil
- if version then
- local asked_library=joinfile(required_path,version,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- if not found or found=="" then
- local asked_library=joinfile(required_path,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- return found and found~="" and found or false
+ found=locate(asked_library,...)
+ end
+ if not found or found=="" then
+ local asked_library=joinfile(required_path,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function attempt(checkpattern)
- if trace then
- report("checking tds lib paths strictly")
- end
- local found=findfile and check(findfile,"lib")
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- if trace then
- report("checking tds lib paths with wildcard")
- end
- local asked_library=joinfile(required_path,".*",required_name)
- if trace then
- report("checking %s: %a","latest version",asked_library)
- end
- local list=findfiles(asked_library,"lib",true)
- if list and #list>0 then
- sort(list)
- local found=list[#list]
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- if trace then
- report("checking lib paths")
- end
- package.extralibpath(environment.ownpath)
- local paths=package.libpaths()
- local pattern="/[^/]+%."..os.libsuffix.."$"
- for i=1,#paths do
- required_path=gsub(paths[i],pattern,"")
- local found=check(lfs.isfound)
- if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- return false
+ found=locate(asked_library,...)
+ end
+ return found and found~="" and found or false
+ end
+ local function attempt(checkpattern)
+ if trace then
+ report("checking tds lib paths strictly")
+ end
+ local found=findfile and check(findfile,"lib")
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
+ end
+ if trace then
+ report("checking tds lib paths with wildcard")
+ end
+ local asked_library=joinfile(required_path,".*",required_name)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
+ end
+ local list=findfiles(asked_library,"lib",true)
+ if list and #list>0 then
+ sort(list)
+ local found=list[#list]
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
end
- if engine then
- if trace then
- report("attemp 1, engine %a",engine)
- end
- found_library=attempt("/"..engine.."/")
- if not found_library then
- if trace then
- report("attemp 2, no engine",asked_library)
- end
- found_library=attempt()
- end
- else
- found_library=attempt()
+ end
+ if trace then
+ report("checking lib paths")
+ end
+ package.extralibpath(environment.ownpath)
+ local paths=package.libpaths()
+ local pattern="/[^/]+%."..os.libsuffix.."$"
+ for i=1,#paths do
+ required_path=gsub(paths[i],pattern,"")
+ local found=check(lfs.isfound)
+ if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
+ return found
end
+ end
+ return false
end
- if not found_library then
+ if engine then
+ if trace then
+ report("attemp 1, engine %a",engine)
+ end
+ found_library=attempt("/"..engine.."/")
+ if not found_library then
if trace then
- report("not found: %a",required)
+ report("attemp 2, no engine",asked_library)
end
- library=false
+ found_library=attempt()
+ end
else
- if trace then
- report("found: %a",found_library)
- end
- local result,message=action(found_library,required_base)
- if result then
- library=result
- else
- library=false
- report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
- end
+ found_library=attempt()
end
+ end
+ if not found_library then
if trace then
- if not library then
- report("unknown library: %a",required)
- else
- report("stored library: %a",required)
- end
+ report("not found: %a",required)
+ end
+ library=false
+ else
+ if trace then
+ report("found: %a",found_library)
+ end
+ local result,message=action(found_library,required_base)
+ if result then
+ library=result
+ else
+ library=false
+ report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
end
- return library or nil
+ end
+ if trace then
+ if not library then
+ report("unknown library: %a",required)
+ else
+ report("stored library: %a",required)
+ end
+ end
+ return library or nil
end
do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
- local library=loadedlibs[library]
- if library==nil then
- local trace_swiglib=trace_swiglib or package.helpers.trace
- library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
- pushdir(pathpart(name))
- local opener="luaopen_"..base
- if trace_swiglib then
- report_swiglib("opening: %a with %a",name,opener)
- end
- local library,message=loadlib(name,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
- else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
- end
- popdir()
- return library
- end)
- loadedlibs[required]=library or false
- end
- return library
- end
- function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
+ local report_swiglib=logs.reporter("swiglib")
+ local trace_swiglib=false
+ local savedrequire=require
+ local loadedlibs={}
+ local loadlib=package.loadlib
+ local pushdir=dir.push
+ local popdir=dir.pop
+ trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+ function requireswiglib(required,version)
+ local library=loadedlibs[library]
+ if library==nil then
+ local trace_swiglib=trace_swiglib or package.helpers.trace
+ library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ pushdir(pathpart(name))
+ local opener="luaopen_"..base
+ if trace_swiglib then
+ report_swiglib("opening: %a with %a",name,opener)
+ end
+ local library,message=loadlib(name,opener)
+ local libtype=type(library)
+ if libtype=="function" then
+ library=library()
else
- return savedrequire(name)
- end
- end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
- else
- fullname="swiglib."..name
- end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library=false
end
+ popdir()
return library
+ end)
+ loadedlibs[required]=library or false
+ end
+ return library
+ end
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
+ else
+ return savedrequire(name)
+ end
+ end
+ local swiglibs={}
+ local initializer="core"
+ function swiglib(name,version)
+ local library=swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
+ if trace_swiglib then
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%."..initializer.."$") then
+ fullname="swiglib."..name.."."..initializer
+ else
+ fullname="swiglib."..name
+ end
+ library=requireswiglib(fullname,version)
+ swiglibs[name]=library
+ statistics.stoptiming(swiglibs)
end
- statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
- end)
+ return library
+ end
+ statistics.register("used swiglibs",function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
+ end
+ end)
end
if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
- name=removesuffix(name)
- local l=loaded[name]
- if l==nil then
- local state,library=pcall(savedffiload,name)
- if type(library)=="userdata" then
- l=library
- elseif type(state)=="userdata" then
- l=state
- else
- l=false
- end
- loaded[name]=l
- elseif trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
+ local report_ffilib=logs.reporter("ffilib")
+ local trace_ffilib=false
+ local savedffiload=ffi.load
+ trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+ local loaded={}
+ local function locateindeed(name)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l==nil then
+ local state,library=pcall(savedffiload,name)
+ if type(library)=="userdata" then
+ l=library
+ elseif type(state)=="userdata" then
+ l=state
+ else
+ l=false
+ end
+ loaded[name]=l
+ elseif trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
end
- local function getlist(required)
- local list=directives.value("system.librarynames" )
- if type(list)=="table" then
- list=list[required]
- if type(list)=="table" then
- if trace then
- report("using lookup list for library %a: % | t",required,list)
- end
- return list
- end
+ return l
+ end
+ local function getlist(required)
+ local list=directives.value("system.librarynames" )
+ if type(list)=="table" then
+ list=list[required]
+ if type(list)=="table" then
+ if trace then
+ report("using lookup list for library %a: % | t",required,list)
end
- return { required }
+ return list
+ end
end
- function ffilib(name,version)
- name=removesuffix(name)
- local l=loaded[name]
- if l~=nil then
- if trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- end
- local list=getlist(name)
- if version=="system" then
- for i=1,#list do
- local library=locateindeed(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- else
- for i=1,#list do
- local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
- if type(library)=="userdata" then
- return library
- end
- end
- end
+ return { required }
+ end
+ function ffilib(name,version)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l~=nil then
+ if trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
+ end
+ return l
end
- function ffi.load(name)
- local list=getlist(name)
- for i=1,#list do
- local library=ffilib(list[i])
- if type(library)=="userdata" then
- return library
- end
- end
- if trace_ffilib then
- report_ffilib("trying to load %a using normal loader",name)
+ local list=getlist(name)
+ if version=="system" then
+ for i=1,#list do
+ local library=locateindeed(list[i])
+ if type(library)=="userdata" then
+ return library
end
- for i=1,#list do
- local state,library=pcall(savedffiload,list[i])
- if type(library)=="userdata" then
- return library
- elseif type(state)=="userdata" then
- return library
- end
+ end
+ else
+ for i=1,#list do
+ local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
+ if type(library)=="userdata" then
+ return library
end
+ end
+ end
+ end
+ function ffi.load(name)
+ local list=getlist(name)
+ for i=1,#list do
+ local library=ffilib(list[i])
+ if type(library)=="userdata" then
+ return library
+ end
+ end
+ if trace_ffilib then
+ report_ffilib("trying to load %a using normal loader",name)
+ end
+ for i=1,#list do
+ local state,library=pcall(savedffiload,list[i])
+ if type(library)=="userdata" then
+ return library
+ elseif type(state)=="userdata" then
+ return library
+ end
end
+ end
end
@@ -24441,13 +24449,13 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-sta"] = package.loaded["luat-sta"] or true
--- original size: 5703, stripped down to: 2507
+-- original size: 5703, stripped down to: 2321
if not modules then modules={} end modules ['luat-sta']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local gmatch,match=string.gmatch,string.match
local type=type
@@ -24460,81 +24468,81 @@ local hash=states.hash
states.tag=states.tag or ""
states.filename=states.filename or ""
function states.save(filename,tag)
- tag=tag or states.tag
- filename=file.addsuffix(filename or states.filename,'lus')
- io.savedata(filename,
- "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
- )
+ tag=tag or states.tag
+ filename=file.addsuffix(filename or states.filename,'lus')
+ io.savedata(filename,
+ "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
+ )
end
function states.load(filename,tag)
- states.filename=filename
- states.tag=tag or "whatever"
- states.filename=file.addsuffix(states.filename,'lus')
- data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
+ states.filename=filename
+ states.tag=tag or "whatever"
+ states.filename=file.addsuffix(states.filename,'lus')
+ data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
end
local function set_by_tag(tag,key,value,default,persistent)
- local d,h=data[tag],hash[tag]
- if d then
- if type(d)=="table" then
- local dkey,hkey=key,key
- local pre,post=match(key,"(.+)%.([^%.]+)$")
- if pre and post then
- for k in gmatch(pre,"[^%.]+") do
- local dk=d[k]
- if not dk then
- dk={}
- d[k]=dk
- elseif type(dk)=="string" then
- break
- end
- d=dk
- end
- dkey,hkey=post,key
- end
- if value==nil then
- value=default
- elseif value==false then
- elseif persistent then
- value=value or d[dkey] or default
- else
- value=value or default
- end
- d[dkey],h[hkey]=value,value
- elseif type(d)=="string" then
- data[tag],hash[tag]=value,value
+ local d,h=data[tag],hash[tag]
+ if d then
+ if type(d)=="table" then
+ local dkey,hkey=key,key
+ local pre,post=match(key,"(.+)%.([^%.]+)$")
+ if pre and post then
+ for k in gmatch(pre,"[^%.]+") do
+ local dk=d[k]
+ if not dk then
+ dk={}
+ d[k]=dk
+ elseif type(dk)=="string" then
+ break
+ end
+ d=dk
end
+ dkey,hkey=post,key
+ end
+ if value==nil then
+ value=default
+ elseif value==false then
+ elseif persistent then
+ value=value or d[dkey] or default
+ else
+ value=value or default
+ end
+ d[dkey],h[hkey]=value,value
+ elseif type(d)=="string" then
+ data[tag],hash[tag]=value,value
end
+ end
end
local function get_by_tag(tag,key,default)
- local h=hash[tag]
- if h and h[key] then
- return h[key]
- else
- local d=data[tag]
- if d then
- for k in gmatch(key,"[^%.]+") do
- local dk=d[k]
- if dk~=nil then
- d=dk
- else
- return default
- end
- end
- if d==false then
- return false
- else
- return d or default
- end
+ local h=hash[tag]
+ if h and h[key] then
+ return h[key]
+ else
+ local d=data[tag]
+ if d then
+ for k in gmatch(key,"[^%.]+") do
+ local dk=d[k]
+ if dk~=nil then
+ d=dk
+ else
+ return default
end
+ end
+ if d==false then
+ return false
+ else
+ return d or default
+ end
end
+ end
end
states.set_by_tag=set_by_tag
states.get_by_tag=get_by_tag
function states.set(key,value,default,persistent)
- set_by_tag(states.tag,key,value,default,persistent)
+ set_by_tag(states.tag,key,value,default,persistent)
end
function states.get(key,default)
- return get_by_tag(states.tag,key,default)
+ return get_by_tag(states.tag,key,default)
end
@@ -24544,14 +24552,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
--- original size: 9346, stripped down to: 7465
+-- original size: 9346, stripped down to: 7085
if not modules then modules={} end modules ['luat-fmt']={
- version=1.001,
- comment="companion to mtxrun",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to mtxrun",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format=string.format
local concat=table.concat
@@ -24559,223 +24567,223 @@ local quoted=string.quoted
local luasuffixes=utilities.lua.suffixes
local report_format=logs.reporter("resolvers","formats")
local function primaryflags()
- local arguments=environment.arguments
- local flags={}
- if arguments.silent then
- flags[#flags+1]="--interaction=batchmode"
- end
- if arguments.jit then
- flags[#flags+1]="--jiton"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local flags={}
+ if arguments.silent then
+ flags[#flags+1]="--interaction=batchmode"
+ end
+ if arguments.jit then
+ flags[#flags+1]="--jiton"
+ end
+ return concat(flags," ")
end
local function secondaryflags()
- local arguments=environment.arguments
- local trackers=arguments.trackers
- local directives=arguments.directives
- local flags={}
- if trackers and trackers~="" then
- flags[#flags+1]="--c:trackers="..quoted(trackers)
- end
- if directives and directives~="" then
- flags[#flags+1]="--c:directives="..quoted(directives)
- end
- if arguments.silent then
- flags[#flags+1]="--c:silent"
- end
- if arguments.errors then
- flags[#flags+1]="--c:errors"
- end
- if arguments.jit then
- flags[#flags+1]="--c:jiton"
- end
- if arguments.ansi then
- flags[#flags+1]="--c:ansi"
- end
- if arguments.strip then
- flags[#flags+1]="--c:strip"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local trackers=arguments.trackers
+ local directives=arguments.directives
+ local flags={}
+ if trackers and trackers~="" then
+ flags[#flags+1]="--c:trackers="..quoted(trackers)
+ end
+ if directives and directives~="" then
+ flags[#flags+1]="--c:directives="..quoted(directives)
+ end
+ if arguments.silent then
+ flags[#flags+1]="--c:silent"
+ end
+ if arguments.errors then
+ flags[#flags+1]="--c:errors"
+ end
+ if arguments.jit then
+ flags[#flags+1]="--c:jiton"
+ end
+ if arguments.ansi then
+ flags[#flags+1]="--c:ansi"
+ end
+ if arguments.strip then
+ flags[#flags+1]="--c:strip"
+ end
+ return concat(flags," ")
end
local template=[[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]]
local checkers={
- primaryflags="string",
- secondaryflags="string",
- luafile="readable",
- texfile="readable",
- redirect="string",
- dump="string",
+ primaryflags="string",
+ secondaryflags="string",
+ luafile="readable",
+ texfile="readable",
+ redirect="string",
+ dump="string",
}
local runners={
- luatex=sandbox.registerrunner {
- name="make luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="make luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="make luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="make luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.make_format(name,arguments)
- local engine=environment.ownmain or "luatex"
- local silent=environment.arguments.silent
- local errors=environment.arguments.errors
- local olddir=dir.current()
- local path=caches.getwritablepath("formats",engine) or ""
- if path~="" then
- lfs.chdir(path)
- end
- report_format("using format path %a",dir.current())
- local texsourcename=file.addsuffix(name,"mkiv")
- local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- if fulltexsourcename=="" then
- texsourcename=file.addsuffix(name,"tex")
- fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- end
- if fulltexsourcename=="" then
- report_format("no tex source file with name %a (mkiv or tex)",name)
- lfs.chdir(olddir)
- return
- else
- report_format("using tex source file %a",fulltexsourcename)
- end
- local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
- local specificationname=file.replacesuffix(fulltexsourcename,"lus")
- local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- if fullspecificationname=="" then
- specificationname=file.join(texsourcepath,"context.lus")
- fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- end
- if fullspecificationname=="" then
- report_format("unknown stub specification %a",specificationname)
- lfs.chdir(olddir)
- return
- end
- local specificationpath=file.dirname(fullspecificationname)
- local usedluastub=nil
- local usedlualibs=dofile(fullspecificationname)
- if type(usedlualibs)=="string" then
- usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
- elseif type(usedlualibs)=="table" then
- report_format("using stub specification %a",fullspecificationname)
- local texbasename=file.basename(name)
- local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
- local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
- report_format("creating initialization file %a",luastubname)
- utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
- if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
- report_format("using compiled initialization file %a",lucstubname)
- usedluastub=lucstubname
- else
- report_format("using uncompiled initialization file %a",luastubname)
- usedluastub=luastubname
- end
- else
- report_format("invalid stub specification %a",fullspecificationname)
- lfs.chdir(olddir)
- return
- end
- local specification={
- primaryflags=primaryflags(),
- secondaryflags=secondaryflags(),
- luafile=quoted(usedluastub),
- texfile=quoted(fulltexsourcename),
- dump=os.platform=="unix" and "\\\\dump" or "\\dump",
- }
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
- elseif silent then
- statistics.starttiming()
- specification.redirect="> temp.log"
- local result=runner(specification)
- local runtime=statistics.stoptiming()
- if result~=0 then
- print(format("%s silent make > fatal error when making format %q",engine,name))
- else
- print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
- end
- os.remove("temp.log")
- else
- runner(specification)
- end
- local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
- local mp=dir.glob(pattern)
- if mp then
- for i=1,#mp do
- local name=mp[i]
- report_format("removing related mplib format %a",file.basename(name))
- os.remove(name)
- end
- end
+ local engine=environment.ownmain or "luatex"
+ local silent=environment.arguments.silent
+ local errors=environment.arguments.errors
+ local olddir=dir.current()
+ local path=caches.getwritablepath("formats",engine) or ""
+ if path~="" then
+ lfs.chdir(path)
+ end
+ report_format("using format path %a",dir.current())
+ local texsourcename=file.addsuffix(name,"mkiv")
+ local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ if fulltexsourcename=="" then
+ texsourcename=file.addsuffix(name,"tex")
+ fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ end
+ if fulltexsourcename=="" then
+ report_format("no tex source file with name %a (mkiv or tex)",name)
lfs.chdir(olddir)
+ return
+ else
+ report_format("using tex source file %a",fulltexsourcename)
+ end
+ local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
+ local specificationname=file.replacesuffix(fulltexsourcename,"lus")
+ local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ if fullspecificationname=="" then
+ specificationname=file.join(texsourcepath,"context.lus")
+ fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ end
+ if fullspecificationname=="" then
+ report_format("unknown stub specification %a",specificationname)
+ lfs.chdir(olddir)
+ return
+ end
+ local specificationpath=file.dirname(fullspecificationname)
+ local usedluastub=nil
+ local usedlualibs=dofile(fullspecificationname)
+ if type(usedlualibs)=="string" then
+ usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
+ elseif type(usedlualibs)=="table" then
+ report_format("using stub specification %a",fullspecificationname)
+ local texbasename=file.basename(name)
+ local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
+ local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
+ report_format("creating initialization file %a",luastubname)
+ utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
+ if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
+ report_format("using compiled initialization file %a",lucstubname)
+ usedluastub=lucstubname
+ else
+ report_format("using uncompiled initialization file %a",luastubname)
+ usedluastub=luastubname
+ end
+ else
+ report_format("invalid stub specification %a",fullspecificationname)
+ lfs.chdir(olddir)
+ return
+ end
+ local specification={
+ primaryflags=primaryflags(),
+ secondaryflags=secondaryflags(),
+ luafile=quoted(usedluastub),
+ texfile=quoted(fulltexsourcename),
+ dump=os.platform=="unix" and "\\\\dump" or "\\dump",
+ }
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
+ elseif silent then
+ statistics.starttiming()
+ specification.redirect="> temp.log"
+ local result=runner(specification)
+ local runtime=statistics.stoptiming()
+ if result~=0 then
+ print(format("%s silent make > fatal error when making format %q",engine,name))
+ else
+ print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
+ end
+ os.remove("temp.log")
+ else
+ runner(specification)
+ end
+ local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
+ local mp=dir.glob(pattern)
+ if mp then
+ for i=1,#mp do
+ local name=mp[i]
+ report_format("removing related mplib format %a",file.basename(name))
+ os.remove(name)
+ end
+ end
+ lfs.chdir(olddir)
end
local template=[[%flags% --fmt=%fmtfile% --lua=%luafile% %texfile% %more%]]
local checkers={
- flags="string",
- more="string",
- fmtfile="readable",
- luafile="readable",
- texfile="readable",
+ flags="string",
+ more="string",
+ fmtfile="readable",
+ luafile="readable",
+ texfile="readable",
}
local runners={
- luatex=sandbox.registerrunner {
- name="run luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="run luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="run luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="run luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.run_format(name,data,more)
- if name and name~="" then
- local engine=environment.ownmain or "luatex"
- local barename=file.removesuffix(name)
- local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
- if fmtname=="" then
- fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
- end
- fmtname=resolvers.cleanpath(fmtname)
- if fmtname=="" then
- report_format("no format with name %a",name)
+ if name and name~="" then
+ local engine=environment.ownmain or "luatex"
+ local barename=file.removesuffix(name)
+ local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
+ if fmtname=="" then
+ fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
+ end
+ fmtname=resolvers.cleanpath(fmtname)
+ if fmtname=="" then
+ report_format("no format with name %a",name)
+ else
+ local barename=file.removesuffix(name)
+ local luaname=file.addsuffix(barename,"luc")
+ if not lfs.isfile(luaname) then
+ luaname=file.addsuffix(barename,"lua")
+ end
+ if not lfs.isfile(luaname) then
+ report_format("using format name %a",fmtname)
+ report_format("no luc/lua file with name %a",barename)
+ else
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be run, no runner available for engine %a",name,engine)
else
- local barename=file.removesuffix(name)
- local luaname=file.addsuffix(barename,"luc")
- if not lfs.isfile(luaname) then
- luaname=file.addsuffix(barename,"lua")
- end
- if not lfs.isfile(luaname) then
- report_format("using format name %a",fmtname)
- report_format("no luc/lua file with name %a",barename)
- else
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be run, no runner available for engine %a",name,engine)
- else
- runner {
- flags=primaryflags(),
- fmtfile=quoted(barename),
- luafile=quoted(luaname),
- texfile=quoted(data),
- more=more,
- }
- end
- end
+ runner {
+ flags=primaryflags(),
+ fmtfile=quoted(barename),
+ luafile=quoted(luaname),
+ texfile=quoted(data),
+ more=more,
+ }
end
+ end
end
+ end
end
@@ -24783,8 +24791,8 @@ end -- of closure
-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 988986
--- stripped bytes : 349358
+-- original bytes : 989364
+-- stripped bytes : 391967
-- end library merge
@@ -25707,7 +25715,7 @@ function runners.timedrun(filename) -- just for me
end
function runners.timed(action)
- statistics.timed(action)
+ statistics.timed(action,true)
end
function runners.associate(filename)
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 30a77ed87..d46a2dc0d 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2019.01.17 22:10}
+\newcontextversion{2019.01.19 12:06}
%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/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index df046d115..b3946bb4f 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2019.01.17 22:10}
+\edef\contextversion{2019.01.19 12:06}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/back-ini.lua b/tex/context/base/mkiv/back-ini.lua
index 3d12fe946..e21f0ce6d 100644
--- a/tex/context/base/mkiv/back-ini.lua
+++ b/tex/context/base/mkiv/back-ini.lua
@@ -62,7 +62,7 @@ backends.tables = { } setmetatableindex(backends.tables, tables
backends.current = "unknown"
-local lmtx_mode = nil
+local lmtx_mode = nil
local function lmtxmode()
if lmtx_mode == nil then
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index d09b56df9..2de482d5b 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2019.01.17 22:10}
+\newcontextversion{2019.01.19 12:06}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 5d3401226..1ab97d706 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -42,7 +42,7 @@
%D has to match \type {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2019.01.17 22:10}
+\edef\contextversion{2019.01.19 12:06}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/core-uti.lua b/tex/context/base/mkiv/core-uti.lua
index 9074d1da9..7c70cee7a 100644
--- a/tex/context/base/mkiv/core-uti.lua
+++ b/tex/context/base/mkiv/core-uti.lua
@@ -432,6 +432,7 @@ end)
-- local used_wood_factor = watts_per_core * kg_per_watt_per_second / speedup_by_other_engine
-- local used_wood_factor = (50 / 15000000) / 1.2
+
function statistics.formatruntime(runtime)
if not environment.initex then -- else error when testing as not counters yet
-- stoptiming(statistics) -- to be sure
@@ -440,19 +441,15 @@ function statistics.formatruntime(runtime)
if pages > shipped then
pages = shipped
end
+ runtime = tonumber(runtime)
if shipped > 0 or pages > 0 then
- runtime = tonumber(runtime)
local persecond = (runtime > 0) and (shipped/runtime) or pages
- if pages == 0 then pages = shipped end
- -- if TEXENGINE == "luajittex" then
- -- local saved = watts_per_core * runtime * kg_per_watt_per_second / speedup_by_other_engine
- -- local saved = used_wood_factor * runtime
- -- return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second, %f mg tree saved by using luajittex",runtime,pages,shipped,persecond,saved*1000*1000)
- -- else
- return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second",runtime,pages,shipped,persecond)
- -- end
+ if pages == 0 then
+ pages = shipped
+ end
+ return format("%0.3f seconds, %i processed pages, %i shipped pages, %.3f pages/second",runtime,pages,shipped,persecond)
else
- return format("%s seconds",runtime)
+ return format("%0.3f seconds",runtime)
end
end
end
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index ea126a755..1c6c30f81 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -3800,7 +3800,7 @@ do
local initialrl = 0
if getid(head) == localpar_code and getsubtype(head) == 0 then
- initialrl = pardirstate(start)
+ initialrl = pardirstate(head)
elseif direction == 1 or direction == "TRT" then
initialrl = -1
end
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index d1c0f7bca..d02146c5a 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index e70941e70..85c6b3477 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/trac-inf.lua b/tex/context/base/mkiv/trac-inf.lua
index 6c08f34f6..2c1dbbfe7 100644
--- a/tex/context/base/mkiv/trac-inf.lua
+++ b/tex/context/base/mkiv/trac-inf.lua
@@ -253,16 +253,23 @@ end
function statistics.runtime()
stoptiming(statistics)
-- stoptiming(statistics) -- somehow we can start the timer twice, but where
- return statistics.formatruntime(elapsedtime(statistics))
+ local runtime = lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
end
local report = logs.reporter("system")
-function statistics.timed(action)
+function statistics.timed(action,all)
starttiming("run")
action()
stoptiming("run")
- report("total runtime: %s seconds",elapsedtime("run"))
+ local runtime = tonumber(elapsedtime("run"))
+ if all then
+ local alltime = lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime)
+ else
+ report("total runtime: %0.3f seconds",runtime)
+ end
end
-- goodie
diff --git a/tex/context/base/mkiv/util-mrg.lua b/tex/context/base/mkiv/util-mrg.lua
index 690188ef8..bc835bf56 100644
--- a/tex/context/base/mkiv/util-mrg.lua
+++ b/tex/context/base/mkiv/util-mrg.lua
@@ -113,6 +113,7 @@ local pack = digit * space^1 * operator4 * optionalspacing +
optionalspaces * separator * optionalspaces
local lines = emptyline^2 / "\n"
local spaces = (space * space) / " "
+local spaces = (space * space * space * space) / " "
----- spaces = ((space+eol)^1 ) / " "
local compact = Cs ( (
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index 1809a7c91..cb329ec26 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index 367a76106..46c87adc2 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 109d123fb..127074771 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,15 +1,15 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 01/17/19 22:10:09
+-- merge date : 01/19/19 12:06:39
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,tonumber=next,type,tonumber
LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
@@ -17,111 +17,111 @@ LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5
LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1
LUAVERSION=LUAMAJORVERSION+LUAMINORVERSION/10
if LUAVERSION<5.2 and jit then
- MINORVERSION=2
- LUAVERSION=5.2
+ MINORVERSION=2
+ LUAVERSION=5.2
end
_LUAVERSION=LUAVERSION
if not lpeg then
- lpeg=require("lpeg")
+ lpeg=require("lpeg")
end
if loadstring then
- local loadnormal=load
- function load(first,...)
- if type(first)=="string" then
- return loadstring(first,...)
- else
- return loadnormal(first,...)
- end
+ local loadnormal=load
+ function load(first,...)
+ if type(first)=="string" then
+ return loadstring(first,...)
+ else
+ return loadnormal(first,...)
end
+ end
else
- loadstring=load
+ loadstring=load
end
if not ipairs then
- local function iterate(a,i)
- i=i+1
- local v=a[i]
- if v~=nil then
- return i,v
- end
- end
- function ipairs(a)
- return iterate,a,0
+ local function iterate(a,i)
+ i=i+1
+ local v=a[i]
+ if v~=nil then
+ return i,v
end
+ end
+ function ipairs(a)
+ return iterate,a,0
+ end
end
if not pairs then
- function pairs(t)
- return next,t
- end
+ function pairs(t)
+ return next,t
+ end
end
if not table.unpack then
- table.unpack=_G.unpack
+ table.unpack=_G.unpack
elseif not unpack then
- _G.unpack=table.unpack
+ _G.unpack=table.unpack
end
if not package.loaders then
- package.loaders=package.searchers
+ package.loaders=package.searchers
end
local print,select,tostring=print,select,tostring
local inspectors={}
function setinspector(kind,inspector)
- inspectors[kind]=inspector
+ inspectors[kind]=inspector
end
function inspect(...)
- for s=1,select("#",...) do
- local value=select(s,...)
- if value==nil then
- print("nil")
- else
- local done=false
- local kind=type(value)
- local inspector=inspectors[kind]
- if inspector then
- done=inspector(value)
- if done then
- break
- end
- end
- for kind,inspector in next,inspectors do
- done=inspector(value)
- if done then
- break
- end
- end
- if not done then
- print(tostring(value))
- end
+ for s=1,select("#",...) do
+ local value=select(s,...)
+ if value==nil then
+ print("nil")
+ else
+ local done=false
+ local kind=type(value)
+ local inspector=inspectors[kind]
+ if inspector then
+ done=inspector(value)
+ if done then
+ break
end
+ end
+ for kind,inspector in next,inspectors do
+ done=inspector(value)
+ if done then
+ break
+ end
+ end
+ if not done then
+ print(tostring(value))
+ end
end
+ end
end
local dummy=function() end
function optionalrequire(...)
- local ok,result=xpcall(require,dummy,...)
- if ok then
- return result
- end
+ local ok,result=xpcall(require,dummy,...)
+ if ok then
+ return result
+ end
end
if lua then
- lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
+ lua.mask=load([[τεχ = 1]]) and "utf" or "ascii"
end
local flush=io.flush
if flush then
- local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
- local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
- local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
- local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
+ local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end
+ local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end
+ local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end
+ local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end
end
FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
if not FFISUPPORTED then
- local okay;okay,ffi=pcall(require,"ffi")
- FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
+ local okay;okay,ffi=pcall(require,"ffi")
+ FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load
end
if not FFISUPPORTED then
- ffi=nil
+ ffi=nil
elseif not ffi.number then
- ffi.number=tonumber
+ ffi.number=tonumber
end
if not bit32 then
- bit32=require("l-bit32")
+ bit32=require("l-bit32")
end
end -- closure
@@ -129,11 +129,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-lpeg']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
lpeg=require("lpeg")
local lpeg=lpeg
@@ -144,7 +144,7 @@ local floor=math.floor
local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt
local lpegtype,lpegmatch,lpegprint=lpeg.type,lpeg.match,lpeg.print
if setinspector then
- setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
+ setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end)
end
lpeg.patterns=lpeg.patterns or {}
local patterns=lpeg.patterns
@@ -167,7 +167,7 @@ local underscore=P("_")
local hexdigit=digit+lowercase+uppercase
local hexdigits=hexdigit^1
local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
-local newline=P("\r")*(P("\n")+P(true))+P("\n")
+local newline=P("\r")*(P("\n")+P(true))+P("\n")
local escaped=P("\\")*anything
local squote=P("'")
local dquote=P('"')
@@ -176,9 +176,9 @@ local period=P(".")
local comma=P(",")
local utfbom_32_be=P('\000\000\254\255')
local utfbom_32_le=P('\255\254\000\000')
-local utfbom_16_be=P('\254\255')
-local utfbom_16_le=P('\255\254')
-local utfbom_8=P('\239\187\191')
+local utfbom_16_be=P('\254\255')
+local utfbom_16_le=P('\255\254')
+local utfbom_8=P('\239\187\191')
local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8
local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8")
local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")
@@ -210,7 +210,7 @@ patterns.utf8character=utf8character
patterns.validutf8=validutf8char
patterns.validutf8char=validutf8char
local eol=S("\n\r")
-local spacer=S(" \t\f\v")
+local spacer=S(" \t\f\v")
local whitespace=eol+spacer
local nonspacer=1-spacer
local nonwhitespace=1-whitespace
@@ -219,7 +219,7 @@ patterns.spacer=spacer
patterns.whitespace=whitespace
patterns.nonspacer=nonspacer
patterns.nonwhitespace=nonwhitespace
-local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
+local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0)
local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0)
@@ -296,82 +296,82 @@ patterns.somecontent=(anything-newline-space)^1
patterns.beginline=#(1-newline)
patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0))
function anywhere(pattern)
- return (1-P(pattern))^0*P(pattern)
+ return (1-P(pattern))^0*P(pattern)
end
lpeg.anywhere=anywhere
function lpeg.instringchecker(p)
- p=anywhere(p)
- return function(str)
- return lpegmatch(p,str) and true or false
- end
+ p=anywhere(p)
+ return function(str)
+ return lpegmatch(p,str) and true or false
+ end
end
function lpeg.splitter(pattern,action)
- if action then
- return (((1-P(pattern))^1)/action+1)^0
- else
- return (Cs((1-P(pattern))^1)+1)^0
- end
+ if action then
+ return (((1-P(pattern))^1)/action+1)^0
+ else
+ return (Cs((1-P(pattern))^1)+1)^0
+ end
end
function lpeg.tsplitter(pattern,action)
- if action then
- return Ct((((1-P(pattern))^1)/action+1)^0)
- else
- return Ct((Cs((1-P(pattern))^1)+1)^0)
- end
+ if action then
+ return Ct((((1-P(pattern))^1)/action+1)^0)
+ else
+ return Ct((Cs((1-P(pattern))^1)+1)^0)
+ end
end
local splitters_s,splitters_m,splitters_t={},{},{}
local function splitat(separator,single)
- local splitter=(single and splitters_s[separator]) or splitters_m[separator]
- if not splitter then
- separator=P(separator)
- local other=C((1-separator)^0)
- if single then
- local any=anything
- splitter=other*(separator*C(any^0)+"")
- splitters_s[separator]=splitter
- else
- splitter=other*(separator*other)^0
- splitters_m[separator]=splitter
- end
+ local splitter=(single and splitters_s[separator]) or splitters_m[separator]
+ if not splitter then
+ separator=P(separator)
+ local other=C((1-separator)^0)
+ if single then
+ local any=anything
+ splitter=other*(separator*C(any^0)+"")
+ splitters_s[separator]=splitter
+ else
+ splitter=other*(separator*other)^0
+ splitters_m[separator]=splitter
end
- return splitter
+ end
+ return splitter
end
local function tsplitat(separator)
- local splitter=splitters_t[separator]
- if not splitter then
- splitter=Ct(splitat(separator))
- splitters_t[separator]=splitter
- end
- return splitter
+ local splitter=splitters_t[separator]
+ if not splitter then
+ splitter=Ct(splitat(separator))
+ splitters_t[separator]=splitter
+ end
+ return splitter
end
lpeg.splitat=splitat
lpeg.tsplitat=tsplitat
function string.splitup(str,separator)
- if not separator then
- separator=","
- end
- return lpegmatch(splitters_m[separator] or splitat(separator),str)
+ if not separator then
+ separator=","
+ end
+ return lpegmatch(splitters_m[separator] or splitat(separator),str)
end
local cache={}
function lpeg.split(separator,str)
+ local c=cache[separator]
+ if not c then
+ c=tsplitat(separator)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+function string.split(str,separator)
+ if separator then
local c=cache[separator]
if not c then
- c=tsplitat(separator)
- cache[separator]=c
+ c=tsplitat(separator)
+ cache[separator]=c
end
return lpegmatch(c,str)
-end
-function string.split(str,separator)
- if separator then
- local c=cache[separator]
- if not c then
- c=tsplitat(separator)
- cache[separator]=c
- end
- return lpegmatch(c,str)
- else
- return { str }
- end
+ else
+ return { str }
+ end
end
local spacing=patterns.spacer^0*newline
local empty=spacing*Cc("")
@@ -381,463 +381,463 @@ patterns.textline=content
local linesplitter=tsplitat(newline)
patterns.linesplitter=linesplitter
function string.splitlines(str)
- return lpegmatch(linesplitter,str)
+ return lpegmatch(linesplitter,str)
end
local cache={}
function lpeg.checkedsplit(separator,str)
- local c=cache[separator]
- if not c then
- separator=P(separator)
- local other=C((1-separator)^1)
- c=Ct(separator^0*other*(separator^1*other)^0)
- cache[separator]=c
- end
- return lpegmatch(c,str)
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
end
function string.checkedsplit(str,separator)
- local c=cache[separator]
- if not c then
- separator=P(separator)
- local other=C((1-separator)^1)
- c=Ct(separator^0*other*(separator^1*other)^0)
- cache[separator]=c
- end
- return lpegmatch(c,str)
-end
-local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
-local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
+ local c=cache[separator]
+ if not c then
+ separator=P(separator)
+ local other=C((1-separator)^1)
+ c=Ct(separator^0*other*(separator^1*other)^0)
+ cache[separator]=c
+ end
+ return lpegmatch(c,str)
+end
+local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end
+local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end
local function f4(s) local c1,c2,c3,c4=byte(s,1,4) return ((c1*64+c2)*64+c3)*64+c4-63447168 end
local utf8byte=patterns.utf8one/byte+patterns.utf8two/f2+patterns.utf8three/f3+patterns.utf8four/f4
patterns.utf8byte=utf8byte
local cache={}
function lpeg.stripper(str)
- if type(str)=="string" then
- local s=cache[str]
- if not s then
- s=Cs(((S(str)^1)/""+1)^0)
- cache[str]=s
- end
- return s
- else
- return Cs(((str^1)/""+1)^0)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs(((S(str)^1)/""+1)^0)
+ cache[str]=s
end
+ return s
+ else
+ return Cs(((str^1)/""+1)^0)
+ end
end
local cache={}
function lpeg.keeper(str)
- if type(str)=="string" then
- local s=cache[str]
- if not s then
- s=Cs((((1-S(str))^1)/""+1)^0)
- cache[str]=s
- end
- return s
- else
- return Cs((((1-str)^1)/""+1)^0)
+ if type(str)=="string" then
+ local s=cache[str]
+ if not s then
+ s=Cs((((1-S(str))^1)/""+1)^0)
+ cache[str]=s
end
+ return s
+ else
+ return Cs((((1-str)^1)/""+1)^0)
+ end
end
function lpeg.frontstripper(str)
- return (P(str)+P(true))*Cs(anything^0)
+ return (P(str)+P(true))*Cs(anything^0)
end
function lpeg.endstripper(str)
- return Cs((1-P(str)*endofstring)^0)
+ return Cs((1-P(str)*endofstring)^0)
end
function lpeg.replacer(one,two,makefunction,isutf)
- local pattern
- local u=isutf and utf8char or 1
- if type(one)=="table" then
- local no=#one
- local p=P(false)
- if no==0 then
- for k,v in next,one do
- p=p+P(k)/v
- end
- pattern=Cs((p+u)^0)
- elseif no==1 then
- local o=one[1]
- one,two=P(o[1]),o[2]
- pattern=Cs((one/two+u)^0)
- else
- for i=1,no do
- local o=one[i]
- p=p+P(o[1])/o[2]
- end
- pattern=Cs((p+u)^0)
- end
- else
- pattern=Cs((P(one)/(two or "")+u)^0)
- end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
+ local pattern
+ local u=isutf and utf8char or 1
+ if type(one)=="table" then
+ local no=#one
+ local p=P(false)
+ if no==0 then
+ for k,v in next,one do
+ p=p+P(k)/v
+ end
+ pattern=Cs((p+u)^0)
+ elseif no==1 then
+ local o=one[1]
+ one,two=P(o[1]),o[2]
+ pattern=Cs((one/two+u)^0)
else
- return pattern
+ for i=1,no do
+ local o=one[i]
+ p=p+P(o[1])/o[2]
+ end
+ pattern=Cs((p+u)^0)
+ end
+ else
+ pattern=Cs((P(one)/(two or "")+u)^0)
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
end
+ else
+ return pattern
+ end
end
function lpeg.finder(lst,makefunction,isutf)
- local pattern
- if type(lst)=="table" then
- pattern=P(false)
- if #lst==0 then
- for k,v in next,lst do
- pattern=pattern+P(k)
- end
- else
- for i=1,#lst do
- pattern=pattern+P(lst[i])
- end
- end
- else
- pattern=P(lst)
- end
- if isutf then
- pattern=((utf8char or 1)-pattern)^0*pattern
+ local pattern
+ if type(lst)=="table" then
+ pattern=P(false)
+ if #lst==0 then
+ for k,v in next,lst do
+ pattern=pattern+P(k)
+ end
else
- pattern=(1-pattern)^0*pattern
- end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ for i=1,#lst do
+ pattern=pattern+P(lst[i])
+ end
+ end
+ else
+ pattern=P(lst)
+ end
+ if isutf then
+ pattern=((utf8char or 1)-pattern)^0*pattern
+ else
+ pattern=(1-pattern)^0*pattern
+ end
+ if makefunction then
+ return function(str)
+ return lpegmatch(pattern,str)
end
+ else
+ return pattern
+ end
end
local splitters_f,splitters_s={},{}
function lpeg.firstofsplit(separator)
- local splitter=splitters_f[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)
- splitters_f[separator]=splitter
- end
- return splitter
+ local splitter=splitters_f[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)
+ splitters_f[separator]=splitter
+ end
+ return splitter
end
function lpeg.secondofsplit(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=(1-pattern)^0*pattern*C(anything^0)
- splitters_s[separator]=splitter
- end
- return splitter
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=(1-pattern)^0*pattern*C(anything^0)
+ splitters_s[separator]=splitter
+ end
+ return splitter
end
local splitters_s,splitters_p={},{}
function lpeg.beforesuffix(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)*pattern*endofstring
- splitters_s[separator]=splitter
- end
- return splitter
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)*pattern*endofstring
+ splitters_s[separator]=splitter
+ end
+ return splitter
end
function lpeg.afterprefix(separator)
- local splitter=splitters_p[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=pattern*C(anything^0)
- splitters_p[separator]=splitter
- end
- return splitter
+ local splitter=splitters_p[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=pattern*C(anything^0)
+ splitters_p[separator]=splitter
+ end
+ return splitter
end
function lpeg.balancer(left,right)
- left,right=P(left),P(right)
- return P { left*((1-left-right)+V(1))^0*right }
+ left,right=P(left),P(right)
+ return P { left*((1-left-right)+V(1))^0*right }
end
function lpeg.counter(pattern,action)
- local n=0
- local pattern=(P(pattern)/function() n=n+1 end+anything)^0
- if action then
- return function(str) n=0;lpegmatch(pattern,str);action(n) end
- else
- return function(str) n=0;lpegmatch(pattern,str);return n end
- end
+ local n=0
+ local pattern=(P(pattern)/function() n=n+1 end+anything)^0
+ if action then
+ return function(str) n=0;lpegmatch(pattern,str);action(n) end
+ else
+ return function(str) n=0;lpegmatch(pattern,str);return n end
+ end
end
function lpeg.is_lpeg(p)
- return p and lpegtype(p)=="pattern"
+ return p and lpegtype(p)=="pattern"
end
function lpeg.oneof(list,...)
- if type(list)~="table" then
- list={ list,... }
- end
- local p=P(list[1])
- for l=2,#list do
- p=p+P(list[l])
- end
- return p
+ if type(list)~="table" then
+ list={ list,... }
+ end
+ local p=P(list[1])
+ for l=2,#list do
+ p=p+P(list[l])
+ end
+ return p
end
local sort=table.sort
local function copyindexed(old)
- local new={}
- for i=1,#old do
- new[i]=old
- end
- return new
+ local new={}
+ for i=1,#old do
+ new[i]=old
+ end
+ return new
end
local function sortedkeys(tab)
- local keys,s={},0
- for key,_ in next,tab do
- s=s+1
- keys[s]=key
- end
- sort(keys)
- return keys
+ local keys,s={},0
+ for key,_ in next,tab do
+ s=s+1
+ keys[s]=key
+ end
+ sort(keys)
+ return keys
end
function lpeg.append(list,pp,delayed,checked)
- local p=pp
- if #list>0 then
- local keys=copyindexed(list)
- sort(keys)
- for i=#keys,1,-1 do
- local k=keys[i]
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- elseif delayed then
- local keys=sortedkeys(list)
+ local p=pp
+ if #list>0 then
+ local keys=copyindexed(list)
+ sort(keys)
+ for i=#keys,1,-1 do
+ local k=keys[i]
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
+ end
+ elseif delayed then
+ local keys=sortedkeys(list)
+ if p then
+ for i=1,#keys,1 do
+ local k=keys[i]
+ local v=list[k]
+ p=P(k)/list+p
+ end
+ else
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
if p then
- for i=1,#keys,1 do
- local k=keys[i]
- local v=list[k]
- p=P(k)/list+p
- end
+ p=P(k)+p
else
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- if p then
- p=p/list
- end
+ p=P(k)
end
- elseif checked then
- local keys=sortedkeys(list)
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- if k==v then
- p=P(k)+p
- else
- p=P(k)/v+p
- end
- else
- if k==v then
- p=P(k)
- else
- p=P(k)/v
- end
- end
+ end
+ if p then
+ p=p/list
+ end
+ end
+ elseif checked then
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ if k==v then
+ p=P(k)+p
+ else
+ p=P(k)/v+p
end
- else
- local keys=sortedkeys(list)
- for i=1,#keys do
- local k=keys[i]
- local v=list[k]
- if p then
- p=P(k)/v+p
- else
- p=P(k)/v
- end
+ else
+ if k==v then
+ p=P(k)
+ else
+ p=P(k)/v
end
+ end
end
- return p
+ else
+ local keys=sortedkeys(list)
+ for i=1,#keys do
+ local k=keys[i]
+ local v=list[k]
+ if p then
+ p=P(k)/v+p
+ else
+ p=P(k)/v
+ end
+ end
+ end
+ return p
end
local p_false=P(false)
local p_true=P(true)
local lower=utf and utf.lower or string.lower
local upper=utf and utf.upper or string.upper
function lpeg.setutfcasers(l,u)
- lower=l or lower
- upper=u or upper
+ lower=l or lower
+ upper=u or upper
end
local function make1(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
- local k=keys[i]
- if k~="" then
- local v=t[k]
- if v==true then
- p=p+P(k)*p_true
- elseif v==false then
- else
- p=p+P(k)*make1(v,v[""])
- end
- end
- end
- if rest then
- p=p+p_true
- end
- return p
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+P(k)*p_true
+ elseif v==false then
+ else
+ p=p+P(k)*make1(v,v[""])
+ end
+ end
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
end
local function make2(t,rest)
- local p=p_false
- local keys=sortedkeys(t)
- for i=1,#keys do
- local k=keys[i]
- if k~="" then
- local v=t[k]
- if v==true then
- p=p+(P(lower(k))+P(upper(k)))*p_true
- elseif v==false then
- else
- p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
- end
- end
- end
- if rest then
- p=p+p_true
- end
- return p
+ local p=p_false
+ local keys=sortedkeys(t)
+ for i=1,#keys do
+ local k=keys[i]
+ if k~="" then
+ local v=t[k]
+ if v==true then
+ p=p+(P(lower(k))+P(upper(k)))*p_true
+ elseif v==false then
+ else
+ p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""])
+ end
+ end
+ end
+ if rest then
+ p=p+p_true
+ end
+ return p
end
local function utfchartabletopattern(list,insensitive)
- local tree={}
- local n=#list
- if n==0 then
- for s in next,list do
- local t=tree
- local p,pk
- for c in gmatch(s,".") do
- if t==true then
- t={ [c]=true,[""]=true }
- p[pk]=t
- p=t
- t=false
- elseif t==false then
- t={ [c]=false }
- p[pk]=t
- p=t
- t=false
- else
- local tc=t[c]
- if not tc then
- tc=false
- t[c]=false
- end
- p=t
- t=tc
- end
- pk=c
- end
- if t==false then
- p[pk]=true
- elseif t==true then
- else
- t[""]=true
- end
- end
- else
- for i=1,n do
- local s=list[i]
- local t=tree
- local p,pk
- for c in gmatch(s,".") do
- if t==true then
- t={ [c]=true,[""]=true }
- p[pk]=t
- p=t
- t=false
- elseif t==false then
- t={ [c]=false }
- p[pk]=t
- p=t
- t=false
- else
- local tc=t[c]
- if not tc then
- tc=false
- t[c]=false
- end
- p=t
- t=tc
- end
- pk=c
- end
- if t==false then
- p[pk]=true
- elseif t==true then
- else
- t[""]=true
- end
+ local tree={}
+ local n=#list
+ if n==0 then
+ for s in next,list do
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
+ end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
+ end
+ else
+ for i=1,n do
+ local s=list[i]
+ local t=tree
+ local p,pk
+ for c in gmatch(s,".") do
+ if t==true then
+ t={ [c]=true,[""]=true }
+ p[pk]=t
+ p=t
+ t=false
+ elseif t==false then
+ t={ [c]=false }
+ p[pk]=t
+ p=t
+ t=false
+ else
+ local tc=t[c]
+ if not tc then
+ tc=false
+ t[c]=false
+ end
+ p=t
+ t=tc
end
+ pk=c
+ end
+ if t==false then
+ p[pk]=true
+ elseif t==true then
+ else
+ t[""]=true
+ end
end
- return (insensitive and make2 or make1)(tree)
+ end
+ return (insensitive and make2 or make1)(tree)
end
lpeg.utfchartabletopattern=utfchartabletopattern
function lpeg.utfreplacer(list,insensitive)
- local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
- return function(str)
- return lpegmatch(pattern,str) or str
- end
+ local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0)
+ return function(str)
+ return lpegmatch(pattern,str) or str
+ end
end
patterns.containseol=lpeg.finder(eol)
local function nextstep(n,step,result)
- local m=n%step
- local d=floor(n/step)
- if d>0 then
- local v=V(tostring(step))
- local s=result.start
- for i=1,d do
- if s then
- s=v*s
- else
- s=v
- end
- end
- result.start=s
- end
- if step>1 and result.start then
- local v=V(tostring(step/2))
- result[tostring(step)]=v*v
- end
- if step>0 then
- return nextstep(m,step/2,result)
- else
- return result
- end
+ local m=n%step
+ local d=floor(n/step)
+ if d>0 then
+ local v=V(tostring(step))
+ local s=result.start
+ for i=1,d do
+ if s then
+ s=v*s
+ else
+ s=v
+ end
+ end
+ result.start=s
+ end
+ if step>1 and result.start then
+ local v=V(tostring(step/2))
+ result[tostring(step)]=v*v
+ end
+ if step>0 then
+ return nextstep(m,step/2,result)
+ else
+ return result
+ end
end
function lpeg.times(pattern,n)
- return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
+ return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
end
do
- local trailingzeros=zero^0*-digit
- local stripper=Cs((
- digits*(
- period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
- )+1
- )^0)
- lpeg.patterns.stripzeros=stripper
- local nonzero=digit-zero
- local trailingzeros=zero^1*endofstring
- local stripper=Cs((1-period)^0*(
- period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
- ))
- lpeg.patterns.stripzero=stripper
+ local trailingzeros=zero^0*-digit
+ local stripper=Cs((
+ digits*(
+ period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"")
+ )+1
+ )^0)
+ lpeg.patterns.stripzeros=stripper
+ local nonzero=digit-zero
+ local trailingzeros=zero^1*endofstring
+ local stripper=Cs((1-period)^0*(
+ period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring
+ ))
+ lpeg.patterns.stripzero=stripper
end
local byte_to_HEX={}
local byte_to_hex={}
local byte_to_dec={}
local hex_to_byte={}
for i=0,255 do
- local H=format("%02X",i)
- local h=format("%02x",i)
- local d=format("%03i",i)
- local c=char(i)
- byte_to_HEX[c]=H
- byte_to_hex[c]=h
- byte_to_dec[c]=d
- hex_to_byte[h]=c
- hex_to_byte[H]=c
+ local H=format("%02X",i)
+ local h=format("%02x",i)
+ local d=format("%03i",i)
+ local c=char(i)
+ byte_to_HEX[c]=H
+ byte_to_hex[c]=h
+ byte_to_dec[c]=d
+ hex_to_byte[h]=c
+ hex_to_byte[H]=c
end
local hextobyte=P(2)/hex_to_byte
local bytetoHEX=P(1)/byte_to_HEX
@@ -856,47 +856,47 @@ patterns.bytestoHEX=bytestoHEX
patterns.bytestohex=bytestohex
patterns.bytestodec=bytestodec
function string.toHEX(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestoHEX,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestoHEX,s)
+ end
end
function string.tohex(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestohex,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestohex,s)
+ end
end
function string.todec(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(bytestodec,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(bytestodec,s)
+ end
end
function string.tobytes(s)
- if not s or s=="" then
- return s
- else
- return lpegmatch(hextobytes,s)
- end
+ if not s or s=="" then
+ return s
+ else
+ return lpegmatch(hextobytes,s)
+ end
end
local patterns={}
local function containsws(what)
- local p=patterns[what]
- if not p then
- local p1=P(what)*(whitespace+endofstring)*Cc(true)
- local p2=whitespace*P(p1)
- p=P(p1)+P(1-p2)^0*p2+Cc(false)
- patterns[what]=p
- end
- return p
+ local p=patterns[what]
+ if not p then
+ local p1=P(what)*(whitespace+endofstring)*Cc(true)
+ local p2=whitespace*P(p1)
+ p=P(p1)+P(1-p2)^0*p2+Cc(false)
+ patterns[what]=p
+ end
+ return p
end
lpeg.containsws=containsws
function string.containsws(str,what)
- return lpegmatch(patterns[what] or containsws(what),str)
+ return lpegmatch(patterns[what] or containsws(what),str)
end
end -- closure
@@ -904,11 +904,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-functions']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
functions=functions or {}
function functions.dummy() end
@@ -918,11 +918,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-string']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local string=string
local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower
@@ -930,25 +930,25 @@ local lpegmatch,patterns=lpeg.match,lpeg.patterns
local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs
local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote
function string.unquoted(str)
- return lpegmatch(unquoted,str) or str
+ return lpegmatch(unquoted,str) or str
end
function string.quoted(str)
- return format("%q",str)
+ return format("%q",str)
end
function string.count(str,pattern)
- local n=0
- for _ in gmatch(str,pattern) do
- n=n+1
- end
- return n
+ local n=0
+ for _ in gmatch(str,pattern) do
+ n=n+1
+ end
+ return n
end
function string.limit(str,n,sentinel)
- if #str>n then
- sentinel=sentinel or "..."
- return sub(str,1,(n-#sentinel))..sentinel
- else
- return str
- end
+ if #str>n then
+ sentinel=sentinel or "..."
+ return sub(str,1,(n-#sentinel))..sentinel
+ else
+ return str
+ end
end
local stripper=patterns.stripper
local fullstripper=patterns.fullstripper
@@ -956,81 +956,81 @@ local collapser=patterns.collapser
local nospacer=patterns.nospacer
local longtostring=patterns.longtostring
function string.strip(str)
- return str and lpegmatch(stripper,str) or ""
+ return str and lpegmatch(stripper,str) or ""
end
function string.fullstrip(str)
- return str and lpegmatch(fullstripper,str) or ""
+ return str and lpegmatch(fullstripper,str) or ""
end
function string.collapsespaces(str)
- return str and lpegmatch(collapser,str) or ""
+ return str and lpegmatch(collapser,str) or ""
end
function string.nospaces(str)
- return str and lpegmatch(nospacer,str) or ""
+ return str and lpegmatch(nospacer,str) or ""
end
function string.longtostring(str)
- return str and lpegmatch(longtostring,str) or ""
+ return str and lpegmatch(longtostring,str) or ""
end
local pattern=P(" ")^0*P(-1)
function string.is_empty(str)
- if not str or str=="" then
- return true
- else
- return lpegmatch(pattern,str) and true or false
- end
+ if not str or str=="" then
+ return true
+ else
+ return lpegmatch(pattern,str) and true or false
+ end
end
local anything=patterns.anything
local allescapes=Cc("%")*S(".-+%?()[]*")
-local someescapes=Cc("%")*S(".-+%()[]")
-local matchescapes=Cc(".")*S("*?")
+local someescapes=Cc("%")*S(".-+%()[]")
+local matchescapes=Cc(".")*S("*?")
local pattern_a=Cs ((allescapes+anything )^0 )
local pattern_b=Cs ((someescapes+matchescapes+anything )^0 )
local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") )
function string.escapedpattern(str,simple)
- return lpegmatch(simple and pattern_b or pattern_a,str)
+ return lpegmatch(simple and pattern_b or pattern_a,str)
end
function string.topattern(str,lowercase,strict)
- if str=="" or type(str)~="string" then
- return ".*"
- elseif strict then
- str=lpegmatch(pattern_c,str)
- else
- str=lpegmatch(pattern_b,str)
- end
- if lowercase then
- return lower(str)
- else
- return str
- end
+ if str=="" or type(str)~="string" then
+ return ".*"
+ elseif strict then
+ str=lpegmatch(pattern_c,str)
+ else
+ str=lpegmatch(pattern_b,str)
+ end
+ if lowercase then
+ return lower(str)
+ else
+ return str
+ end
end
function string.valid(str,default)
- return (type(str)=="string" and str~="" and str) or default or nil
+ return (type(str)=="string" and str~="" and str) or default or nil
end
string.itself=function(s) return s end
local pattern_c=Ct(C(1)^0)
local pattern_b=Ct((C(1)/byte)^0)
function string.totable(str,bytes)
- return lpegmatch(bytes and pattern_b or pattern_c,str)
+ return lpegmatch(bytes and pattern_b or pattern_c,str)
end
local replacer=lpeg.replacer("@","%%")
function string.tformat(fmt,...)
- return format(lpegmatch(replacer,fmt),...)
+ return format(lpegmatch(replacer,fmt),...)
end
string.quote=string.quoted
string.unquote=string.unquoted
if not string.bytetable then
- local limit=5000
- function string.bytetable(str)
- local n=#str
- if n>limit then
- local t={ byte(str,1,limit) }
- for i=limit+1,n do
- t[i]=byte(str,i)
- end
- return t
- else
- return { byte(str,1,n) }
- end
+ local limit=5000
+ function string.bytetable(str)
+ local n=#str
+ if n>limit then
+ local t={ byte(str,1,limit) }
+ for i=limit+1,n do
+ t[i]=byte(str,i)
+ end
+ return t
+ else
+ return { byte(str,1,n) }
end
+ end
end
end -- closure
@@ -1038,11 +1038,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-table']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,next,tostring,tonumber,select=type,next,tostring,tonumber,select
local table,string=table,string
@@ -1053,147 +1053,147 @@ local lpegmatch,patterns=lpeg.match,lpeg.patterns
local floor=math.floor
local stripper=patterns.stripper
function table.getn(t)
- return t and #t
+ return t and #t
end
function table.strip(tab)
- local lst,l={},0
- for i=1,#tab do
- local s=lpegmatch(stripper,tab[i]) or ""
- if s=="" then
- else
- l=l+1
- lst[l]=s
- end
+ local lst,l={},0
+ for i=1,#tab do
+ local s=lpegmatch(stripper,tab[i]) or ""
+ if s=="" then
+ else
+ l=l+1
+ lst[l]=s
end
- return lst
+ end
+ return lst
end
function table.keys(t)
- if t then
- local keys,k={},0
- for key in next,t do
- k=k+1
- keys[k]=key
- end
- return keys
- else
- return {}
+ if t then
+ local keys,k={},0
+ for key in next,t do
+ k=k+1
+ keys[k]=key
end
+ return keys
+ else
+ return {}
+ end
end
local function compare(a,b)
- local ta=type(a)
- if ta=="number" then
- local tb=type(b)
- if ta==tb then
- return a<b
- elseif tb=="string" then
- return tostring(a)<b
- end
- elseif ta=="string" then
- local tb=type(b)
- if ta==tb then
- return a<b
- else
- return a<tostring(b)
- end
+ local ta=type(a)
+ if ta=="number" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ elseif tb=="string" then
+ return tostring(a)<b
+ end
+ elseif ta=="string" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ else
+ return a<tostring(b)
end
- return tostring(a)<tostring(b)
+ end
+ return tostring(a)<tostring(b)
end
local function sortedkeys(tab)
- if tab then
- local srt,category,s={},0,0
- for key in next,tab do
- s=s+1
- srt[s]=key
- if category==3 then
- elseif category==1 then
- if type(key)~="string" then
- category=3
- end
- elseif category==2 then
- if type(key)~="number" then
- category=3
- end
- else
- local tkey=type(key)
- if tkey=="string" then
- category=1
- elseif tkey=="number" then
- category=2
- else
- category=3
- end
- end
- end
- if s<2 then
- elseif category==3 then
- sort(srt,compare)
+ if tab then
+ local srt,category,s={},0,0
+ for key in next,tab do
+ s=s+1
+ srt[s]=key
+ if category==3 then
+ elseif category==1 then
+ if type(key)~="string" then
+ category=3
+ end
+ elseif category==2 then
+ if type(key)~="number" then
+ category=3
+ end
+ else
+ local tkey=type(key)
+ if tkey=="string" then
+ category=1
+ elseif tkey=="number" then
+ category=2
else
- sort(srt)
+ category=3
end
- return srt
+ end
+ end
+ if s<2 then
+ elseif category==3 then
+ sort(srt,compare)
else
- return {}
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="string" then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if type(key)=="string" then
+ s=s+1
+ srt[s]=key
+ end
end
+ if s>1 then
+ sort(srt)
+ end
+ return srt
+ else
+ return {}
+ end
end
local function sortedindexonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="number" then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if type(key)=="number" then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashkeys(tab,cmp)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if key then
- s=s+1
- srt[s]=key
- end
- end
- if s>1 then
- sort(srt,cmp)
- end
- return srt
- else
- return {}
+ if tab then
+ local srt,s={},0
+ for key in next,tab do
+ if key then
+ s=s+1
+ srt[s]=key
+ end
+ end
+ if s>1 then
+ sort(srt,cmp)
end
+ return srt
+ else
+ return {}
+ end
end
function table.allkeys(t)
- local keys={}
- for k,v in next,t do
- for k in next,v do
- keys[k]=true
- end
+ local keys={}
+ for k,v in next,t do
+ for k in next,v do
+ keys[k]=true
end
- return sortedkeys(keys)
+ end
+ return sortedkeys(keys)
end
table.sortedkeys=sortedkeys
table.sortedhashonly=sortedhashonly
@@ -1201,927 +1201,927 @@ table.sortedindexonly=sortedindexonly
table.sortedhashkeys=sortedhashkeys
local function nothing() end
local function sortedhash(t,cmp)
- if t then
- local s
- if cmp then
- s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
- else
- s=sortedkeys(t)
- end
- local m=#s
- if m==1 then
- return next,t
- elseif m>0 then
- local n=0
- return function()
- if n<m then
- n=n+1
- local k=s[n]
- return k,t[k]
- end
- end
+ if t then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local m=#s
+ if m==1 then
+ return next,t
+ elseif m>0 then
+ local n=0
+ return function()
+ if n<m then
+ n=n+1
+ local k=s[n]
+ return k,t[k]
end
+ end
end
- return nothing
+ end
+ return nothing
end
table.sortedhash=sortedhash
table.sortedpairs=sortedhash
function table.append(t,list)
- local n=#t
- for i=1,#list do
- n=n+1
- t[n]=list[i]
- end
- return t
+ local n=#t
+ for i=1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ return t
end
function table.prepend(t,list)
- local nl=#list
- local nt=nl+#t
- for i=#t,1,-1 do
- t[nt]=t[i]
- nt=nt-1
- end
- for i=1,#list do
- t[i]=list[i]
- end
- return t
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+ t[nt]=t[i]
+ nt=nt-1
+ end
+ for i=1,#list do
+ t[i]=list[i]
+ end
+ return t
end
function table.merge(t,...)
- t=t or {}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ t=t or {}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.merged(...)
- local t={}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ local t={}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.imerge(t,...)
- local nt=#t
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- nt=nt+1
- t[nt]=nst[j]
- end
+ local nt=#t
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ nt=nt+1
+ t[nt]=nst[j]
end
- return t
+ end
+ return t
end
function table.imerged(...)
- local tmp,ntmp={},0
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- ntmp=ntmp+1
- tmp[ntmp]=nst[j]
- end
+ local tmp,ntmp={},0
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ ntmp=ntmp+1
+ tmp[ntmp]=nst[j]
end
- return tmp
+ end
+ return tmp
end
local function fastcopy(old,metatabletoo)
- if old then
- local new={}
- for k,v in next,old do
- if type(v)=="table" then
- new[k]=fastcopy(v,metatabletoo)
- else
- new[k]=v
- end
- end
- if metatabletoo then
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ if type(v)=="table" then
+ new[k]=fastcopy(v,metatabletoo)
+ else
+ new[k]=v
+ end
+ end
+ if metatabletoo then
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
end
+ return new
+ else
+ return {}
+ end
end
local function copy(t,tables)
- tables=tables or {}
- local tcopy={}
- if not tables[t] then
- tables[t]=tcopy
- end
- for i,v in next,t do
- if type(i)=="table" then
- if tables[i] then
- i=tables[i]
- else
- i=copy(i,tables)
- end
- end
- if type(v)~="table" then
- tcopy[i]=v
- elseif tables[v] then
- tcopy[i]=tables[v]
- else
- tcopy[i]=copy(v,tables)
- end
- end
- local mt=getmetatable(t)
- if mt then
- setmetatable(tcopy,mt)
+ tables=tables or {}
+ local tcopy={}
+ if not tables[t] then
+ tables[t]=tcopy
+ end
+ for i,v in next,t do
+ if type(i)=="table" then
+ if tables[i] then
+ i=tables[i]
+ else
+ i=copy(i,tables)
+ end
+ end
+ if type(v)~="table" then
+ tcopy[i]=v
+ elseif tables[v] then
+ tcopy[i]=tables[v]
+ else
+ tcopy[i]=copy(v,tables)
end
- return tcopy
+ end
+ local mt=getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
end
table.fastcopy=fastcopy
table.copy=copy
function table.derive(parent)
- local child={}
- if parent then
- setmetatable(child,{ __index=parent })
- end
- return child
+ local child={}
+ if parent then
+ setmetatable(child,{ __index=parent })
+ end
+ return child
end
function table.tohash(t,value)
- local h={}
- if t then
- if value==nil then value=true end
- for _,v in next,t do
- h[v]=value
- end
+ local h={}
+ if t then
+ if value==nil then value=true end
+ for _,v in next,t do
+ h[v]=value
end
- return h
+ end
+ return h
end
function table.fromhash(t)
- local hsh,h={},0
- for k,v in next,t do
- if v then
- h=h+1
- hsh[h]=k
- end
+ local hsh,h={},0
+ for k,v in next,t do
+ if v then
+ h=h+1
+ hsh[h]=k
end
- return hsh
+ end
+ return hsh
end
local noquotes,hexify,handle,compact,inline,functions,metacheck
local reserved=table.tohash {
- 'and','break','do','else','elseif','end','false','for','function','if',
- 'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
}
local function is_simple_table(t,hexify)
- local nt=#t
- if nt>0 then
- local n=0
- for _,v in next,t do
- n=n+1
- if type(v)=="table" then
- return nil
- end
- end
- local haszero=rawget(t,0)
- if n==nt then
- local tt={}
- for i=1,nt do
- local v=t[i]
- local tv=type(v)
- if tv=="number" then
- if hexify then
- tt[i]=format("0x%X",v)
- else
- tt[i]=v
- end
- elseif tv=="string" then
- tt[i]=format("%q",v)
- elseif tv=="boolean" then
- tt[i]=v and "true" or "false"
- else
- return nil
- end
- end
- return tt
- elseif haszero and (n==nt+1) then
- local tt={}
- for i=0,nt do
- local v=t[i]
- local tv=type(v)
- if tv=="number" then
- if hexify then
- tt[i+1]=format("0x%X",v)
- else
- tt[i+1]=v
- end
- elseif tv=="string" then
- tt[i+1]=format("%q",v)
- elseif tv=="boolean" then
- tt[i+1]=v and "true" or "false"
- else
- return nil
- end
- end
- tt[1]="[0] = "..tt[1]
- return tt
+ local nt=#t
+ if nt>0 then
+ local n=0
+ for _,v in next,t do
+ n=n+1
+ if type(v)=="table" then
+ return nil
+ end
+ end
+ local haszero=rawget(t,0)
+ if n==nt then
+ local tt={}
+ for i=1,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i]=format("0x%X",v)
+ else
+ tt[i]=v
+ end
+ elseif tv=="string" then
+ tt[i]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i]=v and "true" or "false"
+ else
+ return nil
end
+ end
+ return tt
+ elseif haszero and (n==nt+1) then
+ local tt={}
+ for i=0,nt do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="number" then
+ if hexify then
+ tt[i+1]=format("0x%X",v)
+ else
+ tt[i+1]=v
+ end
+ elseif tv=="string" then
+ tt[i+1]=format("%q",v)
+ elseif tv=="boolean" then
+ tt[i+1]=v and "true" or "false"
+ else
+ return nil
+ end
+ end
+ tt[1]="[0] = "..tt[1]
+ return tt
end
- return nil
+ end
+ return nil
end
table.is_simple_table=is_simple_table
local propername=patterns.propername
local function dummy() end
local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- depth=depth.." "
- if indexed then
- handle(format("%s{",depth))
+ if level>0 then
+ depth=depth.." "
+ if indexed then
+ handle(format("%s{",depth))
+ else
+ local tn=type(name)
+ if tn=="number" then
+ if hexify then
+ handle(format("%s[0x%X]={",depth,name))
else
- local tn=type(name)
- if tn=="number" then
- if hexify then
- handle(format("%s[0x%X]={",depth,name))
- else
- handle(format("%s[%s]={",depth,name))
- end
- elseif tn=="string" then
- if noquotes and not reserved[name] and lpegmatch(propername,name) then
- handle(format("%s%s={",depth,name))
- else
- handle(format("%s[%q]={",depth,name))
- end
- elseif tn=="boolean" then
- handle(format("%s[%s]={",depth,name and "true" or "false"))
+ handle(format("%s[%s]={",depth,name))
+ end
+ elseif tn=="string" then
+ if noquotes and not reserved[name] and lpegmatch(propername,name) then
+ handle(format("%s%s={",depth,name))
+ else
+ handle(format("%s[%q]={",depth,name))
+ end
+ elseif tn=="boolean" then
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
+ else
+ handle(format("%s{",depth))
+ end
+ end
+ end
+ if root and next(root)~=nil then
+ local first,last=nil,0
+ if compact then
+ last=#root
+ for k=1,last do
+ if rawget(root,k)==nil then
+ last=k-1
+ break
+ end
+ end
+ if last>0 then
+ first=1
+ end
+ end
+ local sk=sortedkeys(root)
+ for i=1,#sk do
+ local k=sk[i]
+ local v=root[k]
+ local tv=type(v)
+ local tk=type(k)
+ if compact and first and tk=="number" and k>=first and k<=last then
+ if tv=="number" then
+ if hexify then
+ handle(format("%s 0x%X,",depth,v))
+ else
+ handle(format("%s %s,",depth,v))
+ end
+ elseif tv=="string" then
+ handle(format("%s %q,",depth,v))
+ elseif tv=="table" then
+ if next(v)==nil then
+ handle(format("%s {},",depth))
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ handle(format("%s { %s },",depth,concat(st,", ")))
else
- handle(format("%s{",depth))
+ do_serialize(v,k,depth,level+1,true)
end
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ elseif tv=="boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv=="function" then
+ if functions then
+ handle(format('%s load(%q),',depth,dump(v)))
+ else
+ handle(format('%s "function",',depth))
+ end
+ else
+ handle(format("%s %q,",depth,tostring(v)))
end
- end
- if root and next(root)~=nil then
- local first,last=nil,0
- if compact then
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
+ elseif k=="__p__" then
+ if false then
+ handle(format("%s __p__=nil,",depth))
+ end
+ elseif tv=="number" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ if hexify then
+ handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ else
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
+ end
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ if hexify then
+ handle(format("%s %s=0x%X,",depth,k,v))
+ else
+ handle(format("%s %s=%s,",depth,k,v))
+ end
+ else
+ if hexify then
+ handle(format("%s [%q]=0x%X,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v))
+ end
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,v))
+ else
+ handle(format("%s [%s]=%q,",depth,k,v))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,v))
+ else
+ handle(format("%s [%q]=%q,",depth,k,v))
+ end
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={},",depth,k))
+ else
+ handle(format("%s [%s]={},",depth,k))
end
- if last>0 then
- first=1
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={},",depth,k))
+ else
+ handle(format("%s [%q]={},",depth,k))
+ end
+ elseif inline then
+ local st=is_simple_table(v,hexify)
+ if st then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
+ else
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
end
+ else
+ do_serialize(v,k,depth,level+1)
+ end
+ else
+ do_serialize(v,k,depth,level+1)
end
- local sk=sortedkeys(root)
- for i=1,#sk do
- local k=sk[i]
- local v=root[k]
- local tv=type(v)
- local tk=type(k)
- if compact and first and tk=="number" and k>=first and k<=last then
- if tv=="number" then
- if hexify then
- handle(format("%s 0x%X,",depth,v))
- else
- handle(format("%s %s,",depth,v))
- end
- elseif tv=="string" then
- handle(format("%s %q,",depth,v))
- elseif tv=="table" then
- if next(v)==nil then
- handle(format("%s {},",depth))
- elseif inline then
- local st=is_simple_table(v,hexify)
- if st then
- handle(format("%s { %s },",depth,concat(st,", ")))
- else
- do_serialize(v,k,depth,level+1,true)
- end
- else
- do_serialize(v,k,depth,level+1,true)
- end
- elseif tv=="boolean" then
- handle(format("%s %s,",depth,v and "true" or "false"))
- elseif tv=="function" then
- if functions then
- handle(format('%s load(%q),',depth,dump(v)))
- else
- handle(format('%s "function",',depth))
- end
- else
- handle(format("%s %q,",depth,tostring(v)))
- end
- elseif k=="__p__" then
- if false then
- handle(format("%s __p__=nil,",depth))
- end
- elseif tv=="number" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=0x%X,",depth,k,v))
- else
- handle(format("%s [%s]=%s,",depth,k,v))
- end
- elseif tk=="boolean" then
- if hexify then
- handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
- else
- handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
- end
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- if hexify then
- handle(format("%s %s=0x%X,",depth,k,v))
- else
- handle(format("%s %s=%s,",depth,k,v))
- end
- else
- if hexify then
- handle(format("%s [%q]=0x%X,",depth,k,v))
- else
- handle(format("%s [%q]=%s,",depth,k,v))
- end
- end
- elseif tv=="string" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%q,",depth,k,v))
- else
- handle(format("%s [%s]=%q,",depth,k,v))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%q,",depth,k,v))
- else
- handle(format("%s [%q]=%q,",depth,k,v))
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]={},",depth,k))
- else
- handle(format("%s [%s]={},",depth,k))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]={},",depth,k and "true" or "false"))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s={},",depth,k))
- else
- handle(format("%s [%q]={},",depth,k))
- end
- elseif inline then
- local st=is_simple_table(v,hexify)
- if st then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
- else
- handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
- else
- handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
- end
- else
- do_serialize(v,k,depth,level+1)
- end
- else
- do_serialize(v,k,depth,level+1)
- end
- elseif tv=="boolean" then
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
- else
- handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
- else
- handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
- end
- elseif tv=="function" then
- if functions then
- local getinfo=debug and debug.getinfo
- if getinfo then
- local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=load(%q),",depth,k,f))
- else
- handle(format("%s [%s]=load(%q),",depth,k,f))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=load(%q),",depth,k,f))
- else
- handle(format("%s [%q]=load(%q),",depth,k,f))
- end
- end
- end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
+ end
+ elseif tv=="function" then
+ if functions then
+ local getinfo=debug and debug.getinfo
+ if getinfo then
+ local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%s]=load(%q),",depth,k,f))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=load(%q),",depth,k,f))
else
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
- else
- handle(format("%s [%s]=%q,",depth,k,tostring(v)))
- end
- elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%q,",depth,k,tostring(v)))
- else
- handle(format("%s [%q]=%q,",depth,k,tostring(v)))
- end
+ handle(format("%s [%q]=load(%q),",depth,k,f))
end
+ end
end
+ else
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%s]=%q,",depth,k,tostring(v)))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=%q,",depth,k,tostring(v)))
+ else
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
+ end
+ end
end
- if level>0 then
- handle(format("%s},",depth))
- end
+ end
+ if level>0 then
+ handle(format("%s},",depth))
+ end
end
local function serialize(_handle,root,name,specification)
- local tname=type(name)
- if type(specification)=="table" then
- noquotes=specification.noquotes
- hexify=specification.hexify
- handle=_handle or specification.handle or print
- functions=specification.functions
- compact=specification.compact
- inline=specification.inline and compact
- metacheck=specification.metacheck
- if functions==nil then
- functions=true
- end
- if compact==nil then
- compact=true
- end
- if inline==nil then
- inline=compact
- end
- if metacheck==nil then
- metacheck=true
- end
+ local tname=type(name)
+ if type(specification)=="table" then
+ noquotes=specification.noquotes
+ hexify=specification.hexify
+ handle=_handle or specification.handle or print
+ functions=specification.functions
+ compact=specification.compact
+ inline=specification.inline and compact
+ metacheck=specification.metacheck
+ if functions==nil then
+ functions=true
+ end
+ if compact==nil then
+ compact=true
+ end
+ if inline==nil then
+ inline=compact
+ end
+ if metacheck==nil then
+ metacheck=true
+ end
+ else
+ noquotes=false
+ hexify=false
+ handle=_handle or print
+ compact=true
+ inline=true
+ functions=true
+ metacheck=true
+ end
+ if tname=="string" then
+ if name=="return" then
+ handle("return {")
else
- noquotes=false
- hexify=false
- handle=_handle or print
- compact=true
- inline=true
- functions=true
- metacheck=true
- end
- if tname=="string" then
- if name=="return" then
- handle("return {")
- else
- handle(name.."={")
- end
- elseif tname=="number" then
- if hexify then
- handle(format("[0x%X]={",name))
- else
- handle("["..name.."]={")
- end
- elseif tname=="boolean" then
- if name then
- handle("return {")
- else
- handle("{")
- end
+ handle(name.."={")
+ end
+ elseif tname=="number" then
+ if hexify then
+ handle(format("[0x%X]={",name))
else
- handle("t={")
+ handle("["..name.."]={")
end
- if root then
- if metacheck and getmetatable(root) then
- local dummy=root._w_h_a_t_e_v_e_r_
- root._w_h_a_t_e_v_e_r_=nil
- end
- if next(root)~=nil then
- do_serialize(root,name,"",0)
- end
+ elseif tname=="boolean" then
+ if name then
+ handle("return {")
+ else
+ handle("{")
+ end
+ else
+ handle("t={")
+ end
+ if root then
+ if metacheck and getmetatable(root) then
+ local dummy=root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_=nil
+ end
+ if next(root)~=nil then
+ do_serialize(root,name,"",0)
end
- handle("}")
+ end
+ handle("}")
end
function table.serialize(root,name,specification)
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
- end
- serialize(flush,root,name,specification)
- return concat(t,"\n")
+ local t,n={},0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ end
+ serialize(flush,root,name,specification)
+ return concat(t,"\n")
end
table.tohandle=serialize
local maxtab=2*1024
function table.tofile(filename,root,name,specification)
- local f=io.open(filename,'w')
- if f then
- if maxtab>1 then
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
- if n>maxtab then
- f:write(concat(t,"\n"),"\n")
- t,n={},0
- end
- end
- serialize(flush,root,name,specification)
- f:write(concat(t,"\n"),"\n")
- else
- local function flush(s)
- f:write(s,"\n")
- end
- serialize(flush,root,name,specification)
+ local f=io.open(filename,'w')
+ if f then
+ if maxtab>1 then
+ local t,n={},0
+ local function flush(s)
+ n=n+1
+ t[n]=s
+ if n>maxtab then
+ f:write(concat(t,"\n"),"\n")
+ t,n={},0
end
- f:close()
- io.flush()
+ end
+ serialize(flush,root,name,specification)
+ f:write(concat(t,"\n"),"\n")
+ else
+ local function flush(s)
+ f:write(s,"\n")
+ end
+ serialize(flush,root,name,specification)
end
+ f:close()
+ io.flush()
+ end
end
local function flattened(t,f,depth)
- if f==nil then
- f={}
- depth=0xFFFF
- elseif tonumber(f) then
- depth=f
- f={}
- elseif not depth then
- depth=0xFFFF
- end
- for k,v in next,t do
- if type(k)~="number" then
- if depth>0 and type(v)=="table" then
- flattened(v,f,depth-1)
- else
- f[#f+1]=v
- end
- end
- end
- for k=1,#t do
- local v=t[k]
- if depth>0 and type(v)=="table" then
- flattened(v,f,depth-1)
- else
- f[#f+1]=v
- end
+ if f==nil then
+ f={}
+ depth=0xFFFF
+ elseif tonumber(f) then
+ depth=f
+ f={}
+ elseif not depth then
+ depth=0xFFFF
+ end
+ for k,v in next,t do
+ if type(k)~="number" then
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
+ end
+ end
+ end
+ for k=1,#t do
+ local v=t[k]
+ if depth>0 and type(v)=="table" then
+ flattened(v,f,depth-1)
+ else
+ f[#f+1]=v
end
- return f
+ end
+ return f
end
table.flattened=flattened
local function collapsed(t,f,h)
- if f==nil then
- f={}
- h={}
- end
- for k=1,#t do
- local v=t[k]
- if type(v)=="table" then
- collapsed(v,f,h)
- elseif not h[v] then
- f[#f+1]=v
- h[v]=true
- end
- end
- return f
+ if f==nil then
+ f={}
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsed(v,f,h)
+ elseif not h[v] then
+ f[#f+1]=v
+ h[v]=true
+ end
+ end
+ return f
end
local function collapsedhash(t,h)
- if h==nil then
- h={}
- end
- for k=1,#t do
- local v=t[k]
- if type(v)=="table" then
- collapsedhash(v,h)
- else
- h[v]=true
- end
+ if h==nil then
+ h={}
+ end
+ for k=1,#t do
+ local v=t[k]
+ if type(v)=="table" then
+ collapsedhash(v,h)
+ else
+ h[v]=true
end
- return h
+ end
+ return h
end
-table.collapsed=collapsed
+table.collapsed=collapsed
table.collapsedhash=collapsedhash
local function unnest(t,f)
- if not f then
- f={}
- end
- for i=1,#t do
- local v=t[i]
- if type(v)=="table" then
- if type(v[1])=="table" then
- unnest(v,f)
- else
- f[#f+1]=v
- end
- else
- f[#f+1]=v
- end
+ if not f then
+ f={}
+ end
+ for i=1,#t do
+ local v=t[i]
+ if type(v)=="table" then
+ if type(v[1])=="table" then
+ unnest(v,f)
+ else
+ f[#f+1]=v
+ end
+ else
+ f[#f+1]=v
end
- return f
+ end
+ return f
end
function table.unnest(t)
- return unnest(t)
+ return unnest(t)
end
local function are_equal(a,b,n,m)
- if a==b then
- return true
- elseif a and b and #a==#b then
- n=n or 1
- m=m or #a
- for i=n,m do
- local ai,bi=a[i],b[i]
- if ai==bi then
- elseif type(ai)=="table" and type(bi)=="table" then
- if not are_equal(ai,bi) then
- return false
- end
- else
- return false
- end
- end
- return true
- else
+ if a==b then
+ return true
+ elseif a and b and #a==#b then
+ n=n or 1
+ m=m or #a
+ for i=n,m do
+ local ai,bi=a[i],b[i]
+ if ai==bi then
+ elseif type(ai)=="table" and type(bi)=="table" then
+ if not are_equal(ai,bi) then
+ return false
+ end
+ else
return false
+ end
end
+ return true
+ else
+ return false
+ end
end
local function identical(a,b)
- if a~=b then
- for ka,va in next,a do
- local vb=b[ka]
- if va==vb then
- elseif type(va)=="table" and type(vb)=="table" then
- if not identical(va,vb) then
- return false
- end
- else
- return false
- end
- end
+ if a~=b then
+ for ka,va in next,a do
+ local vb=b[ka]
+ if va==vb then
+ elseif type(va)=="table" and type(vb)=="table" then
+ if not identical(va,vb) then
+ return false
+ end
+ else
+ return false
+ end
end
- return true
+ end
+ return true
end
table.identical=identical
table.are_equal=are_equal
local function sparse(old,nest,keeptables)
- local new={}
- for k,v in next,old do
- if not (v=="" or v==false) then
- if nest and type(v)=="table" then
- v=sparse(v,nest)
- if keeptables or next(v)~=nil then
- new[k]=v
- end
- else
- new[k]=v
- end
+ local new={}
+ for k,v in next,old do
+ if not (v=="" or v==false) then
+ if nest and type(v)=="table" then
+ v=sparse(v,nest)
+ if keeptables or next(v)~=nil then
+ new[k]=v
end
+ else
+ new[k]=v
+ end
end
- return new
+ end
+ return new
end
table.sparse=sparse
function table.compact(t)
- return sparse(t,true,true)
+ return sparse(t,true,true)
end
function table.contains(t,v)
- if t then
- for i=1,#t do
- if t[i]==v then
- return i
- end
- end
+ if t then
+ for i=1,#t do
+ if t[i]==v then
+ return i
+ end
end
- return false
+ end
+ return false
end
function table.count(t)
- local n=0
- for k,v in next,t do
- n=n+1
- end
- return n
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ end
+ return n
end
function table.swapped(t,s)
- local n={}
- if s then
- for k,v in next,s do
- n[k]=v
- end
- end
- for k,v in next,t do
- n[v]=k
+ local n={}
+ if s then
+ for k,v in next,s do
+ n[k]=v
end
- return n
+ end
+ for k,v in next,t do
+ n[v]=k
+ end
+ return n
end
function table.hashed(t)
- for i=1,#t do
- t[t[i]]=i
- end
- return t
+ for i=1,#t do
+ t[t[i]]=i
+ end
+ return t
end
function table.mirrored(t)
- local n={}
- for k,v in next,t do
- n[v]=k
- n[k]=v
- end
- return n
+ local n={}
+ for k,v in next,t do
+ n[v]=k
+ n[k]=v
+ end
+ return n
end
function table.reversed(t)
- if t then
- local tt,tn={},#t
- if tn>0 then
- local ttn=0
- for i=tn,1,-1 do
- ttn=ttn+1
- tt[ttn]=t[i]
- end
- end
- return tt
- end
+ if t then
+ local tt,tn={},#t
+ if tn>0 then
+ local ttn=0
+ for i=tn,1,-1 do
+ ttn=ttn+1
+ tt[ttn]=t[i]
+ end
+ end
+ return tt
+ end
end
function table.reverse(t)
- if t then
- local n=#t
- local m=n+1
- for i=1,floor(n/2) do
- local j=m-i
- t[i],t[j]=t[j],t[i]
- end
- return t
+ if t then
+ local n=#t
+ local m=n+1
+ for i=1,floor(n/2) do
+ local j=m-i
+ t[i],t[j]=t[j],t[i]
end
+ return t
+ end
end
local function sequenced(t,sep,simple)
- if not t then
- return ""
- elseif type(t)=="string" then
- return t
- end
- local n=#t
- local s={}
- if n>0 then
- for i=1,n do
- local v=t[i]
- if type(v)=="table" then
- s[i]="{"..sequenced(v,sep,simple).."}"
- else
- s[i]=tostring(t[i])
- end
+ if not t then
+ return ""
+ elseif type(t)=="string" then
+ return t
+ end
+ local n=#t
+ local s={}
+ if n>0 then
+ for i=1,n do
+ local v=t[i]
+ if type(v)=="table" then
+ s[i]="{"..sequenced(v,sep,simple).."}"
+ else
+ s[i]=tostring(t[i])
+ end
+ end
+ else
+ n=0
+ for k,v in sortedhash(t) do
+ if simple then
+ if v==true then
+ n=n+1
+ s[n]=k
+ elseif v and v~="" then
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
+ end
end
- else
- n=0
- for k,v in sortedhash(t) do
- if simple then
- if v==true then
- n=n+1
- s[n]=k
- elseif v and v~="" then
- n=n+1
- if type(v)=="table" then
- s[n]=k.."={"..sequenced(v,sep,simple).."}"
- else
- s[n]=k.."="..tostring(v)
- end
- end
- else
- n=n+1
- if type(v)=="table" then
- s[n]=k.."={"..sequenced(v,sep,simple).."}"
- else
- s[n]=k.."="..tostring(v)
- end
- end
+ else
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k.."={"..sequenced(v,sep,simple).."}"
+ else
+ s[n]=k.."="..tostring(v)
end
+ end
end
- return concat(s,sep or " | ")
+ end
+ return concat(s,sep or " | ")
end
table.sequenced=sequenced
function table.print(t,...)
- if type(t)~="table" then
- print(tostring(t))
- else
- serialize(print,t,...)
- end
+ if type(t)~="table" then
+ print(tostring(t))
+ else
+ serialize(print,t,...)
+ end
end
if setinspector then
- setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
+ setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end)
end
function table.sub(t,i,j)
- return { unpack(t,i,j) }
+ return { unpack(t,i,j) }
end
function table.is_empty(t)
- return not t or next(t)==nil
+ return not t or next(t)==nil
end
function table.has_one_entry(t)
- return t and next(t,next(t))==nil
+ return t and next(t,next(t))==nil
end
function table.loweredkeys(t)
- local l={}
- for k,v in next,t do
- l[lower(k)]=v
- end
- return l
+ local l={}
+ for k,v in next,t do
+ l[lower(k)]=v
+ end
+ return l
end
function table.unique(old)
- local hash={}
- local new={}
- local n=0
- for i=1,#old do
- local oi=old[i]
- if not hash[oi] then
- n=n+1
- new[n]=oi
- hash[oi]=true
- end
- end
- return new
+ local hash={}
+ local new={}
+ local n=0
+ for i=1,#old do
+ local oi=old[i]
+ if not hash[oi] then
+ n=n+1
+ new[n]=oi
+ hash[oi]=true
+ end
+ end
+ return new
end
function table.sorted(t,...)
- sort(t,...)
- return t
+ sort(t,...)
+ return t
end
function table.values(t,s)
- if t then
- local values,keys,v={},{},0
- for key,value in next,t do
- if not keys[value] then
- v=v+1
- values[v]=value
- keys[k]=key
- end
- end
- if s then
- sort(values)
- end
- return values
- else
- return {}
+ if t then
+ local values,keys,v={},{},0
+ for key,value in next,t do
+ if not keys[value] then
+ v=v+1
+ values[v]=value
+ keys[k]=key
+ end
end
+ if s then
+ sort(values)
+ end
+ return values
+ else
+ return {}
+ end
end
function table.filtered(t,pattern,sort,cmp)
- if t and type(pattern)=="string" then
- if sort then
- local s
- if cmp then
- s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
- else
- s=sortedkeys(t)
- end
- local n=0
- local m=#s
- local function kv(s)
- while n<m do
- n=n+1
- local k=s[n]
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return kv,s
- else
- local n=next(t)
- local function iterator()
- while n~=nil do
- local k=n
- n=next(t,k)
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return iterator,t
+ if t and type(pattern)=="string" then
+ if sort then
+ local s
+ if cmp then
+ s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end)
+ else
+ s=sortedkeys(t)
+ end
+ local n=0
+ local m=#s
+ local function kv(s)
+ while n<m do
+ n=n+1
+ local k=s[n]
+ if find(k,pattern) then
+ return k,t[k]
+ end
end
+ end
+ return kv,s
else
- return nothing
+ local n=next(t)
+ local function iterator()
+ while n~=nil do
+ local k=n
+ n=next(t,k)
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return iterator,t
end
+ else
+ return nothing
+ end
end
if not table.move then
- function table.move(a1,f,e,t,a2)
- if a2 and a1~=a2 then
- for i=f,e do
- a2[t]=a1[i]
- t=t+1
- end
- return a2
- else
- t=t+e-f
- for i=e,f,-1 do
- a1[t]=a1[i]
- t=t-1
- end
- return a1
- end
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1~=a2 then
+ for i=f,e do
+ a2[t]=a1[i]
+ t=t+1
+ end
+ return a2
+ else
+ t=t+e-f
+ for i=e,f,-1 do
+ a1[t]=a1[i]
+ t=t-1
+ end
+ return a1
end
+ end
end
end -- closure
@@ -2129,11 +2129,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-io']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local io=io
local open,flush,write,read=io.open,io.flush,io.write,io.read
@@ -2141,334 +2141,334 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
local concat=table.concat
local type=type
if string.find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator="\\",";"
+ io.fileseparator,io.pathseparator="\\",";"
else
- io.fileseparator,io.pathseparator="/",":"
+ io.fileseparator,io.pathseparator="/",":"
end
local large=0x01000000
local medium=0x00100000
local small=0x00020000
local function readall(f)
- local size=f:seek("end")
- if size>0 then
- f:seek("set",0)
- return f:read(size)
- else
- return ""
- end
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ return f:read(size)
+ else
+ return ""
+ end
end
io.readall=readall
function io.loaddata(filename,textmode)
- local f=open(filename,(textmode and 'r') or 'rb')
- if f then
- local size=f:seek("end")
- local data=nil
- if size>0 then
- f:seek("set",0)
- data=f:read(size)
- end
- f:close()
- return data
+ local f=open(filename,(textmode and 'r') or 'rb')
+ if f then
+ local size=f:seek("end")
+ local data=nil
+ if size>0 then
+ f:seek("set",0)
+ data=f:read(size)
end
+ f:close()
+ return data
+ end
end
function io.copydata(source,target,action)
- local f=open(source,"rb")
- if f then
- local g=open(target,"wb")
- if g then
- local size=f:seek("end")
- if size>0 then
- f:seek("set",0)
- local data=f:read(size)
- if action then
- data=action(data)
- end
- if data then
- g:write(data)
- end
- end
- g:close()
+ local f=open(source,"rb")
+ if f then
+ local g=open(target,"wb")
+ if g then
+ local size=f:seek("end")
+ if size>0 then
+ f:seek("set",0)
+ local data=f:read(size)
+ if action then
+ data=action(data)
+ end
+ if data then
+ g:write(data)
end
- f:close()
- flush()
+ end
+ g:close()
end
+ f:close()
+ flush()
+ end
end
function io.savedata(filename,data,joiner)
- local f=open(filename,"wb")
- if f then
- if type(data)=="table" then
- f:write(concat(data,joiner or ""))
- elseif type(data)=="function" then
- data(f)
- else
- f:write(data or "")
- end
- f:close()
- flush()
- return true
+ local f=open(filename,"wb")
+ if f then
+ if type(data)=="table" then
+ f:write(concat(data,joiner or ""))
+ elseif type(data)=="function" then
+ data(f)
else
- return false
+ f:write(data or "")
end
+ f:close()
+ flush()
+ return true
+ else
+ return false
+ end
end
if fio and fio.readline then
- local readline=fio.readline
- function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=readline(f)
- if line then
- lines[i]=line
- else
- break
- end
- end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
+ local readline=fio.readline
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=readline(f)
+ if line then
+ lines[i]=line
else
- local line=readline(f)
- f:close()
- if line and #line>0 then
- return line
- end
- end
+ break
+ end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=readline(f)
+ f:close()
+ if line and #line>0 then
+ return line
+ end
end
+ end
else
- function io.loadlines(filename,n)
- local f=open(filename,'r')
- if not f then
- elseif n then
- local lines={}
- for i=1,n do
- local line=f:read("*lines")
- if line then
- lines[i]=line
- else
- break
- end
- end
- f:close()
- lines=concat(lines,"\n")
- if #lines>0 then
- return lines
- end
+ function io.loadlines(filename,n)
+ local f=open(filename,'r')
+ if not f then
+ elseif n then
+ local lines={}
+ for i=1,n do
+ local line=f:read("*lines")
+ if line then
+ lines[i]=line
else
- local line=f:read("*line") or ""
- f:close()
- if #line>0 then
- return line
- end
- end
+ break
+ end
+ end
+ f:close()
+ lines=concat(lines,"\n")
+ if #lines>0 then
+ return lines
+ end
+ else
+ local line=f:read("*line") or ""
+ f:close()
+ if #line>0 then
+ return line
+ end
end
+ end
end
function io.loadchunk(filename,n)
- local f=open(filename,'rb')
- if f then
- local data=f:read(n or 1024)
- f:close()
- if #data>0 then
- return data
- end
+ local f=open(filename,'rb')
+ if f then
+ local data=f:read(n or 1024)
+ f:close()
+ if #data>0 then
+ return data
end
+ end
end
function io.exists(filename)
- local f=open(filename)
- if f==nil then
- return false
- else
- f:close()
- return true
- end
+ local f=open(filename)
+ if f==nil then
+ return false
+ else
+ f:close()
+ return true
+ end
end
function io.size(filename)
- local f=open(filename)
- if f==nil then
- return 0
- else
- local s=f:seek("end")
- f:close()
- return s
- end
+ local f=open(filename)
+ if f==nil then
+ return 0
+ else
+ local s=f:seek("end")
+ f:close()
+ return s
+ end
end
local function noflines(f)
- if type(f)=="string" then
- local f=open(filename)
- if f then
- local n=f and noflines(f) or 0
- f:close()
- return n
- else
- return 0
- end
+ if type(f)=="string" then
+ local f=open(filename)
+ if f then
+ local n=f and noflines(f) or 0
+ f:close()
+ return n
else
- local n=0
- for _ in f:lines() do
- n=n+1
- end
- f:seek('set',0)
- return n
+ return 0
+ end
+ else
+ local n=0
+ for _ in f:lines() do
+ n=n+1
end
+ f:seek('set',0)
+ return n
+ end
end
io.noflines=noflines
local nextchar={
- [ 4]=function(f)
- return f:read(1,1,1,1)
- end,
- [ 2]=function(f)
- return f:read(1,1)
- end,
- [ 1]=function(f)
- return f:read(1)
- end,
- [-2]=function(f)
- local a,b=f:read(1,1)
- return b,a
- end,
- [-4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- return d,c,b,a
- end
+ [ 4]=function(f)
+ return f:read(1,1,1,1)
+ end,
+ [ 2]=function(f)
+ return f:read(1,1)
+ end,
+ [ 1]=function(f)
+ return f:read(1)
+ end,
+ [-2]=function(f)
+ local a,b=f:read(1,1)
+ return b,a
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ return d,c,b,a
+ end
}
function io.characters(f,n)
- if f then
- return nextchar[n or 1],f
- end
+ if f then
+ return nextchar[n or 1],f
+ end
end
local nextbyte={
- [4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- if d then
- return byte(a),byte(b),byte(c),byte(d)
- end
- end,
- [3]=function(f)
- local a,b,c=f:read(1,1,1)
- if b then
- return byte(a),byte(b),byte(c)
- end
- end,
- [2]=function(f)
- local a,b=f:read(1,1)
- if b then
- return byte(a),byte(b)
- end
- end,
- [1]=function (f)
- local a=f:read(1)
- if a then
- return byte(a)
- end
- end,
- [-2]=function (f)
- local a,b=f:read(1,1)
- if b then
- return byte(b),byte(a)
- end
- end,
- [-3]=function(f)
- local a,b,c=f:read(1,1,1)
- if b then
- return byte(c),byte(b),byte(a)
- end
- end,
- [-4]=function(f)
- local a,b,c,d=f:read(1,1,1,1)
- if d then
- return byte(d),byte(c),byte(b),byte(a)
- end
- end
+ [4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(a),byte(b),byte(c),byte(d)
+ end
+ end,
+ [3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(a),byte(b),byte(c)
+ end
+ end,
+ [2]=function(f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(a),byte(b)
+ end
+ end,
+ [1]=function (f)
+ local a=f:read(1)
+ if a then
+ return byte(a)
+ end
+ end,
+ [-2]=function (f)
+ local a,b=f:read(1,1)
+ if b then
+ return byte(b),byte(a)
+ end
+ end,
+ [-3]=function(f)
+ local a,b,c=f:read(1,1,1)
+ if b then
+ return byte(c),byte(b),byte(a)
+ end
+ end,
+ [-4]=function(f)
+ local a,b,c,d=f:read(1,1,1,1)
+ if d then
+ return byte(d),byte(c),byte(b),byte(a)
+ end
+ end
}
function io.bytes(f,n)
- if f then
- return nextbyte[n or 1],f
- else
- return nil,nil
- end
+ if f then
+ return nextbyte[n or 1],f
+ else
+ return nil,nil
+ end
end
function io.ask(question,default,options)
- while true do
- write(question)
- if options then
- write(format(" [%s]",concat(options,"|")))
- end
- if default then
- write(format(" [%s]",default))
- end
- write(format(" "))
- flush()
- local answer=read()
- answer=gsub(answer,"^%s*(.*)%s*$","%1")
- if answer=="" and default then
- return default
- elseif not options then
- return answer
- else
- for k=1,#options do
- if options[k]==answer then
- return answer
- end
- end
- local pattern="^"..answer
- for k=1,#options do
- local v=options[k]
- if find(v,pattern) then
- return v
- end
- end
+ while true do
+ write(question)
+ if options then
+ write(format(" [%s]",concat(options,"|")))
+ end
+ if default then
+ write(format(" [%s]",default))
+ end
+ write(format(" "))
+ flush()
+ local answer=read()
+ answer=gsub(answer,"^%s*(.*)%s*$","%1")
+ if answer=="" and default then
+ return default
+ elseif not options then
+ return answer
+ else
+ for k=1,#options do
+ if options[k]==answer then
+ return answer
+ end
+ end
+ local pattern="^"..answer
+ for k=1,#options do
+ local v=options[k]
+ if find(v,pattern) then
+ return v
end
+ end
end
+ end
end
local function readnumber(f,n,m)
- if m then
- f:seek("set",n)
- n=m
- end
- if n==1 then
- return byte(f:read(1))
- elseif n==2 then
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
- elseif n==3 then
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
- elseif n==4 then
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==8 then
- local a,b=readnumber(f,4),readnumber(f,4)
- return 0x100*a+b
- elseif n==12 then
- local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
- return 0x10000*a+0x100*b+c
- elseif n==-2 then
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
- elseif n==-3 then
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
- elseif n==-4 then
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
- elseif n==-8 then
- local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
- return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
- else
- return 0
- end
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ if n==1 then
+ return byte(f:read(1))
+ elseif n==2 then
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==3 then
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==4 then
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==8 then
+ local a,b=readnumber(f,4),readnumber(f,4)
+ return 0x100*a+b
+ elseif n==12 then
+ local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4)
+ return 0x10000*a+0x100*b+c
+ elseif n==-2 then
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
+ elseif n==-3 then
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
+ elseif n==-4 then
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ elseif n==-8 then
+ local h,g,f,e,d,c,b,a=byte(f:read(8),1,8)
+ return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+ else
+ return 0
+ end
end
io.readnumber=readnumber
function io.readstring(f,n,m)
- if m then
- f:seek("set",n)
- n=m
- end
- local str=gsub(f:read(n),"\000","")
- return str
+ if m then
+ f:seek("set",n)
+ n=m
+ end
+ local str=gsub(f:read(n),"\000","")
+ return str
end
end -- closure
@@ -2476,16 +2476,16 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-file']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
file=file or {}
local file=file
if not lfs then
- lfs=optionalrequire("lfs")
+ lfs=optionalrequire("lfs")
end
local insert,concat=table.insert,table.concat
local match,find,gmatch=string.match,string.find,string.gmatch
@@ -2495,20 +2495,20 @@ local checkedsplit=string.checkedsplit
local P,R,S,C,Cs,Cp,Cc,Ct=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cp,lpeg.Cc,lpeg.Ct
local attributes=lfs.attributes
function lfs.isdir(name)
- return attributes(name,"mode")=="directory"
+ return attributes(name,"mode")=="directory"
end
function lfs.isfile(name)
- local a=attributes(name,"mode")
- return a=="file" or a=="link" or nil
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
end
function lfs.isfound(name)
- local a=attributes(name,"mode")
- return (a=="file" or a=="link") and name or nil
+ local a=attributes(name,"mode")
+ return (a=="file" or a=="link") and name or nil
end
if sandbox then
- sandbox.redefine(lfs.isfile,"lfs.isfile")
- sandbox.redefine(lfs.isdir,"lfs.isdir")
- sandbox.redefine(lfs.isfound,"lfs.isfound")
+ sandbox.redefine(lfs.isfile,"lfs.isfile")
+ sandbox.redefine(lfs.isdir,"lfs.isdir")
+ sandbox.redefine(lfs.isfound,"lfs.isfound")
end
local colon=P(":")
local period=P(".")
@@ -2522,27 +2522,27 @@ local name=noperiod^1
local suffix=period/""*(1-period-slashes)^1*-1
local pattern=C((1-(slashes^1*noslashes^1*-1))^1)*P(1)
local function pathpart(name,default)
- return name and lpegmatch(pattern,name) or default or ""
+ return name and lpegmatch(pattern,name) or default or ""
end
local pattern=(noslashes^0*slashes)^1*C(noslashes^1)*-1
local function basename(name)
- return name and lpegmatch(pattern,name) or name
+ return name and lpegmatch(pattern,name) or name
end
local pattern=(noslashes^0*slashes^1)^0*Cs((1-suffix)^1)*suffix^0
local function nameonly(name)
- return name and lpegmatch(pattern,name) or name
+ return name and lpegmatch(pattern,name) or name
end
local pattern=(noslashes^0*slashes)^0*(noperiod^1*period)^1*C(noperiod^1)*-1
local function suffixonly(name)
- return name and lpegmatch(pattern,name) or ""
+ return name and lpegmatch(pattern,name) or ""
end
local pattern=(noslashes^0*slashes)^0*noperiod^1*((period*C(noperiod^1))^1)*-1+Cc("")
local function suffixesonly(name)
- if name then
- return lpegmatch(pattern,name)
- else
- return ""
- end
+ if name then
+ return lpegmatch(pattern,name)
+ else
+ return ""
+ end
end
file.pathpart=pathpart
file.basename=basename
@@ -2551,7 +2551,7 @@ file.suffixonly=suffixonly
file.suffix=suffixonly
file.suffixesonly=suffixesonly
file.suffixes=suffixesonly
-file.dirname=pathpart
+file.dirname=pathpart
file.extname=suffixonly
local drive=C(R("az","AZ"))*colon
local path=C((noslashes^0*slashes)^0)
@@ -2567,142 +2567,142 @@ local pattern_b=path*base*suffix
local pattern_c=C(drive*path)*C(base*suffix)
local pattern_d=path*rest
function file.splitname(str,splitdrive)
- if not str then
- elseif splitdrive then
- return lpegmatch(pattern_a,str)
- else
- return lpegmatch(pattern_b,str)
- end
+ if not str then
+ elseif splitdrive then
+ return lpegmatch(pattern_a,str)
+ else
+ return lpegmatch(pattern_b,str)
+ end
end
function file.splitbase(str)
- if str then
- return lpegmatch(pattern_d,str)
- else
- return "",str
- end
+ if str then
+ return lpegmatch(pattern_d,str)
+ else
+ return "",str
+ end
end
function file.nametotable(str,splitdrive)
- if str then
- local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
- if splitdrive then
- return {
- path=path,
- drive=drive,
- subpath=subpath,
- name=name,
- base=base,
- suffix=suffix,
- }
- else
- return {
- path=path,
- name=name,
- base=base,
- suffix=suffix,
- }
- end
+ if str then
+ local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str)
+ if splitdrive then
+ return {
+ path=path,
+ drive=drive,
+ subpath=subpath,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
+ else
+ return {
+ path=path,
+ name=name,
+ base=base,
+ suffix=suffix,
+ }
end
+ end
end
local pattern=Cs(((period*(1-period-slashes)^1*-1)/""+1)^1)
function file.removesuffix(name)
- return name and lpegmatch(pattern,name)
+ return name and lpegmatch(pattern,name)
end
local suffix=period/""*(1-period-slashes)^1*-1
local pattern=Cs((noslashes^0*slashes^1)^0*((1-suffix)^1))*Cs(suffix)
function file.addsuffix(filename,suffix,criterium)
- if not filename or not suffix or suffix=="" then
- return filename
- elseif criterium==true then
- return filename.."."..suffix
- elseif not criterium then
- local n,s=lpegmatch(pattern,filename)
- if not s or s=="" then
- return filename.."."..suffix
- else
+ if not filename or not suffix or suffix=="" then
+ return filename
+ elseif criterium==true then
+ return filename.."."..suffix
+ elseif not criterium then
+ local n,s=lpegmatch(pattern,filename)
+ if not s or s=="" then
+ return filename.."."..suffix
+ else
+ return filename
+ end
+ else
+ local n,s=lpegmatch(pattern,filename)
+ if s and s~="" then
+ local t=type(criterium)
+ if t=="table" then
+ for i=1,#criterium do
+ if s==criterium[i] then
return filename
+ end
end
- else
- local n,s=lpegmatch(pattern,filename)
- if s and s~="" then
- local t=type(criterium)
- if t=="table" then
- for i=1,#criterium do
- if s==criterium[i] then
- return filename
- end
- end
- elseif t=="string" then
- if s==criterium then
- return filename
- end
- end
+ elseif t=="string" then
+ if s==criterium then
+ return filename
end
- return (n or filename).."."..suffix
+ end
end
+ return (n or filename).."."..suffix
+ end
end
local suffix=period*(1-period-slashes)^1*-1
local pattern=Cs((1-suffix)^0)
function file.replacesuffix(name,suffix)
- if name and suffix and suffix~="" then
- return lpegmatch(pattern,name).."."..suffix
- else
- return name
- end
+ if name and suffix and suffix~="" then
+ return lpegmatch(pattern,name).."."..suffix
+ else
+ return name
+ end
end
local reslasher=lpeg.replacer(P("\\"),"/")
function file.reslash(str)
- return str and lpegmatch(reslasher,str)
+ return str and lpegmatch(reslasher,str)
end
function file.is_writable(name)
- if not name then
- elseif lfs.isdir(name) then
- name=name.."/m_t_x_t_e_s_t.tmp"
- local f=io.open(name,"wb")
- if f then
- f:close()
- os.remove(name)
- return true
- end
- elseif lfs.isfile(name) then
- local f=io.open(name,"ab")
- if f then
- f:close()
- return true
- end
- else
- local f=io.open(name,"ab")
- if f then
- f:close()
- os.remove(name)
- return true
- end
+ if not name then
+ elseif lfs.isdir(name) then
+ name=name.."/m_t_x_t_e_s_t.tmp"
+ local f=io.open(name,"wb")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
end
- return false
+ elseif lfs.isfile(name) then
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ return true
+ end
+ else
+ local f=io.open(name,"ab")
+ if f then
+ f:close()
+ os.remove(name)
+ return true
+ end
+ end
+ return false
end
local readable=P("r")*Cc(true)
function file.is_readable(name)
- if name then
- local a=attributes(name)
- return a and lpegmatch(readable,a.permissions) or false
- else
- return false
- end
+ if name then
+ local a=attributes(name)
+ return a and lpegmatch(readable,a.permissions) or false
+ else
+ return false
+ end
end
file.isreadable=file.is_readable
file.iswritable=file.is_writable
function file.size(name)
- if name then
- local a=attributes(name)
- return a and a.size or 0
- else
- return 0
- end
+ if name then
+ local a=attributes(name)
+ return a and a.size or 0
+ else
+ return 0
+ end
end
function file.splitpath(str,separator)
- return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
+ return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator)
end
function file.joinpath(tab,separator)
- return tab and concat(tab,separator or io.pathseparator)
+ return tab and concat(tab,separator or io.pathseparator)
end
local someslash=S("\\/")
local stripper=Cs(P(fwslash)^0/""*reslasher)
@@ -2712,30 +2712,30 @@ local hasroot=fwslash^1
local reslasher=lpeg.replacer(S("\\/"),"/")
local deslasher=lpeg.replacer(S("\\/")^1,"/")
function file.join(one,two,three,...)
- if not two then
- return one=="" and one or lpegmatch(reslasher,one)
- end
- if one=="" then
- return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
+ if not two then
+ return one=="" and one or lpegmatch(reslasher,one)
+ end
+ if one=="" then
+ return lpegmatch(stripper,three and concat({ two,three,... },"/") or two)
+ end
+ if lpegmatch(isnetwork,one) then
+ local one=lpegmatch(reslasher,one)
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return one..two
+ else
+ return one.."/"..two
end
- if lpegmatch(isnetwork,one) then
- local one=lpegmatch(reslasher,one)
- local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
- if lpegmatch(hasroot,two) then
- return one..two
- else
- return one.."/"..two
- end
- elseif lpegmatch(isroot,one) then
- local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
- if lpegmatch(hasroot,two) then
- return two
- else
- return "/"..two
- end
+ elseif lpegmatch(isroot,one) then
+ local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two)
+ if lpegmatch(hasroot,two) then
+ return two
else
- return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+ return "/"..two
end
+ else
+ return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+ end
end
local drivespec=R("az","AZ")^1*colon
local anchors=fwslash+drivespec
@@ -2745,56 +2745,56 @@ local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//")
local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
local absolute=fwslash
function file.collapsepath(str,anchor)
- if not str then
- return
- end
- if anchor==true and not lpegmatch(anchors,str) then
- str=getcurrentdir().."/"..str
- end
- if str=="" or str=="." then
- return "."
- elseif lpegmatch(untouched,str) then
- return lpegmatch(reslasher,str)
- end
- local starter,oldelements=lpegmatch(splitstarter,str)
- local newelements={}
- local i=#oldelements
- while i>0 do
- local element=oldelements[i]
- if element=='.' then
- elseif element=='..' then
- local n=i-1
- while n>0 do
- local element=oldelements[n]
- if element~='..' and element~='.' then
- oldelements[n]='.'
- break
- else
- n=n-1
- end
- end
- if n<1 then
- insert(newelements,1,'..')
- end
- elseif element~="" then
- insert(newelements,1,element)
- end
- i=i-1
- end
- if #newelements==0 then
- return starter or "."
- elseif starter then
- return starter..concat(newelements,'/')
- elseif lpegmatch(absolute,str) then
- return "/"..concat(newelements,'/')
- else
- newelements=concat(newelements,'/')
- if anchor=="." and find(str,"^%./") then
- return "./"..newelements
+ if not str then
+ return
+ end
+ if anchor==true and not lpegmatch(anchors,str) then
+ str=getcurrentdir().."/"..str
+ end
+ if str=="" or str=="." then
+ return "."
+ elseif lpegmatch(untouched,str) then
+ return lpegmatch(reslasher,str)
+ end
+ local starter,oldelements=lpegmatch(splitstarter,str)
+ local newelements={}
+ local i=#oldelements
+ while i>0 do
+ local element=oldelements[i]
+ if element=='.' then
+ elseif element=='..' then
+ local n=i-1
+ while n>0 do
+ local element=oldelements[n]
+ if element~='..' and element~='.' then
+ oldelements[n]='.'
+ break
else
- return newelements
- end
+ n=n-1
+ end
+ end
+ if n<1 then
+ insert(newelements,1,'..')
+ end
+ elseif element~="" then
+ insert(newelements,1,element)
+ end
+ i=i-1
+ end
+ if #newelements==0 then
+ return starter or "."
+ elseif starter then
+ return starter..concat(newelements,'/')
+ elseif lpegmatch(absolute,str) then
+ return "/"..concat(newelements,'/')
+ else
+ newelements=concat(newelements,'/')
+ if anchor=="." and find(str,"^%./") then
+ return "./"..newelements
+ else
+ return newelements
end
+ end
end
local validchars=R("az","09","AZ","--","..")
local pattern_a=lpeg.replacer(1-validchars)
@@ -2802,26 +2802,26 @@ local pattern_a=Cs((validchars+P(1)/"-")^1)
local whatever=P("-")^0/""
local pattern_b=Cs(whatever*(1-whatever*-1)^1)
function file.robustname(str,strict)
- if str then
- str=lpegmatch(pattern_a,str) or str
- if strict then
- return lpegmatch(pattern_b,str) or str
- else
- return str
- end
+ if str then
+ str=lpegmatch(pattern_a,str) or str
+ if strict then
+ return lpegmatch(pattern_b,str) or str
+ else
+ return str
end
+ end
end
local loaddata=io.loaddata
local savedata=io.savedata
file.readdata=loaddata
file.savedata=savedata
function file.copy(oldname,newname)
- if oldname and newname then
- local data=loaddata(oldname)
- if data and data~="" then
- savedata(newname,data)
- end
+ if oldname and newname then
+ local data=loaddata(oldname)
+ if data and data~="" then
+ savedata(newname,data)
end
+ end
end
local letter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -2830,44 +2830,44 @@ local rootbased=fwslash+letter*colon
lpeg.patterns.qualified=qualified
lpeg.patterns.rootbased=rootbased
function file.is_qualified_path(filename)
- return filename and lpegmatch(qualified,filename)~=nil
+ return filename and lpegmatch(qualified,filename)~=nil
end
function file.is_rootbased_path(filename)
- return filename and lpegmatch(rootbased,filename)~=nil
+ return filename and lpegmatch(rootbased,filename)~=nil
end
function file.strip(name,dir)
- if name then
- local b,a=match(name,"^(.-)"..dir.."(.*)$")
- return a~="" and a or name
- end
+ if name then
+ local b,a=match(name,"^(.-)"..dir.."(.*)$")
+ return a~="" and a or name
+ end
end
function lfs.mkdirs(path)
- local full=""
- for sub in gmatch(path,"(/*[^\\/]+)") do
- full=full..sub
- lfs.mkdir(full)
- end
+ local full=""
+ for sub in gmatch(path,"(/*[^\\/]+)") do
+ full=full..sub
+ lfs.mkdir(full)
+ end
end
function file.withinbase(path)
- local l=0
- if not find(path,"^/") then
- path="/"..path
- end
- for dir in gmatch(path,"/([^/]+)") do
- if dir==".." then
- l=l-1
- elseif dir~="." then
- l=l+1
- end
- if l<0 then
- return false
- end
- end
- return true
+ local l=0
+ if not find(path,"^/") then
+ path="/"..path
+ end
+ for dir in gmatch(path,"/([^/]+)") do
+ if dir==".." then
+ l=l-1
+ elseif dir~="." then
+ l=l+1
+ end
+ if l<0 then
+ return false
+ end
+ end
+ return true
end
local symlinkattributes=lfs.symlinkattributes
function lfs.readlink(name)
- return symlinkattributes(name,"target") or nil
+ return symlinkattributes(name,"target") or nil
end
end -- closure
@@ -2875,66 +2875,66 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-boolean']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber=type,tonumber
boolean=boolean or {}
local boolean=boolean
function boolean.tonumber(b)
- if b then return 1 else return 0 end
+ if b then return 1 else return 0 end
end
function toboolean(str,tolerant)
- if str==nil then
- return false
- elseif str==false then
- return false
- elseif str==true then
- return true
- elseif str=="true" then
- return true
- elseif str=="false" then
- return false
- elseif not tolerant then
- return false
- elseif str==0 then
- return false
- elseif (tonumber(str) or 0)>0 then
- return true
- else
- return str=="yes" or str=="on" or str=="t"
- end
+ if str==nil then
+ return false
+ elseif str==false then
+ return false
+ elseif str==true then
+ return true
+ elseif str=="true" then
+ return true
+ elseif str=="false" then
+ return false
+ elseif not tolerant then
+ return false
+ elseif str==0 then
+ return false
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
end
string.toboolean=toboolean
function string.booleanstring(str)
- if str=="0" then
- return false
- elseif str=="1" then
- return true
- elseif str=="" then
- return false
- elseif str=="false" then
- return false
- elseif str=="true" then
- return true
- elseif (tonumber(str) or 0)>0 then
- return true
- else
- return str=="yes" or str=="on" or str=="t"
- end
+ if str=="0" then
+ return false
+ elseif str=="1" then
+ return true
+ elseif str=="" then
+ return false
+ elseif str=="false" then
+ return false
+ elseif str=="true" then
+ return true
+ elseif (tonumber(str) or 0)>0 then
+ return true
+ else
+ return str=="yes" or str=="on" or str=="t"
+ end
end
function string.is_boolean(str,default,strict)
- if type(str)=="string" then
- if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
- return true
- elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
- return false
- end
+ if type(str)=="string" then
+ if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then
+ return true
+ elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then
+ return false
end
- return default
+ end
+ return default
end
end -- closure
@@ -2942,90 +2942,90 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-math']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not math.ceiling then
- math.ceiling=math.ceil
+ math.ceiling=math.ceil
end
if not math.round then
- local floor=math.floor
- function math.round(x) return floor(x+0.5) end
+ local floor=math.floor
+ function math.round(x) return floor(x+0.5) end
end
if not math.div then
- local floor=math.floor
- function math.div(n,m) return floor(n/m) end
+ local floor=math.floor
+ function math.div(n,m) return floor(n/m) end
end
if not math.mod then
- function math.mod(n,m) return n%m end
+ function math.mod(n,m) return n%m end
end
if not math.sind then
- local sin,cos,tan=math.sin,math.cos,math.tan
- local pipi=2*math.pi/360
- function math.sind(d) return sin(d*pipi) end
- function math.cosd(d) return cos(d*pipi) end
- function math.tand(d) return tan(d*pipi) end
+ local sin,cos,tan=math.sin,math.cos,math.tan
+ local pipi=2*math.pi/360
+ function math.sind(d) return sin(d*pipi) end
+ function math.cosd(d) return cos(d*pipi) end
+ function math.tand(d) return tan(d*pipi) end
end
if not math.odd then
- function math.odd (n) return n%2~=0 end
- function math.even(n) return n%2==0 end
+ function math.odd (n) return n%2~=0 end
+ function math.even(n) return n%2==0 end
end
if not math.cosh then
- local exp=math.exp
- function math.cosh(x)
- local xx=exp(x)
- return (xx+1/xx)/2
- end
- function math.sinh(x)
- local xx=exp(x)
- return (xx-1/xx)/2
- end
- function math.tanh(x)
- local xx=exp(x)
- return (xx-1/xx)/(xx+1/xx)
- end
+ local exp=math.exp
+ function math.cosh(x)
+ local xx=exp(x)
+ return (xx+1/xx)/2
+ end
+ function math.sinh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/2
+ end
+ function math.tanh(x)
+ local xx=exp(x)
+ return (xx-1/xx)/(xx+1/xx)
+ end
end
if not math.pow then
- function math.pow(x,y)
- return x^y
- end
+ function math.pow(x,y)
+ return x^y
+ end
end
if not math.atan2 then
- math.atan2=math.atan
+ math.atan2=math.atan
end
if not math.ldexp then
- function math.ldexp(x,e)
- return x*2.0^e
- end
+ function math.ldexp(x,e)
+ return x*2.0^e
+ end
end
if not math.log10 then
- local log=math.log
- function math.log10(x)
- return log(x,10)
- end
+ local log=math.log
+ function math.log10(x)
+ return log(x,10)
+ end
end
if not math.type then
- function math.type()
- return "float"
- end
+ function math.type()
+ return "float"
+ end
end
if not math.tointeger then
- math.mininteger=-0x4FFFFFFFFFFF
- math.maxinteger=0x4FFFFFFFFFFF
- local floor=math.floor
- function math.tointeger(n)
- local f=floor(n)
- return f==n and f or nil
- end
+ math.mininteger=-0x4FFFFFFFFFFF
+ math.maxinteger=0x4FFFFFFFFFFF
+ local floor=math.floor
+ function math.tointeger(n)
+ local f=floor(n)
+ return f==n and f or nil
+ end
end
if not math.ult then
- local floor=math.floor
- function math.tointeger(m,n)
- return floor(m)<floor(n)
- end
+ local floor=math.floor
+ function math.tointeger(m,n)
+ return floor(m)<floor(n)
+ end
end
end -- closure
@@ -3033,11 +3033,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['util-str']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
utilities=utilities or {}
utilities.strings=utilities.strings or {}
@@ -3053,17 +3053,17 @@ local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len
local loadstripped=nil
local oldfashioned=LUAVERSION<5.2
if oldfashioned then
- loadstripped=function(str,shortcuts)
- return load(str)
- end
+ loadstripped=function(str,shortcuts)
+ return load(str)
+ end
else
- loadstripped=function(str,shortcuts)
- if shortcuts then
- return load(dump(load(str),true),nil,nil,shortcuts)
- else
- return load(dump(load(str),true))
- end
+ loadstripped=function(str,shortcuts)
+ if shortcuts then
+ return load(dump(load(str),true),nil,nil,shortcuts)
+ else
+ return load(dump(load(str),true))
end
+ end
end
if not number then number={} end
local stripzero=patterns.stripzero
@@ -3081,32 +3081,32 @@ local period=patterns.period
local ptf=1/65536
local bpf=(7200/7227)/65536
local function points(n)
- if n==0 then
- return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
- return "0pt"
- end
- n=n*ptf
- if n%1==0 then
- return format("%ipt",n)
- end
- return lpegmatch(stripzeros,format("%.5fpt",n))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*ptf
+ if n%1==0 then
+ return format("%ipt",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fpt",n))
end
local function basepoints(n)
- if n==0 then
- return "0pt"
- end
- n=tonumber(n)
- if not n or n==0 then
- return "0pt"
- end
- n=n*bpf
- if n%1==0 then
- return format("%ibp",n)
- end
- return lpegmatch(stripzeros,format("%.5fbp",n))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ if not n or n==0 then
+ return "0pt"
+ end
+ n=n*bpf
+ if n%1==0 then
+ return format("%ibp",n)
+ end
+ return lpegmatch(stripzeros,format("%.5fbp",n))
end
number.points=points
number.basepoints=basepoints
@@ -3118,65 +3118,65 @@ local trailing=(anyrubish^1*endofstring)/""
local redundant=rubish^3/"\n"
local pattern=Cs(leading*(trailing+redundant+stripped+anything)^0)
function strings.collapsecrlf(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local repeaters={}
function strings.newrepeater(str,offset)
- offset=offset or 0
- local s=repeaters[str]
- if not s then
- s={}
- repeaters[str]=s
- end
- local t=s[offset]
- if t then
- return t
- end
- t={}
- setmetatable(t,{ __index=function(t,k)
- if not k then
- return ""
- end
- local n=k+offset
- local s=n>0 and rep(str,n) or ""
- t[k]=s
- return s
- end })
- s[offset]=t
+ offset=offset or 0
+ local s=repeaters[str]
+ if not s then
+ s={}
+ repeaters[str]=s
+ end
+ local t=s[offset]
+ if t then
return t
+ end
+ t={}
+ setmetatable(t,{ __index=function(t,k)
+ if not k then
+ return ""
+ end
+ local n=k+offset
+ local s=n>0 and rep(str,n) or ""
+ t[k]=s
+ return s
+ end })
+ s[offset]=t
+ return t
end
local extra,tab,start=0,0,4,0
local nspaces=strings.newrepeater(" ")
string.nspaces=nspaces
local pattern=Carg(1)/function(t)
- extra,tab,start=0,t or 7,1
- end*Cs((
+ extra,tab,start=0,t or 7,1
+ end*Cs((
Cp()*patterns.tab/function(position)
- local current=(position-start+1)+extra
- local spaces=tab-(current-1)%tab
- if spaces>0 then
- extra=extra+spaces-1
- return nspaces[spaces]
- else
- return ""
- end
+ local current=(position-start+1)+extra
+ local spaces=tab-(current-1)%tab
+ if spaces>0 then
+ extra=extra+spaces-1
+ return nspaces[spaces]
+ else
+ return ""
+ end
end+newline*Cp()/function(position)
- extra,start=0,position
+ extra,start=0,position
end+anything
- )^1)
+ )^1)
function strings.tabtospace(str,tab)
- return lpegmatch(pattern,str,1,tab or 7)
+ return lpegmatch(pattern,str,1,tab or 7)
end
function string.utfpadding(s,n)
- if not n or n==0 then
- return ""
- end
- local l=utflen(s)
- if n>0 then
- return nspaces[n-l]
- else
- return nspaces[-n-l]
- end
+ if not n or n==0 then
+ return ""
+ end
+ local l=utflen(s)
+ if n>0 then
+ return nspaces[n-l]
+ else
+ return nspaces[-n-l]
+ end
end
local optionalspace=spacer^0
local nospace=optionalspace/""
@@ -3194,130 +3194,130 @@ local notrailing=noleading*endofstring
local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 )
local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 )
local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 )
-local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
+local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
local p_retain_normal=Cs ((normalline+normalempty )^0 )
local p_retain_collapse=Cs ((normalline+doubleempty )^0 )
local p_retain_noempty=Cs ((normalline+singleempty )^0 )
local striplinepatterns={
- ["prune"]=p_prune_normal,
- ["prune and collapse"]=p_prune_collapse,
- ["prune and no empty"]=p_prune_noempty,
- ["prune and to space"]=p_prune_intospace,
- ["retain"]=p_retain_normal,
- ["retain and collapse"]=p_retain_collapse,
- ["retain and no empty"]=p_retain_noempty,
- ["collapse"]=patterns.collapser,
+ ["prune"]=p_prune_normal,
+ ["prune and collapse"]=p_prune_collapse,
+ ["prune and no empty"]=p_prune_noempty,
+ ["prune and to space"]=p_prune_intospace,
+ ["retain"]=p_retain_normal,
+ ["retain and collapse"]=p_retain_collapse,
+ ["retain and no empty"]=p_retain_noempty,
+ ["collapse"]=patterns.collapser,
}
setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end })
strings.striplinepatterns=striplinepatterns
function strings.striplines(str,how)
- return str and lpegmatch(striplinepatterns[how],str) or str
+ return str and lpegmatch(striplinepatterns[how],str) or str
end
function strings.collapse(str)
- return str and lpegmatch(p_prune_intospace,str) or str
+ return str and lpegmatch(p_prune_intospace,str) or str
end
strings.striplong=strings.striplines
function strings.nice(str)
- str=gsub(str,"[:%-+_]+"," ")
- return str
+ str=gsub(str,"[:%-+_]+"," ")
+ return str
end
local n=0
local sequenced=table.sequenced
function string.autodouble(s,sep)
- if s==nil then
- return '""'
- end
- local t=type(s)
- if t=="number" then
- return tostring(s)
- end
- if t=="table" then
- return ('"'..sequenced(s,sep or ",")..'"')
- end
- return ('"'..tostring(s)..'"')
+ if s==nil then
+ return '""'
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ('"'..sequenced(s,sep or ",")..'"')
+ end
+ return ('"'..tostring(s)..'"')
end
function string.autosingle(s,sep)
- if s==nil then
- return "''"
- end
- local t=type(s)
- if t=="number" then
- return tostring(s)
- end
- if t=="table" then
- return ("'"..sequenced(s,sep or ",").."'")
- end
- return ("'"..tostring(s).."'")
+ if s==nil then
+ return "''"
+ end
+ local t=type(s)
+ if t=="number" then
+ return tostring(s)
+ end
+ if t=="table" then
+ return ("'"..sequenced(s,sep or ",").."'")
+ end
+ return ("'"..tostring(s).."'")
end
local tracedchars={ [0]=
- "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
- "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
- "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
- "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
- "[space]",
+ "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]",
+ "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]",
+ "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]",
+ "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]",
+ "[space]",
}
string.tracedchars=tracedchars
strings.tracers=tracedchars
function string.tracedchar(b)
- if type(b)=="number" then
- return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
- else
- local c=utfbyte(b)
- return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
- end
+ if type(b)=="number" then
+ return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")")
+ else
+ local c=utfbyte(b)
+ return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")")
+ end
end
function number.signed(i)
- if i>0 then
- return "+",i
- else
- return "-",-i
- end
+ if i>0 then
+ return "+",i
+ else
+ return "-",-i
+ end
end
local two=digit*digit
local three=two*digit
local prefix=(Carg(1)*three)^1
local splitter=Cs (
- (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
+ (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2)
)
local splitter3=Cs (
- three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
+ three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit
)
patterns.formattednumber=splitter
function number.formatted(n,sep1,sep2)
- if sep1==false then
- if type(n)=="number" then
- n=tostring(n)
- end
- return lpegmatch(splitter3,n,1,sep2 or ".")
+ if sep1==false then
+ if type(n)=="number" then
+ n=tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n)=="number" then
+ n=format("%0.2f",n)
+ end
+ if sep1==true then
+ return lpegmatch(splitter,n,1,".",",")
+ elseif sep1=="." then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
+ elseif sep1=="," then
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
else
- if type(n)=="number" then
- n=format("%0.2f",n)
- end
- if sep1==true then
- return lpegmatch(splitter,n,1,".",",")
- elseif sep1=="." then
- return lpegmatch(splitter,n,1,sep1,sep2 or ",")
- elseif sep1=="," then
- return lpegmatch(splitter,n,1,sep1,sep2 or ".")
- else
- return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
- end
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
end
+ end
end
local p=Cs(
- P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
- )
+ P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0
+ )
function number.compactfloat(n,fmt)
- if n==0 then
- return "0"
- elseif n==1 then
- return "1"
- end
- n=lpegmatch(p,format(fmt or "%0.3f",n))
- if n=="." or n=="" or n=="-" then
- return "0"
- end
- return n
+ if n==0 then
+ return "0"
+ elseif n==1 then
+ return "1"
+ end
+ n=lpegmatch(p,format(fmt or "%0.3f",n))
+ if n=="." or n=="" or n=="-" then
+ return "0"
+ end
+ return n
end
local zero=P("0")^1/""
local plus=P("+")/""
@@ -3328,41 +3328,41 @@ local exponent=(S("eE")*(plus+Cs((minus*zero^0*endofstring)/"")+minus)*zero^0*(e
local pattern_a=Cs(minus^0*digit^1*(separator/""*trailing+separator*(trailing+digit)^0)*exponent)
local pattern_b=Cs((exponent+anything)^0)
function number.sparseexponent(f,n)
- if not n then
- n=f
- f="%e"
- end
- local tn=type(n)
- if tn=="string" then
- local m=tonumber(n)
- if m then
- return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
- end
- elseif tn=="number" then
- return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ if not n then
+ n=f
+ f="%e"
+ end
+ local tn=type(n)
+ if tn=="string" then
+ local m=tonumber(n)
+ if m then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m))
end
- return tostring(n)
+ elseif tn=="number" then
+ return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n))
+ end
+ return tostring(n)
end
local hf={}
local hs={}
setmetatable(hf,{ __index=function(t,k)
- local v="%."..k.."f"
- t[k]=v
- return v
+ local v="%."..k.."f"
+ t[k]=v
+ return v
end } )
setmetatable(hs,{ __index=function(t,k)
- local v="%"..k.."s"
- t[k]=v
- return v
+ local v="%"..k.."s"
+ t[k]=v
+ return v
end } )
function number.formattedfloat(n,b,a)
- local s=format(hf[a],n)
- local l=(b or 0)+(a or 0)+1
- if #s<l then
- return format(hs[l],s)
- else
- return s
- end
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
end
local template=[[
%s
@@ -3371,7 +3371,7 @@ return function(%s) return %s end
]]
local preamble,environment="",{}
if oldfashioned then
- preamble=[[
+ preamble=[[
local lpeg=lpeg
local type=type
local tostring=tostring
@@ -3397,339 +3397,339 @@ local stripzero=lpeg.patterns.stripzero
local stripzeros=lpeg.patterns.stripzeros
]]
else
- environment={
- global=global or _G,
- lpeg=lpeg,
- type=type,
- tostring=tostring,
- tonumber=tonumber,
- format=string.format,
- concat=table.concat,
- signed=number.signed,
- points=number.points,
- basepoints=number.basepoints,
- utfchar=utf.char,
- utfbyte=utf.byte,
- lpegmatch=lpeg.match,
- nspaces=string.nspaces,
- utfpadding=string.utfpadding,
- tracedchar=string.tracedchar,
- autosingle=string.autosingle,
- autodouble=string.autodouble,
- sequenced=table.sequenced,
- formattednumber=number.formatted,
- sparseexponent=number.sparseexponent,
- formattedfloat=number.formattedfloat,
- stripzero=lpeg.patterns.stripzero,
- stripzeros=lpeg.patterns.stripzeros,
- }
+ environment={
+ global=global or _G,
+ lpeg=lpeg,
+ type=type,
+ tostring=tostring,
+ tonumber=tonumber,
+ format=string.format,
+ concat=table.concat,
+ signed=number.signed,
+ points=number.points,
+ basepoints=number.basepoints,
+ utfchar=utf.char,
+ utfbyte=utf.byte,
+ lpegmatch=lpeg.match,
+ nspaces=string.nspaces,
+ utfpadding=string.utfpadding,
+ tracedchar=string.tracedchar,
+ autosingle=string.autosingle,
+ autodouble=string.autodouble,
+ sequenced=table.sequenced,
+ formattednumber=number.formatted,
+ sparseexponent=number.sparseexponent,
+ formattedfloat=number.formattedfloat,
+ stripzero=lpeg.patterns.stripzero,
+ stripzeros=lpeg.patterns.stripzeros,
+ }
end
local arguments={ "a1" }
setmetatable(arguments,{ __index=function(t,k)
- local v=t[k-1]..",a"..k
- t[k]=v
- return v
- end
+ local v=t[k-1]..",a"..k
+ t[k]=v
+ return v
+ end
})
local prefix_any=C((sign+space+period+digit)^0)
local prefix_sub=(C((sign+digit)^0)+Cc(0))*period*(C((sign+digit)^0)+Cc(0))
local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
local format_s=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',a%s)",f,n)
- else
- return format("(a%s or '')",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("(a%s or '')",n)
+ end
end
local format_S=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',tostring(a%s))",f,n)
- else
- return format("tostring(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',tostring(a%s))",f,n)
+ else
+ return format("tostring(a%s)",n)
+ end
end
local format_right=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
- return format("(a%s or '')",n)
- elseif f>0 then
- return format("utfpadding(a%s,%i)..a%s",n,f,n)
- else
- return format("a%s..utfpadding(a%s,%i)",n,n,f)
- end
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ elseif f>0 then
+ return format("utfpadding(a%s,%i)..a%s",n,f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,f)
+ end
end
local format_left=function(f)
- n=n+1
- f=tonumber(f)
- if not f or f==0 then
- return format("(a%s or '')",n)
- end
- if f<0 then
- return format("utfpadding(a%s,%i)..a%s",n,-f,n)
- else
- return format("a%s..utfpadding(a%s,%i)",n,n,-f)
- end
+ n=n+1
+ f=tonumber(f)
+ if not f or f==0 then
+ return format("(a%s or '')",n)
+ end
+ if f<0 then
+ return format("utfpadding(a%s,%i)..a%s",n,-f,n)
+ else
+ return format("a%s..utfpadding(a%s,%i)",n,n,-f)
+ end
end
local format_q=function()
- n=n+1
- return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
end
local format_Q=function()
- n=n+1
- return format("format('%%q',tostring(a%s))",n)
+ n=n+1
+ return format("format('%%q',tostring(a%s))",n)
end
local format_i=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%si',a%s)",f,n)
- else
- return format("format('%%i',a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%si',a%s)",f,n)
+ else
+ return format("format('%%i',a%s)",n)
+ end
end
local format_d=format_i
local format_I=function(f)
- n=n+1
- return format("format('%%s%%%si',signed(a%s))",f,n)
+ n=n+1
+ return format("format('%%s%%%si',signed(a%s))",f,n)
end
local format_f=function(f)
- n=n+1
- return format("format('%%%sf',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sf',a%s)",f,n)
end
local format_F=function(f)
- n=n+1
- if not f or f=="" then
- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
- else
- return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
- end
+ n=n+1
+ if not f or f=="" then
+ return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n)
+ else
+ return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n)
+ end
end
local format_k=function(b,a)
- n=n+1
- return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
+ n=n+1
+ return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0)
end
local format_g=function(f)
- n=n+1
- return format("format('%%%sg',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sg',a%s)",f,n)
end
local format_G=function(f)
- n=n+1
- return format("format('%%%sG',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sG',a%s)",f,n)
end
local format_e=function(f)
- n=n+1
- return format("format('%%%se',a%s)",f,n)
+ n=n+1
+ return format("format('%%%se',a%s)",f,n)
end
local format_E=function(f)
- n=n+1
- return format("format('%%%sE',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sE',a%s)",f,n)
end
local format_j=function(f)
- n=n+1
- return format("sparseexponent('%%%se',a%s)",f,n)
+ n=n+1
+ return format("sparseexponent('%%%se',a%s)",f,n)
end
local format_J=function(f)
- n=n+1
- return format("sparseexponent('%%%sE',a%s)",f,n)
+ n=n+1
+ return format("sparseexponent('%%%sE',a%s)",f,n)
end
local format_x=function(f)
- n=n+1
- return format("format('%%%sx',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sx',a%s)",f,n)
end
local format_X=function(f)
- n=n+1
- return format("format('%%%sX',a%s)",f,n)
+ n=n+1
+ return format("format('%%%sX',a%s)",f,n)
end
local format_o=function(f)
- n=n+1
- return format("format('%%%so',a%s)",f,n)
+ n=n+1
+ return format("format('%%%so',a%s)",f,n)
end
local format_c=function()
- n=n+1
- return format("utfchar(a%s)",n)
+ n=n+1
+ return format("utfchar(a%s)",n)
end
local format_C=function()
- n=n+1
- return format("tracedchar(a%s)",n)
+ n=n+1
+ return format("tracedchar(a%s)",n)
end
local format_r=function(f)
- n=n+1
- return format("format('%%%s.0f',a%s)",f,n)
+ n=n+1
+ return format("format('%%%s.0f',a%s)",f,n)
end
local format_h=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_H=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_u=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_U=function(f)
- n=n+1
- if f=="-" then
- f=sub(f,2)
- return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- else
- return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
- end
+ n=n+1
+ if f=="-" then
+ f=sub(f,2)
+ return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ else
+ return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n)
+ end
end
local format_p=function()
- n=n+1
- return format("points(a%s)",n)
+ n=n+1
+ return format("points(a%s)",n)
end
local format_b=function()
- n=n+1
- return format("basepoints(a%s)",n)
+ n=n+1
+ return format("basepoints(a%s)",n)
end
local format_t=function(f)
- n=n+1
- if f and f~="" then
- return format("concat(a%s,%q)",n,f)
- else
- return format("concat(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("concat(a%s,%q)",n,f)
+ else
+ return format("concat(a%s)",n)
+ end
end
local format_T=function(f)
- n=n+1
- if f and f~="" then
- return format("sequenced(a%s,%q)",n,f)
- else
- return format("sequenced(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("sequenced(a%s,%q)",n,f)
+ else
+ return format("sequenced(a%s)",n)
+ end
end
local format_l=function()
- n=n+1
- return format("(a%s and 'true' or 'false')",n)
+ n=n+1
+ return format("(a%s and 'true' or 'false')",n)
end
local format_L=function()
- n=n+1
- return format("(a%s and 'TRUE' or 'FALSE')",n)
+ n=n+1
+ return format("(a%s and 'TRUE' or 'FALSE')",n)
end
local format_n=function()
- n=n+1
- return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
+ n=n+1
+ return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n)
end
local format_N=function(f)
- n=n+1
- if not f or f=="" then
- f=".9"
- end
- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
+ n=n+1
+ if not f or f=="" then
+ f=".9"
+ end
+ return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n)
end
local format_a=function(f)
- n=n+1
- if f and f~="" then
- return format("autosingle(a%s,%q)",n,f)
- else
- return format("autosingle(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("autosingle(a%s,%q)",n,f)
+ else
+ return format("autosingle(a%s)",n)
+ end
end
local format_A=function(f)
- n=n+1
- if f and f~="" then
- return format("autodouble(a%s,%q)",n,f)
- else
- return format("autodouble(a%s)",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("autodouble(a%s,%q)",n,f)
+ else
+ return format("autodouble(a%s)",n)
+ end
end
local format_w=function(f)
- n=n+1
- f=tonumber(f)
- if f then
- return format("nspaces[%s+a%s]",f,n)
- else
- return format("nspaces[a%s]",n)
- end
+ n=n+1
+ f=tonumber(f)
+ if f then
+ return format("nspaces[%s+a%s]",f,n)
+ else
+ return format("nspaces[a%s]",n)
+ end
end
local format_W=function(f)
- return format("nspaces[%s]",tonumber(f) or 0)
+ return format("nspaces[%s]",tonumber(f) or 0)
end
local format_m=function(f)
- n=n+1
- if not f or f=="" then
- f=","
- end
- if f=="0" then
- return format([[formattednumber(a%s,false)]],n)
- else
- return format([[formattednumber(a%s,%q,".")]],n,f)
- end
+ n=n+1
+ if not f or f=="" then
+ f=","
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,".")]],n,f)
+ end
end
local format_M=function(f)
- n=n+1
- if not f or f=="" then
- f="."
- end
- if f=="0" then
- return format([[formattednumber(a%s,false)]],n)
- else
- return format([[formattednumber(a%s,%q,",")]],n,f)
- end
+ n=n+1
+ if not f or f=="" then
+ f="."
+ end
+ if f=="0" then
+ return format([[formattednumber(a%s,false)]],n)
+ else
+ return format([[formattednumber(a%s,%q,",")]],n,f)
+ end
end
local format_z=function(f)
- n=n+(tonumber(f) or 1)
- return "''"
+ n=n+(tonumber(f) or 1)
+ return "''"
end
local format_rest=function(s)
- return format("%q",s)
+ return format("%q",s)
end
local format_extension=function(extensions,f,name)
- local extension=extensions[name] or "tostring(%s)"
- local f=tonumber(f) or 1
- local w=find(extension,"%.%.%.")
- if f==0 then
- if w then
- extension=gsub(extension,"%.%.%.","")
- end
- return extension
- elseif f==1 then
- if w then
- extension=gsub(extension,"%.%.%.","%%s")
- end
- n=n+1
- local a="a"..n
- return format(extension,a,a)
- elseif f<0 then
- local a="a"..(n+f+1)
- return format(extension,a,a)
- else
- if w then
- extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
- end
- local t={}
- for i=1,f do
- n=n+1
- t[i]="a"..n
- end
- return format(extension,unpack(t))
+ local extension=extensions[name] or "tostring(%s)"
+ local f=tonumber(f) or 1
+ local w=find(extension,"%.%.%.")
+ if f==0 then
+ if w then
+ extension=gsub(extension,"%.%.%.","")
+ end
+ return extension
+ elseif f==1 then
+ if w then
+ extension=gsub(extension,"%.%.%.","%%s")
+ end
+ n=n+1
+ local a="a"..n
+ return format(extension,a,a)
+ elseif f<0 then
+ local a="a"..(n+f+1)
+ return format(extension,a,a)
+ else
+ if w then
+ extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s")
+ end
+ local t={}
+ for i=1,f do
+ n=n+1
+ t[i]="a"..n
end
+ return format(extension,unpack(t))
+ end
end
local builder=Cs { "start",
- start=(
- (
- P("%")/""*(
- V("!")
+ start=(
+ (
+ P("%")/""*(
+ V("!")
+V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o")
+V("c")+V("C")+V("S")
+V("Q")
@@ -3745,119 +3745,119 @@ local builder=Cs { "start",
+V("z")
+V(">")
+V("<")
- )+V("*")
- )*(endofstring+Carg(1))
- )^0,
- ["s"]=(prefix_any*P("s"))/format_s,
- ["q"]=(prefix_any*P("q"))/format_q,
- ["i"]=(prefix_any*P("i"))/format_i,
- ["d"]=(prefix_any*P("d"))/format_d,
- ["f"]=(prefix_any*P("f"))/format_f,
- ["F"]=(prefix_any*P("F"))/format_F,
- ["g"]=(prefix_any*P("g"))/format_g,
- ["G"]=(prefix_any*P("G"))/format_G,
- ["e"]=(prefix_any*P("e"))/format_e,
- ["E"]=(prefix_any*P("E"))/format_E,
- ["x"]=(prefix_any*P("x"))/format_x,
- ["X"]=(prefix_any*P("X"))/format_X,
- ["o"]=(prefix_any*P("o"))/format_o,
- ["S"]=(prefix_any*P("S"))/format_S,
- ["Q"]=(prefix_any*P("Q"))/format_Q,
- ["n"]=(prefix_any*P("n"))/format_n,
- ["N"]=(prefix_any*P("N"))/format_N,
- ["k"]=(prefix_sub*P("k"))/format_k,
- ["c"]=(prefix_any*P("c"))/format_c,
- ["C"]=(prefix_any*P("C"))/format_C,
- ["r"]=(prefix_any*P("r"))/format_r,
- ["h"]=(prefix_any*P("h"))/format_h,
- ["H"]=(prefix_any*P("H"))/format_H,
- ["u"]=(prefix_any*P("u"))/format_u,
- ["U"]=(prefix_any*P("U"))/format_U,
- ["p"]=(prefix_any*P("p"))/format_p,
- ["b"]=(prefix_any*P("b"))/format_b,
- ["t"]=(prefix_tab*P("t"))/format_t,
- ["T"]=(prefix_tab*P("T"))/format_T,
- ["l"]=(prefix_any*P("l"))/format_l,
- ["L"]=(prefix_any*P("L"))/format_L,
- ["I"]=(prefix_any*P("I"))/format_I,
- ["w"]=(prefix_any*P("w"))/format_w,
- ["W"]=(prefix_any*P("W"))/format_W,
- ["j"]=(prefix_any*P("j"))/format_j,
- ["J"]=(prefix_any*P("J"))/format_J,
- ["m"]=(prefix_any*P("m"))/format_m,
- ["M"]=(prefix_any*P("M"))/format_M,
- ["z"]=(prefix_any*P("z"))/format_z,
- ["a"]=(prefix_any*P("a"))/format_a,
- ["A"]=(prefix_any*P("A"))/format_A,
- ["<"]=(prefix_any*P("<"))/format_left,
- [">"]=(prefix_any*P(">"))/format_right,
- ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
- ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
- ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
+ )+V("*")
+ )*(endofstring+Carg(1))
+ )^0,
+ ["s"]=(prefix_any*P("s"))/format_s,
+ ["q"]=(prefix_any*P("q"))/format_q,
+ ["i"]=(prefix_any*P("i"))/format_i,
+ ["d"]=(prefix_any*P("d"))/format_d,
+ ["f"]=(prefix_any*P("f"))/format_f,
+ ["F"]=(prefix_any*P("F"))/format_F,
+ ["g"]=(prefix_any*P("g"))/format_g,
+ ["G"]=(prefix_any*P("G"))/format_G,
+ ["e"]=(prefix_any*P("e"))/format_e,
+ ["E"]=(prefix_any*P("E"))/format_E,
+ ["x"]=(prefix_any*P("x"))/format_x,
+ ["X"]=(prefix_any*P("X"))/format_X,
+ ["o"]=(prefix_any*P("o"))/format_o,
+ ["S"]=(prefix_any*P("S"))/format_S,
+ ["Q"]=(prefix_any*P("Q"))/format_Q,
+ ["n"]=(prefix_any*P("n"))/format_n,
+ ["N"]=(prefix_any*P("N"))/format_N,
+ ["k"]=(prefix_sub*P("k"))/format_k,
+ ["c"]=(prefix_any*P("c"))/format_c,
+ ["C"]=(prefix_any*P("C"))/format_C,
+ ["r"]=(prefix_any*P("r"))/format_r,
+ ["h"]=(prefix_any*P("h"))/format_h,
+ ["H"]=(prefix_any*P("H"))/format_H,
+ ["u"]=(prefix_any*P("u"))/format_u,
+ ["U"]=(prefix_any*P("U"))/format_U,
+ ["p"]=(prefix_any*P("p"))/format_p,
+ ["b"]=(prefix_any*P("b"))/format_b,
+ ["t"]=(prefix_tab*P("t"))/format_t,
+ ["T"]=(prefix_tab*P("T"))/format_T,
+ ["l"]=(prefix_any*P("l"))/format_l,
+ ["L"]=(prefix_any*P("L"))/format_L,
+ ["I"]=(prefix_any*P("I"))/format_I,
+ ["w"]=(prefix_any*P("w"))/format_w,
+ ["W"]=(prefix_any*P("W"))/format_W,
+ ["j"]=(prefix_any*P("j"))/format_j,
+ ["J"]=(prefix_any*P("J"))/format_J,
+ ["m"]=(prefix_any*P("m"))/format_m,
+ ["M"]=(prefix_any*P("M"))/format_M,
+ ["z"]=(prefix_any*P("z"))/format_z,
+ ["a"]=(prefix_any*P("a"))/format_a,
+ ["A"]=(prefix_any*P("A"))/format_A,
+ ["<"]=(prefix_any*P("<"))/format_left,
+ [">"]=(prefix_any*P(">"))/format_right,
+ ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
+ ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest,
+ ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
}
local xx=setmetatable({},{ __index=function(t,k) local v=format("%02x",k) t[k]=v return v end })
local XX=setmetatable({},{ __index=function(t,k) local v=format("%02X",k) t[k]=v return v end })
local preset={
- ["%02x"]=function(n) return xx[n] end,
- ["%02X"]=function(n) return XX[n] end,
+ ["%02x"]=function(n) return xx[n] end,
+ ["%02X"]=function(n) return XX[n] end,
}
local direct=P("%")*(sign+space+period+digit)^0*S("sqidfgGeExXo")*endofstring/[[local format = string.format return function(str) return format("%0",str) end]]
local function make(t,str)
- local f=preset[str]
- if f then
- return f
- end
- local p=lpegmatch(direct,str)
- if p then
- f=loadstripped(p)()
+ local f=preset[str]
+ if f then
+ return f
+ end
+ local p=lpegmatch(direct,str)
+ if p then
+ f=loadstripped(p)()
+ else
+ n=0
+ p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
+ if n>0 then
+ p=format(template,preamble,t._preamble_,arguments[n],p)
+ f=loadstripped(p,t._environment_)()
else
- n=0
- p=lpegmatch(builder,str,1,t._connector_,t._extensions_)
- if n>0 then
- p=format(template,preamble,t._preamble_,arguments[n],p)
- f=loadstripped(p,t._environment_)()
- else
- f=function() return str end
- end
+ f=function() return str end
end
- t[str]=f
- return f
+ end
+ t[str]=f
+ return f
end
local function use(t,fmt,...)
- return t[fmt](...)
+ return t[fmt](...)
end
strings.formatters={}
if oldfashioned then
- function strings.formatters.new(noconcat)
- local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} }
- setmetatable(t,{ __index=make,__call=use })
- return t
- end
+ function strings.formatters.new(noconcat)
+ local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
+ end
else
- function strings.formatters.new(noconcat)
- local e={}
- for k,v in next,environment do
- e[k]=v
- end
- local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e }
- setmetatable(t,{ __index=make,__call=use })
- return t
+ function strings.formatters.new(noconcat)
+ local e={}
+ for k,v in next,environment do
+ e[k]=v
end
+ local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e }
+ setmetatable(t,{ __index=make,__call=use })
+ return t
+ end
end
local formatters=strings.formatters.new()
string.formatters=formatters
string.formatter=function(str,...) return formatters[str](...) end
local function add(t,name,template,preamble)
- if type(t)=="table" and t._type_=="formatter" then
- t._extensions_[name]=template or "%s"
- if type(preamble)=="string" then
- t._preamble_=preamble.."\n"..t._preamble_
- elseif type(preamble)=="table" then
- for k,v in next,preamble do
- t._environment_[k]=v
- end
- end
+ if type(t)=="table" and t._type_=="formatter" then
+ t._extensions_[name]=template or "%s"
+ if type(preamble)=="string" then
+ t._preamble_=preamble.."\n"..t._preamble_
+ elseif type(preamble)=="table" then
+ for k,v in next,preamble do
+ t._environment_[k]=v
+ end
end
+ end
end
strings.formatters.add=add
patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+anything)^0)
@@ -3865,44 +3865,44 @@ patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+anything)^0)
patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0)
patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"'))
if oldfashioned then
- add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
- add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
- add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
+ add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape")
+ add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape")
+ add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape")
else
- add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape })
- add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
- add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
+ add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape })
+ add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape })
+ add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape })
end
local dquote=patterns.dquote
local equote=patterns.escaped+dquote/'\\"'+1
local cquote=Cc('"')
-local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
+local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
+Cs(cquote*(equote-space)^0*space*equote^0*cquote)
function string.optionalquoted(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local pattern=Cs((newline/(os.newline or "\r")+1)^0)
function string.replacenewlines(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function strings.newcollector()
- local result,r={},0
- return
- function(fmt,str,...)
- r=r+1
- result[r]=str==nil and fmt or formatters[fmt](str,...)
- end,
- function(connector)
- if result then
- local str=concat(result,connector)
- result,r={},0
- return str
- end
- end
+ local result,r={},0
+ return
+ function(fmt,str,...)
+ r=r+1
+ result[r]=str==nil and fmt or formatters[fmt](str,...)
+ end,
+ function(connector)
+ if result then
+ local str=concat(result,connector)
+ result,r={},0
+ return str
+ end
+ end
end
local f_16_16=formatters["%0.5N"]
function number.to16dot16(n)
- return f_16_16(n/65536.0)
+ return f_16_16(n/65536.0)
end
end -- closure
@@ -3910,11 +3910,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['util-fil']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber=tonumber
local byte=string.byte
@@ -3924,280 +3924,280 @@ local files={}
utilities.files=files
local zerobased={}
function files.open(filename,zb)
- local f=io.open(filename,"rb")
- if f then
- zerobased[f]=zb or false
- end
- return f
+ local f=io.open(filename,"rb")
+ if f then
+ zerobased[f]=zb or false
+ end
+ return f
end
function files.close(f)
- zerobased[f]=nil
- f:close()
+ zerobased[f]=nil
+ f:close()
end
function files.size(f)
- local current=f:seek()
- local size=f:seek("end")
- f:seek("set",current)
- return size
+ local current=f:seek()
+ local size=f:seek("end")
+ f:seek("set",current)
+ return size
end
files.getsize=files.size
function files.setposition(f,n)
- if zerobased[f] then
- f:seek("set",n)
- else
- f:seek("set",n-1)
- end
+ if zerobased[f] then
+ f:seek("set",n)
+ else
+ f:seek("set",n-1)
+ end
end
function files.getposition(f)
- if zerobased[f] then
- return f:seek()
- else
- return f:seek()+1
- end
+ if zerobased[f] then
+ return f:seek()
+ else
+ return f:seek()+1
+ end
end
function files.look(f,n,chars)
- local p=f:seek()
- local s=f:read(n)
- f:seek("set",p)
- if chars then
- return s
- else
- return byte(s,1,#s)
- end
+ local p=f:seek()
+ local s=f:read(n)
+ f:seek("set",p)
+ if chars then
+ return s
+ else
+ return byte(s,1,#s)
+ end
end
function files.skip(f,n)
- if n==1 then
- f:read(n)
- else
- f:seek("set",f:seek()+n)
- end
+ if n==1 then
+ f:read(n)
+ else
+ f:seek("set",f:seek()+n)
+ end
end
function files.readbyte(f)
- return byte(f:read(1))
+ return byte(f:read(1))
end
function files.readbytes(f,n)
- return byte(f:read(n),1,n)
+ return byte(f:read(n),1,n)
end
function files.readbytetable(f,n)
- local s=f:read(n or 1)
- return { byte(s,1,#s) }
+ local s=f:read(n or 1)
+ return { byte(s,1,#s) }
end
function files.readchar(f)
- return f:read(1)
+ return f:read(1)
end
function files.readstring(f,n)
- return f:read(n or 1)
+ return f:read(n or 1)
end
-function files.readinteger1(f)
- local n=byte(f:read(1))
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+function files.readinteger1(f)
+ local n=byte(f:read(1))
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-files.readcardinal1=files.readbyte
+files.readcardinal1=files.readbyte
files.readcardinal=files.readcardinal1
files.readinteger=files.readinteger1
files.readsignedbyte=files.readinteger1
function files.readcardinal2(f)
- local a,b=byte(f:read(2),1,2)
- return 0x100*a+b
+ local a,b=byte(f:read(2),1,2)
+ return 0x100*a+b
end
function files.readcardinal2le(f)
- local b,a=byte(f:read(2),1,2)
- return 0x100*a+b
+ local b,a=byte(f:read(2),1,2)
+ return 0x100*a+b
end
function files.readinteger2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function files.readinteger2le(f)
- local b,a=byte(f:read(2),1,2)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local b,a=byte(f:read(2),1,2)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function files.readcardinal3(f)
- local a,b,c=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
+ local a,b,c=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
end
function files.readcardinal3le(f)
- local c,b,a=byte(f:read(3),1,3)
- return 0x10000*a+0x100*b+c
+ local c,b,a=byte(f:read(3),1,3)
+ return 0x10000*a+0x100*b+c
end
function files.readinteger3(f)
- local a,b,c=byte(f:read(3),1,3)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local a,b,c=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function files.readinteger3le(f)
- local c,b,a=byte(f:read(3),1,3)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local c,b,a=byte(f:read(3),1,3)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function files.readcardinal4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local a,b,c,d=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function files.readcardinal4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local d,c,b,a=byte(f:read(4),1,4)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function files.readinteger4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function files.readinteger4le(f)
- local d,c,b,a=byte(f:read(4),1,4)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local d,c,b,a=byte(f:read(4),1,4)
+ if a>=0x80 then
+ return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
+ else
+ return 0x1000000*a+0x10000*b+0x100*c+d
+ end
end
function files.readfixed2(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- tonumber((a-0x100).."."..b)
- else
- tonumber((a ).."."..b)
- end
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function files.readfixed4(f)
- local a,b,c,d=byte(f:read(4),1,4)
- if a>=0x80 then
- tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
- else
- tonumber((0x100*a+b ).."."..(0x100*c+d))
- end
+ local a,b,c,d=byte(f:read(4),1,4)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
end
if bit32 then
- local extract=bit32.extract
- local band=bit32.band
- function files.read2dot14(f)
- local a,b=byte(f:read(2),1,2)
- if a>=0x80 then
- local n=-(0x100*a+b)
- return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- else
- local n=0x100*a+b
- return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
- end
+ local extract=bit32.extract
+ local band=bit32.band
+ function files.read2dot14(f)
+ local a,b=byte(f:read(2),1,2)
+ if a>=0x80 then
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
+ else
+ local n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function files.skipshort(f,n)
- f:read(2*(n or 1))
+ f:read(2*(n or 1))
end
function files.skiplong(f,n)
- f:read(4*(n or 1))
+ f:read(4*(n or 1))
end
if bit32 then
- local rshift=bit32.rshift
- function files.writecardinal2(f,n)
- local a=char(n%256)
- n=rshift(n,8)
- local b=char(n%256)
- f:write(b,a)
- end
-else
- local floor=math.floor
- function files.writecardinal2(f,n)
- local a=char(n%256)
- n=floor(n/256)
- local b=char(n%256)
- f:write(b,a)
- end
-end
-function files.writecardinal4(f,n)
+ local rshift=bit32.rshift
+ function files.writecardinal2(f,n)
local a=char(n%256)
n=rshift(n,8)
local b=char(n%256)
- n=rshift(n,8)
- local c=char(n%256)
- n=rshift(n,8)
- local d=char(n%256)
- f:write(d,c,b,a)
+ f:write(b,a)
+ end
+else
+ local floor=math.floor
+ function files.writecardinal2(f,n)
+ local a=char(n%256)
+ n=floor(n/256)
+ local b=char(n%256)
+ f:write(b,a)
+ end
+end
+function files.writecardinal4(f,n)
+ local a=char(n%256)
+ n=rshift(n,8)
+ local b=char(n%256)
+ n=rshift(n,8)
+ local c=char(n%256)
+ n=rshift(n,8)
+ local d=char(n%256)
+ f:write(d,c,b,a)
end
function files.writestring(f,s)
- f:write(char(byte(s,1,#s)))
+ f:write(char(byte(s,1,#s)))
end
function files.writebyte(f,b)
- f:write(char(b))
+ f:write(char(b))
end
if fio and fio.readcardinal1 then
- files.readcardinal1=fio.readcardinal1
- files.readcardinal2=fio.readcardinal2
- files.readcardinal3=fio.readcardinal3
- files.readcardinal4=fio.readcardinal4
- files.readinteger1=fio.readinteger1
- files.readinteger2=fio.readinteger2
- files.readinteger3=fio.readinteger3
- files.readinteger4=fio.readinteger4
- files.readfixed2=fio.readfixed2
- files.readfixed4=fio.readfixed4
- files.read2dot14=fio.read2dot14
- files.setposition=fio.setposition
- files.getposition=fio.getposition
- files.readbyte=files.readcardinal1
- files.readsignedbyte=files.readinteger1
- files.readcardinal=files.readcardinal1
- files.readinteger=files.readinteger1
- local skipposition=fio.skipposition
- files.skipposition=skipposition
- files.readbytes=fio.readbytes
- files.readbytetable=fio.readbytetable
- function files.skipshort(f,n)
- skipposition(f,2*(n or 1))
- end
- function files.skiplong(f,n)
- skipposition(f,4*(n or 1))
- end
+ files.readcardinal1=fio.readcardinal1
+ files.readcardinal2=fio.readcardinal2
+ files.readcardinal3=fio.readcardinal3
+ files.readcardinal4=fio.readcardinal4
+ files.readinteger1=fio.readinteger1
+ files.readinteger2=fio.readinteger2
+ files.readinteger3=fio.readinteger3
+ files.readinteger4=fio.readinteger4
+ files.readfixed2=fio.readfixed2
+ files.readfixed4=fio.readfixed4
+ files.read2dot14=fio.read2dot14
+ files.setposition=fio.setposition
+ files.getposition=fio.getposition
+ files.readbyte=files.readcardinal1
+ files.readsignedbyte=files.readinteger1
+ files.readcardinal=files.readcardinal1
+ files.readinteger=files.readinteger1
+ local skipposition=fio.skipposition
+ files.skipposition=skipposition
+ files.readbytes=fio.readbytes
+ files.readbytetable=fio.readbytetable
+ function files.skipshort(f,n)
+ skipposition(f,2*(n or 1))
+ end
+ function files.skiplong(f,n)
+ skipposition(f,4*(n or 1))
+ end
end
if fio and fio.readcardinaltable then
- files.readcardinaltable=fio.readcardinaltable
- files.readintegertable=fio.readintegertable
+ files.readcardinaltable=fio.readcardinaltable
+ files.readintegertable=fio.readintegertable
else
- local readcardinal1=files.readcardinal1
- local readcardinal2=files.readcardinal2
- local readcardinal3=files.readcardinal3
- local readcardinal4=files.readcardinal4
- function files.readcardinaltable(f,n,b)
- local t={}
- if b==1 then for i=1,n do t[i]=readcardinal1(f) end
- elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
- elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
- elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
- return t
- end
- local readinteger1=files.readinteger1
- local readinteger2=files.readinteger2
- local readinteger3=files.readinteger3
- local readinteger4=files.readinteger4
- function files.readintegertable(f,n,b)
- local t={}
- if b==1 then for i=1,n do t[i]=readinteger1(f) end
- elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
- elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
- elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
- return t
- end
+ local readcardinal1=files.readcardinal1
+ local readcardinal2=files.readcardinal2
+ local readcardinal3=files.readcardinal3
+ local readcardinal4=files.readcardinal4
+ function files.readcardinaltable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readcardinal1(f) end
+ elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end
+ elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end
+ elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end
+ return t
+ end
+ local readinteger1=files.readinteger1
+ local readinteger2=files.readinteger2
+ local readinteger3=files.readinteger3
+ local readinteger4=files.readinteger4
+ function files.readintegertable(f,n,b)
+ local t={}
+ if b==1 then for i=1,n do t[i]=readinteger1(f) end
+ elseif b==2 then for i=1,n do t[i]=readinteger2(f) end
+ elseif b==3 then for i=1,n do t[i]=readinteger3(f) end
+ elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end
+ return t
+ end
end
end -- closure
@@ -4205,11 +4205,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['luat-basics-gen']={
- version=1.100,
- comment="companion to luatex-*.tex",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if context then
--removed
@@ -4223,365 +4223,365 @@ local floor=math.floor
local dummyfunction=function()
end
local dummyreporter=function(c)
- return function(f,...)
- local r=texio.reporter or texio.write_nl
- if f then
- r(c.." : "..(formatters or format)(f,...))
- else
- r("")
- end
- end
-end
-local dummyreport=function(c,f,...)
+ return function(f,...)
local r=texio.reporter or texio.write_nl
if f then
- r(c.." : "..(formatters or format)(f,...))
+ r(c.." : "..(formatters or format)(f,...))
else
- r("")
+ r("")
end
+ end
+end
+local dummyreport=function(c,f,...)
+ local r=texio.reporter or texio.write_nl
+ if f then
+ r(c.." : "..(formatters or format)(f,...))
+ else
+ r("")
+ end
end
statistics={
- register=dummyfunction,
- starttiming=dummyfunction,
- stoptiming=dummyfunction,
- elapsedtime=nil,
+ register=dummyfunction,
+ starttiming=dummyfunction,
+ stoptiming=dummyfunction,
+ elapsedtime=nil,
}
directives={
- register=dummyfunction,
- enable=dummyfunction,
- disable=dummyfunction,
+ register=dummyfunction,
+ enable=dummyfunction,
+ disable=dummyfunction,
}
trackers={
- register=dummyfunction,
- enable=dummyfunction,
- disable=dummyfunction,
+ register=dummyfunction,
+ enable=dummyfunction,
+ disable=dummyfunction,
}
experiments={
- register=dummyfunction,
- enable=dummyfunction,
- disable=dummyfunction,
+ register=dummyfunction,
+ enable=dummyfunction,
+ disable=dummyfunction,
}
storage={
- register=dummyfunction,
- shared={},
+ register=dummyfunction,
+ shared={},
}
logs={
- new=dummyreporter,
- reporter=dummyreporter,
- messenger=dummyreporter,
- report=dummyreport,
+ new=dummyreporter,
+ reporter=dummyreporter,
+ messenger=dummyreporter,
+ report=dummyreport,
}
callbacks={
- register=function(n,f)
- return callback.register(n,f)
- end,
+ register=function(n,f)
+ return callback.register(n,f)
+ end,
}
utilities=utilities or {}
utilities.storage=utilities.storage or {
- allocate=function(t)
- return t or {}
- end,
- mark=function(t)
- return t or {}
- end,
+ allocate=function(t)
+ return t or {}
+ end,
+ mark=function(t)
+ return t or {}
+ end,
}
utilities.parsers=utilities.parsers or {
- settings_to_array=function(s)
- return split(s,",")
- end,
- settings_to_hash=function(s)
- local t={}
- for k,v in gmatch(s,"([^%s,=]+)=([^%s,]+)") do
- t[k]=v
- end
- return t
- end,
- settings_to_hash_colon_too=function(s)
- local t={}
- for k,v in gmatch(s,"([^%s,=:]+)[=:]([^%s,]+)") do
- t[k]=v
- end
- return t
- end,
+ settings_to_array=function(s)
+ return split(s,",")
+ end,
+ settings_to_hash=function(s)
+ local t={}
+ for k,v in gmatch(s,"([^%s,=]+)=([^%s,]+)") do
+ t[k]=v
+ end
+ return t
+ end,
+ settings_to_hash_colon_too=function(s)
+ local t={}
+ for k,v in gmatch(s,"([^%s,=:]+)[=:]([^%s,]+)") do
+ t[k]=v
+ end
+ return t
+ end,
}
characters=characters or {
- data={}
+ data={}
}
texconfig.kpse_init=true
resolvers=resolvers or {}
local remapper={
- otf="opentype fonts",
- ttf="truetype fonts",
- ttc="truetype fonts",
- cid="cid maps",
- cidmap="cid maps",
- pfb="type1 fonts",
- afm="afm",
- enc="enc files",
- lua="tex",
+ otf="opentype fonts",
+ ttf="truetype fonts",
+ ttc="truetype fonts",
+ cid="cid maps",
+ cidmap="cid maps",
+ pfb="type1 fonts",
+ afm="afm",
+ enc="enc files",
+ lua="tex",
}
function resolvers.findfile(name,fileformat)
- name=gsub(name,"\\","/")
- if not fileformat or fileformat=="" then
- fileformat=file.suffix(name)
- if fileformat=="" then
- fileformat="tex"
- end
- end
- fileformat=lower(fileformat)
- fileformat=remapper[fileformat] or fileformat
- local found=kpse.find_file(name,fileformat)
- if not found or found=="" then
- found=kpse.find_file(name,"other text files")
- end
- return found
+ name=gsub(name,"\\","/")
+ if not fileformat or fileformat=="" then
+ fileformat=file.suffix(name)
+ if fileformat=="" then
+ fileformat="tex"
+ end
+ end
+ fileformat=lower(fileformat)
+ fileformat=remapper[fileformat] or fileformat
+ local found=kpse.find_file(name,fileformat)
+ if not found or found=="" then
+ found=kpse.find_file(name,"other text files")
+ end
+ return found
end
resolvers.findbinfile=resolvers.findfile
function resolvers.loadbinfile(filename,filetype)
- local data=io.loaddata(filename)
- return true,data,#data
+ local data=io.loaddata(filename)
+ return true,data,#data
end
function resolvers.resolve(s)
- return s
+ return s
end
function resolvers.unresolve(s)
- return s
+ return s
end
caches={}
local writable=nil
local readables={}
local usingjit=jit
if not caches.namespace or caches.namespace=="" or caches.namespace=="context" then
- caches.namespace='generic'
+ caches.namespace='generic'
end
do
- local cachepaths=kpse.expand_var('$TEXMFCACHE') or ""
- if cachepaths=="" or cachepaths=="$TEXMFCACHE" then
- cachepaths=kpse.expand_var('$TEXMFVAR') or ""
- end
- if cachepaths=="" or cachepaths=="$TEXMFVAR" then
- cachepaths=kpse.expand_var('$VARTEXMF') or ""
- end
- if cachepaths=="" then
- local fallbacks={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
- for i=1,#fallbacks do
- cachepaths=os.getenv(fallbacks[i]) or ""
- if cachepath~="" and lfs.isdir(cachepath) then
- break
- end
- end
- end
- if cachepaths=="" then
- cachepaths="."
- end
- cachepaths=split(cachepaths,os.type=="windows" and ";" or ":")
- for i=1,#cachepaths do
- local cachepath=cachepaths[i]
- if not lfs.isdir(cachepath) then
- lfs.mkdirs(cachepath)
- if lfs.isdir(cachepath) then
- logs.report("system","creating cache path '%s'",cachepath)
- end
- end
- if file.is_writable(cachepath) then
- writable=file.join(cachepath,"luatex-cache")
- lfs.mkdir(writable)
- writable=file.join(writable,caches.namespace)
- lfs.mkdir(writable)
- break
- end
- end
- for i=1,#cachepaths do
- if file.is_readable(cachepaths[i]) then
- readables[#readables+1]=file.join(cachepaths[i],"luatex-cache",caches.namespace)
- end
- end
- if not writable then
- logs.report("system","no writeable cache path, quiting")
- os.exit()
- elseif #readables==0 then
- logs.report("system","no readable cache path, quiting")
- os.exit()
- elseif #readables==1 and readables[1]==writable then
- logs.report("system","using cache '%s'",writable)
- else
- logs.report("system","using write cache '%s'",writable)
- logs.report("system","using read cache '%s'",table.concat(readables," "))
- end
+ local cachepaths=kpse.expand_var('$TEXMFCACHE') or ""
+ if cachepaths=="" or cachepaths=="$TEXMFCACHE" then
+ cachepaths=kpse.expand_var('$TEXMFVAR') or ""
+ end
+ if cachepaths=="" or cachepaths=="$TEXMFVAR" then
+ cachepaths=kpse.expand_var('$VARTEXMF') or ""
+ end
+ if cachepaths=="" then
+ local fallbacks={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
+ for i=1,#fallbacks do
+ cachepaths=os.getenv(fallbacks[i]) or ""
+ if cachepath~="" and lfs.isdir(cachepath) then
+ break
+ end
+ end
+ end
+ if cachepaths=="" then
+ cachepaths="."
+ end
+ cachepaths=split(cachepaths,os.type=="windows" and ";" or ":")
+ for i=1,#cachepaths do
+ local cachepath=cachepaths[i]
+ if not lfs.isdir(cachepath) then
+ lfs.mkdirs(cachepath)
+ if lfs.isdir(cachepath) then
+ logs.report("system","creating cache path '%s'",cachepath)
+ end
+ end
+ if file.is_writable(cachepath) then
+ writable=file.join(cachepath,"luatex-cache")
+ lfs.mkdir(writable)
+ writable=file.join(writable,caches.namespace)
+ lfs.mkdir(writable)
+ break
+ end
+ end
+ for i=1,#cachepaths do
+ if file.is_readable(cachepaths[i]) then
+ readables[#readables+1]=file.join(cachepaths[i],"luatex-cache",caches.namespace)
+ end
+ end
+ if not writable then
+ logs.report("system","no writeable cache path, quiting")
+ os.exit()
+ elseif #readables==0 then
+ logs.report("system","no readable cache path, quiting")
+ os.exit()
+ elseif #readables==1 and readables[1]==writable then
+ logs.report("system","using cache '%s'",writable)
+ else
+ logs.report("system","using write cache '%s'",writable)
+ logs.report("system","using read cache '%s'",table.concat(readables," "))
+ end
end
function caches.getwritablepath(category,subcategory)
- local path=file.join(writable,category)
- lfs.mkdir(path)
- path=file.join(path,subcategory)
- lfs.mkdir(path)
- return path
+ local path=file.join(writable,category)
+ lfs.mkdir(path)
+ path=file.join(path,subcategory)
+ lfs.mkdir(path)
+ return path
end
function caches.getreadablepaths(category,subcategory)
- local t={}
- for i=1,#readables do
- t[i]=file.join(readables[i],category,subcategory)
- end
- return t
+ local t={}
+ for i=1,#readables do
+ t[i]=file.join(readables[i],category,subcategory)
+ end
+ return t
end
local function makefullname(path,name)
- if path and path~="" then
- return file.addsuffix(file.join(path,name),"lua"),file.addsuffix(file.join(path,name),usingjit and "lub" or "luc")
- end
+ if path and path~="" then
+ return file.addsuffix(file.join(path,name),"lua"),file.addsuffix(file.join(path,name),usingjit and "lub" or "luc")
+ end
end
function caches.is_writable(path,name)
- local fullname=makefullname(path,name)
- return fullname and file.is_writable(fullname)
+ local fullname=makefullname(path,name)
+ return fullname and file.is_writable(fullname)
end
function caches.loaddata(readables,name,writable)
- for i=1,#readables do
- local path=readables[i]
- local loader=false
- local luaname,lucname=makefullname(path,name)
- if lfs.isfile(lucname) then
- logs.report("system","loading luc file '%s'",lucname)
- loader=loadfile(lucname)
- end
- if not loader and lfs.isfile(luaname) then
- local luacrap,lucname=makefullname(writable,name)
- logs.report("system","compiling luc file '%s'",lucname)
- if lfs.isfile(lucname) then
- loader=loadfile(lucname)
- end
- caches.compile(data,luaname,lucname)
- if lfs.isfile(lucname) then
- logs.report("system","loading luc file '%s'",lucname)
- loader=loadfile(lucname)
- else
- logs.report("system","error in loading luc file '%s'",lucname)
- end
- if not loader then
- logs.report("system","loading lua file '%s'",luaname)
- loader=loadfile(luaname)
- else
- logs.report("system","error in loading lua file '%s'",luaname)
- end
- end
- if loader then
- loader=loader()
- collectgarbage("step")
- return loader
- end
- end
- return false
+ for i=1,#readables do
+ local path=readables[i]
+ local loader=false
+ local luaname,lucname=makefullname(path,name)
+ if lfs.isfile(lucname) then
+ logs.report("system","loading luc file '%s'",lucname)
+ loader=loadfile(lucname)
+ end
+ if not loader and lfs.isfile(luaname) then
+ local luacrap,lucname=makefullname(writable,name)
+ logs.report("system","compiling luc file '%s'",lucname)
+ if lfs.isfile(lucname) then
+ loader=loadfile(lucname)
+ end
+ caches.compile(data,luaname,lucname)
+ if lfs.isfile(lucname) then
+ logs.report("system","loading luc file '%s'",lucname)
+ loader=loadfile(lucname)
+ else
+ logs.report("system","error in loading luc file '%s'",lucname)
+ end
+ if not loader then
+ logs.report("system","loading lua file '%s'",luaname)
+ loader=loadfile(luaname)
+ else
+ logs.report("system","error in loading lua file '%s'",luaname)
+ end
+ end
+ if loader then
+ loader=loader()
+ collectgarbage("step")
+ return loader
+ end
+ end
+ return false
end
function caches.savedata(path,name,data)
- local luaname,lucname=makefullname(path,name)
- if luaname then
- logs.report("system","saving lua file '%s'",luaname)
- table.tofile(luaname,data,true)
- if lucname and type(caches.compile)=="function" then
- os.remove(lucname)
- logs.report("system","saving luc file '%s'",lucname)
- caches.compile(data,luaname,lucname)
- end
+ local luaname,lucname=makefullname(path,name)
+ if luaname then
+ logs.report("system","saving lua file '%s'",luaname)
+ table.tofile(luaname,data,true)
+ if lucname and type(caches.compile)=="function" then
+ os.remove(lucname)
+ logs.report("system","saving luc file '%s'",lucname)
+ caches.compile(data,luaname,lucname)
end
+ end
end
function caches.compile(data,luaname,lucname)
- local d=io.loaddata(luaname)
- if not d or d=="" then
- d=table.serialize(data,true)
- end
- if d and d~="" then
- local f=io.open(lucname,'wb')
- if f then
- local s=loadstring(d)
- if s then
- f:write(dump(s,true))
- end
- f:close()
- end
+ local d=io.loaddata(luaname)
+ if not d or d=="" then
+ d=table.serialize(data,true)
+ end
+ if d and d~="" then
+ local f=io.open(lucname,'wb')
+ if f then
+ local s=loadstring(d)
+ if s then
+ f:write(dump(s,true))
+ end
+ f:close()
end
+ end
end
function table.setmetatableindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- if f=="table" then
- f=function(t,k) local v={} t[k]=v return v end
- end
- if m then
- m.__index=f
- else
- setmetatable(t,{ __index=f })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ if f=="table" then
+ f=function(t,k) local v={} t[k]=v return v end
+ end
+ if m then
+ m.__index=f
+ else
+ setmetatable(t,{ __index=f })
+ end
+ return t
end
function table.makeweak(t)
- local m=getmetatable(t)
- if m then
- m.__mode="v"
- else
- setmetatable(t,{ __mode="v" })
- end
- return t
+ local m=getmetatable(t)
+ if m then
+ m.__mode="v"
+ else
+ setmetatable(t,{ __mode="v" })
+ end
+ return t
end
arguments={}
if arg then
- for i=1,#arg do
- local k,v=match(arg[i],"^%-%-([^=]+)=?(.-)$")
- if k and v then
- arguments[k]=v
- end
+ for i=1,#arg do
+ local k,v=match(arg[i],"^%-%-([^=]+)=?(.-)$")
+ if k and v then
+ arguments[k]=v
end
+ end
end
if not number.idiv then
- function number.idiv(i,d)
- return floor(i/d)
- end
+ function number.idiv(i,d)
+ return floor(i/d)
+ end
end
local u=unicode and unicode.utf8
if u then
- utf.lower=u.lower
- utf.upper=u.upper
- utf.char=u.char
- utf.byte=u.byte
- utf.len=u.len
- if lpeg.setutfcasers then
- lpeg.setutfcasers(u.lower,u.upper)
- end
- local bytepairs=string.bytepairs
- local utfchar=utf.char
- local concat=table.concat
- function utf.utf16_to_utf8_be(s)
- if not s then
- return nil
- elseif s=="" then
- return ""
- end
- local result,r,more={},0,0
- for left,right in bytepairs(s) do
- if right then
- local now=256*left+right
- if more>0 then
- now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
- more=0
- r=r+1
- result[r]=utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- else
- r=r+1
- result[r]=utfchar(now)
- end
- end
+ utf.lower=u.lower
+ utf.upper=u.upper
+ utf.char=u.char
+ utf.byte=u.byte
+ utf.len=u.len
+ if lpeg.setutfcasers then
+ lpeg.setutfcasers(u.lower,u.upper)
+ end
+ local bytepairs=string.bytepairs
+ local utfchar=utf.char
+ local concat=table.concat
+ function utf.utf16_to_utf8_be(s)
+ if not s then
+ return nil
+ elseif s=="" then
+ return ""
+ end
+ local result,r,more={},0,0
+ for left,right in bytepairs(s) do
+ if right then
+ local now=256*left+right
+ if more>0 then
+ now=(more-0xD800)*0x400+(now-0xDC00)+0x10000
+ more=0
+ r=r+1
+ result[r]=utfchar(now)
+ elseif now>=0xD800 and now<=0xDBFF then
+ more=now
+ else
+ r=r+1
+ result[r]=utfchar(now)
end
- return concat(result)
+ end
end
- local characters=string.utfcharacters
- function utf.split(str)
- local t,n={},0
- for s in characters(str) do
- n=n+1
- t[n]=s
- end
- return t
+ return concat(result)
+ end
+ local characters=string.utfcharacters
+ function utf.split(str)
+ local t,n={},0
+ for s in characters(str) do
+ n=n+1
+ t[n]=s
end
+ return t
+ end
end
end -- closure
@@ -4589,113 +4589,113 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['data-con']={
- version=1.100,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.100,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,lower,gsub=string.format,string.lower,string.gsub
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
-local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
-local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end)
+local trace_storage=false trackers.register("resolvers.storage",function(v) trace_storage=v end)
containers=containers or {}
local containers=containers
containers.usecache=true
local report_containers=logs.reporter("resolvers","containers")
local allocated={}
local mt={
- __index=function(t,k)
- if k=="writable" then
- local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
- t.writable=writable
- return writable
- elseif k=="readables" then
- local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
- t.readables=readables
- return readables
- end
- end,
- __storage__=true
+ __index=function(t,k)
+ if k=="writable" then
+ local writable=caches.getwritablepath(t.category,t.subcategory) or { "." }
+ t.writable=writable
+ return writable
+ elseif k=="readables" then
+ local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." }
+ t.readables=readables
+ return readables
+ end
+ end,
+ __storage__=true
}
function containers.define(category,subcategory,version,enabled)
- if category and subcategory then
- local c=allocated[category]
- if not c then
- c={}
- allocated[category]=c
- end
- local s=c[subcategory]
- if not s then
- s={
- category=category,
- subcategory=subcategory,
- storage={},
- enabled=enabled,
- version=version or math.pi,
- trace=false,
- }
- setmetatable(s,mt)
- c[subcategory]=s
- end
- return s
+ if category and subcategory then
+ local c=allocated[category]
+ if not c then
+ c={}
+ allocated[category]=c
+ end
+ local s=c[subcategory]
+ if not s then
+ s={
+ category=category,
+ subcategory=subcategory,
+ storage={},
+ enabled=enabled,
+ version=version or math.pi,
+ trace=false,
+ }
+ setmetatable(s,mt)
+ c[subcategory]=s
end
+ return s
+ end
end
function containers.is_usable(container,name)
- return container.enabled and caches and caches.is_writable(container.writable,name)
+ return container.enabled and caches and caches.is_writable(container.writable,name)
end
function containers.is_valid(container,name)
- if name and name~="" then
- local storage=container.storage[name]
- return storage and storage.cache_version==container.version
- else
- return false
- end
+ if name and name~="" then
+ local storage=container.storage[name]
+ return storage and storage.cache_version==container.version
+ else
+ return false
+ end
end
function containers.read(container,name)
- local storage=container.storage
- local stored=storage[name]
- if not stored and container.enabled and caches and containers.usecache then
- stored=caches.loaddata(container.readables,name,container.writable)
- if stored and stored.cache_version==container.version then
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","load",container.subcategory,name)
- end
- else
- stored=nil
- end
- storage[name]=stored
- elseif stored then
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
- end
+ local storage=container.storage
+ local stored=storage[name]
+ if not stored and container.enabled and caches and containers.usecache then
+ stored=caches.loaddata(container.readables,name,container.writable)
+ if stored and stored.cache_version==container.version then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","load",container.subcategory,name)
+ end
+ else
+ stored=nil
end
- return stored
+ storage[name]=stored
+ elseif stored then
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","reuse",container.subcategory,name)
+ end
+ end
+ return stored
end
function containers.write(container,name,data)
- if data then
- data.cache_version=container.version
- if container.enabled and caches then
- local unique,shared=data.unique,data.shared
- data.unique,data.shared=nil,nil
- caches.savedata(container.writable,name,data)
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","save",container.subcategory,name)
- end
- data.unique,data.shared=unique,shared
- end
- if trace_cache or trace_containers then
- report_containers("action %a, category %a, name %a","store",container.subcategory,name)
- end
- container.storage[name]=data
- end
- return data
+ if data then
+ data.cache_version=container.version
+ if container.enabled and caches then
+ local unique,shared=data.unique,data.shared
+ data.unique,data.shared=nil,nil
+ caches.savedata(container.writable,name,data)
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","save",container.subcategory,name)
+ end
+ data.unique,data.shared=unique,shared
+ end
+ if trace_cache or trace_containers then
+ report_containers("action %a, category %a, name %a","store",container.subcategory,name)
+ end
+ container.storage[name]=data
+ end
+ return data
end
function containers.content(container,name)
- return container.storage[name]
+ return container.storage[name]
end
function containers.cleanname(name)
- return (gsub(lower(name),"[^%w\128-\255]+","-"))
+ return (gsub(lower(name),"[^%w\128-\255]+","-"))
end
end -- closure
@@ -4703,37 +4703,37 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['luatex-fonts-nod']={
- version=1.001,
- comment="companion to luatex-fonts.lua",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luatex-fonts.lua",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if context then
--removed
end
if tex.attribute[0]~=0 then
- texio.write_nl("log","!")
- texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be")
- texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special")
- texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.")
- texio.write_nl("log","!")
- tex.attribute[0]=0
+ texio.write_nl("log","!")
+ texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be")
+ texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special")
+ texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.")
+ texio.write_nl("log","!")
+ tex.attribute[0]=0
end
attributes=attributes or {}
attributes.unsetvalue=-0x7FFFFFFF
local numbers,last={},127
attributes.private=attributes.private or function(name)
- local number=numbers[name]
- if not number then
- if last<255 then
- last=last+1
- end
- number=last
- numbers[name]=number
+ local number=numbers[name]
+ if not number then
+ if last<255 then
+ last=last+1
end
- return number
+ number=last
+ numbers[name]=number
+ end
+ return number
end
nodes={}
nodes.handlers={}
@@ -4741,15 +4741,15 @@ local nodecodes={}
local glyphcodes=node.subtypes("glyph")
local disccodes=node.subtypes("disc")
for k,v in next,node.types() do
- v=string.gsub(v,"_","")
- nodecodes[k]=v
- nodecodes[v]=k
+ v=string.gsub(v,"_","")
+ nodecodes[k]=v
+ nodecodes[v]=k
end
for k,v in next,glyphcodes do
- glyphcodes[v]=k
+ glyphcodes[v]=k
end
for k,v in next,disccodes do
- disccodes[v]=k
+ disccodes[v]=k
end
nodes.nodecodes=nodecodes
nodes.glyphcodes=glyphcodes
@@ -4757,23 +4757,23 @@ nodes.disccodes=disccodes
local flush_node=node.flush_node
local remove_node=node.remove
local traverse_id=node.traverse_id
-nodes.handlers.protectglyphs=node.protect_glyphs
+nodes.handlers.protectglyphs=node.protect_glyphs
nodes.handlers.unprotectglyphs=node.unprotect_glyphs
function nodes.remove(head,current,free_too)
- local t=current
- head,current=remove_node(head,current)
- if t then
- if free_too then
- flush_node(t)
- t=nil
- else
- t.next,t.prev=nil,nil
- end
+ local t=current
+ head,current=remove_node(head,current)
+ if t then
+ if free_too then
+ flush_node(t)
+ t=nil
+ else
+ t.next,t.prev=nil,nil
end
- return head,current,t
+ end
+ return head,current,t
end
function nodes.delete(head,current)
- return nodes.remove(head,current,true)
+ return nodes.remove(head,current,true)
end
local getfield=node.getfield
local setfield=node.setfield
@@ -4883,38 +4883,38 @@ nuts.traverse_char=direct.traverse_char
nuts.traverse_glyph=direct.traverse_glyph
nuts.traverse_id=direct.traverse_id
if not nuts.getdirection then
- local getdir=direct.getdir
- function nuts.getdirection(n)
- local d=getdir(n)
- if d=="TLT" then return 0
- elseif d=="TRT" then return 1
- elseif d=="+TLT" then return 0,false
- elseif d=="+TRT" then return 1,false
- elseif d=="-TLT" then return 0,true
- elseif d=="-TRT" then return 1,true
- else return 0
- end
- end
+ local getdir=direct.getdir
+ function nuts.getdirection(n)
+ local d=getdir(n)
+ if d=="TLT" then return 0
+ elseif d=="TRT" then return 1
+ elseif d=="+TLT" then return 0,false
+ elseif d=="+TRT" then return 1,false
+ elseif d=="-TLT" then return 0,true
+ elseif d=="-TRT" then return 1,true
+ else return 0
+ end
+ end
end
local propertydata=direct.get_properties_table()
nodes.properties={ data=propertydata }
-direct.set_properties_mode(true,true)
+direct.set_properties_mode(true,true)
function direct.set_properties_mode() end
nuts.getprop=function(n,k)
- local p=propertydata[n]
- if p then
- return p[k]
- end
+ local p=propertydata[n]
+ if p then
+ return p[k]
+ end
end
nuts.setprop=function(n,k,v)
- if v then
- local p=propertydata[n]
- if p then
- p[k]=v
- else
- propertydata[n]={ [k]=v }
- end
+ if v then
+ local p=propertydata[n]
+ if p then
+ p[k]=v
+ else
+ propertydata[n]={ [k]=v }
end
+ end
end
nodes.setprop=nodes.setproperty
nodes.getprop=nodes.getproperty
@@ -4933,48 +4933,48 @@ local traverse_id=nuts.traverse_id
local copy_node=nuts.copy_node
local glyph_code=nodes.nodecodes.glyph
function nuts.copy_no_components(g,copyinjection)
- local components=getcomponents(g)
- if components then
- setcomponents(g)
- local n=copy_node(g)
- if copyinjection then
- copyinjection(n,g)
- end
- setcomponents(g,components)
- return n
- else
- local n=copy_node(g)
- if copyinjection then
- copyinjection(n,g)
- end
- return n
+ local components=getcomponents(g)
+ if components then
+ setcomponents(g)
+ local n=copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ setcomponents(g,components)
+ return n
+ else
+ local n=copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
end
+ return n
+ end
end
function nuts.copy_only_glyphs(current)
- local head=nil
- local previous=nil
- for n in traverse_id(glyph_code,current) do
- n=copy_node(n)
- if head then
- setlink(previous,n)
- else
- head=n
- end
- previous=n
+ local head=nil
+ local previous=nil
+ for n in traverse_id(glyph_code,current) do
+ n=copy_node(n)
+ if head then
+ setlink(previous,n)
+ else
+ head=n
end
- return head
+ previous=n
+ end
+ return head
end
nuts.uses_font=direct.uses_font
do
- local dummy=tonut(node.new("glyph"))
- nuts.traversers={
- glyph=nuts.traverse_id(nodecodes.glyph,dummy),
- glue=nuts.traverse_id(nodecodes.glue,dummy),
- disc=nuts.traverse_id(nodecodes.disc,dummy),
- boundary=nuts.traverse_id(nodecodes.boundary,dummy),
- char=nuts.traverse_char(dummy),
- node=nuts.traverse(dummy),
- }
+ local dummy=tonut(node.new("glyph"))
+ nuts.traversers={
+ glyph=nuts.traverse_id(nodecodes.glyph,dummy),
+ glue=nuts.traverse_id(nodecodes.glue,dummy),
+ disc=nuts.traverse_id(nodecodes.disc,dummy),
+ boundary=nuts.traverse_id(nodecodes.boundary,dummy),
+ char=nuts.traverse_char(dummy),
+ node=nuts.traverse(dummy),
+ }
end
end -- closure
@@ -7232,989 +7232,989 @@ characters.classifiers={
}
characters.indicgroups={
["above_mark"]={
- [2304]=true,
- [2305]=true,
- [2306]=true,
- [2362]=true,
- [2373]=true,
- [2374]=true,
- [2375]=true,
- [2376]=true,
- [2385]=true,
- [2387]=true,
- [2388]=true,
- [2389]=true,
- [2631]=true,
- [2632]=true,
- [2635]=true,
- [2636]=true,
- [2757]=true,
- [2759]=true,
- [2760]=true,
- [2879]=true,
- [3008]=true,
- [3021]=true,
- [3134]=true,
- [3135]=true,
- [3136]=true,
- [3142]=true,
- [3143]=true,
- [3144]=true,
- [3146]=true,
- [3147]=true,
- [3148]=true,
- [3149]=true,
- [3263]=true,
- [3270]=true,
- [3406]=true,
- [43232]=true,
- [43233]=true,
- [43234]=true,
- [43235]=true,
- [43236]=true,
- [43237]=true,
- [43238]=true,
- [43239]=true,
- [43240]=true,
- [43241]=true,
- [43242]=true,
- [43243]=true,
- [43244]=true,
- [43245]=true,
- [43246]=true,
- [43247]=true,
- [43248]=true,
- [43249]=true,
+ [2304]=true,
+ [2305]=true,
+ [2306]=true,
+ [2362]=true,
+ [2373]=true,
+ [2374]=true,
+ [2375]=true,
+ [2376]=true,
+ [2385]=true,
+ [2387]=true,
+ [2388]=true,
+ [2389]=true,
+ [2631]=true,
+ [2632]=true,
+ [2635]=true,
+ [2636]=true,
+ [2757]=true,
+ [2759]=true,
+ [2760]=true,
+ [2879]=true,
+ [3008]=true,
+ [3021]=true,
+ [3134]=true,
+ [3135]=true,
+ [3136]=true,
+ [3142]=true,
+ [3143]=true,
+ [3144]=true,
+ [3146]=true,
+ [3147]=true,
+ [3148]=true,
+ [3149]=true,
+ [3263]=true,
+ [3270]=true,
+ [3406]=true,
+ [43232]=true,
+ [43233]=true,
+ [43234]=true,
+ [43235]=true,
+ [43236]=true,
+ [43237]=true,
+ [43238]=true,
+ [43239]=true,
+ [43240]=true,
+ [43241]=true,
+ [43242]=true,
+ [43243]=true,
+ [43244]=true,
+ [43245]=true,
+ [43246]=true,
+ [43247]=true,
+ [43248]=true,
+ [43249]=true,
},
["after_half"]={},
["after_main"]={
- [2864]=true,
- [2879]=true,
- [2902]=true,
- [3376]=true,
+ [2864]=true,
+ [2879]=true,
+ [2902]=true,
+ [3376]=true,
},
["after_postscript"]={
- [2433]=true,
- [2494]=true,
- [2496]=true,
- [2519]=true,
- [2561]=true,
- [2562]=true,
- [2622]=true,
- [2624]=true,
- [2625]=true,
- [2626]=true,
- [2672]=true,
- [2673]=true,
- [2750]=true,
- [2752]=true,
- [2753]=true,
- [2754]=true,
- [2755]=true,
- [2756]=true,
- [2761]=true,
- [2763]=true,
- [2764]=true,
- [2786]=true,
- [2787]=true,
- [2878]=true,
- [2880]=true,
- [2903]=true,
- [2992]=true,
- [3006]=true,
- [3007]=true,
- [3009]=true,
- [3010]=true,
- [3031]=true,
- [3120]=true,
- [3248]=true,
- [3390]=true,
- [3391]=true,
- [3392]=true,
- [3393]=true,
- [3394]=true,
- [3395]=true,
- [3415]=true,
+ [2433]=true,
+ [2494]=true,
+ [2496]=true,
+ [2519]=true,
+ [2561]=true,
+ [2562]=true,
+ [2622]=true,
+ [2624]=true,
+ [2625]=true,
+ [2626]=true,
+ [2672]=true,
+ [2673]=true,
+ [2750]=true,
+ [2752]=true,
+ [2753]=true,
+ [2754]=true,
+ [2755]=true,
+ [2756]=true,
+ [2761]=true,
+ [2763]=true,
+ [2764]=true,
+ [2786]=true,
+ [2787]=true,
+ [2878]=true,
+ [2880]=true,
+ [2903]=true,
+ [2992]=true,
+ [3006]=true,
+ [3007]=true,
+ [3009]=true,
+ [3010]=true,
+ [3031]=true,
+ [3120]=true,
+ [3248]=true,
+ [3390]=true,
+ [3391]=true,
+ [3392]=true,
+ [3393]=true,
+ [3394]=true,
+ [3395]=true,
+ [3415]=true,
},
["after_subscript"]={
- [2366]=true,
- [2368]=true,
- [2369]=true,
- [2370]=true,
- [2371]=true,
- [2372]=true,
- [2373]=true,
- [2374]=true,
- [2375]=true,
- [2376]=true,
- [2377]=true,
- [2378]=true,
- [2379]=true,
- [2380]=true,
- [2402]=true,
- [2403]=true,
- [2480]=true,
- [2497]=true,
- [2498]=true,
- [2499]=true,
- [2500]=true,
- [2530]=true,
- [2531]=true,
- [2544]=true,
- [2631]=true,
- [2632]=true,
- [2635]=true,
- [2636]=true,
- [2757]=true,
- [2759]=true,
- [2760]=true,
- [2881]=true,
- [2882]=true,
- [2883]=true,
- [3008]=true,
- [3139]=true,
- [3140]=true,
- [3267]=true,
- [3268]=true,
- [3285]=true,
- [3286]=true,
+ [2366]=true,
+ [2368]=true,
+ [2369]=true,
+ [2370]=true,
+ [2371]=true,
+ [2372]=true,
+ [2373]=true,
+ [2374]=true,
+ [2375]=true,
+ [2376]=true,
+ [2377]=true,
+ [2378]=true,
+ [2379]=true,
+ [2380]=true,
+ [2402]=true,
+ [2403]=true,
+ [2480]=true,
+ [2497]=true,
+ [2498]=true,
+ [2499]=true,
+ [2500]=true,
+ [2530]=true,
+ [2531]=true,
+ [2544]=true,
+ [2631]=true,
+ [2632]=true,
+ [2635]=true,
+ [2636]=true,
+ [2757]=true,
+ [2759]=true,
+ [2760]=true,
+ [2881]=true,
+ [2882]=true,
+ [2883]=true,
+ [3008]=true,
+ [3139]=true,
+ [3140]=true,
+ [3267]=true,
+ [3268]=true,
+ [3285]=true,
+ [3286]=true,
},
["anudatta"]={
- [2386]=true,
+ [2386]=true,
},
["before_half"]={
- [2367]=true,
- [2382]=true,
- [2495]=true,
- [2503]=true,
- [2504]=true,
- [2623]=true,
- [2751]=true,
- [2887]=true,
+ [2367]=true,
+ [2382]=true,
+ [2495]=true,
+ [2503]=true,
+ [2504]=true,
+ [2623]=true,
+ [2751]=true,
+ [2887]=true,
},
["before_main"]={
- [3014]=true,
- [3015]=true,
- [3016]=true,
- [3398]=true,
- [3399]=true,
- [3400]=true,
+ [3014]=true,
+ [3015]=true,
+ [3016]=true,
+ [3398]=true,
+ [3399]=true,
+ [3400]=true,
},
["before_postscript"]={
- [2352]=true,
- [2736]=true,
+ [2352]=true,
+ [2736]=true,
},
["before_subscript"]={
- [2608]=true,
- [2817]=true,
- [3134]=true,
- [3135]=true,
- [3136]=true,
- [3137]=true,
- [3138]=true,
- [3142]=true,
- [3143]=true,
- [3146]=true,
- [3147]=true,
- [3148]=true,
- [3157]=true,
- [3158]=true,
- [3262]=true,
- [3263]=true,
- [3265]=true,
- [3266]=true,
- [3270]=true,
- [3276]=true,
- [3298]=true,
- [3299]=true,
+ [2608]=true,
+ [2817]=true,
+ [3134]=true,
+ [3135]=true,
+ [3136]=true,
+ [3137]=true,
+ [3138]=true,
+ [3142]=true,
+ [3143]=true,
+ [3146]=true,
+ [3147]=true,
+ [3148]=true,
+ [3157]=true,
+ [3158]=true,
+ [3262]=true,
+ [3263]=true,
+ [3265]=true,
+ [3266]=true,
+ [3270]=true,
+ [3276]=true,
+ [3298]=true,
+ [3299]=true,
},
["below_mark"]={
- [2364]=true,
- [2369]=true,
- [2370]=true,
- [2371]=true,
- [2372]=true,
- [2381]=true,
- [2386]=true,
- [2390]=true,
- [2391]=true,
- [2402]=true,
- [2403]=true,
- [2492]=true,
- [2497]=true,
- [2498]=true,
- [2499]=true,
- [2500]=true,
- [2509]=true,
- [2620]=true,
- [2625]=true,
- [2626]=true,
- [2637]=true,
- [2748]=true,
- [2753]=true,
- [2754]=true,
- [2755]=true,
- [2756]=true,
- [2765]=true,
- [2876]=true,
- [2881]=true,
- [2882]=true,
- [2883]=true,
- [2884]=true,
- [2893]=true,
- [2914]=true,
- [2915]=true,
- [3009]=true,
- [3010]=true,
- [3170]=true,
- [3171]=true,
- [3260]=true,
- [3298]=true,
- [3299]=true,
- [3426]=true,
- [3427]=true,
+ [2364]=true,
+ [2369]=true,
+ [2370]=true,
+ [2371]=true,
+ [2372]=true,
+ [2381]=true,
+ [2386]=true,
+ [2390]=true,
+ [2391]=true,
+ [2402]=true,
+ [2403]=true,
+ [2492]=true,
+ [2497]=true,
+ [2498]=true,
+ [2499]=true,
+ [2500]=true,
+ [2509]=true,
+ [2620]=true,
+ [2625]=true,
+ [2626]=true,
+ [2637]=true,
+ [2748]=true,
+ [2753]=true,
+ [2754]=true,
+ [2755]=true,
+ [2756]=true,
+ [2765]=true,
+ [2876]=true,
+ [2881]=true,
+ [2882]=true,
+ [2883]=true,
+ [2884]=true,
+ [2893]=true,
+ [2914]=true,
+ [2915]=true,
+ [3009]=true,
+ [3010]=true,
+ [3170]=true,
+ [3171]=true,
+ [3260]=true,
+ [3298]=true,
+ [3299]=true,
+ [3426]=true,
+ [3427]=true,
},
["consonant"]={
- [2325]=true,
- [2326]=true,
- [2327]=true,
- [2328]=true,
- [2329]=true,
- [2330]=true,
- [2331]=true,
- [2332]=true,
- [2333]=true,
- [2334]=true,
- [2335]=true,
- [2336]=true,
- [2337]=true,
- [2338]=true,
- [2339]=true,
- [2340]=true,
- [2341]=true,
- [2342]=true,
- [2343]=true,
- [2344]=true,
- [2345]=true,
- [2346]=true,
- [2347]=true,
- [2348]=true,
- [2349]=true,
- [2350]=true,
- [2351]=true,
- [2352]=true,
- [2353]=true,
- [2354]=true,
- [2355]=true,
- [2356]=true,
- [2357]=true,
- [2358]=true,
- [2359]=true,
- [2360]=true,
- [2361]=true,
- [2392]=true,
- [2393]=true,
- [2394]=true,
- [2395]=true,
- [2396]=true,
- [2397]=true,
- [2398]=true,
- [2399]=true,
- [2424]=true,
- [2425]=true,
- [2426]=true,
- [2453]=true,
- [2454]=true,
- [2455]=true,
- [2456]=true,
- [2457]=true,
- [2458]=true,
- [2459]=true,
- [2460]=true,
- [2461]=true,
- [2462]=true,
- [2463]=true,
- [2464]=true,
- [2465]=true,
- [2466]=true,
- [2467]=true,
- [2468]=true,
- [2469]=true,
- [2470]=true,
- [2471]=true,
- [2472]=true,
- [2474]=true,
- [2475]=true,
- [2476]=true,
- [2477]=true,
- [2478]=true,
- [2479]=true,
- [2480]=true,
- [2482]=true,
- [2486]=true,
- [2487]=true,
- [2488]=true,
- [2489]=true,
- [2510]=true,
- [2524]=true,
- [2525]=true,
- [2527]=true,
- [2581]=true,
- [2582]=true,
- [2583]=true,
- [2584]=true,
- [2585]=true,
- [2586]=true,
- [2587]=true,
- [2588]=true,
- [2589]=true,
- [2590]=true,
- [2591]=true,
- [2592]=true,
- [2593]=true,
- [2594]=true,
- [2595]=true,
- [2596]=true,
- [2597]=true,
- [2598]=true,
- [2599]=true,
- [2600]=true,
- [2602]=true,
- [2603]=true,
- [2604]=true,
- [2605]=true,
- [2606]=true,
- [2607]=true,
- [2608]=true,
- [2610]=true,
- [2611]=true,
- [2613]=true,
- [2614]=true,
- [2616]=true,
- [2617]=true,
- [2649]=true,
- [2650]=true,
- [2651]=true,
- [2652]=true,
- [2654]=true,
- [2709]=true,
- [2710]=true,
- [2711]=true,
- [2712]=true,
- [2713]=true,
- [2714]=true,
- [2715]=true,
- [2716]=true,
- [2717]=true,
- [2718]=true,
- [2719]=true,
- [2720]=true,
- [2721]=true,
- [2722]=true,
- [2723]=true,
- [2724]=true,
- [2725]=true,
- [2726]=true,
- [2727]=true,
- [2728]=true,
- [2730]=true,
- [2731]=true,
- [2732]=true,
- [2733]=true,
- [2734]=true,
- [2735]=true,
- [2736]=true,
- [2738]=true,
- [2739]=true,
- [2741]=true,
- [2742]=true,
- [2743]=true,
- [2744]=true,
- [2745]=true,
- [2837]=true,
- [2838]=true,
- [2839]=true,
- [2840]=true,
- [2841]=true,
- [2842]=true,
- [2843]=true,
- [2844]=true,
- [2845]=true,
- [2846]=true,
- [2847]=true,
- [2848]=true,
- [2849]=true,
- [2850]=true,
- [2851]=true,
- [2852]=true,
- [2853]=true,
- [2854]=true,
- [2855]=true,
- [2856]=true,
- [2858]=true,
- [2859]=true,
- [2860]=true,
- [2861]=true,
- [2862]=true,
- [2863]=true,
- [2864]=true,
- [2866]=true,
- [2867]=true,
- [2869]=true,
- [2870]=true,
- [2871]=true,
- [2872]=true,
- [2873]=true,
- [2908]=true,
- [2909]=true,
- [2929]=true,
- [2965]=true,
- [2969]=true,
- [2970]=true,
- [2972]=true,
- [2974]=true,
- [2975]=true,
- [2979]=true,
- [2980]=true,
- [2984]=true,
- [2985]=true,
- [2986]=true,
- [2990]=true,
- [2991]=true,
- [2992]=true,
- [2993]=true,
- [2994]=true,
- [2995]=true,
- [2996]=true,
- [2997]=true,
- [2998]=true,
- [2999]=true,
- [3000]=true,
- [3001]=true,
- [3093]=true,
- [3094]=true,
- [3095]=true,
- [3096]=true,
- [3097]=true,
- [3098]=true,
- [3099]=true,
- [3100]=true,
- [3101]=true,
- [3102]=true,
- [3103]=true,
- [3104]=true,
- [3105]=true,
- [3106]=true,
- [3107]=true,
- [3108]=true,
- [3109]=true,
- [3110]=true,
- [3111]=true,
- [3112]=true,
- [3114]=true,
- [3115]=true,
- [3116]=true,
- [3117]=true,
- [3118]=true,
- [3119]=true,
- [3120]=true,
- [3121]=true,
- [3122]=true,
- [3123]=true,
- [3124]=true,
- [3125]=true,
- [3126]=true,
- [3127]=true,
- [3128]=true,
- [3129]=true,
- [3133]=true,
- [3221]=true,
- [3222]=true,
- [3223]=true,
- [3224]=true,
- [3225]=true,
- [3226]=true,
- [3227]=true,
- [3228]=true,
- [3229]=true,
- [3230]=true,
- [3231]=true,
- [3232]=true,
- [3233]=true,
- [3234]=true,
- [3235]=true,
- [3236]=true,
- [3237]=true,
- [3238]=true,
- [3239]=true,
- [3240]=true,
- [3242]=true,
- [3243]=true,
- [3244]=true,
- [3245]=true,
- [3246]=true,
- [3247]=true,
- [3248]=true,
- [3249]=true,
- [3250]=true,
- [3251]=true,
- [3253]=true,
- [3254]=true,
- [3255]=true,
- [3256]=true,
- [3257]=true,
- [3294]=true,
- [3349]=true,
- [3350]=true,
- [3351]=true,
- [3352]=true,
- [3353]=true,
- [3354]=true,
- [3355]=true,
- [3356]=true,
- [3357]=true,
- [3358]=true,
- [3359]=true,
- [3360]=true,
- [3361]=true,
- [3362]=true,
- [3363]=true,
- [3364]=true,
- [3365]=true,
- [3366]=true,
- [3367]=true,
- [3368]=true,
- [3369]=true,
- [3370]=true,
- [3371]=true,
- [3372]=true,
- [3373]=true,
- [3374]=true,
- [3375]=true,
- [3376]=true,
- [3377]=true,
- [3378]=true,
- [3379]=true,
- [3380]=true,
- [3381]=true,
- [3382]=true,
- [3383]=true,
- [3384]=true,
- [3385]=true,
- [3386]=true,
+ [2325]=true,
+ [2326]=true,
+ [2327]=true,
+ [2328]=true,
+ [2329]=true,
+ [2330]=true,
+ [2331]=true,
+ [2332]=true,
+ [2333]=true,
+ [2334]=true,
+ [2335]=true,
+ [2336]=true,
+ [2337]=true,
+ [2338]=true,
+ [2339]=true,
+ [2340]=true,
+ [2341]=true,
+ [2342]=true,
+ [2343]=true,
+ [2344]=true,
+ [2345]=true,
+ [2346]=true,
+ [2347]=true,
+ [2348]=true,
+ [2349]=true,
+ [2350]=true,
+ [2351]=true,
+ [2352]=true,
+ [2353]=true,
+ [2354]=true,
+ [2355]=true,
+ [2356]=true,
+ [2357]=true,
+ [2358]=true,
+ [2359]=true,
+ [2360]=true,
+ [2361]=true,
+ [2392]=true,
+ [2393]=true,
+ [2394]=true,
+ [2395]=true,
+ [2396]=true,
+ [2397]=true,
+ [2398]=true,
+ [2399]=true,
+ [2424]=true,
+ [2425]=true,
+ [2426]=true,
+ [2453]=true,
+ [2454]=true,
+ [2455]=true,
+ [2456]=true,
+ [2457]=true,
+ [2458]=true,
+ [2459]=true,
+ [2460]=true,
+ [2461]=true,
+ [2462]=true,
+ [2463]=true,
+ [2464]=true,
+ [2465]=true,
+ [2466]=true,
+ [2467]=true,
+ [2468]=true,
+ [2469]=true,
+ [2470]=true,
+ [2471]=true,
+ [2472]=true,
+ [2474]=true,
+ [2475]=true,
+ [2476]=true,
+ [2477]=true,
+ [2478]=true,
+ [2479]=true,
+ [2480]=true,
+ [2482]=true,
+ [2486]=true,
+ [2487]=true,
+ [2488]=true,
+ [2489]=true,
+ [2510]=true,
+ [2524]=true,
+ [2525]=true,
+ [2527]=true,
+ [2581]=true,
+ [2582]=true,
+ [2583]=true,
+ [2584]=true,
+ [2585]=true,
+ [2586]=true,
+ [2587]=true,
+ [2588]=true,
+ [2589]=true,
+ [2590]=true,
+ [2591]=true,
+ [2592]=true,
+ [2593]=true,
+ [2594]=true,
+ [2595]=true,
+ [2596]=true,
+ [2597]=true,
+ [2598]=true,
+ [2599]=true,
+ [2600]=true,
+ [2602]=true,
+ [2603]=true,
+ [2604]=true,
+ [2605]=true,
+ [2606]=true,
+ [2607]=true,
+ [2608]=true,
+ [2610]=true,
+ [2611]=true,
+ [2613]=true,
+ [2614]=true,
+ [2616]=true,
+ [2617]=true,
+ [2649]=true,
+ [2650]=true,
+ [2651]=true,
+ [2652]=true,
+ [2654]=true,
+ [2709]=true,
+ [2710]=true,
+ [2711]=true,
+ [2712]=true,
+ [2713]=true,
+ [2714]=true,
+ [2715]=true,
+ [2716]=true,
+ [2717]=true,
+ [2718]=true,
+ [2719]=true,
+ [2720]=true,
+ [2721]=true,
+ [2722]=true,
+ [2723]=true,
+ [2724]=true,
+ [2725]=true,
+ [2726]=true,
+ [2727]=true,
+ [2728]=true,
+ [2730]=true,
+ [2731]=true,
+ [2732]=true,
+ [2733]=true,
+ [2734]=true,
+ [2735]=true,
+ [2736]=true,
+ [2738]=true,
+ [2739]=true,
+ [2741]=true,
+ [2742]=true,
+ [2743]=true,
+ [2744]=true,
+ [2745]=true,
+ [2837]=true,
+ [2838]=true,
+ [2839]=true,
+ [2840]=true,
+ [2841]=true,
+ [2842]=true,
+ [2843]=true,
+ [2844]=true,
+ [2845]=true,
+ [2846]=true,
+ [2847]=true,
+ [2848]=true,
+ [2849]=true,
+ [2850]=true,
+ [2851]=true,
+ [2852]=true,
+ [2853]=true,
+ [2854]=true,
+ [2855]=true,
+ [2856]=true,
+ [2858]=true,
+ [2859]=true,
+ [2860]=true,
+ [2861]=true,
+ [2862]=true,
+ [2863]=true,
+ [2864]=true,
+ [2866]=true,
+ [2867]=true,
+ [2869]=true,
+ [2870]=true,
+ [2871]=true,
+ [2872]=true,
+ [2873]=true,
+ [2908]=true,
+ [2909]=true,
+ [2929]=true,
+ [2965]=true,
+ [2969]=true,
+ [2970]=true,
+ [2972]=true,
+ [2974]=true,
+ [2975]=true,
+ [2979]=true,
+ [2980]=true,
+ [2984]=true,
+ [2985]=true,
+ [2986]=true,
+ [2990]=true,
+ [2991]=true,
+ [2992]=true,
+ [2993]=true,
+ [2994]=true,
+ [2995]=true,
+ [2996]=true,
+ [2997]=true,
+ [2998]=true,
+ [2999]=true,
+ [3000]=true,
+ [3001]=true,
+ [3093]=true,
+ [3094]=true,
+ [3095]=true,
+ [3096]=true,
+ [3097]=true,
+ [3098]=true,
+ [3099]=true,
+ [3100]=true,
+ [3101]=true,
+ [3102]=true,
+ [3103]=true,
+ [3104]=true,
+ [3105]=true,
+ [3106]=true,
+ [3107]=true,
+ [3108]=true,
+ [3109]=true,
+ [3110]=true,
+ [3111]=true,
+ [3112]=true,
+ [3114]=true,
+ [3115]=true,
+ [3116]=true,
+ [3117]=true,
+ [3118]=true,
+ [3119]=true,
+ [3120]=true,
+ [3121]=true,
+ [3122]=true,
+ [3123]=true,
+ [3124]=true,
+ [3125]=true,
+ [3126]=true,
+ [3127]=true,
+ [3128]=true,
+ [3129]=true,
+ [3133]=true,
+ [3221]=true,
+ [3222]=true,
+ [3223]=true,
+ [3224]=true,
+ [3225]=true,
+ [3226]=true,
+ [3227]=true,
+ [3228]=true,
+ [3229]=true,
+ [3230]=true,
+ [3231]=true,
+ [3232]=true,
+ [3233]=true,
+ [3234]=true,
+ [3235]=true,
+ [3236]=true,
+ [3237]=true,
+ [3238]=true,
+ [3239]=true,
+ [3240]=true,
+ [3242]=true,
+ [3243]=true,
+ [3244]=true,
+ [3245]=true,
+ [3246]=true,
+ [3247]=true,
+ [3248]=true,
+ [3249]=true,
+ [3250]=true,
+ [3251]=true,
+ [3253]=true,
+ [3254]=true,
+ [3255]=true,
+ [3256]=true,
+ [3257]=true,
+ [3294]=true,
+ [3349]=true,
+ [3350]=true,
+ [3351]=true,
+ [3352]=true,
+ [3353]=true,
+ [3354]=true,
+ [3355]=true,
+ [3356]=true,
+ [3357]=true,
+ [3358]=true,
+ [3359]=true,
+ [3360]=true,
+ [3361]=true,
+ [3362]=true,
+ [3363]=true,
+ [3364]=true,
+ [3365]=true,
+ [3366]=true,
+ [3367]=true,
+ [3368]=true,
+ [3369]=true,
+ [3370]=true,
+ [3371]=true,
+ [3372]=true,
+ [3373]=true,
+ [3374]=true,
+ [3375]=true,
+ [3376]=true,
+ [3377]=true,
+ [3378]=true,
+ [3379]=true,
+ [3380]=true,
+ [3381]=true,
+ [3382]=true,
+ [3383]=true,
+ [3384]=true,
+ [3385]=true,
+ [3386]=true,
},
["dependent_vowel"]={
- [2362]=true,
- [2363]=true,
- [2366]=true,
- [2367]=true,
- [2368]=true,
- [2369]=true,
- [2370]=true,
- [2371]=true,
- [2372]=true,
- [2373]=true,
- [2374]=true,
- [2375]=true,
- [2376]=true,
- [2377]=true,
- [2378]=true,
- [2379]=true,
- [2380]=true,
- [2382]=true,
- [2383]=true,
- [2389]=true,
- [2390]=true,
- [2391]=true,
- [2402]=true,
- [2403]=true,
- [2494]=true,
- [2495]=true,
- [2496]=true,
- [2497]=true,
- [2498]=true,
- [2499]=true,
- [2500]=true,
- [2503]=true,
- [2504]=true,
- [2622]=true,
- [2623]=true,
- [2624]=true,
- [2625]=true,
- [2626]=true,
- [2631]=true,
- [2632]=true,
- [2635]=true,
- [2636]=true,
- [2750]=true,
- [2751]=true,
- [2752]=true,
- [2753]=true,
- [2754]=true,
- [2755]=true,
- [2756]=true,
- [2757]=true,
- [2759]=true,
- [2760]=true,
- [2761]=true,
- [2763]=true,
- [2764]=true,
- [2878]=true,
- [2879]=true,
- [2880]=true,
- [2881]=true,
- [2882]=true,
- [2883]=true,
- [2884]=true,
- [2887]=true,
- [2888]=true,
- [2891]=true,
- [2892]=true,
- [2914]=true,
- [2915]=true,
- [3006]=true,
- [3007]=true,
- [3008]=true,
- [3009]=true,
- [3010]=true,
- [3014]=true,
- [3015]=true,
- [3016]=true,
- [3018]=true,
- [3019]=true,
- [3020]=true,
- [3134]=true,
- [3135]=true,
- [3136]=true,
- [3137]=true,
- [3138]=true,
- [3139]=true,
- [3140]=true,
- [3142]=true,
- [3143]=true,
- [3144]=true,
- [3146]=true,
- [3147]=true,
- [3148]=true,
- [3170]=true,
- [3171]=true,
- [3262]=true,
- [3263]=true,
- [3264]=true,
- [3265]=true,
- [3266]=true,
- [3267]=true,
- [3268]=true,
- [3270]=true,
- [3271]=true,
- [3272]=true,
- [3274]=true,
- [3275]=true,
- [3276]=true,
- [3298]=true,
- [3299]=true,
- [3390]=true,
- [3391]=true,
- [3392]=true,
- [3393]=true,
- [3394]=true,
- [3395]=true,
- [3396]=true,
- [3398]=true,
- [3399]=true,
- [3400]=true,
- [3402]=true,
- [3403]=true,
- [3404]=true,
- [3415]=true,
- [3426]=true,
- [3427]=true,
+ [2362]=true,
+ [2363]=true,
+ [2366]=true,
+ [2367]=true,
+ [2368]=true,
+ [2369]=true,
+ [2370]=true,
+ [2371]=true,
+ [2372]=true,
+ [2373]=true,
+ [2374]=true,
+ [2375]=true,
+ [2376]=true,
+ [2377]=true,
+ [2378]=true,
+ [2379]=true,
+ [2380]=true,
+ [2382]=true,
+ [2383]=true,
+ [2389]=true,
+ [2390]=true,
+ [2391]=true,
+ [2402]=true,
+ [2403]=true,
+ [2494]=true,
+ [2495]=true,
+ [2496]=true,
+ [2497]=true,
+ [2498]=true,
+ [2499]=true,
+ [2500]=true,
+ [2503]=true,
+ [2504]=true,
+ [2622]=true,
+ [2623]=true,
+ [2624]=true,
+ [2625]=true,
+ [2626]=true,
+ [2631]=true,
+ [2632]=true,
+ [2635]=true,
+ [2636]=true,
+ [2750]=true,
+ [2751]=true,
+ [2752]=true,
+ [2753]=true,
+ [2754]=true,
+ [2755]=true,
+ [2756]=true,
+ [2757]=true,
+ [2759]=true,
+ [2760]=true,
+ [2761]=true,
+ [2763]=true,
+ [2764]=true,
+ [2878]=true,
+ [2879]=true,
+ [2880]=true,
+ [2881]=true,
+ [2882]=true,
+ [2883]=true,
+ [2884]=true,
+ [2887]=true,
+ [2888]=true,
+ [2891]=true,
+ [2892]=true,
+ [2914]=true,
+ [2915]=true,
+ [3006]=true,
+ [3007]=true,
+ [3008]=true,
+ [3009]=true,
+ [3010]=true,
+ [3014]=true,
+ [3015]=true,
+ [3016]=true,
+ [3018]=true,
+ [3019]=true,
+ [3020]=true,
+ [3134]=true,
+ [3135]=true,
+ [3136]=true,
+ [3137]=true,
+ [3138]=true,
+ [3139]=true,
+ [3140]=true,
+ [3142]=true,
+ [3143]=true,
+ [3144]=true,
+ [3146]=true,
+ [3147]=true,
+ [3148]=true,
+ [3170]=true,
+ [3171]=true,
+ [3262]=true,
+ [3263]=true,
+ [3264]=true,
+ [3265]=true,
+ [3266]=true,
+ [3267]=true,
+ [3268]=true,
+ [3270]=true,
+ [3271]=true,
+ [3272]=true,
+ [3274]=true,
+ [3275]=true,
+ [3276]=true,
+ [3298]=true,
+ [3299]=true,
+ [3390]=true,
+ [3391]=true,
+ [3392]=true,
+ [3393]=true,
+ [3394]=true,
+ [3395]=true,
+ [3396]=true,
+ [3398]=true,
+ [3399]=true,
+ [3400]=true,
+ [3402]=true,
+ [3403]=true,
+ [3404]=true,
+ [3415]=true,
+ [3426]=true,
+ [3427]=true,
},
["halant"]={
- [2381]=true,
- [2509]=true,
- [2637]=true,
- [2765]=true,
- [2893]=true,
- [3021]=true,
- [3149]=true,
- [3277]=true,
- [3405]=true,
+ [2381]=true,
+ [2509]=true,
+ [2637]=true,
+ [2765]=true,
+ [2893]=true,
+ [3021]=true,
+ [3149]=true,
+ [3277]=true,
+ [3405]=true,
},
["independent_vowel"]={
- [2308]=true,
- [2309]=true,
- [2310]=true,
- [2311]=true,
- [2312]=true,
- [2313]=true,
- [2314]=true,
- [2315]=true,
- [2316]=true,
- [2317]=true,
- [2318]=true,
- [2319]=true,
- [2320]=true,
- [2321]=true,
- [2322]=true,
- [2323]=true,
- [2324]=true,
- [2400]=true,
- [2401]=true,
- [2418]=true,
- [2419]=true,
- [2420]=true,
- [2421]=true,
- [2422]=true,
- [2423]=true,
- [2437]=true,
- [2438]=true,
- [2439]=true,
- [2440]=true,
- [2441]=true,
- [2442]=true,
- [2443]=true,
- [2444]=true,
- [2447]=true,
- [2448]=true,
- [2451]=true,
- [2452]=true,
- [2528]=true,
- [2529]=true,
- [2530]=true,
- [2531]=true,
- [2565]=true,
- [2566]=true,
- [2567]=true,
- [2568]=true,
- [2569]=true,
- [2570]=true,
- [2575]=true,
- [2576]=true,
- [2579]=true,
- [2580]=true,
- [2693]=true,
- [2694]=true,
- [2695]=true,
- [2696]=true,
- [2697]=true,
- [2698]=true,
- [2699]=true,
- [2700]=true,
- [2701]=true,
- [2703]=true,
- [2704]=true,
- [2705]=true,
- [2707]=true,
- [2708]=true,
- [2784]=true,
- [2785]=true,
- [2786]=true,
- [2787]=true,
- [2821]=true,
- [2822]=true,
- [2823]=true,
- [2824]=true,
- [2825]=true,
- [2826]=true,
- [2827]=true,
- [2828]=true,
- [2831]=true,
- [2832]=true,
- [2835]=true,
- [2836]=true,
- [2912]=true,
- [2913]=true,
- [2949]=true,
- [2950]=true,
- [2951]=true,
- [2952]=true,
- [2953]=true,
- [2954]=true,
- [2958]=true,
- [2959]=true,
- [2960]=true,
- [2962]=true,
- [2963]=true,
- [2964]=true,
- [3077]=true,
- [3078]=true,
- [3079]=true,
- [3080]=true,
- [3081]=true,
- [3082]=true,
- [3083]=true,
- [3084]=true,
- [3086]=true,
- [3087]=true,
- [3088]=true,
- [3090]=true,
- [3091]=true,
- [3092]=true,
- [3168]=true,
- [3169]=true,
- [3205]=true,
- [3206]=true,
- [3207]=true,
- [3208]=true,
- [3209]=true,
- [3210]=true,
- [3211]=true,
- [3212]=true,
- [3214]=true,
- [3215]=true,
- [3216]=true,
- [3218]=true,
- [3219]=true,
- [3220]=true,
- [3296]=true,
- [3297]=true,
- [3333]=true,
- [3334]=true,
- [3335]=true,
- [3336]=true,
- [3337]=true,
- [3338]=true,
- [3339]=true,
- [3340]=true,
- [3342]=true,
- [3343]=true,
- [3344]=true,
- [3346]=true,
- [3347]=true,
- [3348]=true,
- [3423]=true,
- [3424]=true,
- [3425]=true,
+ [2308]=true,
+ [2309]=true,
+ [2310]=true,
+ [2311]=true,
+ [2312]=true,
+ [2313]=true,
+ [2314]=true,
+ [2315]=true,
+ [2316]=true,
+ [2317]=true,
+ [2318]=true,
+ [2319]=true,
+ [2320]=true,
+ [2321]=true,
+ [2322]=true,
+ [2323]=true,
+ [2324]=true,
+ [2400]=true,
+ [2401]=true,
+ [2418]=true,
+ [2419]=true,
+ [2420]=true,
+ [2421]=true,
+ [2422]=true,
+ [2423]=true,
+ [2437]=true,
+ [2438]=true,
+ [2439]=true,
+ [2440]=true,
+ [2441]=true,
+ [2442]=true,
+ [2443]=true,
+ [2444]=true,
+ [2447]=true,
+ [2448]=true,
+ [2451]=true,
+ [2452]=true,
+ [2528]=true,
+ [2529]=true,
+ [2530]=true,
+ [2531]=true,
+ [2565]=true,
+ [2566]=true,
+ [2567]=true,
+ [2568]=true,
+ [2569]=true,
+ [2570]=true,
+ [2575]=true,
+ [2576]=true,
+ [2579]=true,
+ [2580]=true,
+ [2693]=true,
+ [2694]=true,
+ [2695]=true,
+ [2696]=true,
+ [2697]=true,
+ [2698]=true,
+ [2699]=true,
+ [2700]=true,
+ [2701]=true,
+ [2703]=true,
+ [2704]=true,
+ [2705]=true,
+ [2707]=true,
+ [2708]=true,
+ [2784]=true,
+ [2785]=true,
+ [2786]=true,
+ [2787]=true,
+ [2821]=true,
+ [2822]=true,
+ [2823]=true,
+ [2824]=true,
+ [2825]=true,
+ [2826]=true,
+ [2827]=true,
+ [2828]=true,
+ [2831]=true,
+ [2832]=true,
+ [2835]=true,
+ [2836]=true,
+ [2912]=true,
+ [2913]=true,
+ [2949]=true,
+ [2950]=true,
+ [2951]=true,
+ [2952]=true,
+ [2953]=true,
+ [2954]=true,
+ [2958]=true,
+ [2959]=true,
+ [2960]=true,
+ [2962]=true,
+ [2963]=true,
+ [2964]=true,
+ [3077]=true,
+ [3078]=true,
+ [3079]=true,
+ [3080]=true,
+ [3081]=true,
+ [3082]=true,
+ [3083]=true,
+ [3084]=true,
+ [3086]=true,
+ [3087]=true,
+ [3088]=true,
+ [3090]=true,
+ [3091]=true,
+ [3092]=true,
+ [3168]=true,
+ [3169]=true,
+ [3205]=true,
+ [3206]=true,
+ [3207]=true,
+ [3208]=true,
+ [3209]=true,
+ [3210]=true,
+ [3211]=true,
+ [3212]=true,
+ [3214]=true,
+ [3215]=true,
+ [3216]=true,
+ [3218]=true,
+ [3219]=true,
+ [3220]=true,
+ [3296]=true,
+ [3297]=true,
+ [3333]=true,
+ [3334]=true,
+ [3335]=true,
+ [3336]=true,
+ [3337]=true,
+ [3338]=true,
+ [3339]=true,
+ [3340]=true,
+ [3342]=true,
+ [3343]=true,
+ [3344]=true,
+ [3346]=true,
+ [3347]=true,
+ [3348]=true,
+ [3423]=true,
+ [3424]=true,
+ [3425]=true,
},
["nukta"]={
- [2364]=true,
- [2492]=true,
- [2620]=true,
- [2748]=true,
- [2876]=true,
- [3260]=true,
+ [2364]=true,
+ [2492]=true,
+ [2620]=true,
+ [2748]=true,
+ [2876]=true,
+ [3260]=true,
},
["post_mark"]={
- [2307]=true,
- [2363]=true,
- [2366]=true,
- [2368]=true,
- [2377]=true,
- [2378]=true,
- [2379]=true,
- [2380]=true,
- [2383]=true,
- [2494]=true,
- [2496]=true,
- [2503]=true,
- [2504]=true,
- [2622]=true,
- [2624]=true,
- [2750]=true,
- [2752]=true,
- [2761]=true,
- [2763]=true,
- [2764]=true,
- [2878]=true,
- [2880]=true,
- [3006]=true,
- [3007]=true,
- [3137]=true,
- [3138]=true,
- [3139]=true,
- [3140]=true,
- [3262]=true,
- [3264]=true,
- [3265]=true,
- [3266]=true,
- [3267]=true,
- [3268]=true,
- [3271]=true,
- [3272]=true,
- [3274]=true,
- [3275]=true,
- [3276]=true,
- [3390]=true,
- [3391]=true,
- [3392]=true,
- [3393]=true,
- [3394]=true,
- [3395]=true,
- [3396]=true,
- [3415]=true,
+ [2307]=true,
+ [2363]=true,
+ [2366]=true,
+ [2368]=true,
+ [2377]=true,
+ [2378]=true,
+ [2379]=true,
+ [2380]=true,
+ [2383]=true,
+ [2494]=true,
+ [2496]=true,
+ [2503]=true,
+ [2504]=true,
+ [2622]=true,
+ [2624]=true,
+ [2750]=true,
+ [2752]=true,
+ [2761]=true,
+ [2763]=true,
+ [2764]=true,
+ [2878]=true,
+ [2880]=true,
+ [3006]=true,
+ [3007]=true,
+ [3137]=true,
+ [3138]=true,
+ [3139]=true,
+ [3140]=true,
+ [3262]=true,
+ [3264]=true,
+ [3265]=true,
+ [3266]=true,
+ [3267]=true,
+ [3268]=true,
+ [3271]=true,
+ [3272]=true,
+ [3274]=true,
+ [3275]=true,
+ [3276]=true,
+ [3390]=true,
+ [3391]=true,
+ [3392]=true,
+ [3393]=true,
+ [3394]=true,
+ [3395]=true,
+ [3396]=true,
+ [3415]=true,
},
["pre_mark"]={
- [2367]=true,
- [2382]=true,
- [2495]=true,
- [2623]=true,
- [2751]=true,
- [2887]=true,
- [2888]=true,
- [3014]=true,
- [3015]=true,
- [3016]=true,
- [3398]=true,
- [3399]=true,
- [3400]=true,
+ [2367]=true,
+ [2382]=true,
+ [2495]=true,
+ [2623]=true,
+ [2751]=true,
+ [2887]=true,
+ [2888]=true,
+ [3014]=true,
+ [3015]=true,
+ [3016]=true,
+ [3398]=true,
+ [3399]=true,
+ [3400]=true,
},
["ra"]={
- [2352]=true,
- [2480]=true,
- [2608]=true,
- [2736]=true,
- [2864]=true,
- [2992]=true,
- [3120]=true,
- [3248]=true,
- [3376]=true,
+ [2352]=true,
+ [2480]=true,
+ [2608]=true,
+ [2736]=true,
+ [2864]=true,
+ [2992]=true,
+ [3120]=true,
+ [3248]=true,
+ [3376]=true,
},
["stress_tone_mark"]={
- [2385]=true,
- [2386]=true,
- [2387]=true,
- [2388]=true,
- [2507]=true,
- [2508]=true,
- [3277]=true,
- [3405]=true,
+ [2385]=true,
+ [2386]=true,
+ [2387]=true,
+ [2388]=true,
+ [2507]=true,
+ [2508]=true,
+ [3277]=true,
+ [3405]=true,
},
["twopart_mark"]={
- [2891]={ 2887,2878 },
- [2892]={ 2887,2903 },
- [3018]={ 3014,3006 },
- [3019]={ 3015,3006 },
- [3020]={ 3014,3031 },
- [3402]={ 3398,3390 },
- [3403]={ 3399,3390 },
- [3404]={ 3398,3415 },
+ [2891]={ 2887,2878 },
+ [2892]={ 2887,2903 },
+ [3018]={ 3014,3006 },
+ [3019]={ 3015,3006 },
+ [3020]={ 3014,3031 },
+ [3402]={ 3398,3390 },
+ [3403]={ 3399,3390 },
+ [3404]={ 3398,3415 },
},
["vowel_modifier"]={
- [2304]=true,
- [2305]=true,
- [2306]=true,
- [2307]=true,
- [3330]=true,
- [3331]=true,
- [43232]=true,
- [43233]=true,
- [43234]=true,
- [43235]=true,
- [43236]=true,
- [43237]=true,
- [43238]=true,
- [43239]=true,
- [43240]=true,
- [43241]=true,
- [43242]=true,
- [43243]=true,
- [43244]=true,
- [43245]=true,
- [43246]=true,
- [43247]=true,
- [43248]=true,
- [43249]=true,
+ [2304]=true,
+ [2305]=true,
+ [2306]=true,
+ [2307]=true,
+ [3330]=true,
+ [3331]=true,
+ [43232]=true,
+ [43233]=true,
+ [43234]=true,
+ [43235]=true,
+ [43236]=true,
+ [43237]=true,
+ [43238]=true,
+ [43239]=true,
+ [43240]=true,
+ [43241]=true,
+ [43242]=true,
+ [43243]=true,
+ [43244]=true,
+ [43245]=true,
+ [43246]=true,
+ [43247]=true,
+ [43248]=true,
+ [43249]=true,
},
}
@@ -8223,21 +8223,21 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-ini']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local allocate=utilities.storage.allocate
local sortedhash=table.sortedhash
fonts=fonts or {}
local fonts=fonts
local identifiers=allocate()
-fonts.hashes=fonts.hashes or { identifiers=identifiers }
-fonts.tables=fonts.tables or {}
-fonts.helpers=fonts.helpers or {}
-fonts.tracers=fonts.tracers or {}
+fonts.hashes=fonts.hashes or { identifiers=identifiers }
+fonts.tables=fonts.tables or {}
+fonts.helpers=fonts.helpers or {}
+fonts.tracers=fonts.tracers or {}
fonts.specifiers=fonts.specifiers or {}
fonts.analyzers={}
fonts.readers={}
@@ -8249,11 +8249,11 @@ if context then
end
fonts.privateoffsets={
- textbase=0xF0000,
- textextrabase=0xFD000,
- mathextrabase=0xFE000,
- mathbase=0xFF000,
- keepnames=false,
+ textbase=0xF0000,
+ textextrabase=0xFD000,
+ mathextrabase=0xFE000,
+ mathbase=0xFF000,
+ keepnames=false,
}
end -- closure
@@ -8261,11 +8261,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['luatex-font-mis']={
- version=1.001,
- comment="companion to luatex-*.tex",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if context then
--removed
@@ -8278,17 +8278,17 @@ local marks=hashes.marks or {}
hashes.identifiers=identifiers
hashes.marks=marks
table.setmetatableindex(marks,function(t,k)
- if k==true then
- return marks[currentfont()]
- else
- local resources=identifiers[k].resources or {}
- local marks=resources.marks or {}
- t[k]=marks
- return marks
- end
+ if k==true then
+ return marks[currentfont()]
+ else
+ local resources=identifiers[k].resources or {}
+ local marks=resources.marks or {}
+ t[k]=marks
+ return marks
+ end
end)
function font.each()
- return table.sortedhash(fonts.hashes.identifiers)
+ return table.sortedhash(fonts.hashes.identifiers)
end
end -- closure
@@ -8296,11 +8296,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-con']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,tostring,tonumber,rawget=next,tostring,tonumber,rawget
local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find
@@ -8310,8 +8310,8 @@ local derivetable=table.derive
local ioflush=io.flush
local round=math.round
local setmetatable,getmetatable,rawget,rawset=setmetatable,getmetatable,rawget,rawset
-local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
-local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end)
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end)
local report_defining=logs.reporter("fonts","defining")
local fonts=fonts
local constructors=fonts.constructors or {}
@@ -8332,94 +8332,94 @@ constructors.designsizes=designsizes
local loadedfonts=allocate()
constructors.loadedfonts=loadedfonts
local factors={
- pt=65536.0,
- bp=65781.8,
+ pt=65536.0,
+ bp=65781.8,
}
function constructors.setfactor(f)
- constructors.factor=factors[f or 'pt'] or factors.pt
+ constructors.factor=factors[f or 'pt'] or factors.pt
end
constructors.setfactor()
function constructors.scaled(scaledpoints,designsize)
- if scaledpoints<0 then
- local factor=constructors.factor
- if designsize then
- if designsize>factor then
- return (- scaledpoints/1000)*designsize
- else
- return (- scaledpoints/1000)*designsize*factor
- end
- else
- return (- scaledpoints/1000)*10*factor
- end
+ if scaledpoints<0 then
+ local factor=constructors.factor
+ if designsize then
+ if designsize>factor then
+ return (- scaledpoints/1000)*designsize
+ else
+ return (- scaledpoints/1000)*designsize*factor
+ end
else
- return scaledpoints
+ return (- scaledpoints/1000)*10*factor
end
+ else
+ return scaledpoints
+ end
end
function constructors.getprivate(tfmdata)
- local properties=tfmdata.properties
- local private=properties.private
- properties.private=private+1
- return private
+ local properties=tfmdata.properties
+ local private=properties.private
+ properties.private=private+1
+ return private
end
function constructors.setmathparameter(tfmdata,name,value)
- local m=tfmdata.mathparameters
- local c=tfmdata.MathConstants
- if m then
- m[name]=value
- end
- if c and c~=m then
- c[name]=value
- end
+ local m=tfmdata.mathparameters
+ local c=tfmdata.MathConstants
+ if m then
+ m[name]=value
+ end
+ if c and c~=m then
+ c[name]=value
+ end
end
function constructors.getmathparameter(tfmdata,name)
- local p=tfmdata.mathparameters or tfmdata.MathConstants
- if p then
- return p[name]
- end
+ local p=tfmdata.mathparameters or tfmdata.MathConstants
+ if p then
+ return p[name]
+ end
end
function constructors.cleanuptable(tfmdata)
- if constructors.autocleanup and tfmdata.properties.virtualized then
- for k,v in next,tfmdata.characters do
- if v.commands then v.commands=nil end
- end
+ if constructors.autocleanup and tfmdata.properties.virtualized then
+ for k,v in next,tfmdata.characters do
+ if v.commands then v.commands=nil end
end
+ end
end
function constructors.calculatescale(tfmdata,scaledpoints)
- local parameters=tfmdata.parameters
- if scaledpoints<0 then
- scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize)
- end
- return scaledpoints,scaledpoints/(parameters.units or 1000)
+ local parameters=tfmdata.parameters
+ if scaledpoints<0 then
+ scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize)
+ end
+ return scaledpoints,scaledpoints/(parameters.units or 1000)
end
local unscaled={
- ScriptPercentScaleDown=true,
- ScriptScriptPercentScaleDown=true,
- RadicalDegreeBottomRaisePercent=true,
- NoLimitSupFactor=true,
- NoLimitSubFactor=true,
+ ScriptPercentScaleDown=true,
+ ScriptScriptPercentScaleDown=true,
+ RadicalDegreeBottomRaisePercent=true,
+ NoLimitSupFactor=true,
+ NoLimitSubFactor=true,
}
function constructors.assignmathparameters(target,original)
- local mathparameters=original.mathparameters
- if mathparameters and next(mathparameters) then
- local targetparameters=target.parameters
- local targetproperties=target.properties
- local targetmathparameters={}
- local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor
- for name,value in next,mathparameters do
- if unscaled[name] then
- targetmathparameters[name]=value
- else
- targetmathparameters[name]=value*factor
- end
- end
- if not targetmathparameters.FractionDelimiterSize then
- targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size
- end
- if not mathparameters.FractionDelimiterDisplayStyleSize then
- targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size
- end
- target.mathparameters=targetmathparameters
- end
+ local mathparameters=original.mathparameters
+ if mathparameters and next(mathparameters) then
+ local targetparameters=target.parameters
+ local targetproperties=target.properties
+ local targetmathparameters={}
+ local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor
+ for name,value in next,mathparameters do
+ if unscaled[name] then
+ targetmathparameters[name]=value
+ else
+ targetmathparameters[name]=value*factor
+ end
+ end
+ if not targetmathparameters.FractionDelimiterSize then
+ targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size
+ end
+ if not mathparameters.FractionDelimiterDisplayStyleSize then
+ targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size
+ end
+ target.mathparameters=targetmathparameters
+ end
end
function constructors.beforecopyingcharacters(target,original)
end
@@ -8429,1207 +8429,1207 @@ constructors.sharefonts=false
constructors.nofsharedfonts=0
local sharednames={}
function constructors.trytosharefont(target,tfmdata)
- if constructors.sharefonts then
- local characters=target.characters
- local n=1
- local t={ target.psname }
- local u=sortedkeys(characters)
- for i=1,#u do
- local k=u[i]
- n=n+1;t[n]=k
- n=n+1;t[n]=characters[k].index or k
- end
- local h=md5.HEX(concat(t," "))
- local s=sharednames[h]
- if s then
- if trace_defining then
- report_defining("font %a uses backend resources of font %a",target.fullname,s)
- end
- target.fullname=s
- constructors.nofsharedfonts=constructors.nofsharedfonts+1
- target.properties.sharedwith=s
- else
- sharednames[h]=target.fullname
- end
+ if constructors.sharefonts then
+ local characters=target.characters
+ local n=1
+ local t={ target.psname }
+ local u=sortedkeys(characters)
+ for i=1,#u do
+ local k=u[i]
+ n=n+1;t[n]=k
+ n=n+1;t[n]=characters[k].index or k
+ end
+ local h=md5.HEX(concat(t," "))
+ local s=sharednames[h]
+ if s then
+ if trace_defining then
+ report_defining("font %a uses backend resources of font %a",target.fullname,s)
+ end
+ target.fullname=s
+ constructors.nofsharedfonts=constructors.nofsharedfonts+1
+ target.properties.sharedwith=s
+ else
+ sharednames[h]=target.fullname
end
+ end
end
local synonyms={
- exheight="x_height",
- xheight="x_height",
- ex="x_height",
- emwidth="quad",
- em="quad",
- spacestretch="space_stretch",
- stretch="space_stretch",
- spaceshrink="space_shrink",
- shrink="space_shrink",
- extraspace="extra_space",
- xspace="extra_space",
- slantperpoint="slant",
+ exheight="x_height",
+ xheight="x_height",
+ ex="x_height",
+ emwidth="quad",
+ em="quad",
+ spacestretch="space_stretch",
+ stretch="space_stretch",
+ spaceshrink="space_shrink",
+ shrink="space_shrink",
+ extraspace="extra_space",
+ xspace="extra_space",
+ slantperpoint="slant",
}
function constructors.enhanceparameters(parameters)
- local mt=getmetatable(parameters)
- local getter=function(t,k)
- if not k then
- return nil
- end
- local s=synonyms[k]
- if s then
- return rawget(t,s) or (mt and mt[s]) or nil
- end
- if k=="spacing" then
- return {
- width=t.space,
- stretch=t.space_stretch,
- shrink=t.space_shrink,
- extra=t.extra_space,
- }
- end
- return mt and mt[k] or nil
+ local mt=getmetatable(parameters)
+ local getter=function(t,k)
+ if not k then
+ return nil
end
- local setter=function(t,k,v)
- if not k then
- return 0
- end
- local s=synonyms[k]
- if s then
- rawset(t,s,v)
- elseif k=="spacing" then
- if type(v)=="table" then
- rawset(t,"space",v.width or 0)
- rawset(t,"space_stretch",v.stretch or 0)
- rawset(t,"space_shrink",v.shrink or 0)
- rawset(t,"extra_space",v.extra or 0)
- end
- else
- rawset(t,k,v)
- end
+ local s=synonyms[k]
+ if s then
+ return rawget(t,s) or (mt and mt[s]) or nil
+ end
+ if k=="spacing" then
+ return {
+ width=t.space,
+ stretch=t.space_stretch,
+ shrink=t.space_shrink,
+ extra=t.extra_space,
+ }
+ end
+ return mt and mt[k] or nil
+ end
+ local setter=function(t,k,v)
+ if not k then
+ return 0
+ end
+ local s=synonyms[k]
+ if s then
+ rawset(t,s,v)
+ elseif k=="spacing" then
+ if type(v)=="table" then
+ rawset(t,"space",v.width or 0)
+ rawset(t,"space_stretch",v.stretch or 0)
+ rawset(t,"space_shrink",v.shrink or 0)
+ rawset(t,"extra_space",v.extra or 0)
+ end
+ else
+ rawset(t,k,v)
end
- setmetatable(parameters,{
- __index=getter,
- __newindex=setter,
- })
+ end
+ setmetatable(parameters,{
+ __index=getter,
+ __newindex=setter,
+ })
end
local function mathkerns(v,vdelta)
- local k={}
- for i=1,#v do
- local entry=v[i]
- local height=entry.height
- local kern=entry.kern
- k[i]={
- height=height and vdelta*height or 0,
- kern=kern and vdelta*kern or 0,
- }
- end
- return k
+ local k={}
+ for i=1,#v do
+ local entry=v[i]
+ local height=entry.height
+ local kern=entry.kern
+ k[i]={
+ height=height and vdelta*height or 0,
+ kern=kern and vdelta*kern or 0,
+ }
+ end
+ return k
end
local psfake=0
local function fixedpsname(psname,fallback)
- local usedname=psname
- if psname and psname~="" then
- if find(psname," ",1,true) then
- usedname=gsub(psname,"[%s]+","-")
- else
- end
- elseif not fallback or fallback=="" then
- psfake=psfake+1
- psname="fakename-"..psfake
+ local usedname=psname
+ if psname and psname~="" then
+ if find(psname," ",1,true) then
+ usedname=gsub(psname,"[%s]+","-")
else
- psname=fallback
- usedname=gsub(psname,"[^a-zA-Z0-9]+","-")
end
- return usedname,psname~=usedname
+ elseif not fallback or fallback=="" then
+ psfake=psfake+1
+ psname="fakename-"..psfake
+ else
+ psname=fallback
+ usedname=gsub(psname,"[^a-zA-Z0-9]+","-")
+ end
+ return usedname,psname~=usedname
end
function constructors.scale(tfmdata,specification)
- local target={}
- if tonumber(specification) then
- specification={ size=specification }
- end
- target.specification=specification
- local scaledpoints=specification.size
- local relativeid=specification.relativeid
- local properties=tfmdata.properties or {}
- local goodies=tfmdata.goodies or {}
- local resources=tfmdata.resources or {}
- local descriptions=tfmdata.descriptions or {}
- local characters=tfmdata.characters or {}
- local changed=tfmdata.changed or {}
- local shared=tfmdata.shared or {}
- local parameters=tfmdata.parameters or {}
- local mathparameters=tfmdata.mathparameters or {}
- local targetcharacters={}
- local targetdescriptions=derivetable(descriptions)
- local targetparameters=derivetable(parameters)
- local targetproperties=derivetable(properties)
- local targetgoodies=goodies
- target.characters=targetcharacters
- target.descriptions=targetdescriptions
- target.parameters=targetparameters
- target.properties=targetproperties
- target.goodies=targetgoodies
- target.shared=shared
- target.resources=resources
- target.unscaled=tfmdata
- local mathsize=tonumber(specification.mathsize) or 0
- local textsize=tonumber(specification.textsize) or scaledpoints
- local forcedsize=tonumber(parameters.mathsize ) or 0
- local extrafactor=tonumber(specification.factor ) or 1
- if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then
- scaledpoints=parameters.scriptpercentage*textsize/100
- elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then
- scaledpoints=parameters.scriptscriptpercentage*textsize/100
- elseif forcedsize>1000 then
- scaledpoints=forcedsize
- else
- end
- targetparameters.mathsize=mathsize
- targetparameters.textsize=textsize
- targetparameters.forcedsize=forcedsize
- targetparameters.extrafactor=extrafactor
- local tounicode=fonts.mappings.tounicode
- local unknowncode=tounicode(0xFFFD)
- local defaultwidth=resources.defaultwidth or 0
- local defaultheight=resources.defaultheight or 0
- local defaultdepth=resources.defaultdepth or 0
- local units=parameters.units or 1000
- targetproperties.language=properties.language or "dflt"
- targetproperties.script=properties.script or "dflt"
- targetproperties.mode=properties.mode or "base"
- local askedscaledpoints=scaledpoints
- local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification)
- local hdelta=delta
- local vdelta=delta
- target.designsize=parameters.designsize
- target.units=units
- target.units_per_em=units
- local direction=properties.direction or tfmdata.direction or 0
- target.direction=direction
- properties.direction=direction
- target.size=scaledpoints
- target.encodingbytes=properties.encodingbytes or 1
- target.embedding=properties.embedding or "subset"
- target.tounicode=1
- target.cidinfo=properties.cidinfo
- target.format=properties.format
- target.cache=constructors.cacheintex and "yes" or "renew"
- local fontname=properties.fontname or tfmdata.fontname
- local fullname=properties.fullname or tfmdata.fullname
- local filename=properties.filename or tfmdata.filename
- local psname=properties.psname or tfmdata.psname
- local name=properties.name or tfmdata.name
- local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename))
- target.fontname=fontname
- target.fullname=fullname
- target.filename=filename
- target.psname=psname
- target.name=name
- properties.fontname=fontname
- properties.fullname=fullname
- properties.filename=filename
- properties.psname=psname
- properties.name=name
- local expansion=parameters.expansion
- if expansion then
- target.stretch=expansion.stretch
- target.shrink=expansion.shrink
- target.step=expansion.step
- end
- local slantfactor=parameters.slantfactor or 0
- if slantfactor~=0 then
- target.slant=slantfactor*1000
+ local target={}
+ if tonumber(specification) then
+ specification={ size=specification }
+ end
+ target.specification=specification
+ local scaledpoints=specification.size
+ local relativeid=specification.relativeid
+ local properties=tfmdata.properties or {}
+ local goodies=tfmdata.goodies or {}
+ local resources=tfmdata.resources or {}
+ local descriptions=tfmdata.descriptions or {}
+ local characters=tfmdata.characters or {}
+ local changed=tfmdata.changed or {}
+ local shared=tfmdata.shared or {}
+ local parameters=tfmdata.parameters or {}
+ local mathparameters=tfmdata.mathparameters or {}
+ local targetcharacters={}
+ local targetdescriptions=derivetable(descriptions)
+ local targetparameters=derivetable(parameters)
+ local targetproperties=derivetable(properties)
+ local targetgoodies=goodies
+ target.characters=targetcharacters
+ target.descriptions=targetdescriptions
+ target.parameters=targetparameters
+ target.properties=targetproperties
+ target.goodies=targetgoodies
+ target.shared=shared
+ target.resources=resources
+ target.unscaled=tfmdata
+ local mathsize=tonumber(specification.mathsize) or 0
+ local textsize=tonumber(specification.textsize) or scaledpoints
+ local forcedsize=tonumber(parameters.mathsize ) or 0
+ local extrafactor=tonumber(specification.factor ) or 1
+ if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then
+ scaledpoints=parameters.scriptpercentage*textsize/100
+ elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then
+ scaledpoints=parameters.scriptscriptpercentage*textsize/100
+ elseif forcedsize>1000 then
+ scaledpoints=forcedsize
+ else
+ end
+ targetparameters.mathsize=mathsize
+ targetparameters.textsize=textsize
+ targetparameters.forcedsize=forcedsize
+ targetparameters.extrafactor=extrafactor
+ local tounicode=fonts.mappings.tounicode
+ local unknowncode=tounicode(0xFFFD)
+ local defaultwidth=resources.defaultwidth or 0
+ local defaultheight=resources.defaultheight or 0
+ local defaultdepth=resources.defaultdepth or 0
+ local units=parameters.units or 1000
+ targetproperties.language=properties.language or "dflt"
+ targetproperties.script=properties.script or "dflt"
+ targetproperties.mode=properties.mode or "base"
+ local askedscaledpoints=scaledpoints
+ local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification)
+ local hdelta=delta
+ local vdelta=delta
+ target.designsize=parameters.designsize
+ target.units=units
+ target.units_per_em=units
+ local direction=properties.direction or tfmdata.direction or 0
+ target.direction=direction
+ properties.direction=direction
+ target.size=scaledpoints
+ target.encodingbytes=properties.encodingbytes or 1
+ target.embedding=properties.embedding or "subset"
+ target.tounicode=1
+ target.cidinfo=properties.cidinfo
+ target.format=properties.format
+ target.cache=constructors.cacheintex and "yes" or "renew"
+ local fontname=properties.fontname or tfmdata.fontname
+ local fullname=properties.fullname or tfmdata.fullname
+ local filename=properties.filename or tfmdata.filename
+ local psname=properties.psname or tfmdata.psname
+ local name=properties.name or tfmdata.name
+ local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename))
+ target.fontname=fontname
+ target.fullname=fullname
+ target.filename=filename
+ target.psname=psname
+ target.name=name
+ properties.fontname=fontname
+ properties.fullname=fullname
+ properties.filename=filename
+ properties.psname=psname
+ properties.name=name
+ local expansion=parameters.expansion
+ if expansion then
+ target.stretch=expansion.stretch
+ target.shrink=expansion.shrink
+ target.step=expansion.step
+ end
+ local slantfactor=parameters.slantfactor or 0
+ if slantfactor~=0 then
+ target.slant=slantfactor*1000
+ else
+ target.slant=0
+ end
+ local extendfactor=parameters.extendfactor or 0
+ if extendfactor~=0 and extendfactor~=1 then
+ hdelta=hdelta*extendfactor
+ target.extend=extendfactor*1000
+ else
+ target.extend=1000
+ end
+ local squeezefactor=parameters.squeezefactor or 0
+ if squeezefactor~=0 and squeezefactor~=1 then
+ vdelta=vdelta*squeezefactor
+ target.squeeze=squeezefactor*1000
+ else
+ target.squeeze=1000
+ end
+ local mode=parameters.mode or 0
+ if mode~=0 then
+ target.mode=mode
+ end
+ local width=parameters.width or 0
+ if width~=0 then
+ target.width=width*delta*1000/655360
+ end
+ targetparameters.factor=delta
+ targetparameters.hfactor=hdelta
+ targetparameters.vfactor=vdelta
+ targetparameters.size=scaledpoints
+ targetparameters.units=units
+ targetparameters.scaledpoints=askedscaledpoints
+ targetparameters.mode=mode
+ targetparameters.width=width
+ local isvirtual=properties.virtualized or tfmdata.type=="virtual"
+ local hasquality=parameters.expansion or parameters.protrusion
+ local hasitalics=properties.hasitalics
+ local autoitalicamount=properties.autoitalicamount
+ local stackmath=not properties.nostackmath
+ local nonames=properties.noglyphnames
+ local haskerns=properties.haskerns or properties.mode=="base"
+ local hasligatures=properties.hasligatures or properties.mode=="base"
+ local realdimensions=properties.realdimensions
+ local writingmode=properties.writingmode or "horizontal"
+ local identity=properties.identity or "horizontal"
+ local vfonts=target.fonts
+ if vfonts and #vfonts>0 then
+ target.fonts=fastcopy(vfonts)
+ elseif isvirtual then
+ target.fonts={ { id=0 } }
+ end
+ if changed and not next(changed) then
+ changed=false
+ end
+ target.type=isvirtual and "virtual" or "real"
+ target.writingmode=writingmode=="vertical" and "vertical" or "horizontal"
+ target.identity=identity=="vertical" and "vertical" or "horizontal"
+ target.postprocessors=tfmdata.postprocessors
+ local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt
+ local targetspace=(parameters.space or parameters[2] or 0)*hdelta
+ local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta
+ local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta
+ local targetx_height=(parameters.x_height or parameters[5] or 0)*vdelta
+ local targetquad=(parameters.quad or parameters[6] or 0)*hdelta
+ local targetextra_space=(parameters.extra_space or parameters[7] or 0)*hdelta
+ targetparameters.slant=targetslant
+ targetparameters.space=targetspace
+ targetparameters.space_stretch=targetspace_stretch
+ targetparameters.space_shrink=targetspace_shrink
+ targetparameters.x_height=targetx_height
+ targetparameters.quad=targetquad
+ targetparameters.extra_space=targetextra_space
+ local ascender=parameters.ascender
+ if ascender then
+ targetparameters.ascender=delta*ascender
+ end
+ local descender=parameters.descender
+ if descender then
+ targetparameters.descender=delta*descender
+ end
+ constructors.enhanceparameters(targetparameters)
+ local protrusionfactor=(targetquad~=0 and 1000/targetquad) or 0
+ local scaledwidth=defaultwidth*hdelta
+ local scaledheight=defaultheight*vdelta
+ local scaleddepth=defaultdepth*vdelta
+ local hasmath=(properties.hasmath or next(mathparameters)) and true
+ if hasmath then
+ constructors.assignmathparameters(target,tfmdata)
+ properties.hasmath=true
+ target.nomath=false
+ target.MathConstants=target.mathparameters
+ else
+ properties.hasmath=false
+ target.nomath=true
+ target.mathparameters=nil
+ end
+ if hasmath then
+ local mathitalics=properties.mathitalics
+ if mathitalics==false then
+ if trace_defining then
+ report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename)
+ end
+ hasitalics=false
+ autoitalicamount=false
+ end
+ else
+ local textitalics=properties.textitalics
+ if textitalics==false then
+ if trace_defining then
+ report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename)
+ end
+ hasitalics=false
+ autoitalicamount=false
+ end
+ end
+ if trace_defining then
+ report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a",
+ name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta,
+ hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled")
+ end
+ constructors.beforecopyingcharacters(target,tfmdata)
+ local sharedkerns={}
+ for unicode,character in next,characters do
+ local chr,description,index
+ if changed then
+ local c=changed[unicode]
+ if c and c~=unicode then
+ if c then
+ description=descriptions[c] or descriptions[unicode] or character
+ character=characters[c] or character
+ index=description.index or c
+ else
+ description=descriptions[unicode] or character
+ index=description.index or unicode
+ end
+ else
+ description=descriptions[unicode] or character
+ index=description.index or unicode
+ end
else
- target.slant=0
- end
- local extendfactor=parameters.extendfactor or 0
- if extendfactor~=0 and extendfactor~=1 then
- hdelta=hdelta*extendfactor
- target.extend=extendfactor*1000
+ description=descriptions[unicode] or character
+ index=description.index or unicode
+ end
+ local width=description.width
+ local height=description.height
+ local depth=description.depth
+ if realdimensions then
+ if not height or height==0 then
+ local bb=description.boundingbox
+ local ht=bb[4]
+ if ht~=0 then
+ height=ht
+ end
+ if not depth or depth==0 then
+ local dp=-bb[2]
+ if dp~=0 then
+ depth=dp
+ end
+ end
+ elseif not depth or depth==0 then
+ local dp=-description.boundingbox[2]
+ if dp~=0 then
+ depth=dp
+ end
+ end
+ end
+ if width then width=hdelta*width else width=scaledwidth end
+ if height then height=vdelta*height else height=scaledheight end
+ if depth and depth~=0 then
+ depth=delta*depth
+ if nonames then
+ chr={
+ index=index,
+ height=height,
+ depth=depth,
+ width=width,
+ }
+ else
+ chr={
+ name=description.name,
+ index=index,
+ height=height,
+ depth=depth,
+ width=width,
+ }
+ end
else
- target.extend=1000
+ if nonames then
+ chr={
+ index=index,
+ height=height,
+ width=width,
+ }
+ else
+ chr={
+ name=description.name,
+ index=index,
+ height=height,
+ width=width,
+ }
+ end
end
- local squeezefactor=parameters.squeezefactor or 0
- if squeezefactor~=0 and squeezefactor~=1 then
- vdelta=vdelta*squeezefactor
- target.squeeze=squeezefactor*1000
- else
- target.squeeze=1000
- end
- local mode=parameters.mode or 0
- if mode~=0 then
- target.mode=mode
- end
- local width=parameters.width or 0
- if width~=0 then
- target.width=width*delta*1000/655360
- end
- targetparameters.factor=delta
- targetparameters.hfactor=hdelta
- targetparameters.vfactor=vdelta
- targetparameters.size=scaledpoints
- targetparameters.units=units
- targetparameters.scaledpoints=askedscaledpoints
- targetparameters.mode=mode
- targetparameters.width=width
- local isvirtual=properties.virtualized or tfmdata.type=="virtual"
- local hasquality=parameters.expansion or parameters.protrusion
- local hasitalics=properties.hasitalics
- local autoitalicamount=properties.autoitalicamount
- local stackmath=not properties.nostackmath
- local nonames=properties.noglyphnames
- local haskerns=properties.haskerns or properties.mode=="base"
- local hasligatures=properties.hasligatures or properties.mode=="base"
- local realdimensions=properties.realdimensions
- local writingmode=properties.writingmode or "horizontal"
- local identity=properties.identity or "horizontal"
- local vfonts=target.fonts
- if vfonts and #vfonts>0 then
- target.fonts=fastcopy(vfonts)
- elseif isvirtual then
- target.fonts={ { id=0 } }
- end
- if changed and not next(changed) then
- changed=false
- end
- target.type=isvirtual and "virtual" or "real"
- target.writingmode=writingmode=="vertical" and "vertical" or "horizontal"
- target.identity=identity=="vertical" and "vertical" or "horizontal"
- target.postprocessors=tfmdata.postprocessors
- local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt
- local targetspace=(parameters.space or parameters[2] or 0)*hdelta
- local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta
- local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta
- local targetx_height=(parameters.x_height or parameters[5] or 0)*vdelta
- local targetquad=(parameters.quad or parameters[6] or 0)*hdelta
- local targetextra_space=(parameters.extra_space or parameters[7] or 0)*hdelta
- targetparameters.slant=targetslant
- targetparameters.space=targetspace
- targetparameters.space_stretch=targetspace_stretch
- targetparameters.space_shrink=targetspace_shrink
- targetparameters.x_height=targetx_height
- targetparameters.quad=targetquad
- targetparameters.extra_space=targetextra_space
- local ascender=parameters.ascender
- if ascender then
- targetparameters.ascender=delta*ascender
- end
- local descender=parameters.descender
- if descender then
- targetparameters.descender=delta*descender
- end
- constructors.enhanceparameters(targetparameters)
- local protrusionfactor=(targetquad~=0 and 1000/targetquad) or 0
- local scaledwidth=defaultwidth*hdelta
- local scaledheight=defaultheight*vdelta
- local scaleddepth=defaultdepth*vdelta
- local hasmath=(properties.hasmath or next(mathparameters)) and true
- if hasmath then
- constructors.assignmathparameters(target,tfmdata)
- properties.hasmath=true
- target.nomath=false
- target.MathConstants=target.mathparameters
+ local isunicode=description.unicode
+ if isunicode then
+ chr.unicode=isunicode
+ chr.tounicode=tounicode(isunicode)
else
- properties.hasmath=false
- target.nomath=true
- target.mathparameters=nil
+ chr.tounicode=unknowncode
+ end
+ if hasquality then
+ local ve=character.expansion_factor
+ if ve then
+ chr.expansion_factor=ve*1000
+ end
+ local vl=character.left_protruding
+ if vl then
+ chr.left_protruding=protrusionfactor*width*vl
+ end
+ local vr=character.right_protruding
+ if vr then
+ chr.right_protruding=protrusionfactor*width*vr
+ end
end
if hasmath then
- local mathitalics=properties.mathitalics
- if mathitalics==false then
- if trace_defining then
- report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename)
- end
- hasitalics=false
- autoitalicamount=false
- end
- else
- local textitalics=properties.textitalics
- if textitalics==false then
- if trace_defining then
- report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename)
- end
- hasitalics=false
- autoitalicamount=false
- end
- end
- if trace_defining then
- report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a",
- name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta,
- hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled")
- end
- constructors.beforecopyingcharacters(target,tfmdata)
- local sharedkerns={}
- for unicode,character in next,characters do
- local chr,description,index
- if changed then
- local c=changed[unicode]
- if c and c~=unicode then
- if c then
- description=descriptions[c] or descriptions[unicode] or character
- character=characters[c] or character
- index=description.index or c
- else
- description=descriptions[unicode] or character
- index=description.index or unicode
- end
- else
- description=descriptions[unicode] or character
- index=description.index or unicode
- end
+ local vn=character.next
+ if vn then
+ chr.next=vn
+ else
+ local vv=character.vert_variants
+ if vv then
+ local t={}
+ for i=1,#vv do
+ local vvi=vv[i]
+ local s=vvi["start"] or 0
+ local e=vvi["end"] or 0
+ local a=vvi["advance"] or 0
+ t[i]={
+ ["start"]=s==0 and 0 or s*vdelta,
+ ["end"]=e==0 and 0 or e*vdelta,
+ ["advance"]=a==0 and 0 or a*vdelta,
+ ["extender"]=vvi["extender"],
+ ["glyph"]=vvi["glyph"],
+ }
+ end
+ chr.vert_variants=t
else
- description=descriptions[unicode] or character
- index=description.index or unicode
- end
- local width=description.width
- local height=description.height
- local depth=description.depth
- if realdimensions then
- if not height or height==0 then
- local bb=description.boundingbox
- local ht=bb[4]
- if ht~=0 then
- height=ht
- end
- if not depth or depth==0 then
- local dp=-bb[2]
- if dp~=0 then
- depth=dp
- end
- end
- elseif not depth or depth==0 then
- local dp=-description.boundingbox[2]
- if dp~=0 then
- depth=dp
- end
- end
+ local hv=character.horiz_variants
+ if hv then
+ local t={}
+ for i=1,#hv do
+ local hvi=hv[i]
+ local s=hvi["start"] or 0
+ local e=hvi["end"] or 0
+ local a=hvi["advance"] or 0
+ t[i]={
+ ["start"]=s==0 and 0 or s*hdelta,
+ ["end"]=e==0 and 0 or e*hdelta,
+ ["advance"]=a==0 and 0 or a*hdelta,
+ ["extender"]=hvi["extender"],
+ ["glyph"]=hvi["glyph"],
+ }
+ end
+ chr.horiz_variants=t
+ end
end
- if width then width=hdelta*width else width=scaledwidth end
- if height then height=vdelta*height else height=scaledheight end
- if depth and depth~=0 then
- depth=delta*depth
- if nonames then
- chr={
- index=index,
- height=height,
- depth=depth,
- width=width,
- }
- else
- chr={
- name=description.name,
- index=index,
- height=height,
- depth=depth,
- width=width,
- }
- end
+ end
+ local vi=character.vert_italic
+ if vi and vi~=0 then
+ chr.vert_italic=vi*hdelta
+ end
+ local va=character.accent
+ if va then
+ chr.top_accent=vdelta*va
+ end
+ if stackmath then
+ local mk=character.mathkerns
+ if mk then
+ local tr,tl,br,bl=mk.topright,mk.topleft,mk.bottomright,mk.bottomleft
+ chr.mathkern={
+ top_right=tr and mathkerns(tr,vdelta) or nil,
+ top_left=tl and mathkerns(tl,vdelta) or nil,
+ bottom_right=br and mathkerns(br,vdelta) or nil,
+ bottom_left=bl and mathkerns(bl,vdelta) or nil,
+ }
+ end
+ end
+ if hasitalics then
+ local vi=character.italic
+ if vi and vi~=0 then
+ chr.italic=vi*hdelta
+ end
+ end
+ elseif autoitalicamount then
+ local vi=description.italic
+ if not vi then
+ local bb=description.boundingbox
+ if bb then
+ local vi=bb[3]-description.width+autoitalicamount
+ if vi>0 then
+ chr.italic=vi*hdelta
+ end
else
- if nonames then
- chr={
- index=index,
- height=height,
- width=width,
- }
- else
- chr={
- name=description.name,
- index=index,
- height=height,
- width=width,
- }
- end
end
- local isunicode=description.unicode
- if isunicode then
- chr.unicode=isunicode
- chr.tounicode=tounicode(isunicode)
+ elseif vi~=0 then
+ chr.italic=vi*hdelta
+ end
+ elseif hasitalics then
+ local vi=character.italic
+ if vi and vi~=0 then
+ chr.italic=vi*hdelta
+ end
+ end
+ if haskerns then
+ local vk=character.kerns
+ if vk then
+ local s=sharedkerns[vk]
+ if not s then
+ s={}
+ for k,v in next,vk do s[k]=v*hdelta end
+ sharedkerns[vk]=s
+ end
+ chr.kerns=s
+ end
+ end
+ if hasligatures then
+ local vl=character.ligatures
+ if vl then
+ if true then
+ chr.ligatures=vl
else
- chr.tounicode=unknowncode
- end
- if hasquality then
- local ve=character.expansion_factor
- if ve then
- chr.expansion_factor=ve*1000
- end
- local vl=character.left_protruding
- if vl then
- chr.left_protruding=protrusionfactor*width*vl
- end
- local vr=character.right_protruding
- if vr then
- chr.right_protruding=protrusionfactor*width*vr
- end
- end
- if hasmath then
- local vn=character.next
- if vn then
- chr.next=vn
- else
- local vv=character.vert_variants
- if vv then
- local t={}
- for i=1,#vv do
- local vvi=vv[i]
- local s=vvi["start"] or 0
- local e=vvi["end"] or 0
- local a=vvi["advance"] or 0
- t[i]={
- ["start"]=s==0 and 0 or s*vdelta,
- ["end"]=e==0 and 0 or e*vdelta,
- ["advance"]=a==0 and 0 or a*vdelta,
- ["extender"]=vvi["extender"],
- ["glyph"]=vvi["glyph"],
- }
- end
- chr.vert_variants=t
- else
- local hv=character.horiz_variants
- if hv then
- local t={}
- for i=1,#hv do
- local hvi=hv[i]
- local s=hvi["start"] or 0
- local e=hvi["end"] or 0
- local a=hvi["advance"] or 0
- t[i]={
- ["start"]=s==0 and 0 or s*hdelta,
- ["end"]=e==0 and 0 or e*hdelta,
- ["advance"]=a==0 and 0 or a*hdelta,
- ["extender"]=hvi["extender"],
- ["glyph"]=hvi["glyph"],
- }
- end
- chr.horiz_variants=t
- end
- end
- end
- local vi=character.vert_italic
- if vi and vi~=0 then
- chr.vert_italic=vi*hdelta
- end
- local va=character.accent
- if va then
- chr.top_accent=vdelta*va
- end
- if stackmath then
- local mk=character.mathkerns
- if mk then
- local tr,tl,br,bl=mk.topright,mk.topleft,mk.bottomright,mk.bottomleft
- chr.mathkern={
- top_right=tr and mathkerns(tr,vdelta) or nil,
- top_left=tl and mathkerns(tl,vdelta) or nil,
- bottom_right=br and mathkerns(br,vdelta) or nil,
- bottom_left=bl and mathkerns(bl,vdelta) or nil,
- }
- end
- end
- if hasitalics then
- local vi=character.italic
- if vi and vi~=0 then
- chr.italic=vi*hdelta
- end
- end
- elseif autoitalicamount then
- local vi=description.italic
- if not vi then
- local bb=description.boundingbox
- if bb then
- local vi=bb[3]-description.width+autoitalicamount
- if vi>0 then
- chr.italic=vi*hdelta
- end
- else
- end
- elseif vi~=0 then
- chr.italic=vi*hdelta
- end
- elseif hasitalics then
- local vi=character.italic
- if vi and vi~=0 then
- chr.italic=vi*hdelta
- end
- end
- if haskerns then
- local vk=character.kerns
- if vk then
- local s=sharedkerns[vk]
- if not s then
- s={}
- for k,v in next,vk do s[k]=v*hdelta end
- sharedkerns[vk]=s
- end
- chr.kerns=s
- end
+ local tt={}
+ for i,l in next,vl do
+ tt[i]=l
+ end
+ chr.ligatures=tt
end
- if hasligatures then
- local vl=character.ligatures
- if vl then
- if true then
- chr.ligatures=vl
- else
- local tt={}
- for i,l in next,vl do
- tt[i]=l
- end
- chr.ligatures=tt
- end
- end
+ end
+ end
+ if isvirtual then
+ local vc=character.commands
+ if vc then
+ local ok=false
+ for i=1,#vc do
+ local key=vc[i][1]
+ if key=="right" or key=="down" or key=="rule" then
+ ok=true
+ break
+ end
end
- if isvirtual then
- local vc=character.commands
- if vc then
- local ok=false
- for i=1,#vc do
- local key=vc[i][1]
- if key=="right" or key=="down" or key=="rule" then
- ok=true
- break
- end
- end
- if ok then
- local tt={}
- for i=1,#vc do
- local ivc=vc[i]
- local key=ivc[1]
- if key=="right" then
- tt[i]={ key,ivc[2]*hdelta }
- elseif key=="down" then
- tt[i]={ key,ivc[2]*vdelta }
- elseif key=="rule" then
- tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta }
- else
- tt[i]=ivc
- end
- end
- chr.commands=tt
- else
- chr.commands=vc
- end
+ if ok then
+ local tt={}
+ for i=1,#vc do
+ local ivc=vc[i]
+ local key=ivc[1]
+ if key=="right" then
+ tt[i]={ key,ivc[2]*hdelta }
+ elseif key=="down" then
+ tt[i]={ key,ivc[2]*vdelta }
+ elseif key=="rule" then
+ tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta }
+ else
+ tt[i]=ivc
end
+ end
+ chr.commands=tt
+ else
+ chr.commands=vc
end
- targetcharacters[unicode]=chr
+ end
end
- properties.setitalics=hasitalics
- constructors.aftercopyingcharacters(target,tfmdata)
- constructors.trytosharefont(target,tfmdata)
- local vfonts=target.fonts
- if isvirtual or target.type=="virtual" or properties.virtualized then
- properties.virtualized=true
- target.type="virtual"
- if not vfonts or #vfonts==0 then
- target.fonts={ { id=0 } }
- end
- elseif vfonts then
- properties.virtualized=true
- target.type="virtual"
- if #vfonts==0 then
- target.fonts={ { id=0 } }
- end
+ targetcharacters[unicode]=chr
+ end
+ properties.setitalics=hasitalics
+ constructors.aftercopyingcharacters(target,tfmdata)
+ constructors.trytosharefont(target,tfmdata)
+ local vfonts=target.fonts
+ if isvirtual or target.type=="virtual" or properties.virtualized then
+ properties.virtualized=true
+ target.type="virtual"
+ if not vfonts or #vfonts==0 then
+ target.fonts={ { id=0 } }
+ end
+ elseif vfonts then
+ properties.virtualized=true
+ target.type="virtual"
+ if #vfonts==0 then
+ target.fonts={ { id=0 } }
end
- return target
+ end
+ return target
end
function constructors.finalize(tfmdata)
- if tfmdata.properties and tfmdata.properties.finalized then
- return
- end
- if not tfmdata.characters then
- return nil
- end
- if not tfmdata.goodies then
- tfmdata.goodies={}
- end
- local parameters=tfmdata.parameters
- if not parameters then
- return nil
- end
- if not parameters.expansion then
- parameters.expansion={
- stretch=tfmdata.stretch or 0,
- shrink=tfmdata.shrink or 0,
- step=tfmdata.step or 0,
- }
- end
- if not parameters.size then
- parameters.size=tfmdata.size
- end
- if not parameters.mode then
- parameters.mode=0
- end
- if not parameters.width then
- parameters.width=0
- end
- if not parameters.slantfactor then
- parameters.slantfactor=tfmdata.slant or 0
- end
- if not parameters.extendfactor then
- parameters.extendfactor=tfmdata.extend or 0
- end
- if not parameters.squeezefactor then
- parameters.squeezefactor=tfmdata.squeeze or 0
- end
- local designsize=parameters.designsize
- if designsize then
- parameters.minsize=tfmdata.minsize or designsize
- parameters.maxsize=tfmdata.maxsize or designsize
- else
- designsize=factors.pt*10
- parameters.designsize=designsize
- parameters.minsize=designsize
- parameters.maxsize=designsize
- end
- parameters.minsize=tfmdata.minsize or parameters.designsize
- parameters.maxsize=tfmdata.maxsize or parameters.designsize
- if not parameters.units then
- parameters.units=tfmdata.units or tfmdata.units_per_em or 1000
- end
- if not tfmdata.descriptions then
- local descriptions={}
- setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end)
- tfmdata.descriptions=descriptions
- end
- local properties=tfmdata.properties
- if not properties then
- properties={}
- tfmdata.properties=properties
- end
- if not properties.virtualized then
- properties.virtualized=tfmdata.type=="virtual"
- end
- properties.fontname=tfmdata.fontname
- properties.filename=tfmdata.filename
- properties.fullname=tfmdata.fullname
- properties.name=tfmdata.name
- properties.psname=tfmdata.psname
- properties.encodingbytes=tfmdata.encodingbytes or 1
- properties.embedding=tfmdata.embedding or "subset"
- properties.tounicode=tfmdata.tounicode or 1
- properties.cidinfo=tfmdata.cidinfo or nil
- properties.format=tfmdata.format or "type1"
- properties.direction=tfmdata.direction or 0
- properties.writingmode=tfmdata.writingmode or "horizontal"
- properties.identity=tfmdata.identity or "horizontal"
- properties.usedbitmap=tfmdata.usedbitmap
- if not tfmdata.resources then
- tfmdata.resources={}
- end
- if not tfmdata.shared then
- tfmdata.shared={}
- end
- if not properties.hasmath then
- properties.hasmath=not tfmdata.nomath
- end
- tfmdata.MathConstants=nil
- tfmdata.postprocessors=nil
- tfmdata.fontname=nil
- tfmdata.filename=nil
- tfmdata.fullname=nil
- tfmdata.name=nil
- tfmdata.psname=nil
- tfmdata.encodingbytes=nil
- tfmdata.embedding=nil
- tfmdata.tounicode=nil
- tfmdata.cidinfo=nil
- tfmdata.format=nil
- tfmdata.direction=nil
- tfmdata.type=nil
- tfmdata.nomath=nil
- tfmdata.designsize=nil
- tfmdata.size=nil
- tfmdata.stretch=nil
- tfmdata.shrink=nil
- tfmdata.step=nil
- tfmdata.slant=nil
- tfmdata.extend=nil
- tfmdata.squeeze=nil
- tfmdata.mode=nil
- tfmdata.width=nil
- tfmdata.units=nil
- tfmdata.units_per_em=nil
- tfmdata.cache=nil
- properties.finalized=true
- return tfmdata
+ if tfmdata.properties and tfmdata.properties.finalized then
+ return
+ end
+ if not tfmdata.characters then
+ return nil
+ end
+ if not tfmdata.goodies then
+ tfmdata.goodies={}
+ end
+ local parameters=tfmdata.parameters
+ if not parameters then
+ return nil
+ end
+ if not parameters.expansion then
+ parameters.expansion={
+ stretch=tfmdata.stretch or 0,
+ shrink=tfmdata.shrink or 0,
+ step=tfmdata.step or 0,
+ }
+ end
+ if not parameters.size then
+ parameters.size=tfmdata.size
+ end
+ if not parameters.mode then
+ parameters.mode=0
+ end
+ if not parameters.width then
+ parameters.width=0
+ end
+ if not parameters.slantfactor then
+ parameters.slantfactor=tfmdata.slant or 0
+ end
+ if not parameters.extendfactor then
+ parameters.extendfactor=tfmdata.extend or 0
+ end
+ if not parameters.squeezefactor then
+ parameters.squeezefactor=tfmdata.squeeze or 0
+ end
+ local designsize=parameters.designsize
+ if designsize then
+ parameters.minsize=tfmdata.minsize or designsize
+ parameters.maxsize=tfmdata.maxsize or designsize
+ else
+ designsize=factors.pt*10
+ parameters.designsize=designsize
+ parameters.minsize=designsize
+ parameters.maxsize=designsize
+ end
+ parameters.minsize=tfmdata.minsize or parameters.designsize
+ parameters.maxsize=tfmdata.maxsize or parameters.designsize
+ if not parameters.units then
+ parameters.units=tfmdata.units or tfmdata.units_per_em or 1000
+ end
+ if not tfmdata.descriptions then
+ local descriptions={}
+ setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end)
+ tfmdata.descriptions=descriptions
+ end
+ local properties=tfmdata.properties
+ if not properties then
+ properties={}
+ tfmdata.properties=properties
+ end
+ if not properties.virtualized then
+ properties.virtualized=tfmdata.type=="virtual"
+ end
+ properties.fontname=tfmdata.fontname
+ properties.filename=tfmdata.filename
+ properties.fullname=tfmdata.fullname
+ properties.name=tfmdata.name
+ properties.psname=tfmdata.psname
+ properties.encodingbytes=tfmdata.encodingbytes or 1
+ properties.embedding=tfmdata.embedding or "subset"
+ properties.tounicode=tfmdata.tounicode or 1
+ properties.cidinfo=tfmdata.cidinfo or nil
+ properties.format=tfmdata.format or "type1"
+ properties.direction=tfmdata.direction or 0
+ properties.writingmode=tfmdata.writingmode or "horizontal"
+ properties.identity=tfmdata.identity or "horizontal"
+ properties.usedbitmap=tfmdata.usedbitmap
+ if not tfmdata.resources then
+ tfmdata.resources={}
+ end
+ if not tfmdata.shared then
+ tfmdata.shared={}
+ end
+ if not properties.hasmath then
+ properties.hasmath=not tfmdata.nomath
+ end
+ tfmdata.MathConstants=nil
+ tfmdata.postprocessors=nil
+ tfmdata.fontname=nil
+ tfmdata.filename=nil
+ tfmdata.fullname=nil
+ tfmdata.name=nil
+ tfmdata.psname=nil
+ tfmdata.encodingbytes=nil
+ tfmdata.embedding=nil
+ tfmdata.tounicode=nil
+ tfmdata.cidinfo=nil
+ tfmdata.format=nil
+ tfmdata.direction=nil
+ tfmdata.type=nil
+ tfmdata.nomath=nil
+ tfmdata.designsize=nil
+ tfmdata.size=nil
+ tfmdata.stretch=nil
+ tfmdata.shrink=nil
+ tfmdata.step=nil
+ tfmdata.slant=nil
+ tfmdata.extend=nil
+ tfmdata.squeeze=nil
+ tfmdata.mode=nil
+ tfmdata.width=nil
+ tfmdata.units=nil
+ tfmdata.units_per_em=nil
+ tfmdata.cache=nil
+ properties.finalized=true
+ return tfmdata
end
local hashmethods={}
constructors.hashmethods=hashmethods
function constructors.hashfeatures(specification)
- local features=specification.features
- if features then
- local t,n={},0
- for category,list in sortedhash(features) do
- if next(list) then
- local hasher=hashmethods[category]
- if hasher then
- local hash=hasher(list)
- if hash then
- n=n+1
- t[n]=category..":"..hash
- end
- end
- end
- end
- if n>0 then
- return concat(t," & ")
- end
- end
- return "unknown"
-end
-hashmethods.normal=function(list)
- local s={}
- local n=0
- for k,v in next,list do
- if not k then
- elseif k=="number" or k=="features" then
- else
+ local features=specification.features
+ if features then
+ local t,n={},0
+ for category,list in sortedhash(features) do
+ if next(list) then
+ local hasher=hashmethods[category]
+ if hasher then
+ local hash=hasher(list)
+ if hash then
n=n+1
- if type(v)=="table" then
- local t={}
- local m=0
- for k,v in next,v do
- m=m+1
- t[m]=k..'='..tostring(v)
- end
- s[n]=k..'={'..concat(t,",").."}"
- else
- s[n]=k..'='..tostring(v)
- end
+ t[n]=category..":"..hash
+ end
end
+ end
end
if n>0 then
- sort(s)
- return concat(s,"+")
+ return concat(t," & ")
end
+ end
+ return "unknown"
end
-function constructors.hashinstance(specification,force)
- local hash,size,fallbacks=specification.hash,specification.size,specification.fallbacks
- if force or not hash then
- hash=constructors.hashfeatures(specification)
- specification.hash=hash
- end
- if size<1000 and designsizes[hash] then
- size=round(constructors.scaled(size,designsizes[hash]))
- else
- size=round(size)
- end
- specification.size=size
- if fallbacks then
- return hash..' @ '..size..' @ '..fallbacks
+hashmethods.normal=function(list)
+ local s={}
+ local n=0
+ for k,v in next,list do
+ if not k then
+ elseif k=="number" or k=="features" then
else
- return hash..' @ '..size
- end
+ n=n+1
+ if type(v)=="table" then
+ local t={}
+ local m=0
+ for k,v in next,v do
+ m=m+1
+ t[m]=k..'='..tostring(v)
+ end
+ s[n]=k..'={'..concat(t,",").."}"
+ else
+ s[n]=k..'='..tostring(v)
+ end
+ end
+ end
+ if n>0 then
+ sort(s)
+ return concat(s,"+")
+ end
+end
+function constructors.hashinstance(specification,force)
+ local hash,size,fallbacks=specification.hash,specification.size,specification.fallbacks
+ if force or not hash then
+ hash=constructors.hashfeatures(specification)
+ specification.hash=hash
+ end
+ if size<1000 and designsizes[hash] then
+ size=round(constructors.scaled(size,designsizes[hash]))
+ else
+ size=round(size)
+ end
+ specification.size=size
+ if fallbacks then
+ return hash..' @ '..size..' @ '..fallbacks
+ else
+ return hash..' @ '..size
+ end
end
function constructors.setname(tfmdata,specification)
- if constructors.namemode=="specification" then
- local specname=specification.specification
- if specname then
- tfmdata.properties.name=specname
- if trace_defining then
- report_otf("overloaded fontname %a",specname)
- end
- end
+ if constructors.namemode=="specification" then
+ local specname=specification.specification
+ if specname then
+ tfmdata.properties.name=specname
+ if trace_defining then
+ report_otf("overloaded fontname %a",specname)
+ end
end
+ end
end
function constructors.checkedfilename(data)
- local foundfilename=data.foundfilename
- if not foundfilename then
- local askedfilename=data.filename or ""
- if askedfilename~="" then
- askedfilename=resolvers.resolve(askedfilename)
- foundfilename=resolvers.findbinfile(askedfilename,"") or ""
- if foundfilename=="" then
- report_defining("source file %a is not found",askedfilename)
- foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or ""
- if foundfilename~="" then
- report_defining("using source file %a due to cache mismatch",foundfilename)
- end
- end
- end
- data.foundfilename=foundfilename
- end
- return foundfilename
+ local foundfilename=data.foundfilename
+ if not foundfilename then
+ local askedfilename=data.filename or ""
+ if askedfilename~="" then
+ askedfilename=resolvers.resolve(askedfilename)
+ foundfilename=resolvers.findbinfile(askedfilename,"") or ""
+ if foundfilename=="" then
+ report_defining("source file %a is not found",askedfilename)
+ foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or ""
+ if foundfilename~="" then
+ report_defining("using source file %a due to cache mismatch",foundfilename)
+ end
+ end
+ end
+ data.foundfilename=foundfilename
+ end
+ return foundfilename
end
local formats=allocate()
fonts.formats=formats
setmetatableindex(formats,function(t,k)
- local l=lower(k)
- if rawget(t,k) then
- t[k]=l
- return l
- end
- return rawget(t,file.suffix(l))
+ local l=lower(k)
+ if rawget(t,k) then
+ t[k]=l
+ return l
+ end
+ return rawget(t,file.suffix(l))
end)
do
- local function setindeed(mode,source,target,group,name,position)
- local action=source[mode]
- if not action then
- return
- end
- local t=target[mode]
- if not t then
- report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode)
- os.exit()
- elseif position then
- insert(t,position,{ name=name,action=action })
- else
- for i=1,#t do
- local ti=t[i]
- if ti.name==name then
- ti.action=action
- return
- end
- end
- insert(t,{ name=name,action=action })
- end
- end
- local function set(group,name,target,source)
- target=target[group]
- if not target then
- report_defining("fatal target error in setting feature %a, group %a",name,group)
- os.exit()
- end
- local source=source[group]
- if not source then
- report_defining("fatal source error in setting feature %a, group %a",name,group)
- os.exit()
- end
- local position=source.position
- setindeed("node",source,target,group,name,position)
- setindeed("base",source,target,group,name,position)
- setindeed("plug",source,target,group,name,position)
- end
- local function register(where,specification)
- local name=specification.name
- if name and name~="" then
- local default=specification.default
- local description=specification.description
- local initializers=specification.initializers
- local processors=specification.processors
- local manipulators=specification.manipulators
- local modechecker=specification.modechecker
- if default then
- where.defaults[name]=default
- end
- if description and description~="" then
- where.descriptions[name]=description
- end
- if initializers then
- set('initializers',name,where,specification)
- end
- if processors then
- set('processors',name,where,specification)
- end
- if manipulators then
- set('manipulators',name,where,specification)
- end
- if modechecker then
- where.modechecker=modechecker
- end
- end
+ local function setindeed(mode,source,target,group,name,position)
+ local action=source[mode]
+ if not action then
+ return
end
- constructors.registerfeature=register
- function constructors.getfeatureaction(what,where,mode,name)
- what=handlers[what].features
- if what then
- where=what[where]
- if where then
- mode=where[mode]
- if mode then
- for i=1,#mode do
- local m=mode[i]
- if m.name==name then
- return m.action
- end
- end
- end
+ local t=target[mode]
+ if not t then
+ report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode)
+ os.exit()
+ elseif position then
+ insert(t,position,{ name=name,action=action })
+ else
+ for i=1,#t do
+ local ti=t[i]
+ if ti.name==name then
+ ti.action=action
+ return
+ end
+ end
+ insert(t,{ name=name,action=action })
+ end
+ end
+ local function set(group,name,target,source)
+ target=target[group]
+ if not target then
+ report_defining("fatal target error in setting feature %a, group %a",name,group)
+ os.exit()
+ end
+ local source=source[group]
+ if not source then
+ report_defining("fatal source error in setting feature %a, group %a",name,group)
+ os.exit()
+ end
+ local position=source.position
+ setindeed("node",source,target,group,name,position)
+ setindeed("base",source,target,group,name,position)
+ setindeed("plug",source,target,group,name,position)
+ end
+ local function register(where,specification)
+ local name=specification.name
+ if name and name~="" then
+ local default=specification.default
+ local description=specification.description
+ local initializers=specification.initializers
+ local processors=specification.processors
+ local manipulators=specification.manipulators
+ local modechecker=specification.modechecker
+ if default then
+ where.defaults[name]=default
+ end
+ if description and description~="" then
+ where.descriptions[name]=description
+ end
+ if initializers then
+ set('initializers',name,where,specification)
+ end
+ if processors then
+ set('processors',name,where,specification)
+ end
+ if manipulators then
+ set('manipulators',name,where,specification)
+ end
+ if modechecker then
+ where.modechecker=modechecker
+ end
+ end
+ end
+ constructors.registerfeature=register
+ function constructors.getfeatureaction(what,where,mode,name)
+ what=handlers[what].features
+ if what then
+ where=what[where]
+ if where then
+ mode=where[mode]
+ if mode then
+ for i=1,#mode do
+ local m=mode[i]
+ if m.name==name then
+ return m.action
end
+ end
end
- end
- local newfeatures={}
- constructors.newfeatures=newfeatures
- constructors.features=newfeatures
- local function setnewfeatures(what)
- local handler=handlers[what]
- local features=handler.features
- if not features then
- local tables=handler.tables
- local statistics=handler.statistics
- features=allocate {
- defaults={},
- descriptions=tables and tables.features or {},
- used=statistics and statistics.usedfeatures or {},
- initializers={ base={},node={},plug={} },
- processors={ base={},node={},plug={} },
- manipulators={ base={},node={},plug={} },
- }
- features.register=function(specification) return register(features,specification) end
- handler.features=features
- end
- return features
- end
- setmetatable(newfeatures,{
- __call=function(t,k) local v=t[k] return v end,
- __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end,
- })
+ end
+ end
+ end
+ local newfeatures={}
+ constructors.newfeatures=newfeatures
+ constructors.features=newfeatures
+ local function setnewfeatures(what)
+ local handler=handlers[what]
+ local features=handler.features
+ if not features then
+ local tables=handler.tables
+ local statistics=handler.statistics
+ features=allocate {
+ defaults={},
+ descriptions=tables and tables.features or {},
+ used=statistics and statistics.usedfeatures or {},
+ initializers={ base={},node={},plug={} },
+ processors={ base={},node={},plug={} },
+ manipulators={ base={},node={},plug={} },
+ }
+ features.register=function(specification) return register(features,specification) end
+ handler.features=features
+ end
+ return features
+ end
+ setmetatable(newfeatures,{
+ __call=function(t,k) local v=t[k] return v end,
+ __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end,
+ })
end
do
- local newhandler={}
- constructors.handlers=newhandler
- constructors.newhandler=newhandler
- local function setnewhandler(what)
- local handler=handlers[what]
- if not handler then
- handler={}
- handlers[what]=handler
- end
- return handler
- end
- setmetatable(newhandler,{
- __call=function(t,k) local v=t[k] return v end,
- __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end,
- })
+ local newhandler={}
+ constructors.handlers=newhandler
+ constructors.newhandler=newhandler
+ local function setnewhandler(what)
+ local handler=handlers[what]
+ if not handler then
+ handler={}
+ handlers[what]=handler
+ end
+ return handler
+ end
+ setmetatable(newhandler,{
+ __call=function(t,k) local v=t[k] return v end,
+ __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end,
+ })
end
do
- local newenhancer={}
- constructors.enhancers=newenhancer
- constructors.newenhancer=newenhancer
- local function setnewenhancer(format)
- local handler=handlers[format]
- local enhancers=handler.enhancers
- if not enhancers then
- local actions=allocate()
- local before=allocate()
- local after=allocate()
- local order=allocate()
- local known={}
- local nofsteps=0
- local patches={ before=before,after=after }
- local trace=false
- local report=logs.reporter("fonts",format.." enhancing")
- trackers.register(format..".loading",function(v) trace=v end)
- local function enhance(name,data,filename,raw)
- local enhancer=actions[name]
- if enhancer then
- if trace then
- report("apply enhancement %a to file %a",name,filename)
- ioflush()
- end
- enhancer(data,filename,raw)
- else
- end
- end
- local function apply(data,filename,raw)
- local basename=file.basename(lower(filename))
- if trace then
- report("%s enhancing file %a","start",filename)
- end
- ioflush()
- for e=1,nofsteps do
- local enhancer=order[e]
- local b=before[enhancer]
- if b then
- for pattern,action in next,b do
- if find(basename,pattern) then
- action(data,filename,raw)
- end
- end
- end
- enhance(enhancer,data,filename,raw)
- local a=after[enhancer]
- if a then
- for pattern,action in next,a do
- if find(basename,pattern) then
- action(data,filename,raw)
- end
- end
- end
- ioflush()
- end
- if trace then
- report("%s enhancing file %a","stop",filename)
- end
- ioflush()
+ local newenhancer={}
+ constructors.enhancers=newenhancer
+ constructors.newenhancer=newenhancer
+ local function setnewenhancer(format)
+ local handler=handlers[format]
+ local enhancers=handler.enhancers
+ if not enhancers then
+ local actions=allocate()
+ local before=allocate()
+ local after=allocate()
+ local order=allocate()
+ local known={}
+ local nofsteps=0
+ local patches={ before=before,after=after }
+ local trace=false
+ local report=logs.reporter("fonts",format.." enhancing")
+ trackers.register(format..".loading",function(v) trace=v end)
+ local function enhance(name,data,filename,raw)
+ local enhancer=actions[name]
+ if enhancer then
+ if trace then
+ report("apply enhancement %a to file %a",name,filename)
+ ioflush()
+ end
+ enhancer(data,filename,raw)
+ else
+ end
+ end
+ local function apply(data,filename,raw)
+ local basename=file.basename(lower(filename))
+ if trace then
+ report("%s enhancing file %a","start",filename)
+ end
+ ioflush()
+ for e=1,nofsteps do
+ local enhancer=order[e]
+ local b=before[enhancer]
+ if b then
+ for pattern,action in next,b do
+ if find(basename,pattern) then
+ action(data,filename,raw)
+ end
end
- local function register(what,action)
- if action then
- if actions[what] then
- else
- nofsteps=nofsteps+1
- order[nofsteps]=what
- known[what]=nofsteps
- end
- actions[what]=action
- else
- report("bad enhancer %a",what)
- end
+ end
+ enhance(enhancer,data,filename,raw)
+ local a=after[enhancer]
+ if a then
+ for pattern,action in next,a do
+ if find(basename,pattern) then
+ action(data,filename,raw)
+ end
end
- local function patch(what,where,pattern,action)
- local pw=patches[what]
- if pw then
- local ww=pw[where]
- if ww then
- ww[pattern]=action
- else
- pw[where]={ [pattern]=action }
- if not known[where] then
- nofsteps=nofsteps+1
- order[nofsteps]=where
- known[where]=nofsteps
- end
- end
- end
+ end
+ ioflush()
+ end
+ if trace then
+ report("%s enhancing file %a","stop",filename)
+ end
+ ioflush()
+ end
+ local function register(what,action)
+ if action then
+ if actions[what] then
+ else
+ nofsteps=nofsteps+1
+ order[nofsteps]=what
+ known[what]=nofsteps
+ end
+ actions[what]=action
+ else
+ report("bad enhancer %a",what)
+ end
+ end
+ local function patch(what,where,pattern,action)
+ local pw=patches[what]
+ if pw then
+ local ww=pw[where]
+ if ww then
+ ww[pattern]=action
+ else
+ pw[where]={ [pattern]=action }
+ if not known[where] then
+ nofsteps=nofsteps+1
+ order[nofsteps]=where
+ known[where]=nofsteps
end
- enhancers={
- register=register,
- apply=apply,
- patch=patch,
- report=report,
- patches={
- register=patch,
- report=report,
- },
- }
- handler.enhancers=enhancers
+ end
end
- return enhancers
+ end
+ enhancers={
+ register=register,
+ apply=apply,
+ patch=patch,
+ report=report,
+ patches={
+ register=patch,
+ report=report,
+ },
+ }
+ handler.enhancers=enhancers
end
- setmetatable(newenhancer,{
- __call=function(t,k) local v=t[k] return v end,
- __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end,
- })
+ return enhancers
+ end
+ setmetatable(newenhancer,{
+ __call=function(t,k) local v=t[k] return v end,
+ __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end,
+ })
end
function constructors.checkedfeatures(what,features)
- local defaults=handlers[what].features.defaults
- if features and next(features) then
- features=fastcopy(features)
- for key,value in next,defaults do
- if features[key]==nil then
- features[key]=value
- end
- end
- return features
- else
- return fastcopy(defaults)
- end
+ local defaults=handlers[what].features.defaults
+ if features and next(features) then
+ features=fastcopy(features)
+ for key,value in next,defaults do
+ if features[key]==nil then
+ features[key]=value
+ end
+ end
+ return features
+ else
+ return fastcopy(defaults)
+ end
end
function constructors.initializefeatures(what,tfmdata,features,trace,report)
- if features and next(features) then
- local properties=tfmdata.properties or {}
- local whathandler=handlers[what]
- local whatfeatures=whathandler.features
- local whatmodechecker=whatfeatures.modechecker
- local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base"
- properties.mode=mode
- features.mode=mode
- local done={}
- while true do
- local redo=false
- local initializers=whatfeatures.initializers[mode]
- if initializers then
- for i=1,#initializers do
- local step=initializers[i]
- local feature=step.name
- local value=features[feature]
- if not value then
- elseif done[feature] then
- else
- local action=step.action
- if trace then
- report("initializing feature %a to %a for mode %a for font %a",feature,
- value,mode,tfmdata.properties.fullname)
- end
- action(tfmdata,value,features)
- if mode~=properties.mode or mode~=features.mode then
- if whatmodechecker then
- properties.mode=whatmodechecker(tfmdata,features,properties.mode)
- features.mode=properties.mode
- end
- if mode~=properties.mode then
- mode=properties.mode
- redo=true
- end
- end
- done[feature]=true
- end
- if redo then
- break
- end
- end
- if not redo then
- break
- end
- else
- break
+ if features and next(features) then
+ local properties=tfmdata.properties or {}
+ local whathandler=handlers[what]
+ local whatfeatures=whathandler.features
+ local whatmodechecker=whatfeatures.modechecker
+ local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base"
+ properties.mode=mode
+ features.mode=mode
+ local done={}
+ while true do
+ local redo=false
+ local initializers=whatfeatures.initializers[mode]
+ if initializers then
+ for i=1,#initializers do
+ local step=initializers[i]
+ local feature=step.name
+ local value=features[feature]
+ if not value then
+ elseif done[feature] then
+ else
+ local action=step.action
+ if trace then
+ report("initializing feature %a to %a for mode %a for font %a",feature,
+ value,mode,tfmdata.properties.fullname)
+ end
+ action(tfmdata,value,features)
+ if mode~=properties.mode or mode~=features.mode then
+ if whatmodechecker then
+ properties.mode=whatmodechecker(tfmdata,features,properties.mode)
+ features.mode=properties.mode
+ end
+ if mode~=properties.mode then
+ mode=properties.mode
+ redo=true
+ end
end
+ done[feature]=true
+ end
+ if redo then
+ break
+ end
end
- properties.mode=mode
- return true
- else
- return false
+ if not redo then
+ break
+ end
+ else
+ break
+ end
end
+ properties.mode=mode
+ return true
+ else
+ return false
+ end
end
function constructors.collectprocessors(what,tfmdata,features,trace,report)
- local processes,nofprocesses={},0
- if features and next(features) then
- local properties=tfmdata.properties
- local whathandler=handlers[what]
- local whatfeatures=whathandler.features
- local whatprocessors=whatfeatures.processors
- local mode=properties.mode
- local processors=whatprocessors[mode]
- if processors then
- for i=1,#processors do
- local step=processors[i]
- local feature=step.name
- if features[feature] then
- local action=step.action
- if trace then
- report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname)
- end
- if action then
- nofprocesses=nofprocesses+1
- processes[nofprocesses]=action
- end
- end
- end
- elseif trace then
- report("no feature processors for mode %a for font %a",mode,properties.fullname)
+ local processes,nofprocesses={},0
+ if features and next(features) then
+ local properties=tfmdata.properties
+ local whathandler=handlers[what]
+ local whatfeatures=whathandler.features
+ local whatprocessors=whatfeatures.processors
+ local mode=properties.mode
+ local processors=whatprocessors[mode]
+ if processors then
+ for i=1,#processors do
+ local step=processors[i]
+ local feature=step.name
+ if features[feature] then
+ local action=step.action
+ if trace then
+ report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname)
+ end
+ if action then
+ nofprocesses=nofprocesses+1
+ processes[nofprocesses]=action
+ end
end
+ end
+ elseif trace then
+ report("no feature processors for mode %a for font %a",mode,properties.fullname)
end
- return processes
+ end
+ return processes
end
function constructors.applymanipulators(what,tfmdata,features,trace,report)
- if features and next(features) then
- local properties=tfmdata.properties
- local whathandler=handlers[what]
- local whatfeatures=whathandler.features
- local whatmanipulators=whatfeatures.manipulators
- local mode=properties.mode
- local manipulators=whatmanipulators[mode]
- if manipulators then
- for i=1,#manipulators do
- local step=manipulators[i]
- local feature=step.name
- local value=features[feature]
- if value then
- local action=step.action
- if trace then
- report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname)
- end
- if action then
- action(tfmdata,feature,value)
- end
- end
- end
+ if features and next(features) then
+ local properties=tfmdata.properties
+ local whathandler=handlers[what]
+ local whatfeatures=whathandler.features
+ local whatmanipulators=whatfeatures.manipulators
+ local mode=properties.mode
+ local manipulators=whatmanipulators[mode]
+ if manipulators then
+ for i=1,#manipulators do
+ local step=manipulators[i]
+ local feature=step.name
+ local value=features[feature]
+ if value then
+ local action=step.action
+ if trace then
+ report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname)
+ end
+ if action then
+ action(tfmdata,feature,value)
+ end
end
+ end
end
+ end
end
function constructors.addcoreunicodes(unicodes)
- if not unicodes then
- unicodes={}
- end
- unicodes.space=0x0020
- unicodes.hyphen=0x002D
- unicodes.zwj=0x200D
- unicodes.zwnj=0x200C
- return unicodes
+ if not unicodes then
+ unicodes={}
+ end
+ unicodes.space=0x0020
+ unicodes.hyphen=0x002D
+ unicodes.zwj=0x200D
+ unicodes.zwnj=0x200C
+ return unicodes
end
end -- closure
@@ -9637,11 +9637,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['luatex-font-enc']={
- version=1.001,
- comment="companion to luatex-*.tex",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if context then
--removed
@@ -9653,55 +9653,55 @@ fonts.encodings=encodings
encodings.agl={}
encodings.known={}
setmetatable(encodings.agl,{ __index=function(t,k)
- if k=="unicodes" then
- logs.report("fonts","loading (extended) adobe glyph list")
- local unicodes=dofile(resolvers.findfile("font-age.lua"))
- encodings.agl={ unicodes=unicodes }
- return unicodes
- else
- return nil
- end
+ if k=="unicodes" then
+ logs.report("fonts","loading (extended) adobe glyph list")
+ local unicodes=dofile(resolvers.findfile("font-age.lua"))
+ encodings.agl={ unicodes=unicodes }
+ return unicodes
+ else
+ return nil
+ end
end })
encodings.cache=containers.define("fonts","enc",encodings.version,true)
function encodings.load(filename)
- local name=file.removesuffix(filename)
- local data=containers.read(encodings.cache,name)
- if data then
- return data
- end
- local vector,tag,hash,unicodes={},"",{},{}
- local foundname=resolvers.findfile(filename,'enc')
- if foundname and foundname~="" then
- local ok,encoding,size=resolvers.loadbinfile(foundname)
- if ok and encoding then
- encoding=string.gsub(encoding,"%%(.-)\n","")
- local unicoding=encodings.agl.unicodes
- local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def")
- local i=0
- for ch in string.gmatch(vec,"/([%a%d%.]+)") do
- if ch~=".notdef" then
- vector[i]=ch
- if not hash[ch] then
- hash[ch]=i
- else
- end
- local u=unicoding[ch]
- if u then
- unicodes[u]=i
- end
- end
- i=i+1
- end
+ local name=file.removesuffix(filename)
+ local data=containers.read(encodings.cache,name)
+ if data then
+ return data
+ end
+ local vector,tag,hash,unicodes={},"",{},{}
+ local foundname=resolvers.findfile(filename,'enc')
+ if foundname and foundname~="" then
+ local ok,encoding,size=resolvers.loadbinfile(foundname)
+ if ok and encoding then
+ encoding=string.gsub(encoding,"%%(.-)\n","")
+ local unicoding=encodings.agl.unicodes
+ local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def")
+ local i=0
+ for ch in string.gmatch(vec,"/([%a%d%.]+)") do
+ if ch~=".notdef" then
+ vector[i]=ch
+ if not hash[ch] then
+ hash[ch]=i
+ else
+ end
+ local u=unicoding[ch]
+ if u then
+ unicodes[u]=i
+ end
end
- end
- local data={
- name=name,
- tag=tag,
- vector=vector,
- hash=hash,
- unicodes=unicodes
- }
- return containers.write(encodings.cache,name,data)
+ i=i+1
+ end
+ end
+ end
+ local data={
+ name=name,
+ tag=tag,
+ vector=vector,
+ hash=hash,
+ unicodes=unicodes
+ }
+ return containers.write(encodings.cache,name,data)
end
end -- closure
@@ -9709,17 +9709,17 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-cid']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format,match,lower=string.format,string.match,string.lower
local tonumber=tonumber
local P,S,R,C,V,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.match
local fonts,logs,trackers=fonts,logs,trackers
-local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
+local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
local report_otf=logs.reporter("fonts","otf loading")
local cid={}
fonts.cid=cid
@@ -9733,128 +9733,128 @@ local periods=period*period
local name=P("/")*C((1-space)^1)
local unicodes,names={},{}
local function do_one(a,b)
- unicodes[tonumber(a)]=tonumber(b,16)
+ unicodes[tonumber(a)]=tonumber(b,16)
end
local function do_range(a,b,c)
- c=tonumber(c,16)
- for i=tonumber(a),tonumber(b) do
- unicodes[i]=c
- c=c+1
- end
+ c=tonumber(c,16)
+ for i=tonumber(a),tonumber(b) do
+ unicodes[i]=c
+ c=c+1
+ end
end
local function do_name(a,b)
- names[tonumber(a)]=b
+ names[tonumber(a)]=b
end
local grammar=P { "start",
- start=number*spaces*number*V("series"),
- series=(spaces*(V("one")+V("range")+V("named")))^1,
- one=(number*spaces*number)/do_one,
- range=(number*periods*number*spaces*number)/do_range,
- named=(number*spaces*name)/do_name
+ start=number*spaces*number*V("series"),
+ series=(spaces*(V("one")+V("range")+V("named")))^1,
+ one=(number*spaces*number)/do_one,
+ range=(number*periods*number*spaces*number)/do_range,
+ named=(number*spaces*name)/do_name
}
local function loadcidfile(filename)
- local data=io.loaddata(filename)
- if data then
- unicodes,names={},{}
- lpegmatch(grammar,data)
- local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$")
- return {
- supplement=supplement,
- registry=registry,
- ordering=ordering,
- filename=filename,
- unicodes=unicodes,
- names=names,
- }
- end
+ local data=io.loaddata(filename)
+ if data then
+ unicodes,names={},{}
+ lpegmatch(grammar,data)
+ local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$")
+ return {
+ supplement=supplement,
+ registry=registry,
+ ordering=ordering,
+ filename=filename,
+ unicodes=unicodes,
+ names=names,
+ }
+ end
end
cid.loadfile=loadcidfile
local template="%s-%s-%s.cidmap"
local function locate(registry,ordering,supplement)
- local filename=format(template,registry,ordering,supplement)
- local hashname=lower(filename)
- local found=cidmap[hashname]
- if not found then
+ local filename=format(template,registry,ordering,supplement)
+ local hashname=lower(filename)
+ local found=cidmap[hashname]
+ if not found then
+ if trace_loading then
+ report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename)
+ end
+ local fullname=resolvers.findfile(filename,'cid') or ""
+ if fullname~="" then
+ found=loadcidfile(fullname)
+ if found then
if trace_loading then
- report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename)
- end
- local fullname=resolvers.findfile(filename,'cid') or ""
- if fullname~="" then
- found=loadcidfile(fullname)
- if found then
- if trace_loading then
- report_otf("using cidmap file %a",filename)
- end
- cidmap[hashname]=found
- found.usedname=file.basename(filename)
- end
+ report_otf("using cidmap file %a",filename)
end
+ cidmap[hashname]=found
+ found.usedname=file.basename(filename)
+ end
end
- return found
+ end
+ return found
end
function cid.getmap(specification)
- if not specification then
- report_otf("invalid cidinfo specification, table expected")
- return
- end
- local registry=specification.registry
- local ordering=specification.ordering
- local supplement=specification.supplement
- local filename=format(registry,ordering,supplement)
- local lowername=lower(filename)
- local found=cidmap[lowername]
- if found then
- return found
- end
- if ordering=="Identity" then
- local found={
- supplement=supplement,
- registry=registry,
- ordering=ordering,
- filename=filename,
- unicodes={},
- names={},
- }
- cidmap[lowername]=found
- return found
- end
- if trace_loading then
- report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement)
- end
- found=locate(registry,ordering,supplement)
- if not found then
- local supnum=tonumber(supplement)
- local cidnum=nil
- if supnum<cidmax then
- for s=supnum+1,cidmax do
- local c=locate(registry,ordering,s)
- if c then
- found,cidnum=c,s
- break
- end
- end
+ if not specification then
+ report_otf("invalid cidinfo specification, table expected")
+ return
+ end
+ local registry=specification.registry
+ local ordering=specification.ordering
+ local supplement=specification.supplement
+ local filename=format(registry,ordering,supplement)
+ local lowername=lower(filename)
+ local found=cidmap[lowername]
+ if found then
+ return found
+ end
+ if ordering=="Identity" then
+ local found={
+ supplement=supplement,
+ registry=registry,
+ ordering=ordering,
+ filename=filename,
+ unicodes={},
+ names={},
+ }
+ cidmap[lowername]=found
+ return found
+ end
+ if trace_loading then
+ report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement)
+ end
+ found=locate(registry,ordering,supplement)
+ if not found then
+ local supnum=tonumber(supplement)
+ local cidnum=nil
+ if supnum<cidmax then
+ for s=supnum+1,cidmax do
+ local c=locate(registry,ordering,s)
+ if c then
+ found,cidnum=c,s
+ break
end
- if not found and supnum>0 then
- for s=supnum-1,0,-1 do
- local c=locate(registry,ordering,s)
- if c then
- found,cidnum=c,s
- break
- end
- end
+ end
+ end
+ if not found and supnum>0 then
+ for s=supnum-1,0,-1 do
+ local c=locate(registry,ordering,s)
+ if c then
+ found,cidnum=c,s
+ break
end
- registry=lower(registry)
- ordering=lower(ordering)
- if found and cidnum>0 then
- for s=0,cidnum-1 do
- local filename=format(template,registry,ordering,s)
- if not cidmap[filename] then
- cidmap[filename]=found
- end
- end
+ end
+ end
+ registry=lower(registry)
+ ordering=lower(ordering)
+ if found and cidnum>0 then
+ for s=0,cidnum-1 do
+ local filename=format(template,registry,ordering,s)
+ if not cidmap[filename] then
+ cidmap[filename]=found
end
+ end
end
- return found
+ end
+ return found
end
end -- closure
@@ -9862,11 +9862,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-map']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber,next,type=tonumber,next,type
local match,format,find,concat,gsub,lower=string.match,string.format,string.find,table.concat,string.gsub,string.lower
@@ -9874,10 +9874,10 @@ local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.m
local formatters=string.formatters
local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
local rshift=bit32.rshift
-local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end)
-local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end)
+local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end)
+local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end)
local report_fonts=logs.reporter("fonts","loading")
-local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end)
+local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end)
local fonts=fonts or {}
local mappings=fonts.mappings or {}
fonts.mappings=mappings
@@ -9888,82 +9888,82 @@ local hexsix=(hex*hex*hex^-4)/function(s) return tonumber(s,16) end
local dec=(R("09")^1)/tonumber
local period=P(".")
local unicode=(P("uni")+P("UNI"))*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true))
-local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true))
+local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true))
local index=P("index")*dec*Cc(false)
local parser=unicode+ucode+index
local parsers={}
local function makenameparser(str)
- if not str or str=="" then
- return parser
- else
- local p=parsers[str]
- if not p then
- p=P(str)*period*dec*Cc(false)
- parsers[str]=p
- end
- return p
+ if not str or str=="" then
+ return parser
+ else
+ local p=parsers[str]
+ if not p then
+ p=P(str)*period*dec*Cc(false)
+ parsers[str]=p
end
+ return p
+ end
end
local f_single=formatters["%04X"]
local f_double=formatters["%04X%04X"]
local function tounicode16(unicode)
- if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then
- return f_single(unicode)
- else
- unicode=unicode-0x10000
- return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
- end
+ if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then
+ return f_single(unicode)
+ else
+ unicode=unicode-0x10000
+ return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+ end
end
local function tounicode16sequence(unicodes)
- local t={}
- for l=1,#unicodes do
- local u=unicodes[l]
- if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then
- t[l]=f_single(u)
- else
- u=u-0x10000
- t[l]=f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
- end
+ local t={}
+ for l=1,#unicodes do
+ local u=unicodes[l]
+ if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then
+ t[l]=f_single(u)
+ else
+ u=u-0x10000
+ t[l]=f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
end
- return concat(t)
+ end
+ return concat(t)
end
local unknown=f_single(0xFFFD)
local hash={}
local conc={}
table.setmetatableindex(hash,function(t,k)
- if k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then
- v=f_single(k)
- else
- local k=k-0x10000
- v=f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
- end
- t[k]=v
- return v
+ if k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then
+ v=f_single(k)
+ else
+ local k=k-0x10000
+ v=f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
+ end
+ t[k]=v
+ return v
end)
local function tounicode(k)
- if type(k)=="table" then
- local n=#k
- for l=1,n do
- conc[l]=hash[k[l]]
- end
- return concat(conc,"",1,n)
- elseif k>=0x00E000 and k<=0x00F8FF then
- return unknown
- elseif k>=0x0F0000 and k<=0x0FFFFF then
- return unknown
- elseif k>=0x100000 and k<=0x10FFFF then
- return unknown
- else
- return hash[k]
- end
+ if type(k)=="table" then
+ local n=#k
+ for l=1,n do
+ conc[l]=hash[k[l]]
+ end
+ return concat(conc,"",1,n)
+ elseif k>=0x00E000 and k<=0x00F8FF then
+ return unknown
+ elseif k>=0x0F0000 and k<=0x0FFFFF then
+ return unknown
+ elseif k>=0x100000 and k<=0x10FFFF then
+ return unknown
+ else
+ return hash[k]
+ end
end
local function fromunicode16(str)
- if #str==4 then
- return tonumber(str,16)
- else
- local l,r=match(str,"(....)(....)")
- return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00
- end
+ if #str==4 then
+ return tonumber(str,16)
+ else
+ local l,r=match(str,"(....)(....)")
+ return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00
+ end
end
mappings.makenameparser=makenameparser
mappings.tounicode=tounicode
@@ -9974,276 +9974,276 @@ local ligseparator=P("_")
local varseparator=P(".")
local namesplitter=Ct(C((1-ligseparator-varseparator)^1)*(ligseparator*C((1-ligseparator-varseparator)^1))^0)
do
- local overloads={
- IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 },
- ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 },
- ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 },
- fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 },
- fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 },
- ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 },
- ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 },
- fj={ name="f_j",unicode={ 0x66,0x6A } },
- fk={ name="f_k",unicode={ 0x66,0x6B } },
- }
- local o=allocate {}
- for k,v in next,overloads do
- local name=v.name
- local mess=v.mess
- if name then
- o[name]=v
- end
- if mess then
- o[mess]=v
- end
- o[k]=v
+ local overloads={
+ IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 },
+ ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 },
+ ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 },
+ fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 },
+ fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 },
+ ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 },
+ ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 },
+ fj={ name="f_j",unicode={ 0x66,0x6A } },
+ fk={ name="f_k",unicode={ 0x66,0x6B } },
+ }
+ local o=allocate {}
+ for k,v in next,overloads do
+ local name=v.name
+ local mess=v.mess
+ if name then
+ o[name]=v
end
- mappings.overloads=o
+ if mess then
+ o[mess]=v
+ end
+ o[k]=v
+ end
+ mappings.overloads=o
end
function mappings.addtounicode(data,filename,checklookups,forceligatures)
- local resources=data.resources
- local unicodes=resources.unicodes
- if not unicodes then
- if trace_mapping then
- report_fonts("no unicode list, quitting tounicode for %a",filename)
- end
- return
+ local resources=data.resources
+ local unicodes=resources.unicodes
+ if not unicodes then
+ if trace_mapping then
+ report_fonts("no unicode list, quitting tounicode for %a",filename)
end
- local properties=data.properties
- local descriptions=data.descriptions
- local overloads=mappings.overloads
- unicodes['space']=unicodes['space'] or 32
- unicodes['hyphen']=unicodes['hyphen'] or 45
- unicodes['zwj']=unicodes['zwj'] or 0x200D
- unicodes['zwnj']=unicodes['zwnj'] or 0x200C
- local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
- local unicodevector=fonts.encodings.agl.unicodes or {}
- local contextvector=fonts.encodings.agl.ctxcodes or {}
- local missing={}
- local nofmissing=0
- local oparser=nil
- local cidnames=nil
- local cidcodes=nil
- local cidinfo=properties.cidinfo
- local usedmap=cidinfo and fonts.cid.getmap(cidinfo)
- local uparser=makenameparser()
- if usedmap then
- oparser=usedmap and makenameparser(cidinfo.ordering)
- cidnames=usedmap.names
- cidcodes=usedmap.unicodes
- end
- local ns=0
- local nl=0
- local dlist=sortedkeys(descriptions)
- for i=1,#dlist do
- local du=dlist[i]
- local glyph=descriptions[du]
- local name=glyph.name
- if name then
- local overload=overloads[name] or overloads[du]
- if overload then
- glyph.unicode=overload.unicode
- else
- local gu=glyph.unicode
- if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then
- local unicode=unicodevector[name] or contextvector[name]
+ return
+ end
+ local properties=data.properties
+ local descriptions=data.descriptions
+ local overloads=mappings.overloads
+ unicodes['space']=unicodes['space'] or 32
+ unicodes['hyphen']=unicodes['hyphen'] or 45
+ unicodes['zwj']=unicodes['zwj'] or 0x200D
+ unicodes['zwnj']=unicodes['zwnj'] or 0x200C
+ local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
+ local unicodevector=fonts.encodings.agl.unicodes or {}
+ local contextvector=fonts.encodings.agl.ctxcodes or {}
+ local missing={}
+ local nofmissing=0
+ local oparser=nil
+ local cidnames=nil
+ local cidcodes=nil
+ local cidinfo=properties.cidinfo
+ local usedmap=cidinfo and fonts.cid.getmap(cidinfo)
+ local uparser=makenameparser()
+ if usedmap then
+ oparser=usedmap and makenameparser(cidinfo.ordering)
+ cidnames=usedmap.names
+ cidcodes=usedmap.unicodes
+ end
+ local ns=0
+ local nl=0
+ local dlist=sortedkeys(descriptions)
+ for i=1,#dlist do
+ local du=dlist[i]
+ local glyph=descriptions[du]
+ local name=glyph.name
+ if name then
+ local overload=overloads[name] or overloads[du]
+ if overload then
+ glyph.unicode=overload.unicode
+ else
+ local gu=glyph.unicode
+ if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then
+ local unicode=unicodevector[name] or contextvector[name]
+ if unicode then
+ glyph.unicode=unicode
+ ns=ns+1
+ end
+ if (not unicode) and usedmap then
+ local foundindex=lpegmatch(oparser,name)
+ if foundindex then
+ unicode=cidcodes[foundindex]
+ if unicode then
+ glyph.unicode=unicode
+ ns=ns+1
+ else
+ local reference=cidnames[foundindex]
+ if reference then
+ local foundindex=lpegmatch(oparser,reference)
+ if foundindex then
+ unicode=cidcodes[foundindex]
if unicode then
- glyph.unicode=unicode
- ns=ns+1
- end
- if (not unicode) and usedmap then
- local foundindex=lpegmatch(oparser,name)
- if foundindex then
- unicode=cidcodes[foundindex]
- if unicode then
- glyph.unicode=unicode
- ns=ns+1
- else
- local reference=cidnames[foundindex]
- if reference then
- local foundindex=lpegmatch(oparser,reference)
- if foundindex then
- unicode=cidcodes[foundindex]
- if unicode then
- glyph.unicode=unicode
- ns=ns+1
- end
- end
- if not unicode or unicode=="" then
- local foundcodes,multiple=lpegmatch(uparser,reference)
- if foundcodes then
- glyph.unicode=foundcodes
- if multiple then
- nl=nl+1
- unicode=true
- else
- ns=ns+1
- unicode=foundcodes
- end
- end
- end
- end
- end
- end
- end
- if not unicode or unicode=="" then
- local split=lpegmatch(namesplitter,name)
- local nsplit=split and #split or 0
- if nsplit==0 then
- elseif nsplit==1 then
- local base=split[1]
- local u=unicodes[base] or unicodevector[base] or contextvector[name]
- if not u then
- elseif type(u)=="table" then
- if u[1]<private then
- unicode=u
- glyph.unicode=unicode
- end
- elseif u<private then
- unicode=u
- glyph.unicode=unicode
- end
- else
- local t,n={},0
- for l=1,nsplit do
- local base=split[l]
- local u=unicodes[base] or unicodevector[base] or contextvector[name]
- if not u then
- break
- elseif type(u)=="table" then
- if u[1]>=private then
- break
- end
- n=n+1
- t[n]=u[1]
- else
- if u>=private then
- break
- end
- n=n+1
- t[n]=u
- end
- end
- if n>0 then
- if n==1 then
- unicode=t[1]
- else
- unicode=t
- end
- glyph.unicode=unicode
- end
- end
+ glyph.unicode=unicode
+ ns=ns+1
+ end
+ end
+ if not unicode or unicode=="" then
+ local foundcodes,multiple=lpegmatch(uparser,reference)
+ if foundcodes then
+ glyph.unicode=foundcodes
+ if multiple then
nl=nl+1
+ unicode=true
+ else
+ ns=ns+1
+ unicode=foundcodes
+ end
end
- if not unicode or unicode=="" then
- local foundcodes,multiple=lpegmatch(uparser,name)
- if foundcodes then
- glyph.unicode=foundcodes
- if multiple then
- nl=nl+1
- unicode=true
- else
- ns=ns+1
- unicode=foundcodes
- end
- end
- end
- local r=overloads[unicode]
- if r then
- unicode=r.unicode
- glyph.unicode=unicode
- end
- if not unicode then
- missing[du]=true
- nofmissing=nofmissing+1
- end
- else
+ end
end
+ end
end
- else
- local overload=overloads[du]
- if overload then
- glyph.unicode=overload.unicode
- elseif not glyph.unicode then
- missing[du]=true
- nofmissing=nofmissing+1
- end
- end
- end
- if type(checklookups)=="function" then
- checklookups(data,missing,nofmissing)
- end
- local unicoded=0
- local collected=fonts.handlers.otf.readers.getcomponents(data)
- local function resolve(glyph,u)
- local n=#u
- for i=1,n do
- if u[i]>private then
- n=0
- break
- end
- end
- if n>0 then
- if n>1 then
- glyph.unicode=u
+ end
+ if not unicode or unicode=="" then
+ local split=lpegmatch(namesplitter,name)
+ local nsplit=split and #split or 0
+ if nsplit==0 then
+ elseif nsplit==1 then
+ local base=split[1]
+ local u=unicodes[base] or unicodevector[base] or contextvector[name]
+ if not u then
+ elseif type(u)=="table" then
+ if u[1]<private then
+ unicode=u
+ glyph.unicode=unicode
+ end
+ elseif u<private then
+ unicode=u
+ glyph.unicode=unicode
+ end
else
- glyph.unicode=u[1]
- end
- unicoded=unicoded+1
- end
- end
- if not collected then
- elseif forceligatures or force_ligatures then
- for i=1,#dlist do
- local du=dlist[i]
- if du>=private or (du>=0xE000 and du<=0xF8FF) then
- local u=collected[du]
- if u then
- resolve(descriptions[du],u)
+ local t,n={},0
+ for l=1,nsplit do
+ local base=split[l]
+ local u=unicodes[base] or unicodevector[base] or contextvector[name]
+ if not u then
+ break
+ elseif type(u)=="table" then
+ if u[1]>=private then
+ break
+ end
+ n=n+1
+ t[n]=u[1]
+ else
+ if u>=private then
+ break
+ end
+ n=n+1
+ t[n]=u
end
- end
- end
- else
- for i=1,#dlist do
- local du=dlist[i]
- if du>=private or (du>=0xE000 and du<=0xF8FF) then
- local glyph=descriptions[du]
- if glyph.class=="ligature" and not glyph.unicode then
- local u=collected[du]
- if u then
- resolve(glyph,u)
- end
+ end
+ if n>0 then
+ if n==1 then
+ unicode=t[1]
+ else
+ unicode=t
end
+ glyph.unicode=unicode
+ end
end
+ nl=nl+1
+ end
+ if not unicode or unicode=="" then
+ local foundcodes,multiple=lpegmatch(uparser,name)
+ if foundcodes then
+ glyph.unicode=foundcodes
+ if multiple then
+ nl=nl+1
+ unicode=true
+ else
+ ns=ns+1
+ unicode=foundcodes
+ end
+ end
+ end
+ local r=overloads[unicode]
+ if r then
+ unicode=r.unicode
+ glyph.unicode=unicode
+ end
+ if not unicode then
+ missing[du]=true
+ nofmissing=nofmissing+1
+ end
+ else
end
+ end
+ else
+ local overload=overloads[du]
+ if overload then
+ glyph.unicode=overload.unicode
+ elseif not glyph.unicode then
+ missing[du]=true
+ nofmissing=nofmissing+1
+ end
+ end
+ end
+ if type(checklookups)=="function" then
+ checklookups(data,missing,nofmissing)
+ end
+ local unicoded=0
+ local collected=fonts.handlers.otf.readers.getcomponents(data)
+ local function resolve(glyph,u)
+ local n=#u
+ for i=1,n do
+ if u[i]>private then
+ n=0
+ break
+ end
end
- if trace_mapping and unicoded>0 then
- report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded)
+ if n>0 then
+ if n>1 then
+ glyph.unicode=u
+ else
+ glyph.unicode=u[1]
+ end
+ unicoded=unicoded+1
+ end
+ end
+ if not collected then
+ elseif forceligatures or force_ligatures then
+ for i=1,#dlist do
+ local du=dlist[i]
+ if du>=private or (du>=0xE000 and du<=0xF8FF) then
+ local u=collected[du]
+ if u then
+ resolve(descriptions[du],u)
+ end
+ end
end
- if trace_mapping then
- for i=1,#dlist do
- local du=dlist[i]
- local glyph=descriptions[du]
- local name=glyph.name or "-"
- local index=glyph.index or 0
- local unicode=glyph.unicode
- if unicode then
- if type(unicode)=="table" then
- local unicodes={}
- for i=1,#unicode do
- unicodes[i]=formatters("%U",unicode[i])
- end
- report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes)
- else
- report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode)
- end
- else
- report_fonts("internal slot %U, name %a, unicode %U",index,name,du)
- end
+ else
+ for i=1,#dlist do
+ local du=dlist[i]
+ if du>=private or (du>=0xE000 and du<=0xF8FF) then
+ local glyph=descriptions[du]
+ if glyph.class=="ligature" and not glyph.unicode then
+ local u=collected[du]
+ if u then
+ resolve(glyph,u)
+ end
end
+ end
end
- if trace_loading and (ns>0 or nl>0) then
- report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns)
+ end
+ if trace_mapping and unicoded>0 then
+ report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded)
+ end
+ if trace_mapping then
+ for i=1,#dlist do
+ local du=dlist[i]
+ local glyph=descriptions[du]
+ local name=glyph.name or "-"
+ local index=glyph.index or 0
+ local unicode=glyph.unicode
+ if unicode then
+ if type(unicode)=="table" then
+ local unicodes={}
+ for i=1,#unicode do
+ unicodes[i]=formatters("%U",unicode[i])
+ end
+ report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes)
+ else
+ report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode)
+ end
+ else
+ report_fonts("internal slot %U, name %a, unicode %U",index,name,du)
+ end
end
+ end
+ if trace_loading and (ns>0 or nl>0) then
+ report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns)
+ end
end
end -- closure
@@ -10251,11 +10251,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['luatex-fonts-syn']={
- version=1.001,
- comment="companion to luatex-*.tex",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if context then
--removed
@@ -10270,57 +10270,57 @@ local data=nil
local loaded=false
local fileformats={ "lua","tex","other text files" }
function fonts.names.reportmissingbase()
- logs.report("fonts","missing font database, run: mtxrun --script fonts --reload --simple")
- fonts.names.reportmissingbase=nil
+ logs.report("fonts","missing font database, run: mtxrun --script fonts --reload --simple")
+ fonts.names.reportmissingbase=nil
end
function fonts.names.reportmissingname()
- logs.report("fonts","unknown font in font database, run: mtxrun --script fonts --reload --simple")
- fonts.names.reportmissingname=nil
+ logs.report("fonts","unknown font in font database, run: mtxrun --script fonts --reload --simple")
+ fonts.names.reportmissingname=nil
end
function fonts.names.resolve(name,sub)
- if not loaded then
- local basename=fonts.names.basename
- if basename and basename~="" then
- data=containers.read(fonts.names.cache,basename)
- if not data then
- basename=file.addsuffix(basename,"lua")
- for i=1,#fileformats do
- local format=fileformats[i]
- local foundname=resolvers.findfile(basename,format) or ""
- if foundname~="" then
- data=dofile(foundname)
- logs.report("fonts","font database '%s' loaded",foundname)
- break
- end
- end
- end
- end
- loaded=true
- end
- if type(data)=="table" and data.version==fonts.names.version then
- local condensed=string.gsub(string.lower(name),"[^%a%d]","")
- local found=data.mappings and data.mappings[condensed]
- if found then
- local fontname,filename,subfont=found[1],found[2],found[3]
- if subfont then
- return filename,fontname
- else
- return filename,false
- end
- elseif fonts.names.reportmissingname then
- fonts.names.reportmissingname()
- return name,false
+ if not loaded then
+ local basename=fonts.names.basename
+ if basename and basename~="" then
+ data=containers.read(fonts.names.cache,basename)
+ if not data then
+ basename=file.addsuffix(basename,"lua")
+ for i=1,#fileformats do
+ local format=fileformats[i]
+ local foundname=resolvers.findfile(basename,format) or ""
+ if foundname~="" then
+ data=dofile(foundname)
+ logs.report("fonts","font database '%s' loaded",foundname)
+ break
+ end
end
- elseif fonts.names.reportmissingbase then
- fonts.names.reportmissingbase()
+ end
end
+ loaded=true
+ end
+ if type(data)=="table" and data.version==fonts.names.version then
+ local condensed=string.gsub(string.lower(name),"[^%a%d]","")
+ local found=data.mappings and data.mappings[condensed]
+ if found then
+ local fontname,filename,subfont=found[1],found[2],found[3]
+ if subfont then
+ return filename,fontname
+ else
+ return filename,false
+ end
+ elseif fonts.names.reportmissingname then
+ fonts.names.reportmissingname()
+ return name,false
+ end
+ elseif fonts.names.reportmissingbase then
+ fonts.names.reportmissingbase()
+ end
end
fonts.names.resolvespec=fonts.names.resolve
-function fonts.names.getfilename(askedname,suffix)
- return ""
+function fonts.names.getfilename(askedname,suffix)
+ return ""
end
function fonts.names.ignoredfile(filename)
- return false
+ return false
end
end -- closure
@@ -10328,11 +10328,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-vfc']={
- version=1.001,
- comment="companion to font-ini.mkiv and hand-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv and hand-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local select,type=select,type
local insert=table.insert
@@ -10344,83 +10344,83 @@ local push={ "push" }
local pop={ "pop" }
local dummy={ "comment" }
function helpers.prependcommands(commands,...)
- insert(commands,1,push)
- for i=select("#",...),1,-1 do
- local s=(select(i,...))
- if s then
- insert(commands,1,s)
- end
+ insert(commands,1,push)
+ for i=select("#",...),1,-1 do
+ local s=(select(i,...))
+ if s then
+ insert(commands,1,s)
end
- insert(commands,pop)
- return commands
+ end
+ insert(commands,pop)
+ return commands
end
function helpers.appendcommands(commands,...)
- insert(commands,1,push)
- insert(commands,pop)
- for i=1,select("#",...) do
- local s=(select(i,...))
- if s then
- insert(commands,s)
- end
+ insert(commands,1,push)
+ insert(commands,pop)
+ for i=1,select("#",...) do
+ local s=(select(i,...))
+ if s then
+ insert(commands,s)
end
- return commands
+ end
+ return commands
end
function helpers.prependcommandtable(commands,t)
- insert(commands,1,push)
- for i=#t,1,-1 do
- local s=t[i]
- if s then
- insert(commands,1,s)
- end
+ insert(commands,1,push)
+ for i=#t,1,-1 do
+ local s=t[i]
+ if s then
+ insert(commands,1,s)
end
- insert(commands,pop)
- return commands
+ end
+ insert(commands,pop)
+ return commands
end
function helpers.appendcommandtable(commands,t)
- insert(commands,1,push)
- insert(commands,pop)
- for i=1,#t do
- local s=t[i]
- if s then
- insert(commands,s)
- end
+ insert(commands,1,push)
+ insert(commands,pop)
+ for i=1,#t do
+ local s=t[i]
+ if s then
+ insert(commands,s)
end
- return commands
+ end
+ return commands
end
local char=setmetatableindex(function(t,k)
- local v={ "slot",0,k }
- t[k]=v
- return v
+ local v={ "slot",0,k }
+ t[k]=v
+ return v
end)
local right=setmetatableindex(function(t,k)
- local v={ "right",k }
- t[k]=v
- return v
+ local v={ "right",k }
+ t[k]=v
+ return v
end)
local left=setmetatableindex(function(t,k)
- local v={ "right",-k }
- t[k]=v
- return v
+ local v={ "right",-k }
+ t[k]=v
+ return v
end)
local down=setmetatableindex(function(t,k)
- local v={ "down",k }
- t[k]=v
- return v
+ local v={ "down",k }
+ t[k]=v
+ return v
end)
local up=setmetatableindex(function(t,k)
- local v={ "down",-k }
- t[k]=v
- return v
+ local v={ "down",-k }
+ t[k]=v
+ return v
end)
helpers.commands=utilities.storage.allocate {
- char=char,
- right=right,
- left=left,
- down=down,
- up=up,
- push=push,
- pop=pop,
- dummy=dummy,
+ char=char,
+ right=right,
+ left=left,
+ down=down,
+ up=up,
+ push=push,
+ pop=pop,
+ dummy=dummy,
}
end -- closure
@@ -10428,11 +10428,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-otr']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,tonumber=next,type,tonumber
local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub
@@ -10457,7 +10457,7 @@ local otf=handlers.otf or {}
handlers.otf=otf
local readers=otf.readers or {}
otf.readers=readers
-local streamreader=utilities.files
+local streamreader=utilities.files
local streamwriter=utilities.files
readers.streamreader=streamreader
readers.streamwriter=streamwriter
@@ -10467,1785 +10467,1785 @@ local setposition=streamreader.setposition
local skipshort=streamreader.skipshort
local readbytes=streamreader.readbytes
local readstring=streamreader.readstring
-local readbyte=streamreader.readcardinal1
-local readushort=streamreader.readcardinal2
-local readuint=streamreader.readcardinal3
+local readbyte=streamreader.readcardinal1
+local readushort=streamreader.readcardinal2
+local readuint=streamreader.readcardinal3
local readulong=streamreader.readcardinal4
-local readshort=streamreader.readinteger2
-local readlong=streamreader.readinteger4
+local readshort=streamreader.readinteger2
+local readlong=streamreader.readinteger4
local readfixed=streamreader.readfixed4
-local read2dot14=streamreader.read2dot14
-local readfword=readshort
-local readufword=readushort
+local read2dot14=streamreader.read2dot14
+local readfword=readshort
+local readufword=readushort
local readoffset=readushort
local readcardinaltable=streamreader.readcardinaltable
local readintegertable=streamreader.readintegertable
function streamreader.readtag(f)
- return lower(stripstring(readstring(f,4)))
+ return lower(stripstring(readstring(f,4)))
end
local short=2
local ushort=2
local ulong=4
directives.register("fonts.streamreader",function()
- streamreader=utilities.streams
- openfile=streamreader.open
- closefile=streamreader.close
- setposition=streamreader.setposition
- skipshort=streamreader.skipshort
- readbytes=streamreader.readbytes
- readstring=streamreader.readstring
- readbyte=streamreader.readcardinal1
- readushort=streamreader.readcardinal2
- readuint=streamreader.readcardinal3
- readulong=streamreader.readcardinal4
- readshort=streamreader.readinteger2
- readlong=streamreader.readinteger4
- readfixed=streamreader.readfixed4
- read2dot14=streamreader.read2dot14
- readfword=readshort
- readufword=readushort
- readoffset=readushort
- readcardinaltable=streamreader.readcardinaltable
- readintegertable=streamreader.readintegertable
- function streamreader.readtag(f)
- return lower(stripstring(readstring(f,4)))
- end
+ streamreader=utilities.streams
+ openfile=streamreader.open
+ closefile=streamreader.close
+ setposition=streamreader.setposition
+ skipshort=streamreader.skipshort
+ readbytes=streamreader.readbytes
+ readstring=streamreader.readstring
+ readbyte=streamreader.readcardinal1
+ readushort=streamreader.readcardinal2
+ readuint=streamreader.readcardinal3
+ readulong=streamreader.readcardinal4
+ readshort=streamreader.readinteger2
+ readlong=streamreader.readinteger4
+ readfixed=streamreader.readfixed4
+ read2dot14=streamreader.read2dot14
+ readfword=readshort
+ readufword=readushort
+ readoffset=readushort
+ readcardinaltable=streamreader.readcardinaltable
+ readintegertable=streamreader.readintegertable
+ function streamreader.readtag(f)
+ return lower(stripstring(readstring(f,4)))
+ end
end)
local function readlongdatetime(f)
- local a,b,c,d,e,f,g,h=readbytes(f,8)
- return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
+ local a,b,c,d,e,f,g,h=readbytes(f,8)
+ return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h
end
local tableversion=0.004
readers.tableversion=tableversion
local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
local reservednames={ [0]="copyright",
- "family",
- "subfamily",
- "uniqueid",
- "fullname",
- "version",
- "postscriptname",
- "trademark",
- "manufacturer",
- "designer",
- "description",
- "vendorurl",
- "designerurl",
- "license",
- "licenseurl",
- "reserved",
- "typographicfamily",
- "typographicsubfamily",
- "compatiblefullname",
- "sampletext",
- "cidfindfontname",
- "wwsfamily",
- "wwssubfamily",
- "lightbackgroundpalette",
- "darkbackgroundpalette",
- "variationspostscriptnameprefix",
+ "family",
+ "subfamily",
+ "uniqueid",
+ "fullname",
+ "version",
+ "postscriptname",
+ "trademark",
+ "manufacturer",
+ "designer",
+ "description",
+ "vendorurl",
+ "designerurl",
+ "license",
+ "licenseurl",
+ "reserved",
+ "typographicfamily",
+ "typographicsubfamily",
+ "compatiblefullname",
+ "sampletext",
+ "cidfindfontname",
+ "wwsfamily",
+ "wwssubfamily",
+ "lightbackgroundpalette",
+ "darkbackgroundpalette",
+ "variationspostscriptnameprefix",
}
local platforms={ [0]="unicode",
- "macintosh",
- "iso",
- "windows",
- "custom",
+ "macintosh",
+ "iso",
+ "windows",
+ "custom",
}
local encodings={
- unicode={ [0]="unicode 1.0 semantics",
- "unicode 1.1 semantics",
- "iso/iec 10646",
- "unicode 2.0 bmp",
- "unicode 2.0 full",
- "unicode variation sequences",
- "unicode full repertoire",
- },
- macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian",
- "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada",
- "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian",
- "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi",
- "uninterpreted",
- },
- iso={ [0]="7-bit ascii",
- "iso 10646",
- "iso 8859-1",
- },
- windows={ [0]="symbol",
- "unicode bmp",
- "shiftjis",
- "prc",
- "big5",
- "wansung",
- "johab",
- "reserved 7",
- "reserved 8",
- "reserved 9",
- "unicode ucs-4",
- },
- custom={
- }
+ unicode={ [0]="unicode 1.0 semantics",
+ "unicode 1.1 semantics",
+ "iso/iec 10646",
+ "unicode 2.0 bmp",
+ "unicode 2.0 full",
+ "unicode variation sequences",
+ "unicode full repertoire",
+ },
+ macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian",
+ "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada",
+ "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian",
+ "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi",
+ "uninterpreted",
+ },
+ iso={ [0]="7-bit ascii",
+ "iso 10646",
+ "iso 8859-1",
+ },
+ windows={ [0]="symbol",
+ "unicode bmp",
+ "shiftjis",
+ "prc",
+ "big5",
+ "wansung",
+ "johab",
+ "reserved 7",
+ "reserved 8",
+ "reserved 9",
+ "unicode ucs-4",
+ },
+ custom={
+ }
}
local decoders={
- unicode={},
- macintosh={},
- iso={},
- windows={
- ["unicode semantics"]=utf16_to_utf8_be,
- ["unicode bmp"]=utf16_to_utf8_be,
- ["unicode full"]=utf16_to_utf8_be,
- ["unicode 1.0 semantics"]=utf16_to_utf8_be,
- ["unicode 1.1 semantics"]=utf16_to_utf8_be,
- ["unicode 2.0 bmp"]=utf16_to_utf8_be,
- ["unicode 2.0 full"]=utf16_to_utf8_be,
- ["unicode variation sequences"]=utf16_to_utf8_be,
- ["unicode full repertoire"]=utf16_to_utf8_be,
- },
- custom={},
+ unicode={},
+ macintosh={},
+ iso={},
+ windows={
+ ["unicode semantics"]=utf16_to_utf8_be,
+ ["unicode bmp"]=utf16_to_utf8_be,
+ ["unicode full"]=utf16_to_utf8_be,
+ ["unicode 1.0 semantics"]=utf16_to_utf8_be,
+ ["unicode 1.1 semantics"]=utf16_to_utf8_be,
+ ["unicode 2.0 bmp"]=utf16_to_utf8_be,
+ ["unicode 2.0 full"]=utf16_to_utf8_be,
+ ["unicode variation sequences"]=utf16_to_utf8_be,
+ ["unicode full repertoire"]=utf16_to_utf8_be,
+ },
+ custom={},
}
local languages={
- unicode={
- [ 0]="english",
- },
- macintosh={
- [ 0]="english",
- },
- iso={},
- windows={
- [0x0409]="english - united states",
- },
- custom={},
+ unicode={
+ [ 0]="english",
+ },
+ macintosh={
+ [ 0]="english",
+ },
+ iso={},
+ windows={
+ [0x0409]="english - united states",
+ },
+ custom={},
}
local standardromanencoding={ [0]=
- "notdef",".null","nonmarkingreturn","space","exclam","quotedbl",
- "numbersign","dollar","percent","ampersand","quotesingle","parenleft",
- "parenright","asterisk","plus","comma","hyphen","period","slash",
- "zero","one","two","three","four","five","six","seven","eight",
- "nine","colon","semicolon","less","equal","greater","question","at",
- "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O",
- "P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft",
- "backslash","bracketright","asciicircum","underscore","grave","a","b",
- "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q",
- "r","s","t","u","v","w","x","y","z","braceleft","bar",
- "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute",
- "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex",
- "adieresis","atilde","aring","ccedilla","eacute","egrave",
- "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis",
- "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute",
- "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling",
- "section","bullet","paragraph","germandbls","registered","copyright",
- "trademark","acute","dieresis","notequal","AE","Oslash","infinity",
- "plusminus","lessequal","greaterequal","yen","mu","partialdiff",
- "summation","product","pi","integral","ordfeminine","ordmasculine",
- "Omega","ae","oslash","questiondown","exclamdown","logicalnot",
- "radical","florin","approxequal","Delta","guillemotleft",
- "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde",
- "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright",
- "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis",
- "fraction","currency","guilsinglleft","guilsinglright","fi","fl",
- "daggerdbl","periodcentered","quotesinglbase","quotedblbase",
- "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave",
- "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex",
- "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi",
- "circumflex","tilde","macron","breve","dotaccent","ring","cedilla",
- "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron",
- "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn",
- "thorn","minus","multiply","onesuperior","twosuperior","threesuperior",
- "onehalf","onequarter","threequarters","franc","Gbreve","gbreve",
- "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron",
- "dcroat",
+ "notdef",".null","nonmarkingreturn","space","exclam","quotedbl",
+ "numbersign","dollar","percent","ampersand","quotesingle","parenleft",
+ "parenright","asterisk","plus","comma","hyphen","period","slash",
+ "zero","one","two","three","four","five","six","seven","eight",
+ "nine","colon","semicolon","less","equal","greater","question","at",
+ "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O",
+ "P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft",
+ "backslash","bracketright","asciicircum","underscore","grave","a","b",
+ "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q",
+ "r","s","t","u","v","w","x","y","z","braceleft","bar",
+ "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute",
+ "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex",
+ "adieresis","atilde","aring","ccedilla","eacute","egrave",
+ "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis",
+ "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute",
+ "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling",
+ "section","bullet","paragraph","germandbls","registered","copyright",
+ "trademark","acute","dieresis","notequal","AE","Oslash","infinity",
+ "plusminus","lessequal","greaterequal","yen","mu","partialdiff",
+ "summation","product","pi","integral","ordfeminine","ordmasculine",
+ "Omega","ae","oslash","questiondown","exclamdown","logicalnot",
+ "radical","florin","approxequal","Delta","guillemotleft",
+ "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde",
+ "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright",
+ "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis",
+ "fraction","currency","guilsinglleft","guilsinglright","fi","fl",
+ "daggerdbl","periodcentered","quotesinglbase","quotedblbase",
+ "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave",
+ "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex",
+ "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi",
+ "circumflex","tilde","macron","breve","dotaccent","ring","cedilla",
+ "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron",
+ "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn",
+ "thorn","minus","multiply","onesuperior","twosuperior","threesuperior",
+ "onehalf","onequarter","threequarters","franc","Gbreve","gbreve",
+ "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron",
+ "dcroat",
}
local weights={
- [100]="thin",
- [200]="extralight",
- [300]="light",
- [400]="normal",
- [500]="medium",
- [600]="semibold",
- [700]="bold",
- [800]="extrabold",
- [900]="black",
+ [100]="thin",
+ [200]="extralight",
+ [300]="light",
+ [400]="normal",
+ [500]="medium",
+ [600]="semibold",
+ [700]="bold",
+ [800]="extrabold",
+ [900]="black",
}
local widths={
- [1]="ultracondensed",
- [2]="extracondensed",
- [3]="condensed",
- [4]="semicondensed",
- [5]="normal",
- [6]="semiexpanded",
- [7]="expanded",
- [8]="extraexpanded",
- [9]="ultraexpanded",
+ [1]="ultracondensed",
+ [2]="extracondensed",
+ [3]="condensed",
+ [4]="semicondensed",
+ [5]="normal",
+ [6]="semiexpanded",
+ [7]="expanded",
+ [8]="extraexpanded",
+ [9]="ultraexpanded",
}
setmetatableindex(weights,function(t,k)
- local r=floor((k+50)/100)*100
- local v=(r>900 and "black") or rawget(t,r) or "normal"
- return v
+ local r=floor((k+50)/100)*100
+ local v=(r>900 and "black") or rawget(t,r) or "normal"
+ return v
end)
setmetatableindex(widths,function(t,k)
- return "normal"
+ return "normal"
end)
local panoseweights={
- [ 0]="normal",
- [ 1]="normal",
- [ 2]="verylight",
- [ 3]="light",
- [ 4]="thin",
- [ 5]="book",
- [ 6]="medium",
- [ 7]="demi",
- [ 8]="bold",
- [ 9]="heavy",
- [10]="black",
+ [ 0]="normal",
+ [ 1]="normal",
+ [ 2]="verylight",
+ [ 3]="light",
+ [ 4]="thin",
+ [ 5]="book",
+ [ 6]="medium",
+ [ 7]="demi",
+ [ 8]="bold",
+ [ 9]="heavy",
+ [10]="black",
}
local panosewidths={
- [ 0]="normal",
- [ 1]="normal",
- [ 2]="normal",
- [ 3]="normal",
- [ 4]="normal",
- [ 5]="expanded",
- [ 6]="condensed",
- [ 7]="veryexpanded",
- [ 8]="verycondensed",
- [ 9]="monospaced",
+ [ 0]="normal",
+ [ 1]="normal",
+ [ 2]="normal",
+ [ 3]="normal",
+ [ 4]="normal",
+ [ 5]="expanded",
+ [ 6]="condensed",
+ [ 7]="veryexpanded",
+ [ 8]="verycondensed",
+ [ 9]="monospaced",
}
local helpers={}
readers.helpers=helpers
local function gotodatatable(f,fontdata,tag,criterium)
- if criterium and f then
- local tables=fontdata.tables
- if tables then
- local datatable=tables[tag]
- if datatable then
- local tableoffset=datatable.offset
- setposition(f,tableoffset)
- return tableoffset
- end
- else
- report("no tables")
- end
+ if criterium and f then
+ local tables=fontdata.tables
+ if tables then
+ local datatable=tables[tag]
+ if datatable then
+ local tableoffset=datatable.offset
+ setposition(f,tableoffset)
+ return tableoffset
+ end
+ else
+ report("no tables")
end
+ end
end
local function reportskippedtable(f,fontdata,tag,criterium)
- if criterium and f then
- local tables=fontdata.tables
- if tables then
- local datatable=tables[tag]
- if datatable then
- report("loading of table %a skipped",tag)
- end
- else
- report("no tables")
- end
+ if criterium and f then
+ local tables=fontdata.tables
+ if tables then
+ local datatable=tables[tag]
+ if datatable then
+ report("loading of table %a skipped",tag)
+ end
+ else
+ report("no tables")
end
+ end
end
local function setvariabledata(fontdata,tag,data)
- local variabledata=fontdata.variabledata
- if variabledata then
- variabledata[tag]=data
- else
- fontdata.variabledata={ [tag]=data }
- end
+ local variabledata=fontdata.variabledata
+ if variabledata then
+ variabledata[tag]=data
+ else
+ fontdata.variabledata={ [tag]=data }
+ end
end
helpers.gotodatatable=gotodatatable
helpers.setvariabledata=setvariabledata
helpers.reportskippedtable=reportskippedtable
local platformnames={
- postscriptname=true,
- fullname=true,
- family=true,
- subfamily=true,
- typographicfamily=true,
- typographicsubfamily=true,
- compatiblefullname=true,
+ postscriptname=true,
+ fullname=true,
+ family=true,
+ subfamily=true,
+ typographicfamily=true,
+ typographicsubfamily=true,
+ compatiblefullname=true,
}
local platformextras={
- uniqueid=true,
- version=true,
- copyright=true,
- license=true,
- licenseurl=true,
- manufacturer=true,
- vendorurl=true,
+ uniqueid=true,
+ version=true,
+ copyright=true,
+ license=true,
+ licenseurl=true,
+ manufacturer=true,
+ vendorurl=true,
}
function readers.name(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"name",true)
- if tableoffset then
- local format=readushort(f)
- local nofnames=readushort(f)
- local offset=readushort(f)
- local start=tableoffset+offset
- local namelists={
- unicode={},
- windows={},
- macintosh={},
- }
- for i=1,nofnames do
- local platform=platforms[readushort(f)]
- if platform then
- local namelist=namelists[platform]
- if namelist then
- local encoding=readushort(f)
- local language=readushort(f)
- local encodings=encodings[platform]
- local languages=languages[platform]
- if encodings and languages then
- local encoding=encodings[encoding]
- local language=languages[language]
- if encoding and language then
- local index=readushort(f)
- local name=reservednames[index]
- namelist[#namelist+1]={
- platform=platform,
- encoding=encoding,
- language=language,
- name=name,
- index=index,
- length=readushort(f),
- offset=start+readushort(f),
- }
- else
- skipshort(f,3)
- end
- else
- skipshort(f,3)
- end
- else
- skipshort(f,5)
- end
+ local tableoffset=gotodatatable(f,fontdata,"name",true)
+ if tableoffset then
+ local format=readushort(f)
+ local nofnames=readushort(f)
+ local offset=readushort(f)
+ local start=tableoffset+offset
+ local namelists={
+ unicode={},
+ windows={},
+ macintosh={},
+ }
+ for i=1,nofnames do
+ local platform=platforms[readushort(f)]
+ if platform then
+ local namelist=namelists[platform]
+ if namelist then
+ local encoding=readushort(f)
+ local language=readushort(f)
+ local encodings=encodings[platform]
+ local languages=languages[platform]
+ if encodings and languages then
+ local encoding=encodings[encoding]
+ local language=languages[language]
+ if encoding and language then
+ local index=readushort(f)
+ local name=reservednames[index]
+ namelist[#namelist+1]={
+ platform=platform,
+ encoding=encoding,
+ language=language,
+ name=name,
+ index=index,
+ length=readushort(f),
+ offset=start+readushort(f),
+ }
else
- skipshort(f,5)
+ skipshort(f,3)
end
+ else
+ skipshort(f,3)
+ end
+ else
+ skipshort(f,5)
end
- local names={}
- local done={}
- local extras={}
- local function decoded(platform,encoding,content)
- local decoder=decoders[platform]
- if decoder then
- decoder=decoder[encoding]
- end
- if decoder then
- return decoder(content)
+ else
+ skipshort(f,5)
+ end
+ end
+ local names={}
+ local done={}
+ local extras={}
+ local function decoded(platform,encoding,content)
+ local decoder=decoders[platform]
+ if decoder then
+ decoder=decoder[encoding]
+ end
+ if decoder then
+ return decoder(content)
+ else
+ return content
+ end
+ end
+ local function filter(platform,e,l)
+ local namelist=namelists[platform]
+ for i=1,#namelist do
+ local name=namelist[i]
+ local nametag=name.name
+ local index=name.index
+ if not done[nametag or i] then
+ local encoding=name.encoding
+ local language=name.language
+ if (not e or encoding==e) and (not l or language==l) then
+ setposition(f,name.offset)
+ local content=decoded(platform,encoding,readstring(f,name.length))
+ if nametag then
+ names[nametag]={
+ content=content,
+ platform=platform,
+ encoding=encoding,
+ language=language,
+ }
+ end
+ extras[index]=content
+ done[nametag or i]=true
+ end
+ end
+ end
+ end
+ filter("windows","unicode bmp","english - united states")
+ filter("macintosh","roman","english")
+ filter("windows")
+ filter("macintosh")
+ filter("unicode")
+ fontdata.names=names
+ fontdata.extras=extras
+ if specification.platformnames then
+ local collected={}
+ local platformextras=specification.platformextras and platformextras
+ for platform,namelist in next,namelists do
+ local filtered=false
+ for i=1,#namelist do
+ local entry=namelist[i]
+ local name=entry.name
+ if platformnames[name] or (platformextras and platformextras[name]) then
+ setposition(f,entry.offset)
+ local content=decoded(platform,entry.encoding,readstring(f,entry.length))
+ if filtered then
+ filtered[name]=content
else
- return content
- end
- end
- local function filter(platform,e,l)
- local namelist=namelists[platform]
- for i=1,#namelist do
- local name=namelist[i]
- local nametag=name.name
- local index=name.index
- if not done[nametag or i] then
- local encoding=name.encoding
- local language=name.language
- if (not e or encoding==e) and (not l or language==l) then
- setposition(f,name.offset)
- local content=decoded(platform,encoding,readstring(f,name.length))
- if nametag then
- names[nametag]={
- content=content,
- platform=platform,
- encoding=encoding,
- language=language,
- }
- end
- extras[index]=content
- done[nametag or i]=true
- end
- end
+ filtered={ [name]=content }
end
+ end
end
- filter("windows","unicode bmp","english - united states")
- filter("macintosh","roman","english")
- filter("windows")
- filter("macintosh")
- filter("unicode")
- fontdata.names=names
- fontdata.extras=extras
- if specification.platformnames then
- local collected={}
- local platformextras=specification.platformextras and platformextras
- for platform,namelist in next,namelists do
- local filtered=false
- for i=1,#namelist do
- local entry=namelist[i]
- local name=entry.name
- if platformnames[name] or (platformextras and platformextras[name]) then
- setposition(f,entry.offset)
- local content=decoded(platform,entry.encoding,readstring(f,entry.length))
- if filtered then
- filtered[name]=content
- else
- filtered={ [name]=content }
- end
- end
- end
- if filtered then
- collected[platform]=filtered
- end
- end
- fontdata.platformnames=collected
+ if filtered then
+ collected[platform]=filtered
end
- else
- fontdata.names={}
+ end
+ fontdata.platformnames=collected
end
+ else
+ fontdata.names={}
+ end
end
local validutf=lpeg.patterns.validutf8
local function getname(fontdata,key)
- local names=fontdata.names
- if names then
- local value=names[key]
- if value then
- local content=value.content
- return lpegmatch(validutf,content) and content or nil
- end
+ local names=fontdata.names
+ if names then
+ local value=names[key]
+ if value then
+ local content=value.content
+ return lpegmatch(validutf,content) and content or nil
end
+ end
end
readers["os/2"]=function(f,fontdata)
- local tableoffset=gotodatatable(f,fontdata,"os/2",true)
- if tableoffset then
- local version=readushort(f)
- local windowsmetrics={
- version=version,
- averagewidth=readshort(f),
- weightclass=readushort(f),
- widthclass=readushort(f),
- fstype=readushort(f),
- subscriptxsize=readshort(f),
- subscriptysize=readshort(f),
- subscriptxoffset=readshort(f),
- subscriptyoffset=readshort(f),
- superscriptxsize=readshort(f),
- superscriptysize=readshort(f),
- superscriptxoffset=readshort(f),
- superscriptyoffset=readshort(f),
- strikeoutsize=readshort(f),
- strikeoutpos=readshort(f),
- familyclass=readshort(f),
- panose={ readbytes(f,10) },
- unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) },
- vendor=readstring(f,4),
- fsselection=readushort(f),
- firstcharindex=readushort(f),
- lastcharindex=readushort(f),
- typoascender=readshort(f),
- typodescender=readshort(f),
- typolinegap=readshort(f),
- winascent=readushort(f),
- windescent=readushort(f),
- }
- if version>=1 then
- windowsmetrics.codepageranges={ readulong(f),readulong(f) }
- end
- if version>=2 then
- windowsmetrics.xheight=readshort(f)
- windowsmetrics.capheight=readshort(f)
- windowsmetrics.defaultchar=readushort(f)
- windowsmetrics.breakchar=readushort(f)
- end
- windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass]
- windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass]
- windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]]
- windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]]
- fontdata.windowsmetrics=windowsmetrics
- else
- fontdata.windowsmetrics={}
- end
+ local tableoffset=gotodatatable(f,fontdata,"os/2",true)
+ if tableoffset then
+ local version=readushort(f)
+ local windowsmetrics={
+ version=version,
+ averagewidth=readshort(f),
+ weightclass=readushort(f),
+ widthclass=readushort(f),
+ fstype=readushort(f),
+ subscriptxsize=readshort(f),
+ subscriptysize=readshort(f),
+ subscriptxoffset=readshort(f),
+ subscriptyoffset=readshort(f),
+ superscriptxsize=readshort(f),
+ superscriptysize=readshort(f),
+ superscriptxoffset=readshort(f),
+ superscriptyoffset=readshort(f),
+ strikeoutsize=readshort(f),
+ strikeoutpos=readshort(f),
+ familyclass=readshort(f),
+ panose={ readbytes(f,10) },
+ unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) },
+ vendor=readstring(f,4),
+ fsselection=readushort(f),
+ firstcharindex=readushort(f),
+ lastcharindex=readushort(f),
+ typoascender=readshort(f),
+ typodescender=readshort(f),
+ typolinegap=readshort(f),
+ winascent=readushort(f),
+ windescent=readushort(f),
+ }
+ if version>=1 then
+ windowsmetrics.codepageranges={ readulong(f),readulong(f) }
+ end
+ if version>=2 then
+ windowsmetrics.xheight=readshort(f)
+ windowsmetrics.capheight=readshort(f)
+ windowsmetrics.defaultchar=readushort(f)
+ windowsmetrics.breakchar=readushort(f)
+ end
+ windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass]
+ windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass]
+ windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]]
+ windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]]
+ fontdata.windowsmetrics=windowsmetrics
+ else
+ fontdata.windowsmetrics={}
+ end
end
readers.head=function(f,fontdata)
- local tableoffset=gotodatatable(f,fontdata,"head",true)
- if tableoffset then
- local version=readulong(f)
- local fontversion=readulong(f)
- local fontheader={
- version=version,
- fontversion=number.to16dot16(fontversion),
- fontversionnumber=fontversion,
- checksum=readushort(f)*0x10000+readushort(f),
- magic=readulong(f),
- flags=readushort(f),
- units=readushort(f),
- created=readlongdatetime(f),
- modified=readlongdatetime(f),
- xmin=readshort(f),
- ymin=readshort(f),
- xmax=readshort(f),
- ymax=readshort(f),
- macstyle=readushort(f),
- smallpixels=readushort(f),
- directionhint=readshort(f),
- indextolocformat=readshort(f),
- glyphformat=readshort(f),
- }
- fontdata.fontheader=fontheader
- else
- fontdata.fontheader={}
- end
- fontdata.nofglyphs=0
+ local tableoffset=gotodatatable(f,fontdata,"head",true)
+ if tableoffset then
+ local version=readulong(f)
+ local fontversion=readulong(f)
+ local fontheader={
+ version=version,
+ fontversion=number.to16dot16(fontversion),
+ fontversionnumber=fontversion,
+ checksum=readushort(f)*0x10000+readushort(f),
+ magic=readulong(f),
+ flags=readushort(f),
+ units=readushort(f),
+ created=readlongdatetime(f),
+ modified=readlongdatetime(f),
+ xmin=readshort(f),
+ ymin=readshort(f),
+ xmax=readshort(f),
+ ymax=readshort(f),
+ macstyle=readushort(f),
+ smallpixels=readushort(f),
+ directionhint=readshort(f),
+ indextolocformat=readshort(f),
+ glyphformat=readshort(f),
+ }
+ fontdata.fontheader=fontheader
+ else
+ fontdata.fontheader={}
+ end
+ fontdata.nofglyphs=0
end
readers.hhea=function(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details)
- if tableoffset then
- fontdata.horizontalheader={
- version=readulong(f),
- ascender=readfword(f),
- descender=readfword(f),
- linegap=readfword(f),
- maxadvancewidth=readufword(f),
- minleftsidebearing=readfword(f),
- minrightsidebearing=readfword(f),
- maxextent=readfword(f),
- caretsloperise=readshort(f),
- caretsloperun=readshort(f),
- caretoffset=readshort(f),
- reserved_1=readshort(f),
- reserved_2=readshort(f),
- reserved_3=readshort(f),
- reserved_4=readshort(f),
- metricdataformat=readshort(f),
- nofmetrics=readushort(f),
- }
- else
- fontdata.horizontalheader={
- nofmetrics=0,
- }
- end
+ local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details)
+ if tableoffset then
+ fontdata.horizontalheader={
+ version=readulong(f),
+ ascender=readfword(f),
+ descender=readfword(f),
+ linegap=readfword(f),
+ maxadvancewidth=readufword(f),
+ minleftsidebearing=readfword(f),
+ minrightsidebearing=readfword(f),
+ maxextent=readfword(f),
+ caretsloperise=readshort(f),
+ caretsloperun=readshort(f),
+ caretoffset=readshort(f),
+ reserved_1=readshort(f),
+ reserved_2=readshort(f),
+ reserved_3=readshort(f),
+ reserved_4=readshort(f),
+ metricdataformat=readshort(f),
+ nofmetrics=readushort(f),
+ }
+ else
+ fontdata.horizontalheader={
+ nofmetrics=0,
+ }
+ end
end
readers.vhea=function(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details)
- if tableoffset then
- fontdata.verticalheader={
- version=readulong(f),
- ascender=readfword(f),
- descender=readfword(f),
- linegap=readfword(f),
- maxadvanceheight=readufword(f),
- mintopsidebearing=readfword(f),
- minbottomsidebearing=readfword(f),
- maxextent=readfword(f),
- caretsloperise=readshort(f),
- caretsloperun=readshort(f),
- caretoffset=readshort(f),
- reserved_1=readshort(f),
- reserved_2=readshort(f),
- reserved_3=readshort(f),
- reserved_4=readshort(f),
- metricdataformat=readshort(f),
- nofmetrics=readushort(f),
- }
- else
- fontdata.verticalheader={
- nofmetrics=0,
- }
- end
+ local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details)
+ if tableoffset then
+ fontdata.verticalheader={
+ version=readulong(f),
+ ascender=readfword(f),
+ descender=readfword(f),
+ linegap=readfword(f),
+ maxadvanceheight=readufword(f),
+ mintopsidebearing=readfword(f),
+ minbottomsidebearing=readfword(f),
+ maxextent=readfword(f),
+ caretsloperise=readshort(f),
+ caretsloperun=readshort(f),
+ caretoffset=readshort(f),
+ reserved_1=readshort(f),
+ reserved_2=readshort(f),
+ reserved_3=readshort(f),
+ reserved_4=readshort(f),
+ metricdataformat=readshort(f),
+ nofmetrics=readushort(f),
+ }
+ else
+ fontdata.verticalheader={
+ nofmetrics=0,
+ }
+ end
end
readers.maxp=function(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details)
- if tableoffset then
- local version=readulong(f)
- local nofglyphs=readushort(f)
- fontdata.nofglyphs=nofglyphs
- if version==0x00005000 then
- fontdata.maximumprofile={
- version=version,
- nofglyphs=nofglyphs,
- }
- elseif version==0x00010000 then
- fontdata.maximumprofile={
- version=version,
- nofglyphs=nofglyphs,
- points=readushort(f),
- contours=readushort(f),
- compositepoints=readushort(f),
- compositecontours=readushort(f),
- zones=readushort(f),
- twilightpoints=readushort(f),
- storage=readushort(f),
- functiondefs=readushort(f),
- instructiondefs=readushort(f),
- stackelements=readushort(f),
- sizeofinstructions=readushort(f),
- componentelements=readushort(f),
- componentdepth=readushort(f),
- }
- else
- fontdata.maximumprofile={
- version=version,
- nofglyphs=0,
- }
- end
+ local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details)
+ if tableoffset then
+ local version=readulong(f)
+ local nofglyphs=readushort(f)
+ fontdata.nofglyphs=nofglyphs
+ if version==0x00005000 then
+ fontdata.maximumprofile={
+ version=version,
+ nofglyphs=nofglyphs,
+ }
+ elseif version==0x00010000 then
+ fontdata.maximumprofile={
+ version=version,
+ nofglyphs=nofglyphs,
+ points=readushort(f),
+ contours=readushort(f),
+ compositepoints=readushort(f),
+ compositecontours=readushort(f),
+ zones=readushort(f),
+ twilightpoints=readushort(f),
+ storage=readushort(f),
+ functiondefs=readushort(f),
+ instructiondefs=readushort(f),
+ stackelements=readushort(f),
+ sizeofinstructions=readushort(f),
+ componentelements=readushort(f),
+ componentdepth=readushort(f),
+ }
+ else
+ fontdata.maximumprofile={
+ version=version,
+ nofglyphs=0,
+ }
end
+ end
end
readers.hmtx=function(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs)
- if tableoffset then
- local horizontalheader=fontdata.horizontalheader
- local nofmetrics=horizontalheader.nofmetrics
- local glyphs=fontdata.glyphs
- local nofglyphs=fontdata.nofglyphs
- local width=0
- local leftsidebearing=0
- for i=0,nofmetrics-1 do
- local glyph=glyphs[i]
- width=readshort(f)
- leftsidebearing=readshort(f)
- if width~=0 then
- glyph.width=width
- end
- end
- for i=nofmetrics,nofglyphs-1 do
- local glyph=glyphs[i]
- if width~=0 then
- glyph.width=width
- end
- end
- end
+ local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs)
+ if tableoffset then
+ local horizontalheader=fontdata.horizontalheader
+ local nofmetrics=horizontalheader.nofmetrics
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs
+ local width=0
+ local leftsidebearing=0
+ for i=0,nofmetrics-1 do
+ local glyph=glyphs[i]
+ width=readshort(f)
+ leftsidebearing=readshort(f)
+ if width~=0 then
+ glyph.width=width
+ end
+ end
+ for i=nofmetrics,nofglyphs-1 do
+ local glyph=glyphs[i]
+ if width~=0 then
+ glyph.width=width
+ end
+ end
+ end
end
readers.vmtx=function(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs)
- if tableoffset then
- local verticalheader=fontdata.verticalheader
- local nofmetrics=verticalheader.nofmetrics
- local glyphs=fontdata.glyphs
- local nofglyphs=fontdata.nofglyphs
- local vheight=0
- local vdefault=verticalheader.ascender+verticalheader.descender
- local topsidebearing=0
- for i=0,nofmetrics-1 do
- local glyph=glyphs[i]
- vheight=readshort(f)
- topsidebearing=readshort(f)
- if vheight~=0 and vheight~=vdefault then
- glyph.vheight=vheight
- end
- end
- for i=nofmetrics,nofglyphs-1 do
- local glyph=glyphs[i]
- if vheight~=0 and vheight~=vdefault then
- glyph.vheight=vheight
- end
- end
- end
+ local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs)
+ if tableoffset then
+ local verticalheader=fontdata.verticalheader
+ local nofmetrics=verticalheader.nofmetrics
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs
+ local vheight=0
+ local vdefault=verticalheader.ascender+verticalheader.descender
+ local topsidebearing=0
+ for i=0,nofmetrics-1 do
+ local glyph=glyphs[i]
+ vheight=readshort(f)
+ topsidebearing=readshort(f)
+ if vheight~=0 and vheight~=vdefault then
+ glyph.vheight=vheight
+ end
+ end
+ for i=nofmetrics,nofglyphs-1 do
+ local glyph=glyphs[i]
+ if vheight~=0 and vheight~=vdefault then
+ glyph.vheight=vheight
+ end
+ end
+ end
end
readers.vorg=function(f,fontdata,specification)
- reportskippedtable(f,fontdata,"vorg",specification.glyphs)
+ reportskippedtable(f,fontdata,"vorg",specification.glyphs)
end
readers.post=function(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"post",true)
- if tableoffset then
- local version=readulong(f)
- fontdata.postscript={
- version=version,
- italicangle=round(1000*readfixed(f))/1000,
- underlineposition=readfword(f),
- underlinethickness=readfword(f),
- monospaced=readulong(f),
- minmemtype42=readulong(f),
- maxmemtype42=readulong(f),
- minmemtype1=readulong(f),
- maxmemtype1=readulong(f),
- }
- if not specification.glyphs then
- elseif version==0x00010000 then
- for index=0,#standardromanencoding do
- glyphs[index].name=standardromanencoding[index]
- end
- elseif version==0x00020000 then
- local glyphs=fontdata.glyphs
- local nofglyphs=readushort(f)
- local indices={}
- local names={}
- local maxnames=0
- for i=0,nofglyphs-1 do
- local nameindex=readushort(f)
- if nameindex>=258 then
- maxnames=maxnames+1
- nameindex=nameindex-257
- indices[nameindex]=i
- else
- glyphs[i].name=standardromanencoding[nameindex]
- end
- end
- for i=1,maxnames do
- local mapping=indices[i]
- if not mapping then
- report("quit post name fetching at %a of %a: %s",i,maxnames,"no index")
- break
- else
- local length=readbyte(f)
- if length>0 then
- glyphs[mapping].name=readstring(f,length)
- else
- report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow")
- break
- end
- end
- end
+ local tableoffset=gotodatatable(f,fontdata,"post",true)
+ if tableoffset then
+ local version=readulong(f)
+ fontdata.postscript={
+ version=version,
+ italicangle=round(1000*readfixed(f))/1000,
+ underlineposition=readfword(f),
+ underlinethickness=readfword(f),
+ monospaced=readulong(f),
+ minmemtype42=readulong(f),
+ maxmemtype42=readulong(f),
+ minmemtype1=readulong(f),
+ maxmemtype1=readulong(f),
+ }
+ if not specification.glyphs then
+ elseif version==0x00010000 then
+ for index=0,#standardromanencoding do
+ glyphs[index].name=standardromanencoding[index]
+ end
+ elseif version==0x00020000 then
+ local glyphs=fontdata.glyphs
+ local nofglyphs=readushort(f)
+ local indices={}
+ local names={}
+ local maxnames=0
+ for i=0,nofglyphs-1 do
+ local nameindex=readushort(f)
+ if nameindex>=258 then
+ maxnames=maxnames+1
+ nameindex=nameindex-257
+ indices[nameindex]=i
+ else
+ glyphs[i].name=standardromanencoding[nameindex]
+ end
+ end
+ for i=1,maxnames do
+ local mapping=indices[i]
+ if not mapping then
+ report("quit post name fetching at %a of %a: %s",i,maxnames,"no index")
+ break
+ else
+ local length=readbyte(f)
+ if length>0 then
+ glyphs[mapping].name=readstring(f,length)
+ else
+ report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow")
+ break
+ end
end
- else
- fontdata.postscript={}
+ end
end
+ else
+ fontdata.postscript={}
+ end
end
readers.cff=function(f,fontdata,specification)
- reportskippedtable(f,fontdata,"cff",specification.glyphs)
+ reportskippedtable(f,fontdata,"cff",specification.glyphs)
end
local formatreaders={}
local duplicatestoo=true
local sequence={
- { 3,1,4 },
- { 3,10,12 },
- { 0,3,4 },
- { 0,1,4 },
- { 0,0,6 },
- { 3,0,6 },
- { 0,5,14 },
+ { 3,1,4 },
+ { 3,10,12 },
+ { 0,3,4 },
+ { 0,1,4 },
+ { 0,0,6 },
+ { 3,0,6 },
+ { 0,5,14 },
{ 0,4,12 },
- { 3,10,13 },
+ { 3,10,13 },
}
local supported={}
for i=1,#sequence do
- local si=sequence[i]
- local sp,se,sf=si[1],si[2],si[3]
- local p=supported[sp]
- if not p then
- p={}
- supported[sp]=p
- end
- local e=p[se]
- if not e then
- e={}
- p[se]=e
- end
- e[sf]=true
+ local si=sequence[i]
+ local sp,se,sf=si[1],si[2],si[3]
+ local p=supported[sp]
+ if not p then
+ p={}
+ supported[sp]=p
+ end
+ local e=p[se]
+ if not e then
+ e={}
+ p[se]=e
+ end
+ e[sf]=true
end
formatreaders[4]=function(f,fontdata,offset)
- setposition(f,offset+2)
- local length=readushort(f)
- local language=readushort(f)
- local nofsegments=readushort(f)/2
- skipshort(f,3)
- local mapping=fontdata.mapping
- local glyphs=fontdata.glyphs
- local duplicates=fontdata.duplicates
- local nofdone=0
- local endchars=readcardinaltable(f,nofsegments,ushort)
- local reserved=readushort(f)
- local startchars=readcardinaltable(f,nofsegments,ushort)
- local deltas=readcardinaltable(f,nofsegments,ushort)
- local offsets=readcardinaltable(f,nofsegments,ushort)
- local size=(length-2*2-5*2-4*2*nofsegments)/2
- local indices=readcardinaltable(f,size-1,ushort)
- for segment=1,nofsegments do
- local startchar=startchars[segment]
- local endchar=endchars[segment]
- local offset=offsets[segment]
- local delta=deltas[segment]
- if startchar==0xFFFF and endchar==0xFFFF then
- elseif startchar==0xFFFF and offset==0 then
- elseif offset==0xFFFF then
- elseif offset==0 then
- if trace_cmap_detail then
- report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536)
- end
- for unicode=startchar,endchar do
- local index=(unicode+delta)%65536
- if index and index>0 then
- local glyph=glyphs[index]
- if glyph then
- local gu=glyph.unicode
- if not gu then
- glyph.unicode=unicode
- nofdone=nofdone+1
- elseif gu~=unicode then
- if duplicatestoo then
- local d=duplicates[gu]
- if d then
- d[unicode]=true
- else
- duplicates[gu]={ [unicode]=true }
- end
- else
- report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name)
- end
- end
- if not mapping[index] then
- mapping[index]=unicode
- end
- end
+ setposition(f,offset+2)
+ local length=readushort(f)
+ local language=readushort(f)
+ local nofsegments=readushort(f)/2
+ skipshort(f,3)
+ local mapping=fontdata.mapping
+ local glyphs=fontdata.glyphs
+ local duplicates=fontdata.duplicates
+ local nofdone=0
+ local endchars=readcardinaltable(f,nofsegments,ushort)
+ local reserved=readushort(f)
+ local startchars=readcardinaltable(f,nofsegments,ushort)
+ local deltas=readcardinaltable(f,nofsegments,ushort)
+ local offsets=readcardinaltable(f,nofsegments,ushort)
+ local size=(length-2*2-5*2-4*2*nofsegments)/2
+ local indices=readcardinaltable(f,size-1,ushort)
+ for segment=1,nofsegments do
+ local startchar=startchars[segment]
+ local endchar=endchars[segment]
+ local offset=offsets[segment]
+ local delta=deltas[segment]
+ if startchar==0xFFFF and endchar==0xFFFF then
+ elseif startchar==0xFFFF and offset==0 then
+ elseif offset==0xFFFF then
+ elseif offset==0 then
+ if trace_cmap_detail then
+ report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536)
+ end
+ for unicode=startchar,endchar do
+ local index=(unicode+delta)%65536
+ if index and index>0 then
+ local glyph=glyphs[index]
+ if glyph then
+ local gu=glyph.unicode
+ if not gu then
+ glyph.unicode=unicode
+ nofdone=nofdone+1
+ elseif gu~=unicode then
+ if duplicatestoo then
+ local d=duplicates[gu]
+ if d then
+ d[unicode]=true
+ else
+ duplicates[gu]={ [unicode]=true }
end
+ else
+ report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name)
+ end
end
- else
- local shift=(segment-nofsegments+offset/2)-startchar
- if trace_cmap_detail then
- report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536)
- end
- for unicode=startchar,endchar do
- local slot=shift+unicode
- local index=indices[slot]
- if index and index>0 then
- index=(index+delta)%65536
- local glyph=glyphs[index]
- if glyph then
- local gu=glyph.unicode
- if not gu then
- glyph.unicode=unicode
- nofdone=nofdone+1
- elseif gu~=unicode then
- if duplicatestoo then
- local d=duplicates[gu]
- if d then
- d[unicode]=true
- else
- duplicates[gu]={ [unicode]=true }
- end
- else
- report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name)
- end
- end
- if not mapping[index] then
- mapping[index]=unicode
- end
- end
- end
+ if not mapping[index] then
+ mapping[index]=unicode
end
+ end
end
- end
- return nofdone
-end
-formatreaders[6]=function(f,fontdata,offset)
- setposition(f,offset)
- local format=readushort(f)
- local length=readushort(f)
- local language=readushort(f)
- local mapping=fontdata.mapping
- local glyphs=fontdata.glyphs
- local duplicates=fontdata.duplicates
- local start=readushort(f)
- local count=readushort(f)
- local stop=start+count-1
- local nofdone=0
- if trace_cmap_detail then
- report("format 6 from %C to %C",2,start,stop)
- end
- for unicode=start,stop do
- local index=readushort(f)
- if index>0 then
- local glyph=glyphs[index]
- if glyph then
- local gu=glyph.unicode
- if not gu then
- glyph.unicode=unicode
- nofdone=nofdone+1
- elseif gu~=unicode then
- end
- if not mapping[index] then
- mapping[index]=unicode
+ end
+ else
+ local shift=(segment-nofsegments+offset/2)-startchar
+ if trace_cmap_detail then
+ report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536)
+ end
+ for unicode=startchar,endchar do
+ local slot=shift+unicode
+ local index=indices[slot]
+ if index and index>0 then
+ index=(index+delta)%65536
+ local glyph=glyphs[index]
+ if glyph then
+ local gu=glyph.unicode
+ if not gu then
+ glyph.unicode=unicode
+ nofdone=nofdone+1
+ elseif gu~=unicode then
+ if duplicatestoo then
+ local d=duplicates[gu]
+ if d then
+ d[unicode]=true
+ else
+ duplicates[gu]={ [unicode]=true }
end
+ else
+ report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name)
+ end
end
+ if not mapping[index] then
+ mapping[index]=unicode
+ end
+ end
end
+ end
end
- return nofdone
+ end
+ return nofdone
+end
+formatreaders[6]=function(f,fontdata,offset)
+ setposition(f,offset)
+ local format=readushort(f)
+ local length=readushort(f)
+ local language=readushort(f)
+ local mapping=fontdata.mapping
+ local glyphs=fontdata.glyphs
+ local duplicates=fontdata.duplicates
+ local start=readushort(f)
+ local count=readushort(f)
+ local stop=start+count-1
+ local nofdone=0
+ if trace_cmap_detail then
+ report("format 6 from %C to %C",2,start,stop)
+ end
+ for unicode=start,stop do
+ local index=readushort(f)
+ if index>0 then
+ local glyph=glyphs[index]
+ if glyph then
+ local gu=glyph.unicode
+ if not gu then
+ glyph.unicode=unicode
+ nofdone=nofdone+1
+ elseif gu~=unicode then
+ end
+ if not mapping[index] then
+ mapping[index]=unicode
+ end
+ end
+ end
+ end
+ return nofdone
end
formatreaders[12]=function(f,fontdata,offset)
- setposition(f,offset+2+2+4+4)
- local mapping=fontdata.mapping
- local glyphs=fontdata.glyphs
- local duplicates=fontdata.duplicates
- local nofgroups=readulong(f)
- local nofdone=0
- for i=1,nofgroups do
- local first=readulong(f)
- local last=readulong(f)
- local index=readulong(f)
- if trace_cmap_detail then
- report("format 12 from %C to %C starts at index %i",first,last,index)
- end
- for unicode=first,last do
- local glyph=glyphs[index]
- if glyph then
- local gu=glyph.unicode
- if not gu then
- glyph.unicode=unicode
- nofdone=nofdone+1
- elseif gu~=unicode then
- local d=duplicates[gu]
- if d then
- d[unicode]=true
- else
- duplicates[gu]={ [unicode]=true }
- end
- end
- if not mapping[index] then
- mapping[index]=unicode
- end
- end
- index=index+1
+ setposition(f,offset+2+2+4+4)
+ local mapping=fontdata.mapping
+ local glyphs=fontdata.glyphs
+ local duplicates=fontdata.duplicates
+ local nofgroups=readulong(f)
+ local nofdone=0
+ for i=1,nofgroups do
+ local first=readulong(f)
+ local last=readulong(f)
+ local index=readulong(f)
+ if trace_cmap_detail then
+ report("format 12 from %C to %C starts at index %i",first,last,index)
+ end
+ for unicode=first,last do
+ local glyph=glyphs[index]
+ if glyph then
+ local gu=glyph.unicode
+ if not gu then
+ glyph.unicode=unicode
+ nofdone=nofdone+1
+ elseif gu~=unicode then
+ local d=duplicates[gu]
+ if d then
+ d[unicode]=true
+ else
+ duplicates[gu]={ [unicode]=true }
+ end
end
+ if not mapping[index] then
+ mapping[index]=unicode
+ end
+ end
+ index=index+1
end
- return nofdone
+ end
+ return nofdone
end
formatreaders[13]=function(f,fontdata,offset)
- setposition(f,offset+2+2+4+4)
- local mapping=fontdata.mapping
- local glyphs=fontdata.glyphs
- local duplicates=fontdata.duplicates
- local nofgroups=readulong(f)
- local nofdone=0
- for i=1,nofgroups do
- local first=readulong(f)
- local last=readulong(f)
- local index=readulong(f)
- if first<privateoffset then
- if trace_cmap_detail then
- report("format 13 from %C to %C get index %i",first,last,index)
- end
- local glyph=glyphs[index]
- local unicode=glyph.unicode
- if not unicode then
- unicode=first
- glyph.unicode=unicode
- first=first+1
- end
- local list=duplicates[unicode]
- mapping[index]=unicode
- if not list then
- list={}
- duplicates[unicode]=list
- end
- if last>=privateoffset then
- local limit=privateoffset-1
- report("format 13 from %C to %C pruned to %C",first,last,limit)
- last=limit
- end
- for unicode=first,last do
- list[unicode]=true
- end
- nofdone=nofdone+last-first+1
- else
- report("format 13 from %C to %C ignored",first,last)
- end
+ setposition(f,offset+2+2+4+4)
+ local mapping=fontdata.mapping
+ local glyphs=fontdata.glyphs
+ local duplicates=fontdata.duplicates
+ local nofgroups=readulong(f)
+ local nofdone=0
+ for i=1,nofgroups do
+ local first=readulong(f)
+ local last=readulong(f)
+ local index=readulong(f)
+ if first<privateoffset then
+ if trace_cmap_detail then
+ report("format 13 from %C to %C get index %i",first,last,index)
+ end
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=first
+ glyph.unicode=unicode
+ first=first+1
+ end
+ local list=duplicates[unicode]
+ mapping[index]=unicode
+ if not list then
+ list={}
+ duplicates[unicode]=list
+ end
+ if last>=privateoffset then
+ local limit=privateoffset-1
+ report("format 13 from %C to %C pruned to %C",first,last,limit)
+ last=limit
+ end
+ for unicode=first,last do
+ list[unicode]=true
+ end
+ nofdone=nofdone+last-first+1
+ else
+ report("format 13 from %C to %C ignored",first,last)
end
- return nofdone
+ end
+ return nofdone
end
formatreaders[14]=function(f,fontdata,offset)
- if offset and offset~=0 then
- setposition(f,offset)
- local format=readushort(f)
- local length=readulong(f)
- local nofrecords=readulong(f)
- local records={}
- local variants={}
- local nofdone=0
- fontdata.variants=variants
- for i=1,nofrecords do
- records[i]={
- selector=readuint(f),
- default=readulong(f),
- other=readulong(f),
- }
- end
- for i=1,nofrecords do
- local record=records[i]
- local selector=record.selector
- local default=record.default
- local other=record.other
- local other=record.other
- if other~=0 then
- setposition(f,offset+other)
- local mapping={}
- local count=readulong(f)
- for i=1,count do
- mapping[readuint(f)]=readushort(f)
- end
- nofdone=nofdone+count
- variants[selector]=mapping
- end
- end
- return nofdone
- else
- return 0
+ if offset and offset~=0 then
+ setposition(f,offset)
+ local format=readushort(f)
+ local length=readulong(f)
+ local nofrecords=readulong(f)
+ local records={}
+ local variants={}
+ local nofdone=0
+ fontdata.variants=variants
+ for i=1,nofrecords do
+ records[i]={
+ selector=readuint(f),
+ default=readulong(f),
+ other=readulong(f),
+ }
+ end
+ for i=1,nofrecords do
+ local record=records[i]
+ local selector=record.selector
+ local default=record.default
+ local other=record.other
+ local other=record.other
+ if other~=0 then
+ setposition(f,offset+other)
+ local mapping={}
+ local count=readulong(f)
+ for i=1,count do
+ mapping[readuint(f)]=readushort(f)
+ end
+ nofdone=nofdone+count
+ variants[selector]=mapping
+ end
end
+ return nofdone
+ else
+ return 0
+ end
end
local function checkcmap(f,fontdata,records,platform,encoding,format)
- local data=records[platform]
- if not data then
- return 0
- end
- data=data[encoding]
- if not data then
- return 0
- end
- data=data[format]
- if not data then
- return 0
- end
- local reader=formatreaders[format]
- if not reader then
- return 0
- end
- local p=platforms[platform]
- local e=encodings[p]
- local n=reader(f,fontdata,data) or 0
- if trace_cmap then
- report("cmap checked: platform %i (%s), encoding %i (%s), format %i, new unicodes %i",platform,p,encoding,e and e[encoding] or "?",format,n)
- end
- return n
+ local data=records[platform]
+ if not data then
+ return 0
+ end
+ data=data[encoding]
+ if not data then
+ return 0
+ end
+ data=data[format]
+ if not data then
+ return 0
+ end
+ local reader=formatreaders[format]
+ if not reader then
+ return 0
+ end
+ local p=platforms[platform]
+ local e=encodings[p]
+ local n=reader(f,fontdata,data) or 0
+ if trace_cmap then
+ report("cmap checked: platform %i (%s), encoding %i (%s), format %i, new unicodes %i",platform,p,encoding,e and e[encoding] or "?",format,n)
+ end
+ return n
end
function readers.cmap(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs)
- if tableoffset then
- local version=readushort(f)
- local noftables=readushort(f)
- local records={}
- local unicodecid=false
- local variantcid=false
- local variants={}
- local duplicates=fontdata.duplicates or {}
- fontdata.duplicates=duplicates
- for i=1,noftables do
- local platform=readushort(f)
- local encoding=readushort(f)
- local offset=readulong(f)
- local record=records[platform]
- if not record then
- records[platform]={
- [encoding]={
- offsets={ offset },
- formats={},
- }
- }
- else
- local subtables=record[encoding]
- if not subtables then
- record[encoding]={
- offsets={ offset },
- formats={},
- }
- else
- local offsets=subtables.offsets
- offsets[#offsets+1]=offset
- end
- end
+ local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local noftables=readushort(f)
+ local records={}
+ local unicodecid=false
+ local variantcid=false
+ local variants={}
+ local duplicates=fontdata.duplicates or {}
+ fontdata.duplicates=duplicates
+ for i=1,noftables do
+ local platform=readushort(f)
+ local encoding=readushort(f)
+ local offset=readulong(f)
+ local record=records[platform]
+ if not record then
+ records[platform]={
+ [encoding]={
+ offsets={ offset },
+ formats={},
+ }
+ }
+ else
+ local subtables=record[encoding]
+ if not subtables then
+ record[encoding]={
+ offsets={ offset },
+ formats={},
+ }
+ else
+ local offsets=subtables.offsets
+ offsets[#offsets+1]=offset
+ end
+ end
+ end
+ if trace_cmap then
+ report("found cmaps:")
+ end
+ for platform,record in sortedhash(records) do
+ local p=platforms[platform]
+ local e=encodings[p]
+ local sp=supported[platform]
+ local ps=p or "?"
+ if trace_cmap then
+ if sp then
+ report(" platform %i: %s",platform,ps)
+ else
+ report(" platform %i: %s (unsupported)",platform,ps)
end
+ end
+ for encoding,subtables in sortedhash(record) do
+ local se=sp and sp[encoding]
+ local es=e and e[encoding] or "?"
if trace_cmap then
- report("found cmaps:")
- end
- for platform,record in sortedhash(records) do
- local p=platforms[platform]
- local e=encodings[p]
- local sp=supported[platform]
- local ps=p or "?"
- if trace_cmap then
- if sp then
- report(" platform %i: %s",platform,ps)
- else
- report(" platform %i: %s (unsupported)",platform,ps)
- end
- end
- for encoding,subtables in sortedhash(record) do
- local se=sp and sp[encoding]
- local es=e and e[encoding] or "?"
- if trace_cmap then
- if se then
- report(" encoding %i: %s",encoding,es)
- else
- report(" encoding %i: %s (unsupported)",encoding,es)
- end
- end
- local offsets=subtables.offsets
- local formats=subtables.formats
- for i=1,#offsets do
- local offset=tableoffset+offsets[i]
- setposition(f,offset)
- formats[readushort(f)]=offset
- end
- record[encoding]=formats
- if trace_cmap then
- local list=sortedkeys(formats)
- for i=1,#list do
- if not (se and se[list[i]]) then
- list[i]=list[i].." (unsupported)"
- end
- end
- report(" formats: % t",list)
- end
- end
+ if se then
+ report(" encoding %i: %s",encoding,es)
+ else
+ report(" encoding %i: %s (unsupported)",encoding,es)
+ end
end
- local ok=false
- for i=1,#sequence do
- local si=sequence[i]
- local sp,se,sf=si[1],si[2],si[3]
- if checkcmap(f,fontdata,records,sp,se,sf)>0 then
- ok=true
- end
+ local offsets=subtables.offsets
+ local formats=subtables.formats
+ for i=1,#offsets do
+ local offset=tableoffset+offsets[i]
+ setposition(f,offset)
+ formats[readushort(f)]=offset
end
- if not ok then
- report("no useable unicode cmap found")
+ record[encoding]=formats
+ if trace_cmap then
+ local list=sortedkeys(formats)
+ for i=1,#list do
+ if not (se and se[list[i]]) then
+ list[i]=list[i].." (unsupported)"
+ end
+ end
+ report(" formats: % t",list)
end
- fontdata.cidmaps={
- version=version,
- noftables=noftables,
- records=records,
- }
- else
- fontdata.cidmaps={}
+ end
+ end
+ local ok=false
+ for i=1,#sequence do
+ local si=sequence[i]
+ local sp,se,sf=si[1],si[2],si[3]
+ if checkcmap(f,fontdata,records,sp,se,sf)>0 then
+ ok=true
+ end
end
+ if not ok then
+ report("no useable unicode cmap found")
+ end
+ fontdata.cidmaps={
+ version=version,
+ noftables=noftables,
+ records=records,
+ }
+ else
+ fontdata.cidmaps={}
+ end
end
function readers.loca(f,fontdata,specification)
- reportskippedtable(f,fontdata,"loca",specification.glyphs)
+ reportskippedtable(f,fontdata,"loca",specification.glyphs)
end
function readers.glyf(f,fontdata,specification)
- reportskippedtable(f,fontdata,"glyf",specification.glyphs)
+ reportskippedtable(f,fontdata,"glyf",specification.glyphs)
end
function readers.colr(f,fontdata,specification)
- reportskippedtable(f,fontdata,"colr",specification.glyphs)
+ reportskippedtable(f,fontdata,"colr",specification.glyphs)
end
function readers.cpal(f,fontdata,specification)
- reportskippedtable(f,fontdata,"cpal",specification.glyphs)
+ reportskippedtable(f,fontdata,"cpal",specification.glyphs)
end
function readers.svg(f,fontdata,specification)
- reportskippedtable(f,fontdata,"svg",specification.glyphs)
+ reportskippedtable(f,fontdata,"svg",specification.glyphs)
end
function readers.sbix(f,fontdata,specification)
- reportskippedtable(f,fontdata,"sbix",specification.glyphs)
+ reportskippedtable(f,fontdata,"sbix",specification.glyphs)
end
function readers.cbdt(f,fontdata,specification)
- reportskippedtable(f,fontdata,"cbdt",specification.glyphs)
+ reportskippedtable(f,fontdata,"cbdt",specification.glyphs)
end
function readers.cblc(f,fontdata,specification)
- reportskippedtable(f,fontdata,"cblc",specification.glyphs)
+ reportskippedtable(f,fontdata,"cblc",specification.glyphs)
end
function readers.ebdt(f,fontdata,specification)
- reportskippedtable(f,fontdata,"ebdt",specification.glyphs)
+ reportskippedtable(f,fontdata,"ebdt",specification.glyphs)
end
function readers.ebsc(f,fontdata,specification)
- reportskippedtable(f,fontdata,"ebsc",specification.glyphs)
+ reportskippedtable(f,fontdata,"ebsc",specification.glyphs)
end
function readers.eblc(f,fontdata,specification)
- reportskippedtable(f,fontdata,"eblc",specification.glyphs)
+ reportskippedtable(f,fontdata,"eblc",specification.glyphs)
end
function readers.kern(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns)
- if tableoffset then
- local version=readushort(f)
- local noftables=readushort(f)
- for i=1,noftables do
- local version=readushort(f)
- local length=readushort(f)
- local coverage=readushort(f)
- local format=rshift(coverage,8)
- if format==0 then
- local nofpairs=readushort(f)
- local searchrange=readushort(f)
- local entryselector=readushort(f)
- local rangeshift=readushort(f)
- local kerns={}
- local glyphs=fontdata.glyphs
- for i=1,nofpairs do
- local left=readushort(f)
- local right=readushort(f)
- local kern=readfword(f)
- local glyph=glyphs[left]
- local kerns=glyph.kerns
- if kerns then
- kerns[right]=kern
- else
- glyph.kerns={ [right]=kern }
- end
- end
- elseif format==2 then
- report("todo: kern classes")
- else
- report("todo: kerns")
- end
+ local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns)
+ if tableoffset then
+ local version=readushort(f)
+ local noftables=readushort(f)
+ for i=1,noftables do
+ local version=readushort(f)
+ local length=readushort(f)
+ local coverage=readushort(f)
+ local format=rshift(coverage,8)
+ if format==0 then
+ local nofpairs=readushort(f)
+ local searchrange=readushort(f)
+ local entryselector=readushort(f)
+ local rangeshift=readushort(f)
+ local kerns={}
+ local glyphs=fontdata.glyphs
+ for i=1,nofpairs do
+ local left=readushort(f)
+ local right=readushort(f)
+ local kern=readfword(f)
+ local glyph=glyphs[left]
+ local kerns=glyph.kerns
+ if kerns then
+ kerns[right]=kern
+ else
+ glyph.kerns={ [right]=kern }
+ end
end
+ elseif format==2 then
+ report("todo: kern classes")
+ else
+ report("todo: kerns")
+ end
end
+ end
end
function readers.gdef(f,fontdata,specification)
- reportskippedtable(f,fontdata,"gdef",specification.details)
+ reportskippedtable(f,fontdata,"gdef",specification.details)
end
function readers.gsub(f,fontdata,specification)
- reportskippedtable(f,fontdata,"gsub",specification.details)
+ reportskippedtable(f,fontdata,"gsub",specification.details)
end
function readers.gpos(f,fontdata,specification)
- reportskippedtable(f,fontdata,"gpos",specification.details)
+ reportskippedtable(f,fontdata,"gpos",specification.details)
end
function readers.math(f,fontdata,specification)
- reportskippedtable(f,fontdata,"math",specification.details)
+ reportskippedtable(f,fontdata,"math",specification.details)
end
local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames)
- local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata
- local names=fontdata.names
- local info=nil
- if names then
- local metrics=fontdata.windowsmetrics or {}
- local postscript=fontdata.postscript or {}
- local fontheader=fontdata.fontheader or {}
- local cffinfo=fontdata.cffinfo or {}
- local filename=fontdata.filename
- local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight)
- local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width )
- local fontname=getname(fontdata,"postscriptname")
- local fullname=getname(fontdata,"fullname")
- local family=getname(fontdata,"family")
- local subfamily=getname(fontdata,"subfamily")
- local familyname=getname(fontdata,"typographicfamily")
- local subfamilyname=getname(fontdata,"typographicsubfamily")
- local compatiblename=getname(fontdata,"compatiblefullname")
- if rawfamilynames then
- else
- if not familyname then familyname=family end
- if not subfamilyname then subfamilyname=subfamily end
- end
- if platformnames then
- platformnames=fontdata.platformnames
- end
- if instancenames then
- local variabledata=fontdata.variabledata
- if variabledata then
- local instances=variabledata and variabledata.instances
- if instances then
- instancenames={}
- for i=1,#instances do
- instancenames[i]=lower(stripstring(instances[i].subfamily))
- end
- else
- instancenames=nil
- end
- else
- instancenames=nil
- end
- end
- info={
- subfontindex=fontdata.subfontindex or sub or 0,
- version=getname(fontdata,"version"),
- fontname=fontname,
- fullname=fullname,
- family=family,
- subfamily=subfamily,
- familyname=familyname,
- subfamilyname=subfamilyname,
- compatiblename=compatiblename,
- weight=weight and lower(weight),
- width=width and lower(width),
- pfmweight=metrics.weightclass or 400,
- pfmwidth=metrics.widthclass or 5,
- panosewidth=metrics.panosewidth,
- panoseweight=metrics.panoseweight,
- italicangle=postscript.italicangle or 0,
- units=fontheader.units or 0,
- designsize=fontdata.designsize,
- minsize=fontdata.minsize,
- maxsize=fontdata.maxsize,
- boundingbox=fontheader and { fontheader.xmin or 0,fontheader.ymin or 0,fontheader.xmax or 0,fontheader.ymax or 0 } or nil,
- monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced",
- averagewidth=metrics.averagewidth,
- xheight=metrics.xheight,
- capheight=metrics.capheight or fontdata.maxy,
- ascender=metrics.typoascender,
- descender=metrics.typodescender,
- platformnames=platformnames or nil,
- instancenames=instancenames or nil,
- tableoffsets=fontdata.tableoffsets,
- }
- if metricstoo then
- local keys={
- "version",
- "ascender","descender","linegap",
- "maxadvancewidth","maxadvanceheight","maxextent",
- "minbottomsidebearing","mintopsidebearing",
- }
- local h=fontdata.horizontalheader or {}
- local v=fontdata.verticalheader or {}
- if h then
- local th={}
- local tv={}
- for i=1,#keys do
- local key=keys[i]
- th[key]=h[key] or 0
- tv[key]=v[key] or 0
- end
- info.horizontalmetrics=th
- info.verticalmetrics=tv
- end
- end
- elseif n then
- info={
- filename=fontdata.filename,
- comment="there is no info for subfont "..n,
- }
+ local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata
+ local names=fontdata.names
+ local info=nil
+ if names then
+ local metrics=fontdata.windowsmetrics or {}
+ local postscript=fontdata.postscript or {}
+ local fontheader=fontdata.fontheader or {}
+ local cffinfo=fontdata.cffinfo or {}
+ local filename=fontdata.filename
+ local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight)
+ local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width )
+ local fontname=getname(fontdata,"postscriptname")
+ local fullname=getname(fontdata,"fullname")
+ local family=getname(fontdata,"family")
+ local subfamily=getname(fontdata,"subfamily")
+ local familyname=getname(fontdata,"typographicfamily")
+ local subfamilyname=getname(fontdata,"typographicsubfamily")
+ local compatiblename=getname(fontdata,"compatiblefullname")
+ if rawfamilynames then
else
- info={
- filename=fontdata.filename,
- comment="there is no info",
- }
- end
- return info
+ if not familyname then familyname=family end
+ if not subfamilyname then subfamilyname=subfamily end
+ end
+ if platformnames then
+ platformnames=fontdata.platformnames
+ end
+ if instancenames then
+ local variabledata=fontdata.variabledata
+ if variabledata then
+ local instances=variabledata and variabledata.instances
+ if instances then
+ instancenames={}
+ for i=1,#instances do
+ instancenames[i]=lower(stripstring(instances[i].subfamily))
+ end
+ else
+ instancenames=nil
+ end
+ else
+ instancenames=nil
+ end
+ end
+ info={
+ subfontindex=fontdata.subfontindex or sub or 0,
+ version=getname(fontdata,"version"),
+ fontname=fontname,
+ fullname=fullname,
+ family=family,
+ subfamily=subfamily,
+ familyname=familyname,
+ subfamilyname=subfamilyname,
+ compatiblename=compatiblename,
+ weight=weight and lower(weight),
+ width=width and lower(width),
+ pfmweight=metrics.weightclass or 400,
+ pfmwidth=metrics.widthclass or 5,
+ panosewidth=metrics.panosewidth,
+ panoseweight=metrics.panoseweight,
+ italicangle=postscript.italicangle or 0,
+ units=fontheader.units or 0,
+ designsize=fontdata.designsize,
+ minsize=fontdata.minsize,
+ maxsize=fontdata.maxsize,
+ boundingbox=fontheader and { fontheader.xmin or 0,fontheader.ymin or 0,fontheader.xmax or 0,fontheader.ymax or 0 } or nil,
+ monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced",
+ averagewidth=metrics.averagewidth,
+ xheight=metrics.xheight,
+ capheight=metrics.capheight or fontdata.maxy,
+ ascender=metrics.typoascender,
+ descender=metrics.typodescender,
+ platformnames=platformnames or nil,
+ instancenames=instancenames or nil,
+ tableoffsets=fontdata.tableoffsets,
+ }
+ if metricstoo then
+ local keys={
+ "version",
+ "ascender","descender","linegap",
+ "maxadvancewidth","maxadvanceheight","maxextent",
+ "minbottomsidebearing","mintopsidebearing",
+ }
+ local h=fontdata.horizontalheader or {}
+ local v=fontdata.verticalheader or {}
+ if h then
+ local th={}
+ local tv={}
+ for i=1,#keys do
+ local key=keys[i]
+ th[key]=h[key] or 0
+ tv[key]=v[key] or 0
+ end
+ info.horizontalmetrics=th
+ info.verticalmetrics=tv
+ end
+ end
+ elseif n then
+ info={
+ filename=fontdata.filename,
+ comment="there is no info for subfont "..n,
+ }
+ else
+ info={
+ filename=fontdata.filename,
+ comment="there is no info",
+ }
+ end
+ return info
end
local function loadtables(f,specification,offset)
- if offset then
- setposition(f,offset)
- end
- local tables={}
- local basename=file.basename(specification.filename)
- local filesize=specification.filesize
- local filetime=specification.filetime
- local fontdata={
- filename=basename,
- filesize=filesize,
- filetime=filetime,
- version=readstring(f,4),
- noftables=readushort(f),
- searchrange=readushort(f),
- entryselector=readushort(f),
- rangeshift=readushort(f),
- tables=tables,
- foundtables=false,
+ if offset then
+ setposition(f,offset)
+ end
+ local tables={}
+ local basename=file.basename(specification.filename)
+ local filesize=specification.filesize
+ local filetime=specification.filetime
+ local fontdata={
+ filename=basename,
+ filesize=filesize,
+ filetime=filetime,
+ version=readstring(f,4),
+ noftables=readushort(f),
+ searchrange=readushort(f),
+ entryselector=readushort(f),
+ rangeshift=readushort(f),
+ tables=tables,
+ foundtables=false,
+ }
+ for i=1,fontdata.noftables do
+ local tag=lower(stripstring(readstring(f,4)))
+ local checksum=readushort(f)*0x10000+readushort(f)
+ local offset=readulong(f)
+ local length=readulong(f)
+ if offset+length>filesize then
+ report("bad %a table in file %a",tag,basename)
+ end
+ tables[tag]={
+ checksum=checksum,
+ offset=offset,
+ length=length,
}
- for i=1,fontdata.noftables do
- local tag=lower(stripstring(readstring(f,4)))
- local checksum=readushort(f)*0x10000+readushort(f)
- local offset=readulong(f)
- local length=readulong(f)
- if offset+length>filesize then
- report("bad %a table in file %a",tag,basename)
- end
- tables[tag]={
- checksum=checksum,
- offset=offset,
- length=length,
- }
- end
- fontdata.foundtables=sortedkeys(tables)
- if tables.cff or tables.cff2 then
- fontdata.format="opentype"
- else
- fontdata.format="truetype"
- end
- return fontdata,tables
+ end
+ fontdata.foundtables=sortedkeys(tables)
+ if tables.cff or tables.cff2 then
+ fontdata.format="opentype"
+ else
+ fontdata.format="truetype"
+ end
+ return fontdata,tables
end
local function prepareglyps(fontdata)
- local glyphs=setmetatableindex(function(t,k)
- local v={
- index=k,
- }
- t[k]=v
- return v
- end)
- fontdata.glyphs=glyphs
- fontdata.mapping={}
+ local glyphs=setmetatableindex(function(t,k)
+ local v={
+ index=k,
+ }
+ t[k]=v
+ return v
+ end)
+ fontdata.glyphs=glyphs
+ fontdata.mapping={}
end
local function readtable(tag,f,fontdata,specification,...)
- local reader=readers[tag]
- if reader then
- reader(f,fontdata,specification,...)
- end
+ local reader=readers[tag]
+ if reader then
+ reader(f,fontdata,specification,...)
+ end
end
local variablefonts_supported=(context and true) or (logs and logs.application and true) or false
local function readdata(f,offset,specification)
- local fontdata,tables=loadtables(f,specification,offset)
- if specification.glyphs then
- prepareglyps(fontdata)
- end
- if not variablefonts_supported then
- specification.instance=nil
- specification.variable=nil
- specification.factors=nil
- end
- fontdata.temporary={}
- readtable("name",f,fontdata,specification)
- local askedname=specification.askedname
- if askedname then
- local fullname=getname(fontdata,"fullname") or ""
- local cleanname=gsub(askedname,"[^a-zA-Z0-9]","")
- local foundname=gsub(fullname,"[^a-zA-Z0-9]","")
- if lower(cleanname)~=lower(foundname) then
- return
- end
- end
- readtable("stat",f,fontdata,specification)
- readtable("avar",f,fontdata,specification)
- readtable("fvar",f,fontdata,specification)
- if variablefonts_supported then
- local variabledata=fontdata.variabledata
- if variabledata then
- local instances=variabledata.instances
- local axis=variabledata.axis
- if axis and (not instances or #instances==0) then
- instances={}
- variabledata.instances=instances
- local function add(n,subfamily,value)
- local values={}
- for i=1,#axis do
- local a=axis[i]
- values[i]={
- axis=a.tag,
- value=i==n and value or a.default,
- }
- end
- instances[#instances+1]={
- subfamily=subfamily,
- values=values,
- }
- end
- for i=1,#axis do
- local a=axis[i]
- local tag=a.tag
- add(i,"default"..tag,a.default)
- add(i,"minimum"..tag,a.minimum)
- add(i,"maximum"..tag,a.maximum)
- end
- end
- end
- if not specification.factors then
- local instance=specification.instance
- if type(instance)=="string" then
- local factors=helpers.getfactors(fontdata,instance)
- if factors then
- specification.factors=factors
- fontdata.factors=factors
- fontdata.instance=instance
- report("user instance: %s, factors: % t",instance,factors)
- else
- report("user instance: %s, bad factors",instance)
- end
- end
+ local fontdata,tables=loadtables(f,specification,offset)
+ if specification.glyphs then
+ prepareglyps(fontdata)
+ end
+ if not variablefonts_supported then
+ specification.instance=nil
+ specification.variable=nil
+ specification.factors=nil
+ end
+ fontdata.temporary={}
+ readtable("name",f,fontdata,specification)
+ local askedname=specification.askedname
+ if askedname then
+ local fullname=getname(fontdata,"fullname") or ""
+ local cleanname=gsub(askedname,"[^a-zA-Z0-9]","")
+ local foundname=gsub(fullname,"[^a-zA-Z0-9]","")
+ if lower(cleanname)~=lower(foundname) then
+ return
+ end
+ end
+ readtable("stat",f,fontdata,specification)
+ readtable("avar",f,fontdata,specification)
+ readtable("fvar",f,fontdata,specification)
+ if variablefonts_supported then
+ local variabledata=fontdata.variabledata
+ if variabledata then
+ local instances=variabledata.instances
+ local axis=variabledata.axis
+ if axis and (not instances or #instances==0) then
+ instances={}
+ variabledata.instances=instances
+ local function add(n,subfamily,value)
+ local values={}
+ for i=1,#axis do
+ local a=axis[i]
+ values[i]={
+ axis=a.tag,
+ value=i==n and value or a.default,
+ }
+ end
+ instances[#instances+1]={
+ subfamily=subfamily,
+ values=values,
+ }
end
- if not fontdata.factors then
- if fontdata.variabledata then
- local factors=helpers.getfactors(fontdata,true)
- if factors then
- specification.factors=factors
- fontdata.factors=factors
- end
- else
- end
+ for i=1,#axis do
+ local a=axis[i]
+ local tag=a.tag
+ add(i,"default"..tag,a.default)
+ add(i,"minimum"..tag,a.minimum)
+ add(i,"maximum"..tag,a.maximum)
+ end
+ end
+ end
+ if not specification.factors then
+ local instance=specification.instance
+ if type(instance)=="string" then
+ local factors=helpers.getfactors(fontdata,instance)
+ if factors then
+ specification.factors=factors
+ fontdata.factors=factors
+ fontdata.instance=instance
+ report("user instance: %s, factors: % t",instance,factors)
+ else
+ report("user instance: %s, bad factors",instance)
end
+ end
end
- readtable("os/2",f,fontdata,specification)
- readtable("head",f,fontdata,specification)
- readtable("maxp",f,fontdata,specification)
- readtable("hhea",f,fontdata,specification)
- readtable("vhea",f,fontdata,specification)
- readtable("hmtx",f,fontdata,specification)
- readtable("vmtx",f,fontdata,specification)
- readtable("vorg",f,fontdata,specification)
- readtable("post",f,fontdata,specification)
- readtable("mvar",f,fontdata,specification)
- readtable("hvar",f,fontdata,specification)
- readtable("vvar",f,fontdata,specification)
- readtable("gdef",f,fontdata,specification)
- readtable("cff",f,fontdata,specification)
- readtable("cff2",f,fontdata,specification)
- readtable("cmap",f,fontdata,specification)
- readtable("loca",f,fontdata,specification)
- readtable("glyf",f,fontdata,specification)
- readtable("colr",f,fontdata,specification)
- readtable("cpal",f,fontdata,specification)
- readtable("svg",f,fontdata,specification)
- readtable("sbix",f,fontdata,specification)
- readtable("cbdt",f,fontdata,specification)
- readtable("cblc",f,fontdata,specification)
- readtable("ebdt",f,fontdata,specification)
- readtable("eblc",f,fontdata,specification)
- readtable("kern",f,fontdata,specification)
- readtable("gsub",f,fontdata,specification)
- readtable("gpos",f,fontdata,specification)
- readtable("math",f,fontdata,specification)
- fontdata.locations=nil
- fontdata.cidmaps=nil
- fontdata.dictionaries=nil
- if specification.tableoffsets then
- fontdata.tableoffsets=tables
- setmetatableindex(tables,{
- version=fontdata.version,
- noftables=fontdata.noftables,
- searchrange=fontdata.searchrange,
- entryselector=fontdata.entryselector,
- rangeshift=fontdata.rangeshift,
- })
- end
- return fontdata
+ if not fontdata.factors then
+ if fontdata.variabledata then
+ local factors=helpers.getfactors(fontdata,true)
+ if factors then
+ specification.factors=factors
+ fontdata.factors=factors
+ end
+ else
+ end
+ end
+ end
+ readtable("os/2",f,fontdata,specification)
+ readtable("head",f,fontdata,specification)
+ readtable("maxp",f,fontdata,specification)
+ readtable("hhea",f,fontdata,specification)
+ readtable("vhea",f,fontdata,specification)
+ readtable("hmtx",f,fontdata,specification)
+ readtable("vmtx",f,fontdata,specification)
+ readtable("vorg",f,fontdata,specification)
+ readtable("post",f,fontdata,specification)
+ readtable("mvar",f,fontdata,specification)
+ readtable("hvar",f,fontdata,specification)
+ readtable("vvar",f,fontdata,specification)
+ readtable("gdef",f,fontdata,specification)
+ readtable("cff",f,fontdata,specification)
+ readtable("cff2",f,fontdata,specification)
+ readtable("cmap",f,fontdata,specification)
+ readtable("loca",f,fontdata,specification)
+ readtable("glyf",f,fontdata,specification)
+ readtable("colr",f,fontdata,specification)
+ readtable("cpal",f,fontdata,specification)
+ readtable("svg",f,fontdata,specification)
+ readtable("sbix",f,fontdata,specification)
+ readtable("cbdt",f,fontdata,specification)
+ readtable("cblc",f,fontdata,specification)
+ readtable("ebdt",f,fontdata,specification)
+ readtable("eblc",f,fontdata,specification)
+ readtable("kern",f,fontdata,specification)
+ readtable("gsub",f,fontdata,specification)
+ readtable("gpos",f,fontdata,specification)
+ readtable("math",f,fontdata,specification)
+ fontdata.locations=nil
+ fontdata.cidmaps=nil
+ fontdata.dictionaries=nil
+ if specification.tableoffsets then
+ fontdata.tableoffsets=tables
+ setmetatableindex(tables,{
+ version=fontdata.version,
+ noftables=fontdata.noftables,
+ searchrange=fontdata.searchrange,
+ entryselector=fontdata.entryselector,
+ rangeshift=fontdata.rangeshift,
+ })
+ end
+ return fontdata
end
local function loadfontdata(specification)
- local filename=specification.filename
- local fileattr=lfs.attributes(filename)
- local filesize=fileattr and fileattr.size or 0
- local filetime=fileattr and fileattr.modification or 0
- local f=openfile(filename,true)
- if not f then
- report("unable to open %a",filename)
- elseif filesize==0 then
- report("empty file %a",filename)
- closefile(f)
- else
- specification.filesize=filesize
- specification.filetime=filetime
- local version=readstring(f,4)
- local fontdata=nil
- if version=="OTTO" or version=="true" or version=="\0\1\0\0" then
- fontdata=readdata(f,0,specification)
- elseif version=="ttcf" then
- local subfont=tonumber(specification.subfont)
- local ttcversion=readulong(f)
- local nofsubfonts=readulong(f)
- local offsets=readcardinaltable(f,nofsubfonts,ulong)
- if subfont then
- if subfont>=1 and subfont<=nofsubfonts then
- fontdata=readdata(f,offsets[subfont],specification)
- else
- report("no subfont %a in file %a",subfont,filename)
- end
- else
- subfont=specification.subfont
- if type(subfont)=="string" and subfont~="" then
- specification.askedname=subfont
- for i=1,nofsubfonts do
- fontdata=readdata(f,offsets[i],specification)
- if fontdata then
- fontdata.subfontindex=i
- report("subfont named %a has index %a",subfont,i)
- break
- end
- end
- if not fontdata then
- report("no subfont named %a",subfont)
- end
- else
- local subfonts={}
- fontdata={
- filename=filename,
- filesize=filesize,
- filetime=filetime,
- version=version,
- subfonts=subfonts,
- ttcversion=ttcversion,
- nofsubfonts=nofsubfonts,
- }
- for i=1,nofsubfonts do
- subfonts[i]=readdata(f,offsets[i],specification)
- end
- end
+ local filename=specification.filename
+ local fileattr=lfs.attributes(filename)
+ local filesize=fileattr and fileattr.size or 0
+ local filetime=fileattr and fileattr.modification or 0
+ local f=openfile(filename,true)
+ if not f then
+ report("unable to open %a",filename)
+ elseif filesize==0 then
+ report("empty file %a",filename)
+ closefile(f)
+ else
+ specification.filesize=filesize
+ specification.filetime=filetime
+ local version=readstring(f,4)
+ local fontdata=nil
+ if version=="OTTO" or version=="true" or version=="\0\1\0\0" then
+ fontdata=readdata(f,0,specification)
+ elseif version=="ttcf" then
+ local subfont=tonumber(specification.subfont)
+ local ttcversion=readulong(f)
+ local nofsubfonts=readulong(f)
+ local offsets=readcardinaltable(f,nofsubfonts,ulong)
+ if subfont then
+ if subfont>=1 and subfont<=nofsubfonts then
+ fontdata=readdata(f,offsets[subfont],specification)
+ else
+ report("no subfont %a in file %a",subfont,filename)
+ end
+ else
+ subfont=specification.subfont
+ if type(subfont)=="string" and subfont~="" then
+ specification.askedname=subfont
+ for i=1,nofsubfonts do
+ fontdata=readdata(f,offsets[i],specification)
+ if fontdata then
+ fontdata.subfontindex=i
+ report("subfont named %a has index %a",subfont,i)
+ break
end
+ end
+ if not fontdata then
+ report("no subfont named %a",subfont)
+ end
else
- report("unknown version %a in file %a",version,filename)
+ local subfonts={}
+ fontdata={
+ filename=filename,
+ filesize=filesize,
+ filetime=filetime,
+ version=version,
+ subfonts=subfonts,
+ ttcversion=ttcversion,
+ nofsubfonts=nofsubfonts,
+ }
+ for i=1,nofsubfonts do
+ subfonts[i]=readdata(f,offsets[i],specification)
+ end
end
- closefile(f)
- return fontdata or {}
+ end
+ else
+ report("unknown version %a in file %a",version,filename)
end
+ closefile(f)
+ return fontdata or {}
+ end
end
local function loadfont(specification,n,instance)
- if type(specification)=="string" then
- specification={
- filename=specification,
- info=true,
- details=true,
- glyphs=true,
- shapes=true,
- kerns=true,
- variable=true,
- globalkerns=true,
- lookups=true,
- subfont=n or true,
- tounicode=false,
- instance=instance
- }
- end
- if specification.shapes or specification.lookups or specification.kerns then
- specification.glyphs=true
- end
- if specification.glyphs then
- specification.details=true
- end
- if specification.details then
- specification.info=true
- end
- if specification.platformnames then
- specification.platformnames=true
- end
- if specification.instance or instance then
- specification.variable=true
- specification.instance=specification.instance or instance
- end
- local function message(str)
- report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback())
- end
- local ok,result=xpcall(loadfontdata,message,specification)
- if ok then
- return result
- end
+ if type(specification)=="string" then
+ specification={
+ filename=specification,
+ info=true,
+ details=true,
+ glyphs=true,
+ shapes=true,
+ kerns=true,
+ variable=true,
+ globalkerns=true,
+ lookups=true,
+ subfont=n or true,
+ tounicode=false,
+ instance=instance
+ }
+ end
+ if specification.shapes or specification.lookups or specification.kerns then
+ specification.glyphs=true
+ end
+ if specification.glyphs then
+ specification.details=true
+ end
+ if specification.details then
+ specification.info=true
+ end
+ if specification.platformnames then
+ specification.platformnames=true
+ end
+ if specification.instance or instance then
+ specification.variable=true
+ specification.instance=specification.instance or instance
+ end
+ local function message(str)
+ report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback())
+ end
+ local ok,result=xpcall(loadfontdata,message,specification)
+ if ok then
+ return result
+ end
end
function readers.loadshapes(filename,n,instance,streams)
- local fontdata=loadfont {
- filename=filename,
- shapes=true,
- streams=streams,
- variable=true,
- subfont=n,
- instance=instance,
- }
- if fontdata then
- for k,v in next,fontdata.glyphs do
- v.class=nil
- v.index=nil
- v.math=nil
- end
- local names=fontdata.names
- if names then
- for k,v in next,names do
- names[k]=fullstrip(v.content)
- end
- end
+ local fontdata=loadfont {
+ filename=filename,
+ shapes=true,
+ streams=streams,
+ variable=true,
+ subfont=n,
+ instance=instance,
+ }
+ if fontdata then
+ for k,v in next,fontdata.glyphs do
+ v.class=nil
+ v.index=nil
+ v.math=nil
end
- return fontdata and {
- filename=filename,
- format=fontdata.format,
- glyphs=fontdata.glyphs,
- units=fontdata.fontheader.units,
- cffinfo=fontdata.cffinfo,
- fontheader=fontdata.fontheader,
- horizontalheader=fontdata.horizontalheader,
- verticalheader=fontdata.verticalheader,
- maximumprofile=fontdata.maximumprofile,
- names=fontdata.names,
- postscript=fontdata.postscript,
- } or {
- filename=filename,
- format="unknown",
- glyphs={},
- units=0,
- }
+ local names=fontdata.names
+ if names then
+ for k,v in next,names do
+ names[k]=fullstrip(v.content)
+ end
+ end
+ end
+ return fontdata and {
+ filename=filename,
+ format=fontdata.format,
+ glyphs=fontdata.glyphs,
+ units=fontdata.fontheader.units,
+ cffinfo=fontdata.cffinfo,
+ fontheader=fontdata.fontheader,
+ horizontalheader=fontdata.horizontalheader,
+ verticalheader=fontdata.verticalheader,
+ maximumprofile=fontdata.maximumprofile,
+ names=fontdata.names,
+ postscript=fontdata.postscript,
+ } or {
+ filename=filename,
+ format="unknown",
+ glyphs={},
+ units=0,
+ }
end
function readers.loadfont(filename,n,instance)
- local fontdata=loadfont {
+ local fontdata=loadfont {
+ filename=filename,
+ glyphs=true,
+ shapes=false,
+ lookups=true,
+ variable=true,
+ subfont=n,
+ instance=instance,
+ }
+ if fontdata then
+ return {
+ tableversion=tableversion,
+ creator="context mkiv",
+ size=fontdata.filesize,
+ time=fontdata.filetime,
+ glyphs=fontdata.glyphs,
+ descriptions=fontdata.descriptions,
+ format=fontdata.format,
+ goodies={},
+ metadata=getinfo(fontdata,n,false,false,true,true),
+ properties={
+ hasitalics=fontdata.hasitalics or false,
+ maxcolorclass=fontdata.maxcolorclass,
+ hascolor=fontdata.hascolor or false,
+ instance=fontdata.instance,
+ factors=fontdata.factors,
+ },
+ resources={
filename=filename,
- glyphs=true,
- shapes=false,
- lookups=true,
- variable=true,
- subfont=n,
- instance=instance,
+ private=privateoffset,
+ duplicates=fontdata.duplicates or {},
+ features=fontdata.features or {},
+ sublookups=fontdata.sublookups or {},
+ marks=fontdata.marks or {},
+ markclasses=fontdata.markclasses or {},
+ marksets=fontdata.marksets or {},
+ sequences=fontdata.sequences or {},
+ variants=fontdata.variants,
+ version=getname(fontdata,"version"),
+ cidinfo=fontdata.cidinfo,
+ mathconstants=fontdata.mathconstants,
+ colorpalettes=fontdata.colorpalettes,
+ svgshapes=fontdata.svgshapes,
+ pngshapes=fontdata.pngshapes,
+ variabledata=fontdata.variabledata,
+ foundtables=fontdata.foundtables,
+ },
}
- if fontdata then
- return {
- tableversion=tableversion,
- creator="context mkiv",
- size=fontdata.filesize,
- time=fontdata.filetime,
- glyphs=fontdata.glyphs,
- descriptions=fontdata.descriptions,
- format=fontdata.format,
- goodies={},
- metadata=getinfo(fontdata,n,false,false,true,true),
- properties={
- hasitalics=fontdata.hasitalics or false,
- maxcolorclass=fontdata.maxcolorclass,
- hascolor=fontdata.hascolor or false,
- instance=fontdata.instance,
- factors=fontdata.factors,
- },
- resources={
- filename=filename,
- private=privateoffset,
- duplicates=fontdata.duplicates or {},
- features=fontdata.features or {},
- sublookups=fontdata.sublookups or {},
- marks=fontdata.marks or {},
- markclasses=fontdata.markclasses or {},
- marksets=fontdata.marksets or {},
- sequences=fontdata.sequences or {},
- variants=fontdata.variants,
- version=getname(fontdata,"version"),
- cidinfo=fontdata.cidinfo,
- mathconstants=fontdata.mathconstants,
- colorpalettes=fontdata.colorpalettes,
- svgshapes=fontdata.svgshapes,
- pngshapes=fontdata.pngshapes,
- variabledata=fontdata.variabledata,
- foundtables=fontdata.foundtables,
- },
- }
- end
+ end
end
function readers.getinfo(filename,specification)
- local subfont=nil
- local platformnames=false
- local rawfamilynames=false
- local instancenames=true
- local tableoffsets=false
- if type(specification)=="table" then
- subfont=tonumber(specification.subfont)
- platformnames=specification.platformnames
- rawfamilynames=specification.rawfamilynames
- tableoffsets=specification.tableoffsets
+ local subfont=nil
+ local platformnames=false
+ local rawfamilynames=false
+ local instancenames=true
+ local tableoffsets=false
+ if type(specification)=="table" then
+ subfont=tonumber(specification.subfont)
+ platformnames=specification.platformnames
+ rawfamilynames=specification.rawfamilynames
+ tableoffsets=specification.tableoffsets
+ else
+ subfont=tonumber(specification)
+ end
+ local fontdata=loadfont {
+ filename=filename,
+ details=true,
+ platformnames=platformnames,
+ instancenames=true,
+ tableoffsets=tableoffsets,
+ }
+ if fontdata then
+ local subfonts=fontdata.subfonts
+ if not subfonts then
+ return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames)
+ elseif not subfont then
+ local info={}
+ for i=1,#subfonts do
+ info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames)
+ end
+ return info
+ elseif subfont>=1 and subfont<=#subfonts then
+ return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames)
else
- subfont=tonumber(specification)
- end
- local fontdata=loadfont {
+ return {
filename=filename,
- details=true,
- platformnames=platformnames,
- instancenames=true,
- tableoffsets=tableoffsets,
- }
- if fontdata then
- local subfonts=fontdata.subfonts
- if not subfonts then
- return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames)
- elseif not subfont then
- local info={}
- for i=1,#subfonts do
- info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames)
- end
- return info
- elseif subfont>=1 and subfont<=#subfonts then
- return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames)
- else
- return {
- filename=filename,
- comment="there is no subfont "..subfont.." in this file"
- }
- end
- else
- return {
- filename=filename,
- comment="the file cannot be opened for reading",
- }
+ comment="there is no subfont "..subfont.." in this file"
+ }
end
+ else
+ return {
+ filename=filename,
+ comment="the file cannot be opened for reading",
+ }
+ end
end
function readers.rehash(fontdata,hashmethod)
- report("the %a helper is not yet implemented","rehash")
+ report("the %a helper is not yet implemented","rehash")
end
function readers.checkhash(fontdata)
- report("the %a helper is not yet implemented","checkhash")
+ report("the %a helper is not yet implemented","checkhash")
end
function readers.pack(fontdata,hashmethod)
- report("the %a helper is not yet implemented","pack")
+ report("the %a helper is not yet implemented","pack")
end
function readers.unpack(fontdata)
- report("the %a helper is not yet implemented","unpack")
+ report("the %a helper is not yet implemented","unpack")
end
function readers.expand(fontdata)
- report("the %a helper is not yet implemented","unpack")
+ report("the %a helper is not yet implemented","unpack")
end
function readers.compact(fontdata)
- report("the %a helper is not yet implemented","compact")
+ report("the %a helper is not yet implemented","compact")
end
local extenders={}
function readers.registerextender(extender)
- extenders[#extenders+1]=extender
+ extenders[#extenders+1]=extender
end
function readers.extend(fontdata)
- for i=1,#extenders do
- local extender=extenders[i]
- local name=extender.name or "unknown"
- local action=extender.action
- if action then
- action(fontdata)
- end
+ for i=1,#extenders do
+ local extender=extenders[i]
+ local name=extender.name or "unknown"
+ local action=extender.action
+ if action then
+ action(fontdata)
end
+ end
end
end -- closure
@@ -12253,11 +12253,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-oti']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local lower=string.lower
local fonts=fonts
@@ -12269,128 +12269,128 @@ local otftables=otf.tables or {}
otf.tables=otftables
local allocate=utilities.storage.allocate
registerotffeature {
- name="features",
- description="initialization of feature handler",
- default=true,
+ name="features",
+ description="initialization of feature handler",
+ default=true,
}
local function setmode(tfmdata,value)
- if value then
- tfmdata.properties.mode=lower(value)
- end
+ if value then
+ tfmdata.properties.mode=lower(value)
+ end
end
otf.modeinitializer=setmode
local function setlanguage(tfmdata,value)
- if value then
- local cleanvalue=lower(value)
- local languages=otftables and otftables.languages
- local properties=tfmdata.properties
- if not languages then
- properties.language=cleanvalue
- elseif languages[value] then
- properties.language=cleanvalue
- else
- properties.language="dflt"
- end
+ if value then
+ local cleanvalue=lower(value)
+ local languages=otftables and otftables.languages
+ local properties=tfmdata.properties
+ if not languages then
+ properties.language=cleanvalue
+ elseif languages[value] then
+ properties.language=cleanvalue
+ else
+ properties.language="dflt"
end
+ end
end
local function setscript(tfmdata,value)
- if value then
- local cleanvalue=lower(value)
- local scripts=otftables and otftables.scripts
- local properties=tfmdata.properties
- if not scripts then
- properties.script=cleanvalue
- elseif scripts[value] then
- properties.script=cleanvalue
- else
- properties.script="dflt"
- end
+ if value then
+ local cleanvalue=lower(value)
+ local scripts=otftables and otftables.scripts
+ local properties=tfmdata.properties
+ if not scripts then
+ properties.script=cleanvalue
+ elseif scripts[value] then
+ properties.script=cleanvalue
+ else
+ properties.script="dflt"
end
+ end
end
registerotffeature {
- name="mode",
- description="mode",
- initializers={
- base=setmode,
- node=setmode,
- plug=setmode,
- }
+ name="mode",
+ description="mode",
+ initializers={
+ base=setmode,
+ node=setmode,
+ plug=setmode,
+ }
}
registerotffeature {
- name="language",
- description="language",
- initializers={
- base=setlanguage,
- node=setlanguage,
- plug=setlanguage,
- }
+ name="language",
+ description="language",
+ initializers={
+ base=setlanguage,
+ node=setlanguage,
+ plug=setlanguage,
+ }
}
registerotffeature {
- name="script",
- description="script",
- initializers={
- base=setscript,
- node=setscript,
- plug=setscript,
- }
+ name="script",
+ description="script",
+ initializers={
+ base=setscript,
+ node=setscript,
+ plug=setscript,
+ }
}
otftables.featuretypes=allocate {
- gpos_single="position",
- gpos_pair="position",
- gpos_cursive="position",
- gpos_mark2base="position",
- gpos_mark2ligature="position",
- gpos_mark2mark="position",
- gpos_context="position",
- gpos_contextchain="position",
- gsub_single="substitution",
- gsub_multiple="substitution",
- gsub_alternate="substitution",
- gsub_ligature="substitution",
- gsub_context="substitution",
- gsub_contextchain="substitution",
- gsub_reversecontextchain="substitution",
- gsub_reversesub="substitution",
+ gpos_single="position",
+ gpos_pair="position",
+ gpos_cursive="position",
+ gpos_mark2base="position",
+ gpos_mark2ligature="position",
+ gpos_mark2mark="position",
+ gpos_context="position",
+ gpos_contextchain="position",
+ gsub_single="substitution",
+ gsub_multiple="substitution",
+ gsub_alternate="substitution",
+ gsub_ligature="substitution",
+ gsub_context="substitution",
+ gsub_contextchain="substitution",
+ gsub_reversecontextchain="substitution",
+ gsub_reversesub="substitution",
}
function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts)
- if featuretype=="position" then
- local default=scripts.dflt
- if default then
- if autoscript=="position" or autoscript==true then
- return default
- else
- report_otf("script feature %s not applied, enable default positioning")
- end
- else
- end
- elseif featuretype=="substitution" then
- local default=scripts.dflt
- if default then
- if autoscript=="substitution" or autoscript==true then
- return default
- end
- end
+ if featuretype=="position" then
+ local default=scripts.dflt
+ if default then
+ if autoscript=="position" or autoscript==true then
+ return default
+ else
+ report_otf("script feature %s not applied, enable default positioning")
+ end
+ else
+ end
+ elseif featuretype=="substitution" then
+ local default=scripts.dflt
+ if default then
+ if autoscript=="substitution" or autoscript==true then
+ return default
+ end
end
+ end
end
function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
- if featuretype=="position" then
- local default=languages.dflt
- if default then
- if autolanguage=="position" or autolanguage==true then
- return default
- else
- report_otf("language feature %s not applied, enable default positioning")
- end
- else
- end
- elseif featuretype=="substitution" then
- local default=languages.dflt
- if default then
- if autolanguage=="substitution" or autolanguage==true then
- return default
- end
- end
+ if featuretype=="position" then
+ local default=languages.dflt
+ if default then
+ if autolanguage=="position" or autolanguage==true then
+ return default
+ else
+ report_otf("language feature %s not applied, enable default positioning")
+ end
+ else
end
+ elseif featuretype=="substitution" then
+ local default=languages.dflt
+ if default then
+ if autolanguage=="substitution" or autolanguage==true then
+ return default
+ end
+ end
+ end
end
end -- closure
@@ -12398,11 +12398,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ["font-ott"]={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local type,next,tonumber,tostring,rawget,rawset=type,next,tonumber,tostring,rawget,rawset
local gsub,lower,format,match,gmatch,find=string.gsub,string.lower,string.format,string.match,string.gmatch,string.find
@@ -12419,975 +12419,975 @@ otf.tables=tables
local statistics=otf.statistics or {}
otf.statistics=statistics
local scripts=allocate {
- ["arab"]="arabic",
- ["armi"]="imperial aramaic",
- ["armn"]="armenian",
- ["avst"]="avestan",
- ["bali"]="balinese",
- ["bamu"]="bamum",
- ["batk"]="batak",
- ["beng"]="bengali",
- ["bng2"]="bengali variant 2",
- ["bopo"]="bopomofo",
- ["brah"]="brahmi",
- ["brai"]="braille",
- ["bugi"]="buginese",
- ["buhd"]="buhid",
- ["byzm"]="byzantine music",
- ["cakm"]="chakma",
- ["cans"]="canadian syllabics",
- ["cari"]="carian",
- ["cham"]="cham",
- ["cher"]="cherokee",
- ["copt"]="coptic",
- ["cprt"]="cypriot syllabary",
- ["cyrl"]="cyrillic",
- ["deva"]="devanagari",
- ["dev2"]="devanagari variant 2",
- ["dsrt"]="deseret",
- ["egyp"]="egyptian heiroglyphs",
- ["ethi"]="ethiopic",
- ["geor"]="georgian",
- ["glag"]="glagolitic",
- ["goth"]="gothic",
- ["grek"]="greek",
- ["gujr"]="gujarati",
- ["gjr2"]="gujarati variant 2",
- ["guru"]="gurmukhi",
- ["gur2"]="gurmukhi variant 2",
- ["hang"]="hangul",
- ["hani"]="cjk ideographic",
- ["hano"]="hanunoo",
- ["hebr"]="hebrew",
- ["ital"]="old italic",
- ["jamo"]="hangul jamo",
- ["java"]="javanese",
- ["kali"]="kayah li",
- ["kana"]="hiragana and katakana",
- ["khar"]="kharosthi",
- ["khmr"]="khmer",
- ["knda"]="kannada",
- ["knd2"]="kannada variant 2",
- ["kthi"]="kaithi",
- ["lana"]="tai tham",
- ["lao" ]="lao",
- ["latn"]="latin",
- ["lepc"]="lepcha",
- ["limb"]="limbu",
- ["linb"]="linear b",
- ["lisu"]="lisu",
- ["lyci"]="lycian",
- ["lydi"]="lydian",
- ["mand"]="mandaic and mandaean",
- ["math"]="mathematical alphanumeric symbols",
- ["merc"]="meroitic cursive",
- ["mero"]="meroitic hieroglyphs",
- ["mlym"]="malayalam",
- ["mlm2"]="malayalam variant 2",
- ["mong"]="mongolian",
- ["mtei"]="meitei Mayek",
- ["musc"]="musical symbols",
- ["mym2"]="myanmar variant 2",
- ["mymr"]="myanmar",
- ["nko" ]='n"ko',
- ["ogam"]="ogham",
- ["olck"]="ol chiki",
- ["orkh"]="old turkic and orkhon runic",
- ["orya"]="oriya",
- ["ory2"]="odia variant 2",
- ["osma"]="osmanya",
- ["phag"]="phags-pa",
- ["phli"]="inscriptional pahlavi",
- ["phnx"]="phoenician",
- ["prti"]="inscriptional parthian",
- ["rjng"]="rejang",
- ["runr"]="runic",
- ["samr"]="samaritan",
- ["sarb"]="old south arabian",
- ["saur"]="saurashtra",
- ["shaw"]="shavian",
- ["shrd"]="sharada",
- ["sinh"]="sinhala",
- ["sora"]="sora sompeng",
- ["sund"]="sundanese",
- ["sylo"]="syloti nagri",
- ["syrc"]="syriac",
- ["tagb"]="tagbanwa",
- ["takr"]="takri",
- ["tale"]="tai le",
- ["talu"]="tai lu",
- ["taml"]="tamil",
- ["tavt"]="tai viet",
- ["telu"]="telugu",
- ["tel2"]="telugu variant 2",
- ["tfng"]="tifinagh",
- ["tglg"]="tagalog",
- ["thaa"]="thaana",
- ["thai"]="thai",
- ["tibt"]="tibetan",
- ["tml2"]="tamil variant 2",
- ["ugar"]="ugaritic cuneiform",
- ["vai" ]="vai",
- ["xpeo"]="old persian cuneiform",
- ["xsux"]="sumero-akkadian cuneiform",
- ["yi" ]="yi",
+ ["arab"]="arabic",
+ ["armi"]="imperial aramaic",
+ ["armn"]="armenian",
+ ["avst"]="avestan",
+ ["bali"]="balinese",
+ ["bamu"]="bamum",
+ ["batk"]="batak",
+ ["beng"]="bengali",
+ ["bng2"]="bengali variant 2",
+ ["bopo"]="bopomofo",
+ ["brah"]="brahmi",
+ ["brai"]="braille",
+ ["bugi"]="buginese",
+ ["buhd"]="buhid",
+ ["byzm"]="byzantine music",
+ ["cakm"]="chakma",
+ ["cans"]="canadian syllabics",
+ ["cari"]="carian",
+ ["cham"]="cham",
+ ["cher"]="cherokee",
+ ["copt"]="coptic",
+ ["cprt"]="cypriot syllabary",
+ ["cyrl"]="cyrillic",
+ ["deva"]="devanagari",
+ ["dev2"]="devanagari variant 2",
+ ["dsrt"]="deseret",
+ ["egyp"]="egyptian heiroglyphs",
+ ["ethi"]="ethiopic",
+ ["geor"]="georgian",
+ ["glag"]="glagolitic",
+ ["goth"]="gothic",
+ ["grek"]="greek",
+ ["gujr"]="gujarati",
+ ["gjr2"]="gujarati variant 2",
+ ["guru"]="gurmukhi",
+ ["gur2"]="gurmukhi variant 2",
+ ["hang"]="hangul",
+ ["hani"]="cjk ideographic",
+ ["hano"]="hanunoo",
+ ["hebr"]="hebrew",
+ ["ital"]="old italic",
+ ["jamo"]="hangul jamo",
+ ["java"]="javanese",
+ ["kali"]="kayah li",
+ ["kana"]="hiragana and katakana",
+ ["khar"]="kharosthi",
+ ["khmr"]="khmer",
+ ["knda"]="kannada",
+ ["knd2"]="kannada variant 2",
+ ["kthi"]="kaithi",
+ ["lana"]="tai tham",
+ ["lao" ]="lao",
+ ["latn"]="latin",
+ ["lepc"]="lepcha",
+ ["limb"]="limbu",
+ ["linb"]="linear b",
+ ["lisu"]="lisu",
+ ["lyci"]="lycian",
+ ["lydi"]="lydian",
+ ["mand"]="mandaic and mandaean",
+ ["math"]="mathematical alphanumeric symbols",
+ ["merc"]="meroitic cursive",
+ ["mero"]="meroitic hieroglyphs",
+ ["mlym"]="malayalam",
+ ["mlm2"]="malayalam variant 2",
+ ["mong"]="mongolian",
+ ["mtei"]="meitei Mayek",
+ ["musc"]="musical symbols",
+ ["mym2"]="myanmar variant 2",
+ ["mymr"]="myanmar",
+ ["nko" ]='n"ko',
+ ["ogam"]="ogham",
+ ["olck"]="ol chiki",
+ ["orkh"]="old turkic and orkhon runic",
+ ["orya"]="oriya",
+ ["ory2"]="odia variant 2",
+ ["osma"]="osmanya",
+ ["phag"]="phags-pa",
+ ["phli"]="inscriptional pahlavi",
+ ["phnx"]="phoenician",
+ ["prti"]="inscriptional parthian",
+ ["rjng"]="rejang",
+ ["runr"]="runic",
+ ["samr"]="samaritan",
+ ["sarb"]="old south arabian",
+ ["saur"]="saurashtra",
+ ["shaw"]="shavian",
+ ["shrd"]="sharada",
+ ["sinh"]="sinhala",
+ ["sora"]="sora sompeng",
+ ["sund"]="sundanese",
+ ["sylo"]="syloti nagri",
+ ["syrc"]="syriac",
+ ["tagb"]="tagbanwa",
+ ["takr"]="takri",
+ ["tale"]="tai le",
+ ["talu"]="tai lu",
+ ["taml"]="tamil",
+ ["tavt"]="tai viet",
+ ["telu"]="telugu",
+ ["tel2"]="telugu variant 2",
+ ["tfng"]="tifinagh",
+ ["tglg"]="tagalog",
+ ["thaa"]="thaana",
+ ["thai"]="thai",
+ ["tibt"]="tibetan",
+ ["tml2"]="tamil variant 2",
+ ["ugar"]="ugaritic cuneiform",
+ ["vai" ]="vai",
+ ["xpeo"]="old persian cuneiform",
+ ["xsux"]="sumero-akkadian cuneiform",
+ ["yi" ]="yi",
}
local languages=allocate {
- ["aba" ]="abaza",
- ["abk" ]="abkhazian",
- ["ach" ]="acholi",
- ["acr" ]="achi",
- ["ady" ]="adyghe",
- ["afk" ]="afrikaans",
- ["afr" ]="afar",
- ["agw" ]="agaw",
- ["aio" ]="aiton",
- ["aka" ]="akan",
- ["als" ]="alsatian",
- ["alt" ]="altai",
- ["amh" ]="amharic",
- ["ang" ]="anglo-saxon",
- ["apph"]="phonetic transcription—americanist conventions",
- ["ara" ]="arabic",
- ["arg" ]="aragonese",
- ["ari" ]="aari",
- ["ark" ]="rakhine",
- ["asm" ]="assamese",
- ["ast" ]="asturian",
- ["ath" ]="athapaskan",
- ["avr" ]="avar",
- ["awa" ]="awadhi",
- ["aym" ]="aymara",
- ["azb" ]="torki",
- ["aze" ]="azerbaijani",
- ["bad" ]="badaga",
- ["bad0"]="banda",
- ["bag" ]="baghelkhandi",
- ["bal" ]="balkar",
- ["ban" ]="balinese",
- ["bar" ]="bavarian",
- ["bau" ]="baulé",
- ["bbc" ]="batak toba",
- ["bbr" ]="berber",
- ["bch" ]="bench",
- ["bcr" ]="bible cree",
- ["bdy" ]="bandjalang",
- ["bel" ]="belarussian",
- ["bem" ]="bemba",
- ["ben" ]="bengali",
- ["bgc" ]="haryanvi",
- ["bgq" ]="bagri",
- ["bgr" ]="bulgarian",
- ["bhi" ]="bhili",
- ["bho" ]="bhojpuri",
- ["bik" ]="bikol",
- ["bil" ]="bilen",
- ["bis" ]="bislama",
- ["bjj" ]="kanauji",
- ["bkf" ]="blackfoot",
- ["bli" ]="baluchi",
- ["blk" ]="pa'o karen",
- ["bln" ]="balante",
- ["blt" ]="balti",
- ["bmb" ]="bambara (bamanankan)",
- ["bml" ]="bamileke",
- ["bos" ]="bosnian",
- ["bpy" ]="bishnupriya manipuri",
- ["bre" ]="breton",
- ["brh" ]="brahui",
- ["bri" ]="braj bhasha",
- ["brm" ]="burmese",
- ["brx" ]="bodo",
- ["bsh" ]="bashkir",
- ["bti" ]="beti",
- ["bts" ]="batak simalungun",
- ["bug" ]="bugis",
- ["cak" ]="kaqchikel",
- ["cat" ]="catalan",
- ["cbk" ]="zamboanga chavacano",
- ["ceb" ]="cebuano",
- ["cgg" ]="chiga",
- ["cha" ]="chamorro",
- ["che" ]="chechen",
- ["chg" ]="chaha gurage",
- ["chh" ]="chattisgarhi",
- ["chi" ]="chichewa (chewa, nyanja)",
- ["chk" ]="chukchi",
- ["chk0"]="chuukese",
- ["cho" ]="choctaw",
- ["chp" ]="chipewyan",
- ["chr" ]="cherokee",
- ["chu" ]="chuvash",
- ["chy" ]="cheyenne",
- ["cmr" ]="comorian",
- ["cop" ]="coptic",
- ["cor" ]="cornish",
- ["cos" ]="corsican",
- ["cpp" ]="creoles",
- ["cre" ]="cree",
- ["crr" ]="carrier",
- ["crt" ]="crimean tatar",
- ["csb" ]="kashubian",
- ["csl" ]="church slavonic",
- ["csy" ]="czech",
- ["ctg" ]="chittagonian",
- ["cuk" ]="san blas kuna",
- ["dan" ]="danish",
- ["dar" ]="dargwa",
- ["dax" ]="dayi",
- ["dcr" ]="woods cree",
- ["deu" ]="german",
- ["dgo" ]="dogri",
- ["dgr" ]="dogri",
- ["dhg" ]="dhangu",
- ["dhv" ]="divehi (dhivehi, maldivian)",
- ["diq" ]="dimli",
- ["div" ]="divehi (dhivehi, maldivian)",
- ["djr" ]="zarma",
- ["djr0"]="djambarrpuyngu",
- ["dng" ]="dangme",
- ["dnj" ]="dan",
- ["dnk" ]="dinka",
- ["dri" ]="dari",
- ["duj" ]="dhuwal",
- ["dun" ]="dungan",
- ["dzn" ]="dzongkha",
- ["ebi" ]="ebira",
- ["ecr" ]="eastern cree",
- ["edo" ]="edo",
- ["efi" ]="efik",
- ["ell" ]="greek",
- ["emk" ]="eastern maninkakan",
- ["eng" ]="english",
- ["erz" ]="erzya",
- ["esp" ]="spanish",
- ["esu" ]="central yupik",
- ["eti" ]="estonian",
- ["euq" ]="basque",
- ["evk" ]="evenki",
- ["evn" ]="even",
- ["ewe" ]="ewe",
- ["fan" ]="french antillean",
- ["fan0"]=" fang",
- ["far" ]="persian",
- ["fat" ]="fanti",
- ["fin" ]="finnish",
- ["fji" ]="fijian",
- ["fle" ]="dutch (flemish)",
- ["fne" ]="forest nenets",
- ["fon" ]="fon",
- ["fos" ]="faroese",
- ["fra" ]="french",
- ["frc" ]="cajun french",
- ["fri" ]="frisian",
- ["frl" ]="friulian",
- ["frp" ]="arpitan",
- ["fta" ]="futa",
- ["ful" ]="fulah",
- ["fuv" ]="nigerian fulfulde",
- ["gad" ]="ga",
- ["gae" ]="scottish gaelic (gaelic)",
- ["gag" ]="gagauz",
- ["gal" ]="galician",
- ["gar" ]="garshuni",
- ["gaw" ]="garhwali",
- ["gez" ]="ge'ez",
- ["gih" ]="githabul",
- ["gil" ]="gilyak",
- ["gil0"]="kiribati (gilbertese)",
- ["gkp" ]="kpelle (guinea)",
- ["glk" ]="gilaki",
- ["gmz" ]="gumuz",
- ["gnn" ]="gumatj",
- ["gog" ]="gogo",
- ["gon" ]="gondi",
- ["grn" ]="greenlandic",
- ["gro" ]="garo",
- ["gua" ]="guarani",
- ["guc" ]="wayuu",
- ["guf" ]="gupapuyngu",
- ["guj" ]="gujarati",
- ["guz" ]="gusii",
- ["hai" ]="haitian (haitian creole)",
- ["hal" ]="halam",
- ["har" ]="harauti",
- ["hau" ]="hausa",
- ["haw" ]="hawaiian",
- ["hay" ]="haya",
- ["haz" ]="hazaragi",
- ["hbn" ]="hammer-banna",
- ["her" ]="herero",
- ["hil" ]="hiligaynon",
- ["hin" ]="hindi",
- ["hma" ]="high mari",
- ["hmn" ]="hmong",
- ["hmo" ]="hiri motu",
- ["hnd" ]="hindko",
- ["ho" ]="ho",
- ["hri" ]="harari",
- ["hrv" ]="croatian",
- ["hun" ]="hungarian",
- ["hye" ]="armenian",
- ["hye0"]="armenian east",
- ["iba" ]="iban",
- ["ibb" ]="ibibio",
- ["ibo" ]="igbo",
- ["ido" ]="ido",
- ["ijo" ]="ijo languages",
- ["ile" ]="interlingue",
- ["ilo" ]="ilokano",
- ["ina" ]="interlingua",
- ["ind" ]="indonesian",
- ["ing" ]="ingush",
- ["inu" ]="inuktitut",
- ["ipk" ]="inupiat",
- ["ipph"]="phonetic transcription—ipa conventions",
- ["iri" ]="irish",
- ["irt" ]="irish traditional",
- ["isl" ]="icelandic",
- ["ism" ]="inari sami",
- ["ita" ]="italian",
- ["iwr" ]="hebrew",
- ["jam" ]="jamaican creole",
- ["jan" ]="japanese",
- ["jav" ]="javanese",
- ["jbo" ]="lojban",
- ["jii" ]="yiddish",
- ["jud" ]="ladino",
- ["jul" ]="jula",
- ["kab" ]="kabardian",
- ["kab0"]="kabyle",
- ["kac" ]="kachchi",
- ["kal" ]="kalenjin",
- ["kan" ]="kannada",
- ["kar" ]="karachay",
- ["kat" ]="georgian",
- ["kaz" ]="kazakh",
- ["kde" ]="makonde",
- ["kea" ]="kabuverdianu (crioulo)",
- ["keb" ]="kebena",
- ["kek" ]="kekchi",
- ["kge" ]="khutsuri georgian",
- ["kha" ]="khakass",
- ["khk" ]="khanty-kazim",
- ["khm" ]="khmer",
- ["khs" ]="khanty-shurishkar",
- ["kht" ]="khamti shan",
- ["khv" ]="khanty-vakhi",
- ["khw" ]="khowar",
- ["kik" ]="kikuyu (gikuyu)",
- ["kir" ]="kirghiz (kyrgyz)",
- ["kis" ]="kisii",
- ["kiu" ]="kirmanjki",
- ["kjd" ]="southern kiwai",
- ["kjp" ]="eastern pwo karen",
- ["kjz" ]="bumthangkha",
- ["kkn" ]="kokni",
- ["klm" ]="kalmyk",
- ["kmb" ]="kamba",
- ["kmn" ]="kumaoni",
- ["kmo" ]="komo",
- ["kms" ]="komso",
- ["knr" ]="kanuri",
- ["kod" ]="kodagu",
- ["koh" ]="korean old hangul",
- ["kok" ]="konkani",
- ["kom" ]="komi",
- ["kon" ]="kikongo",
- ["kon0"]="kongo",
- ["kop" ]="komi-permyak",
- ["kor" ]="korean",
- ["kos" ]="kosraean",
- ["koz" ]="komi-zyrian",
- ["kpl" ]="kpelle",
- ["kri" ]="krio",
- ["krk" ]="karakalpak",
- ["krl" ]="karelian",
- ["krm" ]="karaim",
- ["krn" ]="karen",
- ["krt" ]="koorete",
- ["ksh" ]="kashmiri",
- ["ksh0"]="ripuarian",
- ["ksi" ]="khasi",
- ["ksm" ]="kildin sami",
- ["ksw" ]="s’gaw karen",
- ["kua" ]="kuanyama",
- ["kui" ]="kui",
- ["kul" ]="kulvi",
- ["kum" ]="kumyk",
- ["kur" ]="kurdish",
- ["kuu" ]="kurukh",
- ["kuy" ]="kuy",
- ["kyk" ]="koryak",
- ["kyu" ]="western kayah",
- ["lad" ]="ladin",
- ["lah" ]="lahuli",
- ["lak" ]="lak",
- ["lam" ]="lambani",
- ["lao" ]="lao",
- ["lat" ]="latin",
- ["laz" ]="laz",
- ["lcr" ]="l-cree",
- ["ldk" ]="ladakhi",
- ["lez" ]="lezgi",
- ["lij" ]="ligurian",
- ["lim" ]="limburgish",
- ["lin" ]="lingala",
- ["lis" ]="lisu",
- ["ljp" ]="lampung",
- ["lki" ]="laki",
- ["lma" ]="low mari",
- ["lmb" ]="limbu",
- ["lmo" ]="lombard",
- ["lmw" ]="lomwe",
- ["lom" ]="loma",
- ["lrc" ]="luri",
- ["lsb" ]="lower sorbian",
- ["lsm" ]="lule sami",
- ["lth" ]="lithuanian",
- ["ltz" ]="luxembourgish",
- ["lua" ]="luba-lulua",
- ["lub" ]="luba-katanga",
- ["lug" ]="ganda",
- ["luh" ]="luyia",
- ["luo" ]="luo",
- ["lvi" ]="latvian",
- ["mad" ]="madura",
- ["mag" ]="magahi",
- ["mah" ]="marshallese",
- ["maj" ]="majang",
- ["mak" ]="makhuwa",
- ["mal" ]="malayalam reformed",
- ["mam" ]="mam",
- ["man" ]="mansi",
- ["map" ]="mapudungun",
- ["mar" ]="marathi",
- ["maw" ]="marwari",
- ["mbn" ]="mbundu",
- ["mch" ]="manchu",
- ["mcr" ]="moose cree",
- ["mde" ]="mende",
- ["mdr" ]="mandar",
- ["men" ]="me'en",
- ["mer" ]="meru",
- ["mfa" ]="pattani malay",
- ["mfe" ]="morisyen",
- ["min" ]="minangkabau",
- ["miz" ]="mizo",
- ["mkd" ]="macedonian",
- ["mkr" ]="makasar",
- ["mkw" ]="kituba",
- ["mle" ]="male",
- ["mlg" ]="malagasy",
- ["mln" ]="malinke",
- ["mly" ]="malay",
- ["mnd" ]="mandinka",
- ["mng" ]="mongolian",
- ["mni" ]="manipuri",
- ["mnk" ]="maninka",
- ["mnx" ]="manx",
- ["moh" ]="mohawk",
- ["mok" ]="moksha",
- ["mol" ]="moldavian",
- ["mon" ]="mon",
- ["mor" ]="moroccan",
- ["mos" ]="mossi",
- ["mri" ]="maori",
- ["mth" ]="maithili",
- ["mts" ]="maltese",
- ["mun" ]="mundari",
- ["mus" ]="muscogee",
- ["mwl" ]="mirandese",
- ["mww" ]="hmong daw",
- ["myn" ]="mayan",
- ["mzn" ]="mazanderani",
- ["nag" ]="naga-assamese",
- ["nah" ]="nahuatl",
- ["nan" ]="nanai",
- ["nap" ]="neapolitan",
- ["nas" ]="naskapi",
- ["nau" ]="nauruan",
- ["nav" ]="navajo",
- ["ncr" ]="n-cree",
- ["ndb" ]="ndebele",
- ["ndc" ]="ndau",
- ["ndg" ]="ndonga",
- ["nds" ]="low saxon",
- ["nep" ]="nepali",
- ["new" ]="newari",
- ["nga" ]="ngbaka",
- ["ngr" ]="nagari",
- ["nhc" ]="norway house cree",
- ["nis" ]="nisi",
- ["niu" ]="niuean",
- ["nkl" ]="nyankole",
- ["nko" ]="n'ko",
- ["nld" ]="dutch",
- ["noe" ]="nimadi",
- ["nog" ]="nogai",
- ["nor" ]="norwegian",
- ["nov" ]="novial",
- ["nsm" ]="northern sami",
- ["nso" ]="sotho, northern",
- ["nta" ]="northern tai",
- ["nto" ]="esperanto",
- ["nym" ]="nyamwezi",
- ["nyn" ]="norwegian nynorsk",
- ["oci" ]="occitan",
- ["ocr" ]="oji-cree",
- ["ojb" ]="ojibway",
- ["ori" ]="odia",
- ["oro" ]="oromo",
- ["oss" ]="ossetian",
- ["paa" ]="palestinian aramaic",
- ["pag" ]="pangasinan",
- ["pal" ]="pali",
- ["pam" ]="pampangan",
- ["pan" ]="punjabi",
- ["pap" ]="palpa",
- ["pap0"]="papiamentu",
- ["pas" ]="pashto",
- ["pau" ]="palauan",
- ["pcc" ]="bouyei",
- ["pcd" ]="picard",
- ["pdc" ]="pennsylvania german",
- ["pgr" ]="polytonic greek",
- ["phk" ]="phake",
- ["pih" ]="norfolk",
- ["pil" ]="filipino",
- ["plg" ]="palaung",
- ["plk" ]="polish",
- ["pms" ]="piemontese",
- ["pnb" ]="western panjabi",
- ["poh" ]="pocomchi",
- ["pon" ]="pohnpeian",
- ["pro" ]="provencal",
- ["ptg" ]="portuguese",
- ["pwo" ]="western pwo karen",
- ["qin" ]="chin",
- ["quc" ]="k’iche’",
- ["quh" ]="quechua (bolivia)",
- ["quz" ]="quechua",
- ["qvi" ]="quechua (ecuador)",
- ["qwh" ]="quechua (peru)",
- ["raj" ]="rajasthani",
- ["rar" ]="rarotongan",
- ["rbu" ]="russian buriat",
- ["rcr" ]="r-cree",
- ["rej" ]="rejang",
- ["ria" ]="riang",
- ["rif" ]="tarifit",
- ["rit" ]="ritarungo",
- ["rkw" ]="arakwal",
- ["rms" ]="romansh",
- ["rmy" ]="vlax romani",
- ["rom" ]="romanian",
- ["roy" ]="romany",
- ["rsy" ]="rusyn",
- ["rtm" ]="rotuman",
- ["rua" ]="kinyarwanda",
- ["run" ]="rundi",
- ["rup" ]="aromanian",
- ["rus" ]="russian",
- ["sad" ]="sadri",
- ["san" ]="sanskrit",
- ["sas" ]="sasak",
- ["sat" ]="santali",
- ["say" ]="sayisi",
- ["scn" ]="sicilian",
- ["sco" ]="scots",
- ["sek" ]="sekota",
- ["sel" ]="selkup",
- ["sga" ]="old irish",
- ["sgo" ]="sango",
- ["sgs" ]="samogitian",
- ["shi" ]="tachelhit",
- ["shn" ]="shan",
- ["sib" ]="sibe",
- ["sid" ]="sidamo",
- ["sig" ]="silte gurage",
- ["sks" ]="skolt sami",
- ["sky" ]="slovak",
- ["sla" ]="slavey",
- ["slv" ]="slovenian",
- ["sml" ]="somali",
- ["smo" ]="samoan",
- ["sna" ]="sena",
- ["sna0"]="shona",
- ["snd" ]="sindhi",
- ["snh" ]="sinhala (sinhalese)",
- ["snk" ]="soninke",
- ["sog" ]="sodo gurage",
- ["sop" ]="songe",
- ["sot" ]="sotho, southern",
- ["sqi" ]="albanian",
- ["srb" ]="serbian",
- ["srd" ]="sardinian",
- ["srk" ]="saraiki",
- ["srr" ]="serer",
- ["ssl" ]="south slavey",
- ["ssm" ]="southern sami",
- ["stq" ]="saterland frisian",
- ["suk" ]="sukuma",
- ["sun" ]="sundanese",
- ["sur" ]="suri",
- ["sva" ]="svan",
- ["sve" ]="swedish",
- ["swa" ]="swadaya aramaic",
- ["swk" ]="swahili",
- ["swz" ]="swati",
- ["sxt" ]="sutu",
- ["sxu" ]="upper saxon",
- ["syl" ]="sylheti",
- ["syr" ]="syriac",
- ["szl" ]="silesian",
- ["tab" ]="tabasaran",
- ["taj" ]="tajiki",
- ["tam" ]="tamil",
- ["tat" ]="tatar",
- ["tcr" ]="th-cree",
- ["tdd" ]="dehong dai",
- ["tel" ]="telugu",
- ["tet" ]="tetum",
- ["tgl" ]="tagalog",
- ["tgn" ]="tongan",
- ["tgr" ]="tigre",
- ["tgy" ]="tigrinya",
- ["tha" ]="thai",
- ["tht" ]="tahitian",
- ["tib" ]="tibetan",
- ["tiv" ]="tiv",
- ["tkm" ]="turkmen",
- ["tmh" ]="tamashek",
- ["tmn" ]="temne",
- ["tna" ]="tswana",
- ["tne" ]="tundra nenets",
- ["tng" ]="tonga",
- ["tod" ]="todo",
- ["tod0"]="toma",
- ["tpi" ]="tok pisin",
- ["trk" ]="turkish",
- ["tsg" ]="tsonga",
- ["tsj" ]="tshangla",
- ["tua" ]="turoyo aramaic",
- ["tul" ]="tulu",
- ["tuv" ]="tuvin",
- ["tvl" ]="tuvalu",
- ["twi" ]="twi",
- ["tyz" ]="tày",
- ["tzm" ]="tamazight",
- ["tzo" ]="tzotzil",
- ["udm" ]="udmurt",
- ["ukr" ]="ukrainian",
- ["umb" ]="umbundu",
- ["urd" ]="urdu",
- ["usb" ]="upper sorbian",
- ["uyg" ]="uyghur",
- ["uzb" ]="uzbek",
- ["vec" ]="venetian",
- ["ven" ]="venda",
- ["vit" ]="vietnamese",
- ["vol" ]="volapük",
- ["vro" ]="võro",
- ["wa" ]="wa",
- ["wag" ]="wagdi",
- ["war" ]="waray-waray",
- ["wcr" ]="west-cree",
- ["wel" ]="welsh",
- ["wlf" ]="wolof",
- ["wln" ]="walloon",
- ["xbd" ]="lü",
- ["xhs" ]="xhosa",
- ["xjb" ]="minjangbal",
- ["xkf" ]="khengkha",
- ["xog" ]="soga",
- ["xpe" ]="kpelle (liberia)",
- ["yak" ]="sakha",
- ["yao" ]="yao",
- ["yap" ]="yapese",
- ["yba" ]="yoruba",
- ["ycr" ]="y-cree",
- ["yic" ]="yi classic",
- ["yim" ]="yi modern",
- ["zea" ]="zealandic",
- ["zgh" ]="standard morrocan tamazigh",
- ["zha" ]="zhuang",
- ["zhh" ]="chinese, hong kong sar",
- ["zhp" ]="chinese phonetic",
- ["zhs" ]="chinese simplified",
- ["zht" ]="chinese traditional",
- ["znd" ]="zande",
- ["zul" ]="zulu",
- ["zza" ]="zazaki",
+ ["aba" ]="abaza",
+ ["abk" ]="abkhazian",
+ ["ach" ]="acholi",
+ ["acr" ]="achi",
+ ["ady" ]="adyghe",
+ ["afk" ]="afrikaans",
+ ["afr" ]="afar",
+ ["agw" ]="agaw",
+ ["aio" ]="aiton",
+ ["aka" ]="akan",
+ ["als" ]="alsatian",
+ ["alt" ]="altai",
+ ["amh" ]="amharic",
+ ["ang" ]="anglo-saxon",
+ ["apph"]="phonetic transcription—americanist conventions",
+ ["ara" ]="arabic",
+ ["arg" ]="aragonese",
+ ["ari" ]="aari",
+ ["ark" ]="rakhine",
+ ["asm" ]="assamese",
+ ["ast" ]="asturian",
+ ["ath" ]="athapaskan",
+ ["avr" ]="avar",
+ ["awa" ]="awadhi",
+ ["aym" ]="aymara",
+ ["azb" ]="torki",
+ ["aze" ]="azerbaijani",
+ ["bad" ]="badaga",
+ ["bad0"]="banda",
+ ["bag" ]="baghelkhandi",
+ ["bal" ]="balkar",
+ ["ban" ]="balinese",
+ ["bar" ]="bavarian",
+ ["bau" ]="baulé",
+ ["bbc" ]="batak toba",
+ ["bbr" ]="berber",
+ ["bch" ]="bench",
+ ["bcr" ]="bible cree",
+ ["bdy" ]="bandjalang",
+ ["bel" ]="belarussian",
+ ["bem" ]="bemba",
+ ["ben" ]="bengali",
+ ["bgc" ]="haryanvi",
+ ["bgq" ]="bagri",
+ ["bgr" ]="bulgarian",
+ ["bhi" ]="bhili",
+ ["bho" ]="bhojpuri",
+ ["bik" ]="bikol",
+ ["bil" ]="bilen",
+ ["bis" ]="bislama",
+ ["bjj" ]="kanauji",
+ ["bkf" ]="blackfoot",
+ ["bli" ]="baluchi",
+ ["blk" ]="pa'o karen",
+ ["bln" ]="balante",
+ ["blt" ]="balti",
+ ["bmb" ]="bambara (bamanankan)",
+ ["bml" ]="bamileke",
+ ["bos" ]="bosnian",
+ ["bpy" ]="bishnupriya manipuri",
+ ["bre" ]="breton",
+ ["brh" ]="brahui",
+ ["bri" ]="braj bhasha",
+ ["brm" ]="burmese",
+ ["brx" ]="bodo",
+ ["bsh" ]="bashkir",
+ ["bti" ]="beti",
+ ["bts" ]="batak simalungun",
+ ["bug" ]="bugis",
+ ["cak" ]="kaqchikel",
+ ["cat" ]="catalan",
+ ["cbk" ]="zamboanga chavacano",
+ ["ceb" ]="cebuano",
+ ["cgg" ]="chiga",
+ ["cha" ]="chamorro",
+ ["che" ]="chechen",
+ ["chg" ]="chaha gurage",
+ ["chh" ]="chattisgarhi",
+ ["chi" ]="chichewa (chewa, nyanja)",
+ ["chk" ]="chukchi",
+ ["chk0"]="chuukese",
+ ["cho" ]="choctaw",
+ ["chp" ]="chipewyan",
+ ["chr" ]="cherokee",
+ ["chu" ]="chuvash",
+ ["chy" ]="cheyenne",
+ ["cmr" ]="comorian",
+ ["cop" ]="coptic",
+ ["cor" ]="cornish",
+ ["cos" ]="corsican",
+ ["cpp" ]="creoles",
+ ["cre" ]="cree",
+ ["crr" ]="carrier",
+ ["crt" ]="crimean tatar",
+ ["csb" ]="kashubian",
+ ["csl" ]="church slavonic",
+ ["csy" ]="czech",
+ ["ctg" ]="chittagonian",
+ ["cuk" ]="san blas kuna",
+ ["dan" ]="danish",
+ ["dar" ]="dargwa",
+ ["dax" ]="dayi",
+ ["dcr" ]="woods cree",
+ ["deu" ]="german",
+ ["dgo" ]="dogri",
+ ["dgr" ]="dogri",
+ ["dhg" ]="dhangu",
+ ["dhv" ]="divehi (dhivehi, maldivian)",
+ ["diq" ]="dimli",
+ ["div" ]="divehi (dhivehi, maldivian)",
+ ["djr" ]="zarma",
+ ["djr0"]="djambarrpuyngu",
+ ["dng" ]="dangme",
+ ["dnj" ]="dan",
+ ["dnk" ]="dinka",
+ ["dri" ]="dari",
+ ["duj" ]="dhuwal",
+ ["dun" ]="dungan",
+ ["dzn" ]="dzongkha",
+ ["ebi" ]="ebira",
+ ["ecr" ]="eastern cree",
+ ["edo" ]="edo",
+ ["efi" ]="efik",
+ ["ell" ]="greek",
+ ["emk" ]="eastern maninkakan",
+ ["eng" ]="english",
+ ["erz" ]="erzya",
+ ["esp" ]="spanish",
+ ["esu" ]="central yupik",
+ ["eti" ]="estonian",
+ ["euq" ]="basque",
+ ["evk" ]="evenki",
+ ["evn" ]="even",
+ ["ewe" ]="ewe",
+ ["fan" ]="french antillean",
+ ["fan0"]=" fang",
+ ["far" ]="persian",
+ ["fat" ]="fanti",
+ ["fin" ]="finnish",
+ ["fji" ]="fijian",
+ ["fle" ]="dutch (flemish)",
+ ["fne" ]="forest nenets",
+ ["fon" ]="fon",
+ ["fos" ]="faroese",
+ ["fra" ]="french",
+ ["frc" ]="cajun french",
+ ["fri" ]="frisian",
+ ["frl" ]="friulian",
+ ["frp" ]="arpitan",
+ ["fta" ]="futa",
+ ["ful" ]="fulah",
+ ["fuv" ]="nigerian fulfulde",
+ ["gad" ]="ga",
+ ["gae" ]="scottish gaelic (gaelic)",
+ ["gag" ]="gagauz",
+ ["gal" ]="galician",
+ ["gar" ]="garshuni",
+ ["gaw" ]="garhwali",
+ ["gez" ]="ge'ez",
+ ["gih" ]="githabul",
+ ["gil" ]="gilyak",
+ ["gil0"]="kiribati (gilbertese)",
+ ["gkp" ]="kpelle (guinea)",
+ ["glk" ]="gilaki",
+ ["gmz" ]="gumuz",
+ ["gnn" ]="gumatj",
+ ["gog" ]="gogo",
+ ["gon" ]="gondi",
+ ["grn" ]="greenlandic",
+ ["gro" ]="garo",
+ ["gua" ]="guarani",
+ ["guc" ]="wayuu",
+ ["guf" ]="gupapuyngu",
+ ["guj" ]="gujarati",
+ ["guz" ]="gusii",
+ ["hai" ]="haitian (haitian creole)",
+ ["hal" ]="halam",
+ ["har" ]="harauti",
+ ["hau" ]="hausa",
+ ["haw" ]="hawaiian",
+ ["hay" ]="haya",
+ ["haz" ]="hazaragi",
+ ["hbn" ]="hammer-banna",
+ ["her" ]="herero",
+ ["hil" ]="hiligaynon",
+ ["hin" ]="hindi",
+ ["hma" ]="high mari",
+ ["hmn" ]="hmong",
+ ["hmo" ]="hiri motu",
+ ["hnd" ]="hindko",
+ ["ho" ]="ho",
+ ["hri" ]="harari",
+ ["hrv" ]="croatian",
+ ["hun" ]="hungarian",
+ ["hye" ]="armenian",
+ ["hye0"]="armenian east",
+ ["iba" ]="iban",
+ ["ibb" ]="ibibio",
+ ["ibo" ]="igbo",
+ ["ido" ]="ido",
+ ["ijo" ]="ijo languages",
+ ["ile" ]="interlingue",
+ ["ilo" ]="ilokano",
+ ["ina" ]="interlingua",
+ ["ind" ]="indonesian",
+ ["ing" ]="ingush",
+ ["inu" ]="inuktitut",
+ ["ipk" ]="inupiat",
+ ["ipph"]="phonetic transcription—ipa conventions",
+ ["iri" ]="irish",
+ ["irt" ]="irish traditional",
+ ["isl" ]="icelandic",
+ ["ism" ]="inari sami",
+ ["ita" ]="italian",
+ ["iwr" ]="hebrew",
+ ["jam" ]="jamaican creole",
+ ["jan" ]="japanese",
+ ["jav" ]="javanese",
+ ["jbo" ]="lojban",
+ ["jii" ]="yiddish",
+ ["jud" ]="ladino",
+ ["jul" ]="jula",
+ ["kab" ]="kabardian",
+ ["kab0"]="kabyle",
+ ["kac" ]="kachchi",
+ ["kal" ]="kalenjin",
+ ["kan" ]="kannada",
+ ["kar" ]="karachay",
+ ["kat" ]="georgian",
+ ["kaz" ]="kazakh",
+ ["kde" ]="makonde",
+ ["kea" ]="kabuverdianu (crioulo)",
+ ["keb" ]="kebena",
+ ["kek" ]="kekchi",
+ ["kge" ]="khutsuri georgian",
+ ["kha" ]="khakass",
+ ["khk" ]="khanty-kazim",
+ ["khm" ]="khmer",
+ ["khs" ]="khanty-shurishkar",
+ ["kht" ]="khamti shan",
+ ["khv" ]="khanty-vakhi",
+ ["khw" ]="khowar",
+ ["kik" ]="kikuyu (gikuyu)",
+ ["kir" ]="kirghiz (kyrgyz)",
+ ["kis" ]="kisii",
+ ["kiu" ]="kirmanjki",
+ ["kjd" ]="southern kiwai",
+ ["kjp" ]="eastern pwo karen",
+ ["kjz" ]="bumthangkha",
+ ["kkn" ]="kokni",
+ ["klm" ]="kalmyk",
+ ["kmb" ]="kamba",
+ ["kmn" ]="kumaoni",
+ ["kmo" ]="komo",
+ ["kms" ]="komso",
+ ["knr" ]="kanuri",
+ ["kod" ]="kodagu",
+ ["koh" ]="korean old hangul",
+ ["kok" ]="konkani",
+ ["kom" ]="komi",
+ ["kon" ]="kikongo",
+ ["kon0"]="kongo",
+ ["kop" ]="komi-permyak",
+ ["kor" ]="korean",
+ ["kos" ]="kosraean",
+ ["koz" ]="komi-zyrian",
+ ["kpl" ]="kpelle",
+ ["kri" ]="krio",
+ ["krk" ]="karakalpak",
+ ["krl" ]="karelian",
+ ["krm" ]="karaim",
+ ["krn" ]="karen",
+ ["krt" ]="koorete",
+ ["ksh" ]="kashmiri",
+ ["ksh0"]="ripuarian",
+ ["ksi" ]="khasi",
+ ["ksm" ]="kildin sami",
+ ["ksw" ]="s’gaw karen",
+ ["kua" ]="kuanyama",
+ ["kui" ]="kui",
+ ["kul" ]="kulvi",
+ ["kum" ]="kumyk",
+ ["kur" ]="kurdish",
+ ["kuu" ]="kurukh",
+ ["kuy" ]="kuy",
+ ["kyk" ]="koryak",
+ ["kyu" ]="western kayah",
+ ["lad" ]="ladin",
+ ["lah" ]="lahuli",
+ ["lak" ]="lak",
+ ["lam" ]="lambani",
+ ["lao" ]="lao",
+ ["lat" ]="latin",
+ ["laz" ]="laz",
+ ["lcr" ]="l-cree",
+ ["ldk" ]="ladakhi",
+ ["lez" ]="lezgi",
+ ["lij" ]="ligurian",
+ ["lim" ]="limburgish",
+ ["lin" ]="lingala",
+ ["lis" ]="lisu",
+ ["ljp" ]="lampung",
+ ["lki" ]="laki",
+ ["lma" ]="low mari",
+ ["lmb" ]="limbu",
+ ["lmo" ]="lombard",
+ ["lmw" ]="lomwe",
+ ["lom" ]="loma",
+ ["lrc" ]="luri",
+ ["lsb" ]="lower sorbian",
+ ["lsm" ]="lule sami",
+ ["lth" ]="lithuanian",
+ ["ltz" ]="luxembourgish",
+ ["lua" ]="luba-lulua",
+ ["lub" ]="luba-katanga",
+ ["lug" ]="ganda",
+ ["luh" ]="luyia",
+ ["luo" ]="luo",
+ ["lvi" ]="latvian",
+ ["mad" ]="madura",
+ ["mag" ]="magahi",
+ ["mah" ]="marshallese",
+ ["maj" ]="majang",
+ ["mak" ]="makhuwa",
+ ["mal" ]="malayalam reformed",
+ ["mam" ]="mam",
+ ["man" ]="mansi",
+ ["map" ]="mapudungun",
+ ["mar" ]="marathi",
+ ["maw" ]="marwari",
+ ["mbn" ]="mbundu",
+ ["mch" ]="manchu",
+ ["mcr" ]="moose cree",
+ ["mde" ]="mende",
+ ["mdr" ]="mandar",
+ ["men" ]="me'en",
+ ["mer" ]="meru",
+ ["mfa" ]="pattani malay",
+ ["mfe" ]="morisyen",
+ ["min" ]="minangkabau",
+ ["miz" ]="mizo",
+ ["mkd" ]="macedonian",
+ ["mkr" ]="makasar",
+ ["mkw" ]="kituba",
+ ["mle" ]="male",
+ ["mlg" ]="malagasy",
+ ["mln" ]="malinke",
+ ["mly" ]="malay",
+ ["mnd" ]="mandinka",
+ ["mng" ]="mongolian",
+ ["mni" ]="manipuri",
+ ["mnk" ]="maninka",
+ ["mnx" ]="manx",
+ ["moh" ]="mohawk",
+ ["mok" ]="moksha",
+ ["mol" ]="moldavian",
+ ["mon" ]="mon",
+ ["mor" ]="moroccan",
+ ["mos" ]="mossi",
+ ["mri" ]="maori",
+ ["mth" ]="maithili",
+ ["mts" ]="maltese",
+ ["mun" ]="mundari",
+ ["mus" ]="muscogee",
+ ["mwl" ]="mirandese",
+ ["mww" ]="hmong daw",
+ ["myn" ]="mayan",
+ ["mzn" ]="mazanderani",
+ ["nag" ]="naga-assamese",
+ ["nah" ]="nahuatl",
+ ["nan" ]="nanai",
+ ["nap" ]="neapolitan",
+ ["nas" ]="naskapi",
+ ["nau" ]="nauruan",
+ ["nav" ]="navajo",
+ ["ncr" ]="n-cree",
+ ["ndb" ]="ndebele",
+ ["ndc" ]="ndau",
+ ["ndg" ]="ndonga",
+ ["nds" ]="low saxon",
+ ["nep" ]="nepali",
+ ["new" ]="newari",
+ ["nga" ]="ngbaka",
+ ["ngr" ]="nagari",
+ ["nhc" ]="norway house cree",
+ ["nis" ]="nisi",
+ ["niu" ]="niuean",
+ ["nkl" ]="nyankole",
+ ["nko" ]="n'ko",
+ ["nld" ]="dutch",
+ ["noe" ]="nimadi",
+ ["nog" ]="nogai",
+ ["nor" ]="norwegian",
+ ["nov" ]="novial",
+ ["nsm" ]="northern sami",
+ ["nso" ]="sotho, northern",
+ ["nta" ]="northern tai",
+ ["nto" ]="esperanto",
+ ["nym" ]="nyamwezi",
+ ["nyn" ]="norwegian nynorsk",
+ ["oci" ]="occitan",
+ ["ocr" ]="oji-cree",
+ ["ojb" ]="ojibway",
+ ["ori" ]="odia",
+ ["oro" ]="oromo",
+ ["oss" ]="ossetian",
+ ["paa" ]="palestinian aramaic",
+ ["pag" ]="pangasinan",
+ ["pal" ]="pali",
+ ["pam" ]="pampangan",
+ ["pan" ]="punjabi",
+ ["pap" ]="palpa",
+ ["pap0"]="papiamentu",
+ ["pas" ]="pashto",
+ ["pau" ]="palauan",
+ ["pcc" ]="bouyei",
+ ["pcd" ]="picard",
+ ["pdc" ]="pennsylvania german",
+ ["pgr" ]="polytonic greek",
+ ["phk" ]="phake",
+ ["pih" ]="norfolk",
+ ["pil" ]="filipino",
+ ["plg" ]="palaung",
+ ["plk" ]="polish",
+ ["pms" ]="piemontese",
+ ["pnb" ]="western panjabi",
+ ["poh" ]="pocomchi",
+ ["pon" ]="pohnpeian",
+ ["pro" ]="provencal",
+ ["ptg" ]="portuguese",
+ ["pwo" ]="western pwo karen",
+ ["qin" ]="chin",
+ ["quc" ]="k’iche’",
+ ["quh" ]="quechua (bolivia)",
+ ["quz" ]="quechua",
+ ["qvi" ]="quechua (ecuador)",
+ ["qwh" ]="quechua (peru)",
+ ["raj" ]="rajasthani",
+ ["rar" ]="rarotongan",
+ ["rbu" ]="russian buriat",
+ ["rcr" ]="r-cree",
+ ["rej" ]="rejang",
+ ["ria" ]="riang",
+ ["rif" ]="tarifit",
+ ["rit" ]="ritarungo",
+ ["rkw" ]="arakwal",
+ ["rms" ]="romansh",
+ ["rmy" ]="vlax romani",
+ ["rom" ]="romanian",
+ ["roy" ]="romany",
+ ["rsy" ]="rusyn",
+ ["rtm" ]="rotuman",
+ ["rua" ]="kinyarwanda",
+ ["run" ]="rundi",
+ ["rup" ]="aromanian",
+ ["rus" ]="russian",
+ ["sad" ]="sadri",
+ ["san" ]="sanskrit",
+ ["sas" ]="sasak",
+ ["sat" ]="santali",
+ ["say" ]="sayisi",
+ ["scn" ]="sicilian",
+ ["sco" ]="scots",
+ ["sek" ]="sekota",
+ ["sel" ]="selkup",
+ ["sga" ]="old irish",
+ ["sgo" ]="sango",
+ ["sgs" ]="samogitian",
+ ["shi" ]="tachelhit",
+ ["shn" ]="shan",
+ ["sib" ]="sibe",
+ ["sid" ]="sidamo",
+ ["sig" ]="silte gurage",
+ ["sks" ]="skolt sami",
+ ["sky" ]="slovak",
+ ["sla" ]="slavey",
+ ["slv" ]="slovenian",
+ ["sml" ]="somali",
+ ["smo" ]="samoan",
+ ["sna" ]="sena",
+ ["sna0"]="shona",
+ ["snd" ]="sindhi",
+ ["snh" ]="sinhala (sinhalese)",
+ ["snk" ]="soninke",
+ ["sog" ]="sodo gurage",
+ ["sop" ]="songe",
+ ["sot" ]="sotho, southern",
+ ["sqi" ]="albanian",
+ ["srb" ]="serbian",
+ ["srd" ]="sardinian",
+ ["srk" ]="saraiki",
+ ["srr" ]="serer",
+ ["ssl" ]="south slavey",
+ ["ssm" ]="southern sami",
+ ["stq" ]="saterland frisian",
+ ["suk" ]="sukuma",
+ ["sun" ]="sundanese",
+ ["sur" ]="suri",
+ ["sva" ]="svan",
+ ["sve" ]="swedish",
+ ["swa" ]="swadaya aramaic",
+ ["swk" ]="swahili",
+ ["swz" ]="swati",
+ ["sxt" ]="sutu",
+ ["sxu" ]="upper saxon",
+ ["syl" ]="sylheti",
+ ["syr" ]="syriac",
+ ["szl" ]="silesian",
+ ["tab" ]="tabasaran",
+ ["taj" ]="tajiki",
+ ["tam" ]="tamil",
+ ["tat" ]="tatar",
+ ["tcr" ]="th-cree",
+ ["tdd" ]="dehong dai",
+ ["tel" ]="telugu",
+ ["tet" ]="tetum",
+ ["tgl" ]="tagalog",
+ ["tgn" ]="tongan",
+ ["tgr" ]="tigre",
+ ["tgy" ]="tigrinya",
+ ["tha" ]="thai",
+ ["tht" ]="tahitian",
+ ["tib" ]="tibetan",
+ ["tiv" ]="tiv",
+ ["tkm" ]="turkmen",
+ ["tmh" ]="tamashek",
+ ["tmn" ]="temne",
+ ["tna" ]="tswana",
+ ["tne" ]="tundra nenets",
+ ["tng" ]="tonga",
+ ["tod" ]="todo",
+ ["tod0"]="toma",
+ ["tpi" ]="tok pisin",
+ ["trk" ]="turkish",
+ ["tsg" ]="tsonga",
+ ["tsj" ]="tshangla",
+ ["tua" ]="turoyo aramaic",
+ ["tul" ]="tulu",
+ ["tuv" ]="tuvin",
+ ["tvl" ]="tuvalu",
+ ["twi" ]="twi",
+ ["tyz" ]="tày",
+ ["tzm" ]="tamazight",
+ ["tzo" ]="tzotzil",
+ ["udm" ]="udmurt",
+ ["ukr" ]="ukrainian",
+ ["umb" ]="umbundu",
+ ["urd" ]="urdu",
+ ["usb" ]="upper sorbian",
+ ["uyg" ]="uyghur",
+ ["uzb" ]="uzbek",
+ ["vec" ]="venetian",
+ ["ven" ]="venda",
+ ["vit" ]="vietnamese",
+ ["vol" ]="volapük",
+ ["vro" ]="võro",
+ ["wa" ]="wa",
+ ["wag" ]="wagdi",
+ ["war" ]="waray-waray",
+ ["wcr" ]="west-cree",
+ ["wel" ]="welsh",
+ ["wlf" ]="wolof",
+ ["wln" ]="walloon",
+ ["xbd" ]="lü",
+ ["xhs" ]="xhosa",
+ ["xjb" ]="minjangbal",
+ ["xkf" ]="khengkha",
+ ["xog" ]="soga",
+ ["xpe" ]="kpelle (liberia)",
+ ["yak" ]="sakha",
+ ["yao" ]="yao",
+ ["yap" ]="yapese",
+ ["yba" ]="yoruba",
+ ["ycr" ]="y-cree",
+ ["yic" ]="yi classic",
+ ["yim" ]="yi modern",
+ ["zea" ]="zealandic",
+ ["zgh" ]="standard morrocan tamazigh",
+ ["zha" ]="zhuang",
+ ["zhh" ]="chinese, hong kong sar",
+ ["zhp" ]="chinese phonetic",
+ ["zhs" ]="chinese simplified",
+ ["zht" ]="chinese traditional",
+ ["znd" ]="zande",
+ ["zul" ]="zulu",
+ ["zza" ]="zazaki",
}
local features=allocate {
- ["aalt"]="access all alternates",
- ["abvf"]="above-base forms",
- ["abvm"]="above-base mark positioning",
- ["abvs"]="above-base substitutions",
- ["afrc"]="alternative fractions",
- ["akhn"]="akhands",
- ["blwf"]="below-base forms",
- ["blwm"]="below-base mark positioning",
- ["blws"]="below-base substitutions",
- ["c2pc"]="petite capitals from capitals",
- ["c2sc"]="small capitals from capitals",
- ["calt"]="contextual alternates",
- ["case"]="case-sensitive forms",
- ["ccmp"]="glyph composition/decomposition",
- ["cfar"]="conjunct form after ro",
- ["cjct"]="conjunct forms",
- ["clig"]="contextual ligatures",
- ["cpct"]="centered cjk punctuation",
- ["cpsp"]="capital spacing",
- ["cswh"]="contextual swash",
- ["curs"]="cursive positioning",
- ["dflt"]="default processing",
- ["dist"]="distances",
- ["dlig"]="discretionary ligatures",
- ["dnom"]="denominators",
- ["dtls"]="dotless forms",
- ["expt"]="expert forms",
- ["falt"]="final glyph alternates",
- ["fin2"]="terminal forms #2",
- ["fin3"]="terminal forms #3",
- ["fina"]="terminal forms",
- ["flac"]="flattened accents over capitals",
- ["frac"]="fractions",
- ["fwid"]="full width",
- ["half"]="half forms",
- ["haln"]="halant forms",
- ["halt"]="alternate half width",
- ["hist"]="historical forms",
- ["hkna"]="horizontal kana alternates",
- ["hlig"]="historical ligatures",
- ["hngl"]="hangul",
- ["hojo"]="hojo kanji forms",
- ["hwid"]="half width",
- ["init"]="initial forms",
- ["isol"]="isolated forms",
- ["ital"]="italics",
- ["jalt"]="justification alternatives",
- ["jp04"]="jis2004 forms",
- ["jp78"]="jis78 forms",
- ["jp83"]="jis83 forms",
- ["jp90"]="jis90 forms",
- ["kern"]="kerning",
- ["lfbd"]="left bounds",
- ["liga"]="standard ligatures",
- ["ljmo"]="leading jamo forms",
- ["lnum"]="lining figures",
- ["locl"]="localized forms",
- ["ltra"]="left-to-right alternates",
- ["ltrm"]="left-to-right mirrored forms",
- ["mark"]="mark positioning",
- ["med2"]="medial forms #2",
- ["medi"]="medial forms",
- ["mgrk"]="mathematical greek",
- ["mkmk"]="mark to mark positioning",
- ["mset"]="mark positioning via substitution",
- ["nalt"]="alternate annotation forms",
- ["nlck"]="nlc kanji forms",
- ["nukt"]="nukta forms",
- ["numr"]="numerators",
- ["onum"]="old style figures",
- ["opbd"]="optical bounds",
- ["ordn"]="ordinals",
- ["ornm"]="ornaments",
- ["palt"]="proportional alternate width",
- ["pcap"]="petite capitals",
- ["pkna"]="proportional kana",
- ["pnum"]="proportional figures",
- ["pref"]="pre-base forms",
- ["pres"]="pre-base substitutions",
- ["pstf"]="post-base forms",
- ["psts"]="post-base substitutions",
- ["pwid"]="proportional widths",
- ["qwid"]="quarter widths",
- ["rand"]="randomize",
- ["rclt"]="required contextual alternates",
- ["rkrf"]="rakar forms",
- ["rlig"]="required ligatures",
- ["rphf"]="reph form",
- ["rtbd"]="right bounds",
- ["rtla"]="right-to-left alternates",
- ["rtlm"]="right to left mirrored forms",
- ["rvrn"]="required variation alternates",
- ["ruby"]="ruby notation forms",
- ["salt"]="stylistic alternates",
- ["sinf"]="scientific inferiors",
- ["size"]="optical size",
- ["smcp"]="small capitals",
- ["smpl"]="simplified forms",
- ["ssty"]="script style",
- ["stch"]="stretching glyph decomposition",
- ["subs"]="subscript",
- ["sups"]="superscript",
- ["swsh"]="swash",
- ["titl"]="titling",
- ["tjmo"]="trailing jamo forms",
- ["tnam"]="traditional name forms",
- ["tnum"]="tabular figures",
- ["trad"]="traditional forms",
- ["twid"]="third widths",
- ["unic"]="unicase",
- ["valt"]="alternate vertical metrics",
- ["vatu"]="vattu variants",
- ["vert"]="vertical writing",
- ["vhal"]="alternate vertical half metrics",
- ["vjmo"]="vowel jamo forms",
- ["vkna"]="vertical kana alternates",
- ["vkrn"]="vertical kerning",
- ["vpal"]="proportional alternate vertical metrics",
- ["vrt2"]="vertical rotation",
- ["zero"]="slashed zero",
- ["trep"]="traditional tex replacements",
- ["tlig"]="traditional tex ligatures",
- ["ss.."]="stylistic set ..",
- ["cv.."]="character variant ..",
- ["js.."]="justification ..",
- ["dv.."]="devanagari ..",
- ["ml.."]="malayalam ..",
+ ["aalt"]="access all alternates",
+ ["abvf"]="above-base forms",
+ ["abvm"]="above-base mark positioning",
+ ["abvs"]="above-base substitutions",
+ ["afrc"]="alternative fractions",
+ ["akhn"]="akhands",
+ ["blwf"]="below-base forms",
+ ["blwm"]="below-base mark positioning",
+ ["blws"]="below-base substitutions",
+ ["c2pc"]="petite capitals from capitals",
+ ["c2sc"]="small capitals from capitals",
+ ["calt"]="contextual alternates",
+ ["case"]="case-sensitive forms",
+ ["ccmp"]="glyph composition/decomposition",
+ ["cfar"]="conjunct form after ro",
+ ["cjct"]="conjunct forms",
+ ["clig"]="contextual ligatures",
+ ["cpct"]="centered cjk punctuation",
+ ["cpsp"]="capital spacing",
+ ["cswh"]="contextual swash",
+ ["curs"]="cursive positioning",
+ ["dflt"]="default processing",
+ ["dist"]="distances",
+ ["dlig"]="discretionary ligatures",
+ ["dnom"]="denominators",
+ ["dtls"]="dotless forms",
+ ["expt"]="expert forms",
+ ["falt"]="final glyph alternates",
+ ["fin2"]="terminal forms #2",
+ ["fin3"]="terminal forms #3",
+ ["fina"]="terminal forms",
+ ["flac"]="flattened accents over capitals",
+ ["frac"]="fractions",
+ ["fwid"]="full width",
+ ["half"]="half forms",
+ ["haln"]="halant forms",
+ ["halt"]="alternate half width",
+ ["hist"]="historical forms",
+ ["hkna"]="horizontal kana alternates",
+ ["hlig"]="historical ligatures",
+ ["hngl"]="hangul",
+ ["hojo"]="hojo kanji forms",
+ ["hwid"]="half width",
+ ["init"]="initial forms",
+ ["isol"]="isolated forms",
+ ["ital"]="italics",
+ ["jalt"]="justification alternatives",
+ ["jp04"]="jis2004 forms",
+ ["jp78"]="jis78 forms",
+ ["jp83"]="jis83 forms",
+ ["jp90"]="jis90 forms",
+ ["kern"]="kerning",
+ ["lfbd"]="left bounds",
+ ["liga"]="standard ligatures",
+ ["ljmo"]="leading jamo forms",
+ ["lnum"]="lining figures",
+ ["locl"]="localized forms",
+ ["ltra"]="left-to-right alternates",
+ ["ltrm"]="left-to-right mirrored forms",
+ ["mark"]="mark positioning",
+ ["med2"]="medial forms #2",
+ ["medi"]="medial forms",
+ ["mgrk"]="mathematical greek",
+ ["mkmk"]="mark to mark positioning",
+ ["mset"]="mark positioning via substitution",
+ ["nalt"]="alternate annotation forms",
+ ["nlck"]="nlc kanji forms",
+ ["nukt"]="nukta forms",
+ ["numr"]="numerators",
+ ["onum"]="old style figures",
+ ["opbd"]="optical bounds",
+ ["ordn"]="ordinals",
+ ["ornm"]="ornaments",
+ ["palt"]="proportional alternate width",
+ ["pcap"]="petite capitals",
+ ["pkna"]="proportional kana",
+ ["pnum"]="proportional figures",
+ ["pref"]="pre-base forms",
+ ["pres"]="pre-base substitutions",
+ ["pstf"]="post-base forms",
+ ["psts"]="post-base substitutions",
+ ["pwid"]="proportional widths",
+ ["qwid"]="quarter widths",
+ ["rand"]="randomize",
+ ["rclt"]="required contextual alternates",
+ ["rkrf"]="rakar forms",
+ ["rlig"]="required ligatures",
+ ["rphf"]="reph form",
+ ["rtbd"]="right bounds",
+ ["rtla"]="right-to-left alternates",
+ ["rtlm"]="right to left mirrored forms",
+ ["rvrn"]="required variation alternates",
+ ["ruby"]="ruby notation forms",
+ ["salt"]="stylistic alternates",
+ ["sinf"]="scientific inferiors",
+ ["size"]="optical size",
+ ["smcp"]="small capitals",
+ ["smpl"]="simplified forms",
+ ["ssty"]="script style",
+ ["stch"]="stretching glyph decomposition",
+ ["subs"]="subscript",
+ ["sups"]="superscript",
+ ["swsh"]="swash",
+ ["titl"]="titling",
+ ["tjmo"]="trailing jamo forms",
+ ["tnam"]="traditional name forms",
+ ["tnum"]="tabular figures",
+ ["trad"]="traditional forms",
+ ["twid"]="third widths",
+ ["unic"]="unicase",
+ ["valt"]="alternate vertical metrics",
+ ["vatu"]="vattu variants",
+ ["vert"]="vertical writing",
+ ["vhal"]="alternate vertical half metrics",
+ ["vjmo"]="vowel jamo forms",
+ ["vkna"]="vertical kana alternates",
+ ["vkrn"]="vertical kerning",
+ ["vpal"]="proportional alternate vertical metrics",
+ ["vrt2"]="vertical rotation",
+ ["zero"]="slashed zero",
+ ["trep"]="traditional tex replacements",
+ ["tlig"]="traditional tex ligatures",
+ ["ss.."]="stylistic set ..",
+ ["cv.."]="character variant ..",
+ ["js.."]="justification ..",
+ ["dv.."]="devanagari ..",
+ ["ml.."]="malayalam ..",
}
local baselines=allocate {
- ["hang"]="hanging baseline",
- ["icfb"]="ideographic character face bottom edge baseline",
- ["icft"]="ideographic character face tope edige baseline",
- ["ideo"]="ideographic em-box bottom edge baseline",
- ["idtp"]="ideographic em-box top edge baseline",
- ["math"]="mathematical centered baseline",
- ["romn"]="roman baseline"
+ ["hang"]="hanging baseline",
+ ["icfb"]="ideographic character face bottom edge baseline",
+ ["icft"]="ideographic character face tope edige baseline",
+ ["ideo"]="ideographic em-box bottom edge baseline",
+ ["idtp"]="ideographic em-box top edge baseline",
+ ["math"]="mathematical centered baseline",
+ ["romn"]="roman baseline"
}
tables.scripts=scripts
tables.languages=languages
tables.features=features
tables.baselines=baselines
-local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end)
-local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end)
+local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end)
+local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end)
local report_checks=logs.reporter("fonts","checks")
if otffeatures.features then
- for k,v in next,otffeatures.features do
- features[k]=v
- end
- otffeatures.features=features
+ for k,v in next,otffeatures.features do
+ features[k]=v
+ end
+ otffeatures.features=features
end
local function swapped(h)
- local r={}
- for k,v in next,h do
- r[gsub(v,"[^a-z0-9]","")]=k
- end
- return r
+ local r={}
+ for k,v in next,h do
+ r[gsub(v,"[^a-z0-9]","")]=k
+ end
+ return r
end
-local verbosescripts=allocate(swapped(scripts ))
+local verbosescripts=allocate(swapped(scripts ))
local verboselanguages=allocate(swapped(languages))
local verbosefeatures=allocate(swapped(features ))
local verbosebaselines=allocate(swapped(baselines))
local function resolve(t,k)
- if k then
- k=gsub(lower(k),"[^a-z0-9]","")
- local v=rawget(t,k)
- if v then
- return v
- end
+ if k then
+ k=gsub(lower(k),"[^a-z0-9]","")
+ local v=rawget(t,k)
+ if v then
+ return v
end
+ end
end
setmetatableindex(verbosescripts,resolve)
setmetatableindex(verboselanguages,resolve)
setmetatableindex(verbosefeatures,resolve)
setmetatableindex(verbosebaselines,resolve)
setmetatableindex(scripts,function(t,k)
- if k then
- k=lower(k)
- if k=="dflt" then
- return k
- end
- local v=rawget(t,k)
- if v then
- return v
- end
- k=gsub(k," ","")
- v=rawget(t,v)
- if v then
- return v
- elseif acceptscripts then
- report_checks("registering extra script %a",k)
- rawset(t,k,k)
- return k
- end
+ if k then
+ k=lower(k)
+ if k=="dflt" then
+ return k
+ end
+ local v=rawget(t,k)
+ if v then
+ return v
end
- return "dflt"
+ k=gsub(k," ","")
+ v=rawget(t,v)
+ if v then
+ return v
+ elseif acceptscripts then
+ report_checks("registering extra script %a",k)
+ rawset(t,k,k)
+ return k
+ end
+ end
+ return "dflt"
end)
setmetatableindex(languages,function(t,k)
- if k then
- k=lower(k)
- if k=="dflt" then
- return k
- end
- local v=rawget(t,k)
- if v then
- return v
- end
- k=gsub(k," ","")
- v=rawget(t,v)
- if v then
- return v
- elseif acceptlanguages then
- report_checks("registering extra language %a",k)
- rawset(t,k,k)
- return k
- end
+ if k then
+ k=lower(k)
+ if k=="dflt" then
+ return k
+ end
+ local v=rawget(t,k)
+ if v then
+ return v
end
- return "dflt"
+ k=gsub(k," ","")
+ v=rawget(t,v)
+ if v then
+ return v
+ elseif acceptlanguages then
+ report_checks("registering extra language %a",k)
+ rawset(t,k,k)
+ return k
+ end
+ end
+ return "dflt"
end)
if setmetatablenewindex then
- setmetatablenewindex(languages,"ignore")
- setmetatablenewindex(scripts,"ignore")
- setmetatablenewindex(baselines,"ignore")
+ setmetatablenewindex(languages,"ignore")
+ setmetatablenewindex(scripts,"ignore")
+ setmetatablenewindex(baselines,"ignore")
end
local function resolve(t,k)
- if k then
- k=lower(k)
- local v=rawget(t,k)
- if v then
- return v
- end
- k=gsub(k," ","")
- local v=rawget(t,k)
+ if k then
+ k=lower(k)
+ local v=rawget(t,k)
+ if v then
+ return v
+ end
+ k=gsub(k," ","")
+ local v=rawget(t,k)
+ if v then
+ return v
+ end
+ local tag,dd=match(k,"(..)(%d+)")
+ if tag and dd then
+ local v=rawget(t,tag)
+ if v then
+ return v
+ else
+ local v=rawget(t,tag.."..")
if v then
- return v
- end
- local tag,dd=match(k,"(..)(%d+)")
- if tag and dd then
- local v=rawget(t,tag)
- if v then
- return v
- else
- local v=rawget(t,tag.."..")
- if v then
- return (gsub(v,"%.%.",tonumber(dd)))
- end
- end
+ return (gsub(v,"%.%.",tonumber(dd)))
end
+ end
end
- return k
+ end
+ return k
end
setmetatableindex(features,resolve)
local function assign(t,k,v)
- if k and v then
- v=lower(v)
- rawset(t,k,v)
- end
+ if k and v then
+ v=lower(v)
+ rawset(t,k,v)
+ end
end
if setmetatablenewindex then
- setmetatablenewindex(features,assign)
+ setmetatablenewindex(features,assign)
end
local checkers={
- rand=function(v)
- return v==true and "random" or v
- end
+ rand=function(v)
+ return v==true and "random" or v
+ end
}
if not storage then
- return
+ return
end
local usedfeatures=statistics.usedfeatures or {}
statistics.usedfeatures=usedfeatures
@@ -13395,58 +13395,58 @@ table.setmetatableindex(usedfeatures,function(t,k) if k then local v={} t[k]=v r
storage.register("fonts/otf/usedfeatures",usedfeatures,"fonts.handlers.otf.statistics.usedfeatures" )
local normalizedaxis=otf.readers.helpers.normalizedaxis or function(s) return s end
function otffeatures.normalize(features,wrap)
- if features then
- local h={}
- for key,value in next,features do
- local k=lower(key)
- if k=="language" then
- local v=gsub(lower(value),"[^a-z0-9]","")
- h.language=rawget(verboselanguages,v) or (languages[v] and v) or "dflt"
- elseif k=="script" then
- local v=gsub(lower(value),"[^a-z0-9]","")
- h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt"
- elseif k=="axis" then
- h[k]=normalizedaxis(value)
- if not callbacks.supported.glyph_stream_provider then
- h.variableshapes=true
- end
+ if features then
+ local h={}
+ for key,value in next,features do
+ local k=lower(key)
+ if k=="language" then
+ local v=gsub(lower(value),"[^a-z0-9]","")
+ h.language=rawget(verboselanguages,v) or (languages[v] and v) or "dflt"
+ elseif k=="script" then
+ local v=gsub(lower(value),"[^a-z0-9]","")
+ h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt"
+ elseif k=="axis" then
+ h[k]=normalizedaxis(value)
+ if not callbacks.supported.glyph_stream_provider then
+ h.variableshapes=true
+ end
+ else
+ local uk=usedfeatures[key]
+ local uv=uk[value]
+ if uv then
+ else
+ uv=tonumber(value)
+ if uv then
+ elseif type(value)=="string" then
+ local b=is_boolean(value)
+ if type(b)=="nil" then
+ if wrap and find(value,",") then
+ uv="{"..lower(value).."}"
+ else
+ uv=lower(value)
+ end
else
- local uk=usedfeatures[key]
- local uv=uk[value]
- if uv then
- else
- uv=tonumber(value)
- if uv then
- elseif type(value)=="string" then
- local b=is_boolean(value)
- if type(b)=="nil" then
- if wrap and find(value,",") then
- uv="{"..lower(value).."}"
- else
- uv=lower(value)
- end
- else
- uv=b
- end
- elseif type(value)=="table" then
- uv=sequenced(t,",")
- else
- uv=value
- end
- if not rawget(features,k) then
- k=rawget(verbosefeatures,k) or k
- end
- local c=checkers[k]
- if c then
- uv=c(uv) or vc
- end
- uk[value]=uv
- end
- h[k]=uv
+ uv=b
end
+ elseif type(value)=="table" then
+ uv=sequenced(t,",")
+ else
+ uv=value
+ end
+ if not rawget(features,k) then
+ k=rawget(verbosefeatures,k) or k
+ end
+ local c=checkers[k]
+ if c then
+ uv=c(uv) or vc
+ end
+ uk[value]=uv
end
- return h
+ h[k]=uv
+ end
end
+ return h
+ end
end
end -- closure
@@ -13454,11 +13454,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-cff']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,tonumber,rawget=next,type,tonumber,rawget
local byte,char,gmatch=string.byte,string.char,string.gmatch
@@ -13473,23 +13473,23 @@ local rshift,band,extract=bit32.rshift,bit32.band,bit32.extract
local readers=fonts.handlers.otf.readers
local streamreader=readers.streamreader
local readstring=streamreader.readstring
-local readbyte=streamreader.readcardinal1
-local readushort=streamreader.readcardinal2
-local readuint=streamreader.readcardinal3
-local readulong=streamreader.readcardinal4
+local readbyte=streamreader.readcardinal1
+local readushort=streamreader.readcardinal2
+local readuint=streamreader.readcardinal3
+local readulong=streamreader.readcardinal4
local setposition=streamreader.setposition
local getposition=streamreader.getposition
local readbytetable=streamreader.readbytetable
directives.register("fonts.streamreader",function()
- streamreader=utilities.streams
- readstring=streamreader.readstring
- readbyte=streamreader.readcardinal1
- readushort=streamreader.readcardinal2
- readuint=streamreader.readcardinal3
- readulong=streamreader.readcardinal4
- setposition=streamreader.setposition
- getposition=streamreader.getposition
- readbytetable=streamreader.readbytetable
+ streamreader=utilities.streams
+ readstring=streamreader.readstring
+ readbyte=streamreader.readcardinal1
+ readushort=streamreader.readcardinal2
+ readuint=streamreader.readcardinal3
+ readulong=streamreader.readcardinal4
+ setposition=streamreader.setposition
+ getposition=streamreader.getposition
+ readbytetable=streamreader.readbytetable
end)
local setmetatableindex=table.setmetatableindex
local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end)
@@ -13502,1972 +13502,1972 @@ local parseprivates
local startparsing
local stopparsing
local defaultstrings={ [0]=
- ".notdef","space","exclam","quotedbl","numbersign","dollar","percent",
- "ampersand","quoteright","parenleft","parenright","asterisk","plus",
- "comma","hyphen","period","slash","zero","one","two","three","four",
- "five","six","seven","eight","nine","colon","semicolon","less",
- "equal","greater","question","at","A","B","C","D","E","F","G","H",
- "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W",
- "X","Y","Z","bracketleft","backslash","bracketright","asciicircum",
- "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j",
- "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y",
- "z","braceleft","bar","braceright","asciitilde","exclamdown","cent",
- "sterling","fraction","yen","florin","section","currency",
- "quotesingle","quotedblleft","guillemotleft","guilsinglleft",
- "guilsinglright","fi","fl","endash","dagger","daggerdbl",
- "periodcentered","paragraph","bullet","quotesinglbase","quotedblbase",
- "quotedblright","guillemotright","ellipsis","perthousand","questiondown",
- "grave","acute","circumflex","tilde","macron","breve","dotaccent",
- "dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash",
- "AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae",
- "dotlessi","lslash","oslash","oe","germandbls","onesuperior",
- "logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn",
- "onequarter","divide","brokenbar","degree","thorn","threequarters",
- "twosuperior","registered","minus","eth","multiply","threesuperior",
- "copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring",
- "Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave",
- "Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute",
- "Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute",
- "Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron",
- "aacute","acircumflex","adieresis","agrave","aring","atilde",
- "ccedilla","eacute","ecircumflex","edieresis","egrave","iacute",
- "icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex",
- "odieresis","ograve","otilde","scaron","uacute","ucircumflex",
- "udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall",
- "Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall",
- "Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader",
- "onedotenleader","zerooldstyle","oneoldstyle","twooldstyle",
- "threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle",
- "sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior",
- "threequartersemdash","periodsuperior","questionsmall","asuperior",
- "bsuperior","centsuperior","dsuperior","esuperior","isuperior",
- "lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior",
- "tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior",
- "Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall",
- "Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall",
- "Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall",
- "Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall",
- "Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah",
- "Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall",
- "Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall",
- "Dotaccentsmall","Macronsmall","figuredash","hypheninferior",
- "Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth",
- "threeeighths","fiveeighths","seveneighths","onethird","twothirds",
- "zerosuperior","foursuperior","fivesuperior","sixsuperior",
- "sevensuperior","eightsuperior","ninesuperior","zeroinferior",
- "oneinferior","twoinferior","threeinferior","fourinferior",
- "fiveinferior","sixinferior","seveninferior","eightinferior",
- "nineinferior","centinferior","dollarinferior","periodinferior",
- "commainferior","Agravesmall","Aacutesmall","Acircumflexsmall",
- "Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall",
- "Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall",
- "Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall",
- "Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall",
- "Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall",
- "Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall",
- "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003",
- "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold",
+ ".notdef","space","exclam","quotedbl","numbersign","dollar","percent",
+ "ampersand","quoteright","parenleft","parenright","asterisk","plus",
+ "comma","hyphen","period","slash","zero","one","two","three","four",
+ "five","six","seven","eight","nine","colon","semicolon","less",
+ "equal","greater","question","at","A","B","C","D","E","F","G","H",
+ "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W",
+ "X","Y","Z","bracketleft","backslash","bracketright","asciicircum",
+ "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j",
+ "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y",
+ "z","braceleft","bar","braceright","asciitilde","exclamdown","cent",
+ "sterling","fraction","yen","florin","section","currency",
+ "quotesingle","quotedblleft","guillemotleft","guilsinglleft",
+ "guilsinglright","fi","fl","endash","dagger","daggerdbl",
+ "periodcentered","paragraph","bullet","quotesinglbase","quotedblbase",
+ "quotedblright","guillemotright","ellipsis","perthousand","questiondown",
+ "grave","acute","circumflex","tilde","macron","breve","dotaccent",
+ "dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash",
+ "AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae",
+ "dotlessi","lslash","oslash","oe","germandbls","onesuperior",
+ "logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn",
+ "onequarter","divide","brokenbar","degree","thorn","threequarters",
+ "twosuperior","registered","minus","eth","multiply","threesuperior",
+ "copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring",
+ "Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave",
+ "Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute",
+ "Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute",
+ "Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron",
+ "aacute","acircumflex","adieresis","agrave","aring","atilde",
+ "ccedilla","eacute","ecircumflex","edieresis","egrave","iacute",
+ "icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex",
+ "odieresis","ograve","otilde","scaron","uacute","ucircumflex",
+ "udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall",
+ "Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall",
+ "Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader",
+ "onedotenleader","zerooldstyle","oneoldstyle","twooldstyle",
+ "threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle",
+ "sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior",
+ "threequartersemdash","periodsuperior","questionsmall","asuperior",
+ "bsuperior","centsuperior","dsuperior","esuperior","isuperior",
+ "lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior",
+ "tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior",
+ "Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall",
+ "Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall",
+ "Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall",
+ "Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall",
+ "Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah",
+ "Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall",
+ "Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall",
+ "Dotaccentsmall","Macronsmall","figuredash","hypheninferior",
+ "Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth",
+ "threeeighths","fiveeighths","seveneighths","onethird","twothirds",
+ "zerosuperior","foursuperior","fivesuperior","sixsuperior",
+ "sevensuperior","eightsuperior","ninesuperior","zeroinferior",
+ "oneinferior","twoinferior","threeinferior","fourinferior",
+ "fiveinferior","sixinferior","seveninferior","eightinferior",
+ "nineinferior","centinferior","dollarinferior","periodinferior",
+ "commainferior","Agravesmall","Aacutesmall","Acircumflexsmall",
+ "Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall",
+ "Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall",
+ "Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall",
+ "Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall",
+ "Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall",
+ "Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall",
+ "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003",
+ "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold",
}
local cffreaders={
- readbyte,
- readushort,
- readuint,
- readulong,
+ readbyte,
+ readushort,
+ readuint,
+ readulong,
}
local function readheader(f)
- local offset=getposition(f)
- local major=readbyte(f)
- local header={
- offset=offset,
- major=major,
- minor=readbyte(f),
- size=readbyte(f),
- }
- if major==1 then
- header.dsize=readbyte(f)
- elseif major==2 then
- header.dsize=readushort(f)
- else
- end
- setposition(f,offset+header.size)
- return header
+ local offset=getposition(f)
+ local major=readbyte(f)
+ local header={
+ offset=offset,
+ major=major,
+ minor=readbyte(f),
+ size=readbyte(f),
+ }
+ if major==1 then
+ header.dsize=readbyte(f)
+ elseif major==2 then
+ header.dsize=readushort(f)
+ else
+ end
+ setposition(f,offset+header.size)
+ return header
end
local function readlengths(f,longcount)
- local count=longcount and readulong(f) or readushort(f)
- if count==0 then
- return {}
- end
- local osize=readbyte(f)
- local read=cffreaders[osize]
- if not read then
- report("bad offset size: %i",osize)
- return {}
- end
- local lengths={}
- local previous=read(f)
- for i=1,count do
- local offset=read(f)
- local length=offset-previous
- if length<0 then
- report("bad offset: %i",length)
- length=0
- end
- lengths[i]=length
- previous=offset
- end
- return lengths
+ local count=longcount and readulong(f) or readushort(f)
+ if count==0 then
+ return {}
+ end
+ local osize=readbyte(f)
+ local read=cffreaders[osize]
+ if not read then
+ report("bad offset size: %i",osize)
+ return {}
+ end
+ local lengths={}
+ local previous=read(f)
+ for i=1,count do
+ local offset=read(f)
+ local length=offset-previous
+ if length<0 then
+ report("bad offset: %i",length)
+ length=0
+ end
+ lengths[i]=length
+ previous=offset
+ end
+ return lengths
end
local function readfontnames(f)
- local names=readlengths(f)
- for i=1,#names do
- names[i]=readstring(f,names[i])
- end
- return names
+ local names=readlengths(f)
+ for i=1,#names do
+ names[i]=readstring(f,names[i])
+ end
+ return names
end
local function readtopdictionaries(f)
- local dictionaries=readlengths(f)
- for i=1,#dictionaries do
- dictionaries[i]=readstring(f,dictionaries[i])
- end
- return dictionaries
+ local dictionaries=readlengths(f)
+ for i=1,#dictionaries do
+ dictionaries[i]=readstring(f,dictionaries[i])
+ end
+ return dictionaries
end
local function readstrings(f)
- local lengths=readlengths(f)
- local strings=setmetatableindex({},defaultstrings)
- local index=#defaultstrings
- for i=1,#lengths do
- index=index+1
- strings[index]=readstring(f,lengths[i])
- end
- return strings
+ local lengths=readlengths(f)
+ local strings=setmetatableindex({},defaultstrings)
+ local index=#defaultstrings
+ for i=1,#lengths do
+ index=index+1
+ strings[index]=readstring(f,lengths[i])
+ end
+ return strings
end
do
- local stack={}
- local top=0
- local result={}
- local strings={}
- local p_single=P("\00")/function()
- result.version=strings[stack[top]] or "unset"
- top=0
- end+P("\01")/function()
- result.notice=strings[stack[top]] or "unset"
- top=0
- end+P("\02")/function()
- result.fullname=strings[stack[top]] or "unset"
- top=0
- end+P("\03")/function()
- result.familyname=strings[stack[top]] or "unset"
- top=0
- end+P("\04")/function()
- result.weight=strings[stack[top]] or "unset"
- top=0
- end+P("\05")/function()
- result.fontbbox={ unpack(stack,1,4) }
- top=0
- end+P("\06")/function()
- result.bluevalues={ unpack(stack,1,top) }
- top=0
- end+P("\07")/function()
- result.otherblues={ unpack(stack,1,top) }
- top=0
- end+P("\08")/function()
- result.familyblues={ unpack(stack,1,top) }
- top=0
- end+P("\09")/function()
- result.familyotherblues={ unpack(stack,1,top) }
- top=0
- end+P("\10")/function()
- result.strhw=stack[top]
- top=0
- end+P("\11")/function()
- result.strvw=stack[top]
- top=0
- end+P("\13")/function()
- result.uniqueid=stack[top]
- top=0
- end+P("\14")/function()
- result.xuid=concat(stack,"",1,top)
- top=0
- end+P("\15")/function()
- result.charset=stack[top]
- top=0
- end+P("\16")/function()
- result.encoding=stack[top]
- top=0
- end+P("\17")/function()
- result.charstrings=stack[top]
- top=0
- end+P("\18")/function()
- result.private={
- size=stack[top-1],
- offset=stack[top],
- }
- top=0
- end+P("\19")/function()
- result.subroutines=stack[top]
- top=0
- end+P("\20")/function()
- result.defaultwidthx=stack[top]
- top=0
- end+P("\21")/function()
- result.nominalwidthx=stack[top]
- top=0
- end
+ local stack={}
+ local top=0
+ local result={}
+ local strings={}
+ local p_single=P("\00")/function()
+ result.version=strings[stack[top]] or "unset"
+ top=0
+ end+P("\01")/function()
+ result.notice=strings[stack[top]] or "unset"
+ top=0
+ end+P("\02")/function()
+ result.fullname=strings[stack[top]] or "unset"
+ top=0
+ end+P("\03")/function()
+ result.familyname=strings[stack[top]] or "unset"
+ top=0
+ end+P("\04")/function()
+ result.weight=strings[stack[top]] or "unset"
+ top=0
+ end+P("\05")/function()
+ result.fontbbox={ unpack(stack,1,4) }
+ top=0
+ end+P("\06")/function()
+ result.bluevalues={ unpack(stack,1,top) }
+ top=0
+ end+P("\07")/function()
+ result.otherblues={ unpack(stack,1,top) }
+ top=0
+ end+P("\08")/function()
+ result.familyblues={ unpack(stack,1,top) }
+ top=0
+ end+P("\09")/function()
+ result.familyotherblues={ unpack(stack,1,top) }
+ top=0
+ end+P("\10")/function()
+ result.strhw=stack[top]
+ top=0
+ end+P("\11")/function()
+ result.strvw=stack[top]
+ top=0
+ end+P("\13")/function()
+ result.uniqueid=stack[top]
+ top=0
+ end+P("\14")/function()
+ result.xuid=concat(stack,"",1,top)
+ top=0
+ end+P("\15")/function()
+ result.charset=stack[top]
+ top=0
+ end+P("\16")/function()
+ result.encoding=stack[top]
+ top=0
+ end+P("\17")/function()
+ result.charstrings=stack[top]
+ top=0
+ end+P("\18")/function()
+ result.private={
+ size=stack[top-1],
+ offset=stack[top],
+ }
+ top=0
+ end+P("\19")/function()
+ result.subroutines=stack[top]
+ top=0
+ end+P("\20")/function()
+ result.defaultwidthx=stack[top]
+ top=0
+ end+P("\21")/function()
+ result.nominalwidthx=stack[top]
+ top=0
+ end
+P("\24")/function()
- result.vstore=stack[top]
- top=0
- end+P("\25")/function()
- result.maxstack=stack[top]
- top=0
- end
- local p_double=P("\12")*(
- P("\00")/function()
- result.copyright=stack[top]
- top=0
- end+P("\01")/function()
- result.monospaced=stack[top]==1 and true or false
- top=0
- end+P("\02")/function()
- result.italicangle=stack[top]
- top=0
- end+P("\03")/function()
- result.underlineposition=stack[top]
- top=0
- end+P("\04")/function()
- result.underlinethickness=stack[top]
- top=0
- end+P("\05")/function()
- result.painttype=stack[top]
- top=0
- end+P("\06")/function()
- result.charstringtype=stack[top]
- top=0
- end+P("\07")/function()
- result.fontmatrix={ unpack(stack,1,6) }
- top=0
- end+P("\08")/function()
- result.strokewidth=stack[top]
- top=0
- end+P("\09")/function()
- result.bluescale=stack[top]
- top=0
- end+P("\10")/function()
- result.bluesnap=stack[top]
- top=0
- end+P("\11")/function()
- result.bluefuzz=stack[top]
- top=0
- end+P("\12")/function()
- result.stemsnaph={ unpack(stack,1,top) }
- top=0
- end+P("\13")/function()
- result.stemsnapv={ unpack(stack,1,top) }
- top=0
- end+P("\20")/function()
- result.syntheticbase=stack[top]
- top=0
- end+P("\21")/function()
- result.postscript=strings[stack[top]] or "unset"
- top=0
- end+P("\22")/function()
- result.basefontname=strings[stack[top]] or "unset"
- top=0
- end+P("\21")/function()
- result.basefontblend=stack[top]
- top=0
- end+P("\30")/function()
- result.cid.registry=strings[stack[top-2]] or "unset"
- result.cid.ordering=strings[stack[top-1]] or "unset"
- result.cid.supplement=stack[top]
- top=0
- end+P("\31")/function()
- result.cid.fontversion=stack[top]
- top=0
- end+P("\32")/function()
- result.cid.fontrevision=stack[top]
- top=0
- end+P("\33")/function()
- result.cid.fonttype=stack[top]
- top=0
- end+P("\34")/function()
- result.cid.count=stack[top]
- top=0
- end+P("\35")/function()
- result.cid.uidbase=stack[top]
- top=0
- end+P("\36")/function()
- result.cid.fdarray=stack[top]
- top=0
- end+P("\37")/function()
- result.cid.fdselect=stack[top]
- top=0
- end+P("\38")/function()
- result.cid.fontname=strings[stack[top]] or "unset"
- top=0
- end
- )
- local remap={
- ["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0",
- ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="1.",["\x1B"]="1E",["\x1C"]="1E-",["\x1D"]="1",["\x1E"]="1-",["\x1F"]="1",
- ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="2.",["\x2B"]="2E",["\x2C"]="2E-",["\x2D"]="2",["\x2E"]="2-",["\x2F"]="2",
- ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="3.",["\x3B"]="3E",["\x3C"]="3E-",["\x3D"]="3",["\x3E"]="3-",["\x3F"]="3",
- ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="4.",["\x4B"]="4E",["\x4C"]="4E-",["\x4D"]="4",["\x4E"]="4-",["\x4F"]="4",
- ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="5.",["\x5B"]="5E",["\x5C"]="5E-",["\x5D"]="5",["\x5E"]="5-",["\x5F"]="5",
- ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="6.",["\x6B"]="6E",["\x6C"]="6E-",["\x6D"]="6",["\x6E"]="6-",["\x6F"]="6",
- ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="7.",["\x7B"]="7E",["\x7C"]="7E-",["\x7D"]="7",["\x7E"]="7-",["\x7F"]="7",
- ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="8.",["\x8B"]="8E",["\x8C"]="8E-",["\x8D"]="8",["\x8E"]="8-",["\x8F"]="8",
- ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="9.",["\x9B"]="9E",["\x9C"]="9E-",["\x9D"]="9",["\x9E"]="9-",["\x9F"]="9",
- ["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".",
- ["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E",
- ["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-",
- ["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-",
- }
- local p_last=S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")+R("\xF0\xFF")
- local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0*(P(1)/remap))/function(n)
- top=top+1
- stack[top]=tonumber(n) or 0
+ result.vstore=stack[top]
+ top=0
+ end+P("\25")/function()
+ result.maxstack=stack[top]
+ top=0
+ end
+ local p_double=P("\12")*(
+ P("\00")/function()
+ result.copyright=stack[top]
+ top=0
+ end+P("\01")/function()
+ result.monospaced=stack[top]==1 and true or false
+ top=0
+ end+P("\02")/function()
+ result.italicangle=stack[top]
+ top=0
+ end+P("\03")/function()
+ result.underlineposition=stack[top]
+ top=0
+ end+P("\04")/function()
+ result.underlinethickness=stack[top]
+ top=0
+ end+P("\05")/function()
+ result.painttype=stack[top]
+ top=0
+ end+P("\06")/function()
+ result.charstringtype=stack[top]
+ top=0
+ end+P("\07")/function()
+ result.fontmatrix={ unpack(stack,1,6) }
+ top=0
+ end+P("\08")/function()
+ result.strokewidth=stack[top]
+ top=0
+ end+P("\09")/function()
+ result.bluescale=stack[top]
+ top=0
+ end+P("\10")/function()
+ result.bluesnap=stack[top]
+ top=0
+ end+P("\11")/function()
+ result.bluefuzz=stack[top]
+ top=0
+ end+P("\12")/function()
+ result.stemsnaph={ unpack(stack,1,top) }
+ top=0
+ end+P("\13")/function()
+ result.stemsnapv={ unpack(stack,1,top) }
+ top=0
+ end+P("\20")/function()
+ result.syntheticbase=stack[top]
+ top=0
+ end+P("\21")/function()
+ result.postscript=strings[stack[top]] or "unset"
+ top=0
+ end+P("\22")/function()
+ result.basefontname=strings[stack[top]] or "unset"
+ top=0
+ end+P("\21")/function()
+ result.basefontblend=stack[top]
+ top=0
+ end+P("\30")/function()
+ result.cid.registry=strings[stack[top-2]] or "unset"
+ result.cid.ordering=strings[stack[top-1]] or "unset"
+ result.cid.supplement=stack[top]
+ top=0
+ end+P("\31")/function()
+ result.cid.fontversion=stack[top]
+ top=0
+ end+P("\32")/function()
+ result.cid.fontrevision=stack[top]
+ top=0
+ end+P("\33")/function()
+ result.cid.fonttype=stack[top]
+ top=0
+ end+P("\34")/function()
+ result.cid.count=stack[top]
+ top=0
+ end+P("\35")/function()
+ result.cid.uidbase=stack[top]
+ top=0
+ end+P("\36")/function()
+ result.cid.fdarray=stack[top]
+ top=0
+ end+P("\37")/function()
+ result.cid.fdselect=stack[top]
+ top=0
+ end+P("\38")/function()
+ result.cid.fontname=strings[stack[top]] or "unset"
+ top=0
+ end
+ )
+ local remap={
+ ["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0",
+ ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="1.",["\x1B"]="1E",["\x1C"]="1E-",["\x1D"]="1",["\x1E"]="1-",["\x1F"]="1",
+ ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="2.",["\x2B"]="2E",["\x2C"]="2E-",["\x2D"]="2",["\x2E"]="2-",["\x2F"]="2",
+ ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="3.",["\x3B"]="3E",["\x3C"]="3E-",["\x3D"]="3",["\x3E"]="3-",["\x3F"]="3",
+ ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="4.",["\x4B"]="4E",["\x4C"]="4E-",["\x4D"]="4",["\x4E"]="4-",["\x4F"]="4",
+ ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="5.",["\x5B"]="5E",["\x5C"]="5E-",["\x5D"]="5",["\x5E"]="5-",["\x5F"]="5",
+ ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="6.",["\x6B"]="6E",["\x6C"]="6E-",["\x6D"]="6",["\x6E"]="6-",["\x6F"]="6",
+ ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="7.",["\x7B"]="7E",["\x7C"]="7E-",["\x7D"]="7",["\x7E"]="7-",["\x7F"]="7",
+ ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="8.",["\x8B"]="8E",["\x8C"]="8E-",["\x8D"]="8",["\x8E"]="8-",["\x8F"]="8",
+ ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="9.",["\x9B"]="9E",["\x9C"]="9E-",["\x9D"]="9",["\x9E"]="9-",["\x9F"]="9",
+ ["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".",
+ ["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E",
+ ["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-",
+ ["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-",
+ }
+ local p_last=S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")+R("\xF0\xFF")
+ local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0*(P(1)/remap))/function(n)
+ top=top+1
+ stack[top]=tonumber(n) or 0
+ end
+ local p_byte=C(R("\32\246"))/function(b0)
+ top=top+1
+ stack[top]=byte(b0)-139
+ end
+ local p_positive=C(R("\247\250"))*C(1)/function(b0,b1)
+ top=top+1
+ stack[top]=(byte(b0)-247)*256+byte(b1)+108
+ end
+ local p_negative=C(R("\251\254"))*C(1)/function(b0,b1)
+ top=top+1
+ stack[top]=-(byte(b0)-251)*256-byte(b1)-108
+ end
+ local p_short=P("\28")*C(1)*C(1)/function(b1,b2)
+ top=top+1
+ local n=0x100*byte(b1)+byte(b2)
+ if n>=0x8000 then
+ stack[top]=n-0xFFFF-1
+ else
+ stack[top]=n
+ end
+ end
+ local p_long=P("\29")*C(1)*C(1)*C(1)*C(1)/function(b1,b2,b3,b4)
+ top=top+1
+ local n=0x1000000*byte(b1)+0x10000*byte(b2)+0x100*byte(b3)+byte(b4)
+ if n>=0x8000000 then
+ stack[top]=n-0xFFFFFFFF-1
+ else
+ stack[top]=n
end
- local p_byte=C(R("\32\246"))/function(b0)
- top=top+1
- stack[top]=byte(b0)-139
+ end
+ local p_unsupported=P(1)/function(detail)
+ top=0
+ end
+ local p_dictionary=(
+ p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported
+ )^1
+ parsedictionaries=function(data,dictionaries,what)
+ stack={}
+ strings=data.strings
+ for i=1,#dictionaries do
+ top=0
+ result=what=="cff" and {
+ monospaced=false,
+ italicangle=0,
+ underlineposition=-100,
+ underlinethickness=50,
+ painttype=0,
+ charstringtype=2,
+ fontmatrix={ 0.001,0,0,0.001,0,0 },
+ fontbbox={ 0,0,0,0 },
+ strokewidth=0,
+ charset=0,
+ encoding=0,
+ cid={
+ fontversion=0,
+ fontrevision=0,
+ fonttype=0,
+ count=8720,
+ }
+ } or {
+ charstringtype=2,
+ charset=0,
+ vstore=0,
+ cid={
+ },
+ }
+ lpegmatch(p_dictionary,dictionaries[i])
+ dictionaries[i]=result
end
- local p_positive=C(R("\247\250"))*C(1)/function(b0,b1)
- top=top+1
- stack[top]=(byte(b0)-247)*256+byte(b1)+108
+ result={}
+ top=0
+ stack={}
+ end
+ parseprivates=function(data,dictionaries)
+ stack={}
+ strings=data.strings
+ for i=1,#dictionaries do
+ local private=dictionaries[i].private
+ if private and private.data then
+ top=0
+ result={
+ forcebold=false,
+ languagegroup=0,
+ expansionfactor=0.06,
+ initialrandomseed=0,
+ subroutines=0,
+ defaultwidthx=0,
+ nominalwidthx=0,
+ cid={
+ },
+ }
+ lpegmatch(p_dictionary,private.data)
+ private.data=result
+ end
end
- local p_negative=C(R("\251\254"))*C(1)/function(b0,b1)
- top=top+1
- stack[top]=-(byte(b0)-251)*256-byte(b1)-108
+ result={}
+ top=0
+ stack={}
+ end
+ local x=0
+ local y=0
+ local width=false
+ local r=0
+ local stems=0
+ local globalbias=0
+ local localbias=0
+ local nominalwidth=0
+ local defaultwidth=0
+ local charset=false
+ local globals=false
+ local locals=false
+ local depth=1
+ local xmin=0
+ local xmax=0
+ local ymin=0
+ local ymax=0
+ local checked=false
+ local keepcurve=false
+ local version=2
+ local regions=false
+ local nofregions=0
+ local region=false
+ local factors=false
+ local axis=false
+ local vsindex=0
+ local function showstate(where)
+ report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top)
+ end
+ local function showvalue(where,value,showstack)
+ if showstack then
+ report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top)
+ else
+ report("%w%-10s : %s",depth*2,where,tostring(value))
end
- local p_short=P("\28")*C(1)*C(1)/function(b1,b2)
- top=top+1
- local n=0x100*byte(b1)+byte(b2)
- if n>=0x8000 then
- stack[top]=n-0xFFFF-1
- else
- stack[top]=n
- end
+ end
+ local function xymoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
end
- local p_long=P("\29")*C(1)*C(1)*C(1)*C(1)/function(b1,b2,b3,b4)
- top=top+1
- local n=0x1000000*byte(b1)+0x10000*byte(b2)+0x100*byte(b3)+byte(b4)
- if n>=0x8000000 then
- stack[top]=n-0xFFFFFFFF-1
- else
- stack[top]=n
+ if checked then
+ if x>xmax then xmax=x elseif x<xmin then xmin=x end
+ if y>ymax then ymax=y elseif y<ymin then ymin=y end
+ else
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ end
+ end
+ local function xmoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif x>xmax then
+ xmax=x
+ elseif x<xmin then
+ xmin=x
+ end
+ end
+ local function ymoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif y>ymax then
+ ymax=y
+ elseif y<ymin then
+ ymin=y
+ end
+ end
+ local function moveto()
+ if trace_charstrings then
+ showstate("moveto")
+ end
+ top=0
+ xymoveto()
+ end
+ local function xylineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if checked then
+ if x>xmax then xmax=x elseif x<xmin then xmin=x end
+ if y>ymax then ymax=y elseif y<ymin then ymin=y end
+ else
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ end
+ end
+ local function xlineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif x>xmax then
+ xmax=x
+ elseif x<xmin then
+ xmin=x
+ end
+ end
+ local function ylineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif y>ymax then
+ ymax=y
+ elseif y<ymin then
+ ymin=y
+ end
+ end
+ local function xycurveto(x1,y1,x2,y2,x3,y3)
+ if trace_charstrings then
+ showstate("curveto")
+ end
+ if keepcurve then
+ r=r+1
+ result[r]={ x1,y1,x2,y2,x3,y3,"c" }
+ end
+ if checked then
+ if x1>xmax then xmax=x1 elseif x1<xmin then xmin=x1 end
+ if y1>ymax then ymax=y1 elseif y1<ymin then ymin=y1 end
+ else
+ xmin=x1
+ ymin=y1
+ xmax=x1
+ ymax=y1
+ checked=true
+ end
+ if x2>xmax then xmax=x2 elseif x2<xmin then xmin=x2 end
+ if y2>ymax then ymax=y2 elseif y2<ymin then ymin=y2 end
+ if x3>xmax then xmax=x3 elseif x3<xmin then xmin=x3 end
+ if y3>ymax then ymax=y3 elseif y3<ymin then ymin=y3 end
+ end
+ local function rmoveto()
+ if not width then
+ if top>2 then
+ width=stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
end
+ else
+ width=true
+ end
end
- local p_unsupported=P(1)/function(detail)
- top=0
+ if trace_charstrings then
+ showstate("rmoveto")
end
- local p_dictionary=(
- p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported
- )^1
- parsedictionaries=function(data,dictionaries,what)
- stack={}
- strings=data.strings
- for i=1,#dictionaries do
- top=0
- result=what=="cff" and {
- monospaced=false,
- italicangle=0,
- underlineposition=-100,
- underlinethickness=50,
- painttype=0,
- charstringtype=2,
- fontmatrix={ 0.001,0,0,0.001,0,0 },
- fontbbox={ 0,0,0,0 },
- strokewidth=0,
- charset=0,
- encoding=0,
- cid={
- fontversion=0,
- fontrevision=0,
- fonttype=0,
- count=8720,
- }
- } or {
- charstringtype=2,
- charset=0,
- vstore=0,
- cid={
- },
- }
- lpegmatch(p_dictionary,dictionaries[i])
- dictionaries[i]=result
- end
- result={}
- top=0
- stack={}
- end
- parseprivates=function(data,dictionaries)
- stack={}
- strings=data.strings
- for i=1,#dictionaries do
- local private=dictionaries[i].private
- if private and private.data then
- top=0
- result={
- forcebold=false,
- languagegroup=0,
- expansionfactor=0.06,
- initialrandomseed=0,
- subroutines=0,
- defaultwidthx=0,
- nominalwidthx=0,
- cid={
- },
- }
- lpegmatch(p_dictionary,private.data)
- private.data=result
- end
- end
- result={}
- top=0
- stack={}
- end
- local x=0
- local y=0
- local width=false
- local r=0
- local stems=0
- local globalbias=0
- local localbias=0
- local nominalwidth=0
- local defaultwidth=0
- local charset=false
- local globals=false
- local locals=false
- local depth=1
- local xmin=0
- local xmax=0
- local ymin=0
- local ymax=0
- local checked=false
- local keepcurve=false
- local version=2
- local regions=false
- local nofregions=0
- local region=false
- local factors=false
- local axis=false
- local vsindex=0
- local function showstate(where)
- report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top)
- end
- local function showvalue(where,value,showstack)
- if showstack then
- report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top)
- else
- report("%w%-10s : %s",depth*2,where,tostring(value))
+ x=x+stack[top-1]
+ y=y+stack[top]
+ top=0
+ xymoveto()
+ end
+ local function hmoveto()
+ if not width then
+ if top>1 then
+ width=stack[1]
+ if trace_charstrings then
+ showvalue("backtrack width",width)
end
+ else
+ width=true
+ end
end
- local function xymoveto()
- if keepcurve then
- r=r+1
- result[r]={ x,y,"m" }
- end
- if checked then
- if x>xmax then xmax=x elseif x<xmin then xmin=x end
- if y>ymax then ymax=y elseif y<ymin then ymin=y end
- else
- xmin=x
- ymin=y
- xmax=x
- ymax=y
- checked=true
- end
+ if trace_charstrings then
+ showstate("hmoveto")
end
- local function xmoveto()
- if keepcurve then
- r=r+1
- result[r]={ x,y,"m" }
- end
- if not checked then
- xmin=x
- ymin=y
- xmax=x
- ymax=y
- checked=true
- elseif x>xmax then
- xmax=x
- elseif x<xmin then
- xmin=x
- end
- end
- local function ymoveto()
- if keepcurve then
- r=r+1
- result[r]={ x,y,"m" }
- end
- if not checked then
- xmin=x
- ymin=y
- xmax=x
- ymax=y
- checked=true
- elseif y>ymax then
- ymax=y
- elseif y<ymin then
- ymin=y
- end
- end
- local function moveto()
+ x=x+stack[top]
+ top=0
+ xmoveto()
+ end
+ local function vmoveto()
+ if not width then
+ if top>1 then
+ width=stack[1]
if trace_charstrings then
- showstate("moveto")
+ showvalue("backtrack width",width)
end
- top=0
- xymoveto()
+ else
+ width=true
+ end
end
- local function xylineto()
- if keepcurve then
- r=r+1
- result[r]={ x,y,"l" }
- end
- if checked then
- if x>xmax then xmax=x elseif x<xmin then xmin=x end
- if y>ymax then ymax=y elseif y<ymin then ymin=y end
- else
- xmin=x
- ymin=y
- xmax=x
- ymax=y
- checked=true
- end
+ if trace_charstrings then
+ showstate("vmoveto")
end
- local function xlineto()
- if keepcurve then
- r=r+1
- result[r]={ x,y,"l" }
- end
- if not checked then
- xmin=x
- ymin=y
- xmax=x
- ymax=y
- checked=true
- elseif x>xmax then
- xmax=x
- elseif x<xmin then
- xmin=x
- end
- end
- local function ylineto()
- if keepcurve then
- r=r+1
- result[r]={ x,y,"l" }
- end
- if not checked then
- xmin=x
- ymin=y
- xmax=x
- ymax=y
- checked=true
- elseif y>ymax then
- ymax=y
- elseif y<ymin then
- ymin=y
- end
- end
- local function xycurveto(x1,y1,x2,y2,x3,y3)
- if trace_charstrings then
- showstate("curveto")
- end
- if keepcurve then
- r=r+1
- result[r]={ x1,y1,x2,y2,x3,y3,"c" }
- end
- if checked then
- if x1>xmax then xmax=x1 elseif x1<xmin then xmin=x1 end
- if y1>ymax then ymax=y1 elseif y1<ymin then ymin=y1 end
- else
- xmin=x1
- ymin=y1
- xmax=x1
- ymax=y1
- checked=true
- end
- if x2>xmax then xmax=x2 elseif x2<xmin then xmin=x2 end
- if y2>ymax then ymax=y2 elseif y2<ymin then ymin=y2 end
- if x3>xmax then xmax=x3 elseif x3<xmin then xmin=x3 end
- if y3>ymax then ymax=y3 elseif y3<ymin then ymin=y3 end
- end
- local function rmoveto()
- if not width then
- if top>2 then
- width=stack[1]
- if trace_charstrings then
- showvalue("backtrack width",width)
- end
- else
- width=true
- end
- end
- if trace_charstrings then
- showstate("rmoveto")
- end
- x=x+stack[top-1]
- y=y+stack[top]
- top=0
- xymoveto()
- end
- local function hmoveto()
- if not width then
- if top>1 then
- width=stack[1]
- if trace_charstrings then
- showvalue("backtrack width",width)
- end
- else
- width=true
- end
- end
- if trace_charstrings then
- showstate("hmoveto")
- end
- x=x+stack[top]
- top=0
- xmoveto()
- end
- local function vmoveto()
- if not width then
- if top>1 then
- width=stack[1]
- if trace_charstrings then
- showvalue("backtrack width",width)
- end
- else
- width=true
- end
- end
- if trace_charstrings then
- showstate("vmoveto")
- end
- y=y+stack[top]
- top=0
- ymoveto()
+ y=y+stack[top]
+ top=0
+ ymoveto()
+ end
+ local function rlineto()
+ if trace_charstrings then
+ showstate("rlineto")
end
- local function rlineto()
- if trace_charstrings then
- showstate("rlineto")
- end
- for i=1,top,2 do
- x=x+stack[i]
- y=y+stack[i+1]
- xylineto()
- end
- top=0
+ for i=1,top,2 do
+ x=x+stack[i]
+ y=y+stack[i+1]
+ xylineto()
end
- local function hlineto()
- if trace_charstrings then
- showstate("hlineto")
- end
- if top==1 then
- x=x+stack[1]
- xlineto()
+ top=0
+ end
+ local function hlineto()
+ if trace_charstrings then
+ showstate("hlineto")
+ end
+ if top==1 then
+ x=x+stack[1]
+ xlineto()
+ else
+ local swap=true
+ for i=1,top do
+ if swap then
+ x=x+stack[i]
+ xlineto()
+ swap=false
else
- local swap=true
- for i=1,top do
- if swap then
- x=x+stack[i]
- xlineto()
- swap=false
- else
- y=y+stack[i]
- ylineto()
- swap=true
- end
- end
+ y=y+stack[i]
+ ylineto()
+ swap=true
end
- top=0
+ end
end
- local function vlineto()
- if trace_charstrings then
- showstate("vlineto")
- end
- if top==1 then
- y=y+stack[1]
- ylineto()
+ top=0
+ end
+ local function vlineto()
+ if trace_charstrings then
+ showstate("vlineto")
+ end
+ if top==1 then
+ y=y+stack[1]
+ ylineto()
+ else
+ local swap=false
+ for i=1,top do
+ if swap then
+ x=x+stack[i]
+ xlineto()
+ swap=false
else
- local swap=false
- for i=1,top do
- if swap then
- x=x+stack[i]
- xlineto()
- swap=false
- else
- y=y+stack[i]
- ylineto()
- swap=true
- end
- end
+ y=y+stack[i]
+ ylineto()
+ swap=true
end
- top=0
+ end
end
- local function rrcurveto()
- if trace_charstrings then
- showstate("rrcurveto")
- end
- for i=1,top,6 do
- local ax=x+stack[i]
- local ay=y+stack[i+1]
- local bx=ax+stack[i+2]
- local by=ay+stack[i+3]
- x=bx+stack[i+4]
- y=by+stack[i+5]
- xycurveto(ax,ay,bx,by,x,y)
- end
- top=0
+ top=0
+ end
+ local function rrcurveto()
+ if trace_charstrings then
+ showstate("rrcurveto")
+ end
+ for i=1,top,6 do
+ local ax=x+stack[i]
+ local ay=y+stack[i+1]
+ local bx=ax+stack[i+2]
+ local by=ay+stack[i+3]
+ x=bx+stack[i+4]
+ y=by+stack[i+5]
+ xycurveto(ax,ay,bx,by,x,y)
end
- local function hhcurveto()
- if trace_charstrings then
- showstate("hhcurveto")
- end
- local s=1
- if top%2~=0 then
- y=y+stack[1]
- s=2
- end
- for i=s,top,4 do
- local ax=x+stack[i]
- local ay=y
- local bx=ax+stack[i+1]
- local by=ay+stack[i+2]
- x=bx+stack[i+3]
- y=by
- xycurveto(ax,ay,bx,by,x,y)
- end
- top=0
+ top=0
+ end
+ local function hhcurveto()
+ if trace_charstrings then
+ showstate("hhcurveto")
+ end
+ local s=1
+ if top%2~=0 then
+ y=y+stack[1]
+ s=2
+ end
+ for i=s,top,4 do
+ local ax=x+stack[i]
+ local ay=y
+ local bx=ax+stack[i+1]
+ local by=ay+stack[i+2]
+ x=bx+stack[i+3]
+ y=by
+ xycurveto(ax,ay,bx,by,x,y)
end
- local function vvcurveto()
- if trace_charstrings then
- showstate("vvcurveto")
- end
- local s=1
- local d=0
- if top%2~=0 then
- d=stack[1]
- s=2
- end
- for i=s,top,4 do
- local ax=x+d
- local ay=y+stack[i]
- local bx=ax+stack[i+1]
- local by=ay+stack[i+2]
- x=bx
- y=by+stack[i+3]
- xycurveto(ax,ay,bx,by,x,y)
- d=0
- end
- top=0
+ top=0
+ end
+ local function vvcurveto()
+ if trace_charstrings then
+ showstate("vvcurveto")
+ end
+ local s=1
+ local d=0
+ if top%2~=0 then
+ d=stack[1]
+ s=2
+ end
+ for i=s,top,4 do
+ local ax=x+d
+ local ay=y+stack[i]
+ local bx=ax+stack[i+1]
+ local by=ay+stack[i+2]
+ x=bx
+ y=by+stack[i+3]
+ xycurveto(ax,ay,bx,by,x,y)
+ d=0
end
- local function xxcurveto(swap)
- local last=top%4~=0 and stack[top]
- if last then
- top=top-1
- end
- for i=1,top,4 do
- local ax,ay,bx,by
- if swap then
- ax=x+stack[i]
- ay=y
- bx=ax+stack[i+1]
- by=ay+stack[i+2]
- y=by+stack[i+3]
- if last and i+3==top then
- x=bx+last
- else
- x=bx
- end
- swap=false
- else
- ax=x
- ay=y+stack[i]
- bx=ax+stack[i+1]
- by=ay+stack[i+2]
- x=bx+stack[i+3]
- if last and i+3==top then
- y=by+last
- else
- y=by
- end
- swap=true
- end
- xycurveto(ax,ay,bx,by,x,y)
+ top=0
+ end
+ local function xxcurveto(swap)
+ local last=top%4~=0 and stack[top]
+ if last then
+ top=top-1
+ end
+ for i=1,top,4 do
+ local ax,ay,bx,by
+ if swap then
+ ax=x+stack[i]
+ ay=y
+ bx=ax+stack[i+1]
+ by=ay+stack[i+2]
+ y=by+stack[i+3]
+ if last and i+3==top then
+ x=bx+last
+ else
+ x=bx
+ end
+ swap=false
+ else
+ ax=x
+ ay=y+stack[i]
+ bx=ax+stack[i+1]
+ by=ay+stack[i+2]
+ x=bx+stack[i+3]
+ if last and i+3==top then
+ y=by+last
+ else
+ y=by
end
- top=0
+ swap=true
+ end
+ xycurveto(ax,ay,bx,by,x,y)
end
- local function hvcurveto()
+ top=0
+ end
+ local function hvcurveto()
+ if trace_charstrings then
+ showstate("hvcurveto")
+ end
+ xxcurveto(true)
+ end
+ local function vhcurveto()
+ if trace_charstrings then
+ showstate("vhcurveto")
+ end
+ xxcurveto(false)
+ end
+ local function rcurveline()
+ if trace_charstrings then
+ showstate("rcurveline")
+ end
+ for i=1,top-2,6 do
+ local ax=x+stack[i]
+ local ay=y+stack[i+1]
+ local bx=ax+stack[i+2]
+ local by=ay+stack[i+3]
+ x=bx+stack[i+4]
+ y=by+stack[i+5]
+ xycurveto(ax,ay,bx,by,x,y)
+ end
+ x=x+stack[top-1]
+ y=y+stack[top]
+ xylineto()
+ top=0
+ end
+ local function rlinecurve()
+ if trace_charstrings then
+ showstate("rlinecurve")
+ end
+ if top>6 then
+ for i=1,top-6,2 do
+ x=x+stack[i]
+ y=y+stack[i+1]
+ xylineto()
+ end
+ end
+ local ax=x+stack[top-5]
+ local ay=y+stack[top-4]
+ local bx=ax+stack[top-3]
+ local by=ay+stack[top-2]
+ x=bx+stack[top-1]
+ y=by+stack[top]
+ xycurveto(ax,ay,bx,by,x,y)
+ top=0
+ end
+ local function flex()
+ if trace_charstrings then
+ showstate("flex")
+ end
+ local ax=x+stack[1]
+ local ay=y+stack[2]
+ local bx=ax+stack[3]
+ local by=ay+stack[4]
+ local cx=bx+stack[5]
+ local cy=by+stack[6]
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx=cx+stack[7]
+ local dy=cy+stack[8]
+ local ex=dx+stack[9]
+ local ey=dy+stack[10]
+ x=ex+stack[11]
+ y=ey+stack[12]
+ xycurveto(dx,dy,ex,ey,x,y)
+ top=0
+ end
+ local function hflex()
+ if trace_charstrings then
+ showstate("hflex")
+ end
+ local ax=x+stack[1]
+ local ay=y
+ local bx=ax+stack[2]
+ local by=ay+stack[3]
+ local cx=bx+stack[4]
+ local cy=by
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx=cx+stack[5]
+ local dy=by
+ local ex=dx+stack[6]
+ local ey=y
+ x=ex+stack[7]
+ xycurveto(dx,dy,ex,ey,x,y)
+ top=0
+ end
+ local function hflex1()
+ if trace_charstrings then
+ showstate("hflex1")
+ end
+ local ax=x+stack[1]
+ local ay=y+stack[2]
+ local bx=ax+stack[3]
+ local by=ay+stack[4]
+ local cx=bx+stack[5]
+ local cy=by
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx=cx+stack[6]
+ local dy=by
+ local ex=dx+stack[7]
+ local ey=dy+stack[8]
+ x=ex+stack[9]
+ xycurveto(dx,dy,ex,ey,x,y)
+ top=0
+ end
+ local function flex1()
+ if trace_charstrings then
+ showstate("flex1")
+ end
+ local ax=x+stack[1]
+ local ay=y+stack[2]
+ local bx=ax+stack[3]
+ local by=ay+stack[4]
+ local cx=bx+stack[5]
+ local cy=by+stack[6]
+ xycurveto(ax,ay,bx,by,cx,cy)
+ local dx=cx+stack[7]
+ local dy=cy+stack[8]
+ local ex=dx+stack[9]
+ local ey=dy+stack[10]
+ if abs(ex-x)>abs(ey-y) then
+ x=ex+stack[11]
+ else
+ y=ey+stack[11]
+ end
+ xycurveto(dx,dy,ex,ey,x,y)
+ top=0
+ end
+ local function getstem()
+ if top==0 then
+ elseif top%2~=0 then
+ if width then
+ remove(stack,1)
+ else
+ width=remove(stack,1)
if trace_charstrings then
- showstate("hvcurveto")
+ showvalue("width",width)
end
- xxcurveto(true)
+ end
+ top=top-1
+ end
+ if trace_charstrings then
+ showstate("stem")
end
- local function vhcurveto()
+ stems=stems+idiv(top,2)
+ top=0
+ end
+ local function getmask()
+ if top==0 then
+ elseif top%2~=0 then
+ if width then
+ remove(stack,1)
+ else
+ width=remove(stack,1)
if trace_charstrings then
- showstate("vhcurveto")
+ showvalue("width",width)
end
- xxcurveto(false)
+ end
+ top=top-1
end
- local function rcurveline()
- if trace_charstrings then
- showstate("rcurveline")
- end
- for i=1,top-2,6 do
- local ax=x+stack[i]
- local ay=y+stack[i+1]
- local bx=ax+stack[i+2]
- local by=ay+stack[i+3]
- x=bx+stack[i+4]
- y=by+stack[i+5]
- xycurveto(ax,ay,bx,by,x,y)
- end
- x=x+stack[top-1]
- y=y+stack[top]
- xylineto()
- top=0
+ if trace_charstrings then
+ showstate(operator==19 and "hintmark" or "cntrmask")
end
- local function rlinecurve()
- if trace_charstrings then
- showstate("rlinecurve")
- end
- if top>6 then
- for i=1,top-6,2 do
- x=x+stack[i]
- y=y+stack[i+1]
- xylineto()
- end
- end
- local ax=x+stack[top-5]
- local ay=y+stack[top-4]
- local bx=ax+stack[top-3]
- local by=ay+stack[top-2]
- x=bx+stack[top-1]
- y=by+stack[top]
- xycurveto(ax,ay,bx,by,x,y)
- top=0
+ stems=stems+idiv(top,2)
+ top=0
+ if stems==0 then
+ elseif stems<=8 then
+ return 1
+ else
+ return idiv(stems+7,8)
end
- local function flex()
- if trace_charstrings then
- showstate("flex")
- end
- local ax=x+stack[1]
- local ay=y+stack[2]
- local bx=ax+stack[3]
- local by=ay+stack[4]
- local cx=bx+stack[5]
- local cy=by+stack[6]
- xycurveto(ax,ay,bx,by,cx,cy)
- local dx=cx+stack[7]
- local dy=cy+stack[8]
- local ex=dx+stack[9]
- local ey=dy+stack[10]
- x=ex+stack[11]
- y=ey+stack[12]
- xycurveto(dx,dy,ex,ey,x,y)
- top=0
+ end
+ local function unsupported(t)
+ if trace_charstrings then
+ showstate("unsupported "..t)
end
- local function hflex()
- if trace_charstrings then
- showstate("hflex")
- end
- local ax=x+stack[1]
- local ay=y
- local bx=ax+stack[2]
- local by=ay+stack[3]
- local cx=bx+stack[4]
- local cy=by
- xycurveto(ax,ay,bx,by,cx,cy)
- local dx=cx+stack[5]
- local dy=by
- local ex=dx+stack[6]
- local ey=y
- x=ex+stack[7]
- xycurveto(dx,dy,ex,ey,x,y)
- top=0
+ top=0
+ end
+ local function unsupportedsub(t)
+ if trace_charstrings then
+ showstate("unsupported sub "..t)
end
- local function hflex1()
- if trace_charstrings then
- showstate("hflex1")
- end
- local ax=x+stack[1]
- local ay=y+stack[2]
- local bx=ax+stack[3]
- local by=ay+stack[4]
- local cx=bx+stack[5]
- local cy=by
- xycurveto(ax,ay,bx,by,cx,cy)
- local dx=cx+stack[6]
- local dy=by
- local ex=dx+stack[7]
- local ey=dy+stack[8]
- x=ex+stack[9]
- xycurveto(dx,dy,ex,ey,x,y)
- top=0
+ top=0
+ end
+ local function getstem3()
+ if trace_charstrings then
+ showstate("stem3")
end
- local function flex1()
- if trace_charstrings then
- showstate("flex1")
- end
- local ax=x+stack[1]
- local ay=y+stack[2]
- local bx=ax+stack[3]
- local by=ay+stack[4]
- local cx=bx+stack[5]
- local cy=by+stack[6]
- xycurveto(ax,ay,bx,by,cx,cy)
- local dx=cx+stack[7]
- local dy=cy+stack[8]
- local ex=dx+stack[9]
- local ey=dy+stack[10]
- if abs(ex-x)>abs(ey-y) then
- x=ex+stack[11]
- else
- y=ey+stack[11]
- end
- xycurveto(dx,dy,ex,ey,x,y)
- top=0
+ top=0
+ end
+ local function divide()
+ if version==1 then
+ local d=stack[top]
+ top=top-1
+ stack[top]=stack[top]/d
+ end
+ end
+ local function closepath()
+ if version==1 then
+ if trace_charstrings then
+ showstate("closepath")
+ end
end
- local function getstem()
- if top==0 then
- elseif top%2~=0 then
- if width then
- remove(stack,1)
- else
- width=remove(stack,1)
- if trace_charstrings then
- showvalue("width",width)
- end
- end
- top=top-1
- end
- if trace_charstrings then
- showstate("stem")
- end
- stems=stems+idiv(top,2)
- top=0
+ top=0
+ end
+ local function hsbw()
+ if version==1 then
+ if trace_charstrings then
+ showstate("hsbw")
+ end
+ width=stack[top]
end
- local function getmask()
- if top==0 then
- elseif top%2~=0 then
- if width then
- remove(stack,1)
- else
- width=remove(stack,1)
- if trace_charstrings then
- showvalue("width",width)
- end
- end
- top=top-1
- end
- if trace_charstrings then
- showstate(operator==19 and "hintmark" or "cntrmask")
- end
- stems=stems+idiv(top,2)
- top=0
- if stems==0 then
- elseif stems<=8 then
- return 1
- else
- return idiv(stems+7,8)
- end
+ top=0
+ end
+ local function seac()
+ if version==1 then
+ if trace_charstrings then
+ showstate("seac")
+ end
end
- local function unsupported(t)
- if trace_charstrings then
- showstate("unsupported "..t)
- end
- top=0
+ top=0
+ end
+ local function sbw()
+ if version==1 then
+ if trace_charstrings then
+ showstate("sbw")
+ end
+ width=stack[top-1]
end
- local function unsupportedsub(t)
- if trace_charstrings then
- showstate("unsupported sub "..t)
- end
- top=0
+ top=0
+ end
+ local function callothersubr()
+ if version==1 then
+ if trace_charstrings then
+ showstate("callothersubr (unsupported)")
+ end
end
- local function getstem3()
- if trace_charstrings then
- showstate("stem3")
- end
- top=0
+ top=0
+ end
+ local function pop()
+ if version==1 then
+ if trace_charstrings then
+ showstate("pop (unsupported)")
+ end
+ top=top+1
+ stack[top]=0
+ else
+ top=0
end
- local function divide()
- if version==1 then
- local d=stack[top]
- top=top-1
- stack[top]=stack[top]/d
- end
+ end
+ local function setcurrentpoint()
+ if version==1 then
+ if trace_charstrings then
+ showstate("pop (unsupported)")
+ end
+ x=x+stack[top-1]
+ y=y+stack[top]
end
- local function closepath()
- if version==1 then
- if trace_charstrings then
- showstate("closepath")
+ top=0
+ end
+ local reginit=false
+ local function updateregions(n)
+ if regions then
+ local current=regions[n] or regions[1]
+ nofregions=#current
+ if axis and n~=reginit then
+ factors={}
+ for i=1,nofregions do
+ local region=current[i]
+ local s=1
+ for j=1,#axis do
+ local f=axis[j]
+ local r=region[j]
+ local start=r.start
+ local peak=r.peak
+ local stop=r.stop
+ if start>peak or peak>stop then
+ elseif start<0 and stop>0 and peak~=0 then
+ elseif peak==0 then
+ elseif f<start or f>stop then
+ s=0
+ break
+ elseif f<peak then
+ s=s*(f-start)/(peak-start)
+ elseif f>peak then
+ s=s*(stop-f)/(stop-peak)
+ else
end
+ end
+ factors[i]=s
+ end
+ end
+ end
+ reginit=n
+ end
+ local function setvsindex()
+ local vsindex=stack[top]
+ if trace_charstrings then
+ showstate(formatters["vsindex %i"](vsindex))
+ end
+ updateregions(vsindex)
+ top=top-1
+ end
+ local function blend()
+ local n=stack[top]
+ top=top-1
+ if axis then
+ if trace_charstrings then
+ local t=top-nofregions*n
+ local m=t-n
+ for i=1,n do
+ local k=m+i
+ local d=m+n+(i-1)*nofregions
+ local old=stack[k]
+ local new=old
+ for r=1,nofregions do
+ new=new+stack[d+r]*factors[r]
+ end
+ stack[k]=new
+ showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new))
+ end
+ top=t
+ elseif n==1 then
+ top=top-nofregions
+ local v=stack[top]
+ for r=1,nofregions do
+ v=v+stack[top+r]*factors[r]
+ end
+ stack[top]=v
+ else
+ top=top-nofregions*n
+ local d=top
+ local k=top-n
+ for i=1,n do
+ k=k+1
+ local v=stack[k]
+ for r=1,nofregions do
+ v=v+stack[d+r]*factors[r]
+ end
+ stack[k]=v
+ d=d+nofregions
end
- top=0
+ end
+ else
end
- local function hsbw()
- if version==1 then
- if trace_charstrings then
- showstate("hsbw")
- end
- width=stack[top]
- end
- top=0
+ end
+ local actions={ [0]=unsupported,
+ getstem,
+ unsupported,
+ getstem,
+ vmoveto,
+ rlineto,
+ hlineto,
+ vlineto,
+ rrcurveto,
+ unsupported,
+ unsupported,
+ unsupported,
+ unsupported,
+ hsbw,
+ unsupported,
+ setvsindex,
+ blend,
+ unsupported,
+ getstem,
+ getmask,
+ getmask,
+ rmoveto,
+ hmoveto,
+ getstem,
+ rcurveline,
+ rlinecurve,
+ vvcurveto,
+ hhcurveto,
+ unsupported,
+ unsupported,
+ vhcurveto,
+ hvcurveto,
+ }
+ local subactions={
+ [000]=dotsection,
+ [001]=getstem3,
+ [002]=getstem3,
+ [006]=seac,
+ [007]=sbw,
+ [012]=divide,
+ [016]=callothersubr,
+ [017]=pop,
+ [033]=setcurrentpoint,
+ [034]=hflex,
+ [035]=flex,
+ [036]=hflex1,
+ [037]=flex1,
+ }
+ local chars=setmetatableindex(function (t,k)
+ local v=char(k)
+ t[k]=v
+ return v
+ end)
+ local c_endchar=chars[14]
+ local encode={}
+ setmetatableindex(encode,function(t,i)
+ for i=-2048,-1130 do
+ t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+ end
+ for i=-1131,-108 do
+ local v=0xFB00-i-108
+ t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF))
+ end
+ for i=-107,107 do
+ t[i]=chars[i+139]
+ end
+ for i=108,1131 do
+ local v=0xF700+i-108
+ t[i]=char(extract(v,8,8),extract(v,0,8))
+ end
+ for i=1132,2048 do
+ t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+ end
+ setmetatableindex(encode,function(t,k)
+ local r=round(k)
+ local v=rawget(t,r)
+ if v then
+ return v
+ end
+ local v1=floor(k)
+ local v2=floor((k-v1)*0x10000)
+ return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8))
+ end)
+ return t[i]
+ end)
+ readers.cffencoder=encode
+ local function p_setvsindex()
+ local vsindex=stack[top]
+ updateregions(vsindex)
+ top=top-1
+ end
+ local function p_blend()
+ local n=stack[top]
+ top=top-1
+ if not axis then
+ elseif n==1 then
+ top=top-nofregions
+ local v=stack[top]
+ for r=1,nofregions do
+ v=v+stack[top+r]*factors[r]
+ end
+ stack[top]=round(v)
+ else
+ top=top-nofregions*n
+ local d=top
+ local k=top-n
+ for i=1,n do
+ k=k+1
+ local v=stack[k]
+ for r=1,nofregions do
+ v=v+stack[d+r]*factors[r]
+ end
+ stack[k]=round(v)
+ d=d+nofregions
+ end
+ end
+ end
+ local function p_getstem()
+ local n=0
+ if top%2~=0 then
+ n=1
end
- local function seac()
- if version==1 then
- if trace_charstrings then
- showstate("seac")
- end
- end
- top=0
+ if top>n then
+ stems=stems+idiv(top-n,2)
end
- local function sbw()
- if version==1 then
- if trace_charstrings then
- showstate("sbw")
- end
- width=stack[top-1]
- end
- top=0
+ end
+ local function p_getmask()
+ local n=0
+ if top%2~=0 then
+ n=1
end
- local function callothersubr()
- if version==1 then
- if trace_charstrings then
- showstate("callothersubr (unsupported)")
- end
- end
+ if top>n then
+ stems=stems+idiv(top-n,2)
+ end
+ if stems==0 then
+ return 0
+ elseif stems<=8 then
+ return 1
+ else
+ return idiv(stems+7,8)
+ end
+ end
+ local process
+ local function call(scope,list,bias)
+ depth=depth+1
+ if top==0 then
+ showstate(formatters["unknown %s call"](scope))
+ top=0
+ else
+ local index=stack[top]+bias
+ top=top-1
+ if trace_charstrings then
+ showvalue(scope,index,true)
+ end
+ local tab=list[index]
+ if tab then
+ process(tab)
+ else
+ showstate(formatters["unknown %s call %i"](scope,index))
top=0
+ end
end
- local function pop()
- if version==1 then
- if trace_charstrings then
- showstate("pop (unsupported)")
- end
- top=top+1
- stack[top]=0
+ depth=depth-1
+ end
+ local justpass=false
+ process=function(tab)
+ local i=1
+ local n=#tab
+ while i<=n do
+ local t=tab[i]
+ if t>=32 then
+ top=top+1
+ if t<=246 then
+ stack[top]=t-139
+ i=i+1
+ elseif t<=250 then
+ stack[top]=t*256-63124+tab[i+1]
+ i=i+2
+ elseif t<=254 then
+ stack[top]=-t*256+64148-tab[i+1]
+ i=i+2
else
- top=0
- end
- end
- local function setcurrentpoint()
- if version==1 then
- if trace_charstrings then
- showstate("pop (unsupported)")
- end
- x=x+stack[top-1]
- y=y+stack[top]
+ local n=0x100*tab[i+1]+tab[i+2]
+ if n>=0x8000 then
+ stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF
+ else
+ stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF
+ end
+ i=i+5
end
- top=0
- end
- local reginit=false
- local function updateregions(n)
- if regions then
- local current=regions[n] or regions[1]
- nofregions=#current
- if axis and n~=reginit then
- factors={}
- for i=1,nofregions do
- local region=current[i]
- local s=1
- for j=1,#axis do
- local f=axis[j]
- local r=region[j]
- local start=r.start
- local peak=r.peak
- local stop=r.stop
- if start>peak or peak>stop then
- elseif start<0 and stop>0 and peak~=0 then
- elseif peak==0 then
- elseif f<start or f>stop then
- s=0
- break
- elseif f<peak then
- s=s*(f-start)/(peak-start)
- elseif f>peak then
- s=s*(stop-f)/(stop-peak)
- else
- end
- end
- factors[i]=s
- end
- end
+ elseif t==28 then
+ top=top+1
+ local n=0x100*tab[i+1]+tab[i+2]
+ if n>=0x8000 then
+ stack[top]=n-0x10000
+ else
+ stack[top]=n
end
- reginit=n
- end
- local function setvsindex()
- local vsindex=stack[top]
+ i=i+3
+ elseif t==11 then
if trace_charstrings then
- showstate(formatters["vsindex %i"](vsindex))
+ showstate("return")
end
- updateregions(vsindex)
- top=top-1
- end
- local function blend()
- local n=stack[top]
- top=top-1
- if axis then
- if trace_charstrings then
- local t=top-nofregions*n
- local m=t-n
- for i=1,n do
- local k=m+i
- local d=m+n+(i-1)*nofregions
- local old=stack[k]
- local new=old
- for r=1,nofregions do
- new=new+stack[d+r]*factors[r]
- end
- stack[k]=new
- showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new))
- end
- top=t
- elseif n==1 then
- top=top-nofregions
- local v=stack[top]
- for r=1,nofregions do
- v=v+stack[top+r]*factors[r]
- end
- stack[top]=v
- else
- top=top-nofregions*n
- local d=top
- local k=top-n
- for i=1,n do
- k=k+1
- local v=stack[k]
- for r=1,nofregions do
- v=v+stack[d+r]*factors[r]
- end
- stack[k]=v
- d=d+nofregions
- end
- end
+ return
+ elseif t==10 then
+ call("local",locals,localbias)
+ i=i+1
+ elseif t==14 then
+ if width then
+ elseif top>0 then
+ width=stack[1]
+ if trace_charstrings then
+ showvalue("width",width)
+ end
else
+ width=true
end
- end
- local actions={ [0]=unsupported,
- getstem,
- unsupported,
- getstem,
- vmoveto,
- rlineto,
- hlineto,
- vlineto,
- rrcurveto,
- unsupported,
- unsupported,
- unsupported,
- unsupported,
- hsbw,
- unsupported,
- setvsindex,
- blend,
- unsupported,
- getstem,
- getmask,
- getmask,
- rmoveto,
- hmoveto,
- getstem,
- rcurveline,
- rlinecurve,
- vvcurveto,
- hhcurveto,
- unsupported,
- unsupported,
- vhcurveto,
- hvcurveto,
- }
- local subactions={
- [000]=dotsection,
- [001]=getstem3,
- [002]=getstem3,
- [006]=seac,
- [007]=sbw,
- [012]=divide,
- [016]=callothersubr,
- [017]=pop,
- [033]=setcurrentpoint,
- [034]=hflex,
- [035]=flex,
- [036]=hflex1,
- [037]=flex1,
- }
- local chars=setmetatableindex(function (t,k)
- local v=char(k)
- t[k]=v
- return v
- end)
- local c_endchar=chars[14]
- local encode={}
- setmetatableindex(encode,function(t,i)
- for i=-2048,-1130 do
- t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
- end
- for i=-1131,-108 do
- local v=0xFB00-i-108
- t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF))
- end
- for i=-107,107 do
- t[i]=chars[i+139]
- end
- for i=108,1131 do
- local v=0xF700+i-108
- t[i]=char(extract(v,8,8),extract(v,0,8))
- end
- for i=1132,2048 do
- t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+ if trace_charstrings then
+ showstate("endchar")
end
- setmetatableindex(encode,function(t,k)
- local r=round(k)
- local v=rawget(t,r)
- if v then
- return v
- end
- local v1=floor(k)
- local v2=floor((k-v1)*0x10000)
- return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8))
- end)
- return t[i]
- end)
- readers.cffencoder=encode
- local function p_setvsindex()
- local vsindex=stack[top]
- updateregions(vsindex)
- top=top-1
- end
- local function p_blend()
- local n=stack[top]
- top=top-1
- if not axis then
- elseif n==1 then
- top=top-nofregions
- local v=stack[top]
- for r=1,nofregions do
- v=v+stack[top+r]*factors[r]
- end
- stack[top]=round(v)
- else
- top=top-nofregions*n
- local d=top
- local k=top-n
- for i=1,n do
- k=k+1
- local v=stack[k]
- for r=1,nofregions do
- v=v+stack[d+r]*factors[r]
- end
- stack[k]=round(v)
- d=d+nofregions
+ return
+ elseif t==29 then
+ call("global",globals,globalbias)
+ i=i+1
+ elseif t==12 then
+ i=i+1
+ local t=tab[i]
+ if justpass then
+ if t>=34 or t<=37 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
end
- end
- end
- local function p_getstem()
- local n=0
- if top%2~=0 then
- n=1
- end
- if top>n then
- stems=stems+idiv(top-n,2)
- end
- end
- local function p_getmask()
- local n=0
- if top%2~=0 then
- n=1
- end
- if top>n then
- stems=stems+idiv(top-n,2)
- end
- if stems==0 then
- return 0
- elseif stems<=8 then
- return 1
- else
- return idiv(stems+7,8)
- end
- end
- local process
- local function call(scope,list,bias)
- depth=depth+1
- if top==0 then
- showstate(formatters["unknown %s call"](scope))
+ r=r+1;result[r]=chars[12]
+ r=r+1;result[r]=chars[t]
top=0
+ else
+ local a=subactions[t]
+ if a then
+ a(t)
+ else
+ top=0
+ end
+ end
else
- local index=stack[top]+bias
- top=top-1
+ local a=subactions[t]
+ if a then
+ a(t)
+ else
if trace_charstrings then
- showvalue(scope,index,true)
+ showvalue("<subaction>",t)
end
- local tab=list[index]
- if tab then
- process(tab)
- else
- showstate(formatters["unknown %s call %i"](scope,index))
- top=0
- end
- end
- depth=depth-1
- end
- local justpass=false
- process=function(tab)
- local i=1
- local n=#tab
- while i<=n do
- local t=tab[i]
- if t>=32 then
- top=top+1
- if t<=246 then
- stack[top]=t-139
- i=i+1
- elseif t<=250 then
- stack[top]=t*256-63124+tab[i+1]
- i=i+2
- elseif t<=254 then
- stack[top]=-t*256+64148-tab[i+1]
- i=i+2
- else
- local n=0x100*tab[i+1]+tab[i+2]
- if n>=0x8000 then
- stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF
- else
- stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF
- end
- i=i+5
- end
- elseif t==28 then
- top=top+1
- local n=0x100*tab[i+1]+tab[i+2]
- if n>=0x8000 then
- stack[top]=n-0x10000
- else
- stack[top]=n
- end
- i=i+3
- elseif t==11 then
- if trace_charstrings then
- showstate("return")
- end
- return
- elseif t==10 then
- call("local",locals,localbias)
- i=i+1
- elseif t==14 then
- if width then
- elseif top>0 then
- width=stack[1]
- if trace_charstrings then
- showvalue("width",width)
- end
- else
- width=true
- end
- if trace_charstrings then
- showstate("endchar")
- end
- return
- elseif t==29 then
- call("global",globals,globalbias)
- i=i+1
- elseif t==12 then
- i=i+1
- local t=tab[i]
- if justpass then
- if t>=34 or t<=37 then
- for i=1,top do
- r=r+1;result[r]=encode[stack[i]]
- end
- r=r+1;result[r]=chars[12]
- r=r+1;result[r]=chars[t]
- top=0
- else
- local a=subactions[t]
- if a then
- a(t)
- else
- top=0
- end
- end
- else
- local a=subactions[t]
- if a then
- a(t)
- else
- if trace_charstrings then
- showvalue("<subaction>",t)
- end
- top=0
- end
- end
- i=i+1
- elseif justpass then
- if t==15 then
- p_setvsindex()
- i=i+1
- elseif t==16 then
- local s=p_blend() or 0
- i=i+s+1
- elseif t==1 or t==3 or t==18 or operation==23 then
- p_getstem()
+ top=0
+ end
+ end
+ i=i+1
+ elseif justpass then
+ if t==15 then
+ p_setvsindex()
+ i=i+1
+ elseif t==16 then
+ local s=p_blend() or 0
+ i=i+s+1
+ elseif t==1 or t==3 or t==18 or operation==23 then
+ p_getstem()
if true then
- if top>0 then
- for i=1,top do
- r=r+1;result[r]=encode[stack[i]]
- end
- top=0
- end
- r=r+1;result[r]=chars[t]
+ if top>0 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ top=0
+ end
+ r=r+1;result[r]=chars[t]
else
- top=0
+ top=0
end
- i=i+1
- elseif t==19 or t==20 then
- local s=p_getmask() or 0
+ i=i+1
+ elseif t==19 or t==20 then
+ local s=p_getmask() or 0
if true then
- if top>0 then
- for i=1,top do
- r=r+1;result[r]=encode[stack[i]]
- end
- top=0
- end
- r=r+1;result[r]=chars[t]
- for j=1,s do
- i=i+1
- r=r+1;result[r]=chars[tab[i]]
- end
-else
- i=i+s
- top=0
-end
- i=i+1
- elseif t==9 then
- top=0
- i=i+1
- elseif t==13 then
- local s=hsbw() or 0
- i=i+s+1
- else
- if top>0 then
- for i=1,top do
- r=r+1;result[r]=encode[stack[i]]
- end
- top=0
- end
- r=r+1;result[r]=chars[t]
- i=i+1
- end
- else
- local a=actions[t]
- if a then
- local s=a(t)
- if s then
- i=i+s+1
- else
- i=i+1
- end
- else
- if trace_charstrings then
- showvalue("<action>",t)
- end
- top=0
- i=i+1
- end
+ if top>0 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
end
- end
- end
- local function setbias(globals,locals)
- local g,l=#globals,#locals
- return
- ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1,
- ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1
- end
- local function processshape(tab,index)
- if not tab then
- glyphs[index]={
- boundingbox={ 0,0,0,0 },
- width=0,
- name=charset and charset[index] or nil,
- }
- return
- end
- tab=bytetable(tab)
- x=0
- y=0
- width=false
- r=0
- top=0
- stems=0
- result={}
- xmin=0
- xmax=0
- ymin=0
- ymax=0
- checked=false
- if trace_charstrings then
- report("glyph: %i",index)
- report("data : % t",tab)
- end
- if regions then
- updateregions(vsindex)
- end
- process(tab)
- local boundingbox={
- round(xmin),
- round(ymin),
- round(xmax),
- round(ymax),
- }
- if width==true or width==false then
- width=defaultwidth
- else
- width=nominalwidth+width
- end
- local glyph=glyphs[index]
- if justpass then
- r=r+1
- result[r]=c_endchar
- local stream=concat(result)
- if glyph then
- glyph.stream=stream
- else
- glyphs[index]={ stream=stream }
- end
- elseif glyph then
- glyph.segments=keepcurve~=false and result or nil
- glyph.boundingbox=boundingbox
- if not glyph.width then
- glyph.width=width
- end
- if charset and not glyph.name then
- glyph.name=charset[index]
- end
- elseif keepcurve then
- glyphs[index]={
- segments=result,
- boundingbox=boundingbox,
- width=width,
- name=charset and charset[index] or nil,
- }
+ top=0
+ end
+ r=r+1;result[r]=chars[t]
+ for j=1,s do
+ i=i+1
+ r=r+1;result[r]=chars[tab[i]]
+ end
+else
+ i=i+s
+ top=0
+end
+ i=i+1
+ elseif t==9 then
+ top=0
+ i=i+1
+ elseif t==13 then
+ local s=hsbw() or 0
+ i=i+s+1
else
- glyphs[index]={
- boundingbox=boundingbox,
- width=width,
- name=charset and charset[index] or nil,
- }
- end
- if trace_charstrings then
- report("width : %s",tostring(width))
- report("boundingbox: % t",boundingbox)
- end
- end
- startparsing=function(fontdata,data,streams)
- reginit=false
- axis=false
- regions=data.regions
- justpass=streams==true
- if regions then
- regions={ regions }
- axis=data.factors or false
+ if top>0 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ top=0
+ end
+ r=r+1;result[r]=chars[t]
+ i=i+1
end
- end
- stopparsing=function(fontdata,data)
- stack={}
- glyphs=false
- result={}
- top=0
- locals=false
- globals=false
- strings=false
- end
- local function setwidths(private)
- if not private then
- return 0,0
- end
- local privatedata=private.data
- if not privatedata then
- return 0,0
- end
- return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0
- end
- parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams)
- local dictionary=data.dictionaries[1]
- local charstrings=dictionary.charstrings
- keepcurve=doshapes
- version=tversion
- strings=data.strings
- globals=data.routines or {}
- locals=dictionary.subroutines or {}
- charset=dictionary.charset
- vsindex=dictionary.vsindex or 0
- glyphs=glphs or {}
- globalbias,localbias=setbias(globals,locals)
- nominalwidth,defaultwidth=setwidths(dictionary.private)
- if charstrings then
- startparsing(fontdata,data,streams)
- for index=1,#charstrings do
- processshape(charstrings[index],index-1)
- end
- stopparsing(fontdata,data)
+ else
+ local a=actions[t]
+ if a then
+ local s=a(t)
+ if s then
+ i=i+s+1
+ else
+ i=i+1
+ end
else
- report("no charstrings")
- end
- return glyphs
- end
- parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams)
- keepcurve=doshapes
- version=tversion
- strings=data.strings
- globals=data.routines or {}
- locals=dictionary.subroutines or {}
- charset=false
- vsindex=dictionary.vsindex or 0
- glyphs=glphs or {}
+ if trace_charstrings then
+ showvalue("<action>",t)
+ end
+ top=0
+ i=i+1
+ end
+ end
+ end
+ end
+ local function setbias(globals,locals)
+ local g,l=#globals,#locals
+ return
+ ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1,
+ ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1
+ end
+ local function processshape(tab,index)
+ if not tab then
+ glyphs[index]={
+ boundingbox={ 0,0,0,0 },
+ width=0,
+ name=charset and charset[index] or nil,
+ }
+ return
+ end
+ tab=bytetable(tab)
+ x=0
+ y=0
+ width=false
+ r=0
+ top=0
+ stems=0
+ result={}
+ xmin=0
+ xmax=0
+ ymin=0
+ ymax=0
+ checked=false
+ if trace_charstrings then
+ report("glyph: %i",index)
+ report("data : % t",tab)
+ end
+ if regions then
+ updateregions(vsindex)
+ end
+ process(tab)
+ local boundingbox={
+ round(xmin),
+ round(ymin),
+ round(xmax),
+ round(ymax),
+ }
+ if width==true or width==false then
+ width=defaultwidth
+ else
+ width=nominalwidth+width
+ end
+ local glyph=glyphs[index]
+ if justpass then
+ r=r+1
+ result[r]=c_endchar
+ local stream=concat(result)
+ if glyph then
+ glyph.stream=stream
+ else
+ glyphs[index]={ stream=stream }
+ end
+ elseif glyph then
+ glyph.segments=keepcurve~=false and result or nil
+ glyph.boundingbox=boundingbox
+ if not glyph.width then
+ glyph.width=width
+ end
+ if charset and not glyph.name then
+ glyph.name=charset[index]
+ end
+ elseif keepcurve then
+ glyphs[index]={
+ segments=result,
+ boundingbox=boundingbox,
+ width=width,
+ name=charset and charset[index] or nil,
+ }
+ else
+ glyphs[index]={
+ boundingbox=boundingbox,
+ width=width,
+ name=charset and charset[index] or nil,
+ }
+ end
+ if trace_charstrings then
+ report("width : %s",tostring(width))
+ report("boundingbox: % t",boundingbox)
+ end
+ end
+ startparsing=function(fontdata,data,streams)
+ reginit=false
+ axis=false
+ regions=data.regions
+ justpass=streams==true
+ if regions then
+ regions={ regions }
+ axis=data.factors or false
+ end
+ end
+ stopparsing=function(fontdata,data)
+ stack={}
+ glyphs=false
+ result={}
+ top=0
+ locals=false
+ globals=false
+ strings=false
+ end
+ local function setwidths(private)
+ if not private then
+ return 0,0
+ end
+ local privatedata=private.data
+ if not privatedata then
+ return 0,0
+ end
+ return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0
+ end
+ parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams)
+ local dictionary=data.dictionaries[1]
+ local charstrings=dictionary.charstrings
+ keepcurve=doshapes
+ version=tversion
+ strings=data.strings
+ globals=data.routines or {}
+ locals=dictionary.subroutines or {}
+ charset=dictionary.charset
+ vsindex=dictionary.vsindex or 0
+ glyphs=glphs or {}
+ globalbias,localbias=setbias(globals,locals)
+ nominalwidth,defaultwidth=setwidths(dictionary.private)
+ if charstrings then
+ startparsing(fontdata,data,streams)
+ for index=1,#charstrings do
+ processshape(charstrings[index],index-1)
+ end
+ stopparsing(fontdata,data)
+ else
+ report("no charstrings")
+ end
+ return glyphs
+ end
+ parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams)
+ keepcurve=doshapes
+ version=tversion
+ strings=data.strings
+ globals=data.routines or {}
+ locals=dictionary.subroutines or {}
+ charset=false
+ vsindex=dictionary.vsindex or 0
+ glyphs=glphs or {}
justpass=streams==true
- globalbias,localbias=setbias(globals,locals)
- nominalwidth,defaultwidth=setwidths(dictionary.private)
- processshape(tab,index-1)
- end
+ globalbias,localbias=setbias(globals,locals)
+ nominalwidth,defaultwidth=setwidths(dictionary.private)
+ processshape(tab,index-1)
+ end
end
local function readglobals(f,data)
- local routines=readlengths(f)
- for i=1,#routines do
- routines[i]=readbytetable(f,routines[i])
- end
- data.routines=routines
+ local routines=readlengths(f)
+ for i=1,#routines do
+ routines[i]=readbytetable(f,routines[i])
+ end
+ data.routines=routines
end
local function readencodings(f,data)
- data.encodings={}
+ data.encodings={}
end
local function readcharsets(f,data,dictionary)
- local header=data.header
- local strings=data.strings
- local nofglyphs=data.nofglyphs
- local charsetoffset=dictionary.charset
- if charsetoffset and charsetoffset~=0 then
- setposition(f,header.offset+charsetoffset)
- local format=readbyte(f)
- local charset={ [0]=".notdef" }
- dictionary.charset=charset
- if format==0 then
- for i=1,nofglyphs do
- charset[i]=strings[readushort(f)]
- end
- elseif format==1 or format==2 then
- local readcount=format==1 and readbyte or readushort
- local i=1
- while i<=nofglyphs do
- local sid=readushort(f)
- local n=readcount(f)
- for s=sid,sid+n do
- charset[i]=strings[s]
- i=i+1
- if i>nofglyphs then
- break
- end
- end
- end
- else
- report("cff parser: unsupported charset format %a",format)
+ local header=data.header
+ local strings=data.strings
+ local nofglyphs=data.nofglyphs
+ local charsetoffset=dictionary.charset
+ if charsetoffset and charsetoffset~=0 then
+ setposition(f,header.offset+charsetoffset)
+ local format=readbyte(f)
+ local charset={ [0]=".notdef" }
+ dictionary.charset=charset
+ if format==0 then
+ for i=1,nofglyphs do
+ charset[i]=strings[readushort(f)]
+ end
+ elseif format==1 or format==2 then
+ local readcount=format==1 and readbyte or readushort
+ local i=1
+ while i<=nofglyphs do
+ local sid=readushort(f)
+ local n=readcount(f)
+ for s=sid,sid+n do
+ charset[i]=strings[s]
+ i=i+1
+ if i>nofglyphs then
+ break
+ end
end
+ end
else
- dictionary.nocharset=true
- dictionary.charset=nil
+ report("cff parser: unsupported charset format %a",format)
end
+ else
+ dictionary.nocharset=true
+ dictionary.charset=nil
+ end
end
local function readprivates(f,data)
- local header=data.header
- local dictionaries=data.dictionaries
- local private=dictionaries[1].private
- if private then
- setposition(f,header.offset+private.offset)
- private.data=readstring(f,private.size)
- end
+ local header=data.header
+ local dictionaries=data.dictionaries
+ local private=dictionaries[1].private
+ if private then
+ setposition(f,header.offset+private.offset)
+ private.data=readstring(f,private.size)
+ end
end
local function readlocals(f,data,dictionary)
- local header=data.header
- local private=dictionary.private
- if private then
- local subroutineoffset=private.data.subroutines
- if subroutineoffset~=0 then
- setposition(f,header.offset+private.offset+subroutineoffset)
- local subroutines=readlengths(f)
- for i=1,#subroutines do
- subroutines[i]=readbytetable(f,subroutines[i])
- end
- dictionary.subroutines=subroutines
- private.data.subroutines=nil
- else
- dictionary.subroutines={}
- end
+ local header=data.header
+ local private=dictionary.private
+ if private then
+ local subroutineoffset=private.data.subroutines
+ if subroutineoffset~=0 then
+ setposition(f,header.offset+private.offset+subroutineoffset)
+ local subroutines=readlengths(f)
+ for i=1,#subroutines do
+ subroutines[i]=readbytetable(f,subroutines[i])
+ end
+ dictionary.subroutines=subroutines
+ private.data.subroutines=nil
else
- dictionary.subroutines={}
+ dictionary.subroutines={}
end
+ else
+ dictionary.subroutines={}
+ end
end
local function readcharstrings(f,data,what)
- local header=data.header
- local dictionaries=data.dictionaries
- local dictionary=dictionaries[1]
- local stringtype=dictionary.charstringtype
- local offset=dictionary.charstrings
- if type(offset)~="number" then
- elseif stringtype==2 then
- setposition(f,header.offset+offset)
- local charstrings=readlengths(f,what=="cff2")
- local nofglyphs=#charstrings
- for i=1,nofglyphs do
- charstrings[i]=readstring(f,charstrings[i])
- end
- data.nofglyphs=nofglyphs
- dictionary.charstrings=charstrings
- else
- report("unsupported charstr type %i",stringtype)
- data.nofglyphs=0
- dictionary.charstrings={}
- end
+ local header=data.header
+ local dictionaries=data.dictionaries
+ local dictionary=dictionaries[1]
+ local stringtype=dictionary.charstringtype
+ local offset=dictionary.charstrings
+ if type(offset)~="number" then
+ elseif stringtype==2 then
+ setposition(f,header.offset+offset)
+ local charstrings=readlengths(f,what=="cff2")
+ local nofglyphs=#charstrings
+ for i=1,nofglyphs do
+ charstrings[i]=readstring(f,charstrings[i])
+ end
+ data.nofglyphs=nofglyphs
+ dictionary.charstrings=charstrings
+ else
+ report("unsupported charstr type %i",stringtype)
+ data.nofglyphs=0
+ dictionary.charstrings={}
+ end
end
local function readcidprivates(f,data)
- local header=data.header
- local dictionaries=data.dictionaries[1].cid.dictionaries
- for i=1,#dictionaries do
- local dictionary=dictionaries[i]
- local private=dictionary.private
- if private then
- setposition(f,header.offset+private.offset)
- private.data=readstring(f,private.size)
- end
+ local header=data.header
+ local dictionaries=data.dictionaries[1].cid.dictionaries
+ for i=1,#dictionaries do
+ local dictionary=dictionaries[i]
+ local private=dictionary.private
+ if private then
+ setposition(f,header.offset+private.offset)
+ private.data=readstring(f,private.size)
end
- parseprivates(data,dictionaries)
+ end
+ parseprivates(data,dictionaries)
end
readers.parsecharstrings=parsecharstrings
local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
- local dictionaries=data.dictionaries
- local dictionary=dictionaries[1]
- readglobals(f,data)
- readcharstrings(f,data,version)
- if version=="cff2" then
- dictionary.charset=nil
- else
- readencodings(f,data)
- readcharsets(f,data,dictionary)
- end
- readprivates(f,data)
- parseprivates(data,data.dictionaries)
- readlocals(f,data,dictionary)
- startparsing(fontdata,data,streams)
- parsecharstrings(fontdata,data,glyphs,doshapes,version,streams)
- stopparsing(fontdata,data)
+ local dictionaries=data.dictionaries
+ local dictionary=dictionaries[1]
+ readglobals(f,data)
+ readcharstrings(f,data,version)
+ if version=="cff2" then
+ dictionary.charset=nil
+ else
+ readencodings(f,data)
+ readcharsets(f,data,dictionary)
+ end
+ readprivates(f,data)
+ parseprivates(data,data.dictionaries)
+ readlocals(f,data,dictionary)
+ startparsing(fontdata,data,streams)
+ parsecharstrings(fontdata,data,glyphs,doshapes,version,streams)
+ stopparsing(fontdata,data)
end
local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
- local header=data.header
- local dictionaries=data.dictionaries
- local dictionary=dictionaries[1]
- local cid=dictionary.cid
- local cidselect=cid and cid.fdselect
- readglobals(f,data)
- readcharstrings(f,data,version)
- if version~="cff2" then
- readencodings(f,data)
- end
- local charstrings=dictionary.charstrings
- local fdindex={}
- local nofglyphs=data.nofglyphs
- local maxindex=-1
- setposition(f,header.offset+cidselect)
- local format=readbyte(f)
- if format==1 then
- for i=0,nofglyphs do
- local index=readbyte(f)
- fdindex[i]=index
- if index>maxindex then
- maxindex=index
- end
- end
- elseif format==3 then
- local nofranges=readushort(f)
- local first=readushort(f)
- local index=readbyte(f)
- while true do
- local last=readushort(f)
- if index>maxindex then
- maxindex=index
- end
- for i=first,last do
- fdindex[i]=index
- end
- if last>=nofglyphs then
- break
- else
- first=last+1
- index=readbyte(f)
- end
- end
+ local header=data.header
+ local dictionaries=data.dictionaries
+ local dictionary=dictionaries[1]
+ local cid=dictionary.cid
+ local cidselect=cid and cid.fdselect
+ readglobals(f,data)
+ readcharstrings(f,data,version)
+ if version~="cff2" then
+ readencodings(f,data)
+ end
+ local charstrings=dictionary.charstrings
+ local fdindex={}
+ local nofglyphs=data.nofglyphs
+ local maxindex=-1
+ setposition(f,header.offset+cidselect)
+ local format=readbyte(f)
+ if format==1 then
+ for i=0,nofglyphs do
+ local index=readbyte(f)
+ fdindex[i]=index
+ if index>maxindex then
+ maxindex=index
+ end
+ end
+ elseif format==3 then
+ local nofranges=readushort(f)
+ local first=readushort(f)
+ local index=readbyte(f)
+ while true do
+ local last=readushort(f)
+ if index>maxindex then
+ maxindex=index
+ end
+ for i=first,last do
+ fdindex[i]=index
+ end
+ if last>=nofglyphs then
+ break
+ else
+ first=last+1
+ index=readbyte(f)
+ end
+ end
+ else
+ end
+ if maxindex>=0 then
+ local cidarray=cid.fdarray
+ if cidarray then
+ setposition(f,header.offset+cidarray)
+ local dictionaries=readlengths(f)
+ for i=1,#dictionaries do
+ dictionaries[i]=readstring(f,dictionaries[i])
+ end
+ parsedictionaries(data,dictionaries)
+ cid.dictionaries=dictionaries
+ readcidprivates(f,data)
+ for i=1,#dictionaries do
+ readlocals(f,data,dictionaries[i])
+ end
+ startparsing(fontdata,data,streams)
+ for i=1,#charstrings do
+ parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version,streams)
+ end
+ stopparsing(fontdata,data)
else
+ report("no cid array")
end
- if maxindex>=0 then
- local cidarray=cid.fdarray
- if cidarray then
- setposition(f,header.offset+cidarray)
- local dictionaries=readlengths(f)
- for i=1,#dictionaries do
- dictionaries[i]=readstring(f,dictionaries[i])
- end
- parsedictionaries(data,dictionaries)
- cid.dictionaries=dictionaries
- readcidprivates(f,data)
- for i=1,#dictionaries do
- readlocals(f,data,dictionaries[i])
- end
- startparsing(fontdata,data,streams)
- for i=1,#charstrings do
- parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version,streams)
- end
- stopparsing(fontdata,data)
- else
- report("no cid array")
- end
- end
+ end
end
local gotodatatable=readers.helpers.gotodatatable
local function cleanup(data,dictionaries)
end
function readers.cff(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs)
- if tableoffset then
- local header=readheader(f)
- if header.major~=1 then
- report("only version %s is supported for table %a",1,"cff")
- return
- end
- local glyphs=fontdata.glyphs
- local names=readfontnames(f)
- local dictionaries=readtopdictionaries(f)
- local strings=readstrings(f)
- local data={
- header=header,
- names=names,
- dictionaries=dictionaries,
- strings=strings,
- nofglyphs=fontdata.nofglyphs,
- }
- parsedictionaries(data,dictionaries,"cff")
- local dic=dictionaries[1]
- local cid=dic.cid
- local cffinfo={
- familyname=dic.familyname,
- fullname=dic.fullname,
- boundingbox=dic.boundingbox,
- weight=dic.weight,
- italicangle=dic.italicangle,
- underlineposition=dic.underlineposition,
- underlinethickness=dic.underlinethickness,
- defaultwidth=dic.defaultwidthx,
- nominalwidth=dic.nominalwidthx,
- monospaced=dic.monospaced,
- }
- fontdata.cidinfo=cid and {
- registry=cid.registry,
- ordering=cid.ordering,
- supplement=cid.supplement,
- }
- fontdata.cffinfo=cffinfo
- local all=specification.shapes or specification.streams or false
- if specification.glyphs or all then
- if cid and cid.fdselect then
- readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
- else
- readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
- end
- end
- local private=dic.private
- if private then
- local data=private.data
- if type(data)=="table" then
- cffinfo.defaultwidth=data.defaultwidth or cffinfo.defaultwidth
- cffinfo.nominalwidth=data.nominalwidth or cffinfo.nominalwidth
- cffinfo.bluevalues=data.bluevalues
- cffinfo.otherblues=data.otherblues
- cffinfo.familyblues=data.familyblues
- cffinfo.familyotherblues=data.familyotherblues
- cffinfo.bluescale=data.bluescale
- cffinfo.blueshift=data.blueshift
- cffinfo.bluefuzz=data.bluefuzz
- cffinfo.stdhw=data.stdhw
- cffinfo.stdvw=data.stdvw
- end
- end
- cleanup(data,dictionaries)
+ local tableoffset=gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs)
+ if tableoffset then
+ local header=readheader(f)
+ if header.major~=1 then
+ report("only version %s is supported for table %a",1,"cff")
+ return
end
+ local glyphs=fontdata.glyphs
+ local names=readfontnames(f)
+ local dictionaries=readtopdictionaries(f)
+ local strings=readstrings(f)
+ local data={
+ header=header,
+ names=names,
+ dictionaries=dictionaries,
+ strings=strings,
+ nofglyphs=fontdata.nofglyphs,
+ }
+ parsedictionaries(data,dictionaries,"cff")
+ local dic=dictionaries[1]
+ local cid=dic.cid
+ local cffinfo={
+ familyname=dic.familyname,
+ fullname=dic.fullname,
+ boundingbox=dic.boundingbox,
+ weight=dic.weight,
+ italicangle=dic.italicangle,
+ underlineposition=dic.underlineposition,
+ underlinethickness=dic.underlinethickness,
+ defaultwidth=dic.defaultwidthx,
+ nominalwidth=dic.nominalwidthx,
+ monospaced=dic.monospaced,
+ }
+ fontdata.cidinfo=cid and {
+ registry=cid.registry,
+ ordering=cid.ordering,
+ supplement=cid.supplement,
+ }
+ fontdata.cffinfo=cffinfo
+ local all=specification.shapes or specification.streams or false
+ if specification.glyphs or all then
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
+ else
+ readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
+ end
+ end
+ local private=dic.private
+ if private then
+ local data=private.data
+ if type(data)=="table" then
+ cffinfo.defaultwidth=data.defaultwidth or cffinfo.defaultwidth
+ cffinfo.nominalwidth=data.nominalwidth or cffinfo.nominalwidth
+ cffinfo.bluevalues=data.bluevalues
+ cffinfo.otherblues=data.otherblues
+ cffinfo.familyblues=data.familyblues
+ cffinfo.familyotherblues=data.familyotherblues
+ cffinfo.bluescale=data.bluescale
+ cffinfo.blueshift=data.blueshift
+ cffinfo.bluefuzz=data.bluefuzz
+ cffinfo.stdhw=data.stdhw
+ cffinfo.stdvw=data.stdvw
+ end
+ end
+ cleanup(data,dictionaries)
+ end
end
function readers.cff2(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"cff2",specification.glyphs)
- if tableoffset then
- local header=readheader(f)
- if header.major~=2 then
- report("only version %s is supported for table %a",2,"cff2")
- return
- end
- local glyphs=fontdata.glyphs
- local dictionaries={ readstring(f,header.dsize) }
- local data={
- header=header,
- dictionaries=dictionaries,
- nofglyphs=fontdata.nofglyphs,
- }
- parsedictionaries(data,dictionaries,"cff2")
- local offset=dictionaries[1].vstore
- if offset>0 then
- local storeoffset=dictionaries[1].vstore+data.header.offset+2
- local regions,deltas=readers.helpers.readvariationdata(f,storeoffset,factors)
- data.regions=regions
- data.deltas=deltas
- else
- data.regions={}
- data.deltas={}
- end
- data.factors=specification.factors
- local cid=data.dictionaries[1].cid
- local all=specification.shapes or specification.streams or false
- if cid and cid.fdselect then
- readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
- else
- readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
- end
- cleanup(data,dictionaries)
+ local tableoffset=gotodatatable(f,fontdata,"cff2",specification.glyphs)
+ if tableoffset then
+ local header=readheader(f)
+ if header.major~=2 then
+ report("only version %s is supported for table %a",2,"cff2")
+ return
+ end
+ local glyphs=fontdata.glyphs
+ local dictionaries={ readstring(f,header.dsize) }
+ local data={
+ header=header,
+ dictionaries=dictionaries,
+ nofglyphs=fontdata.nofglyphs,
+ }
+ parsedictionaries(data,dictionaries,"cff2")
+ local offset=dictionaries[1].vstore
+ if offset>0 then
+ local storeoffset=dictionaries[1].vstore+data.header.offset+2
+ local regions,deltas=readers.helpers.readvariationdata(f,storeoffset,factors)
+ data.regions=regions
+ data.deltas=deltas
+ else
+ data.regions={}
+ data.deltas={}
+ end
+ data.factors=specification.factors
+ local cid=data.dictionaries[1].cid
+ local all=specification.shapes or specification.streams or false
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
+ else
+ readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
end
+ cleanup(data,dictionaries)
+ end
end
function readers.cffcheck(filename)
- local f=io.open(filename,"rb")
- if f then
- local fontdata={
- glyphs={},
- }
- local header=readheader(f)
- if header.major~=1 then
- report("only version %s is supported for table %a",1,"cff")
- return
- end
- local names=readfontnames(f)
- local dictionaries=readtopdictionaries(f)
- local strings=readstrings(f)
- local glyphs={}
- local data={
- header=header,
- names=names,
- dictionaries=dictionaries,
- strings=strings,
- glyphs=glyphs,
- nofglyphs=0,
- }
- parsedictionaries(data,dictionaries,"cff")
- local cid=data.dictionaries[1].cid
- if cid and cid.fdselect then
- readfdselect(f,fontdata,data,glyphs,false)
- else
- readnoselect(f,fontdata,data,glyphs,false)
- end
- return data
+ local f=io.open(filename,"rb")
+ if f then
+ local fontdata={
+ glyphs={},
+ }
+ local header=readheader(f)
+ if header.major~=1 then
+ report("only version %s is supported for table %a",1,"cff")
+ return
+ end
+ local names=readfontnames(f)
+ local dictionaries=readtopdictionaries(f)
+ local strings=readstrings(f)
+ local glyphs={}
+ local data={
+ header=header,
+ names=names,
+ dictionaries=dictionaries,
+ strings=strings,
+ glyphs=glyphs,
+ nofglyphs=0,
+ }
+ parsedictionaries(data,dictionaries,"cff")
+ local cid=data.dictionaries[1].cid
+ if cid and cid.fdselect then
+ readfdselect(f,fontdata,data,glyphs,false)
+ else
+ readnoselect(f,fontdata,data,glyphs,false)
end
+ return data
+ end
end
end -- closure
@@ -15475,11 +15475,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-ttf']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,unpack=next,type,unpack
local band,rshift=bit32.band,bit32.rshift
@@ -15495,29 +15495,29 @@ local streamreader=readers.streamreader
local setposition=streamreader.setposition
local getposition=streamreader.getposition
local skipbytes=streamreader.skip
-local readbyte=streamreader.readcardinal1
-local readushort=streamreader.readcardinal2
-local readulong=streamreader.readcardinal4
-local readchar=streamreader.readinteger1
-local readshort=streamreader.readinteger2
-local read2dot14=streamreader.read2dot14
+local readbyte=streamreader.readcardinal1
+local readushort=streamreader.readcardinal2
+local readulong=streamreader.readcardinal4
+local readchar=streamreader.readinteger1
+local readshort=streamreader.readinteger2
+local read2dot14=streamreader.read2dot14
local readinteger=streamreader.readinteger1
local readcardinaltable=streamreader.readcardinaltable
local readintegertable=streamreader.readintegertable
directives.register("fonts.streamreader",function()
- streamreader=utilities.streams
- setposition=streamreader.setposition
- getposition=streamreader.getposition
- skipbytes=streamreader.skip
- readbyte=streamreader.readcardinal1
- readushort=streamreader.readcardinal2
- readulong=streamreader.readcardinal4
- readchar=streamreader.readinteger1
- readshort=streamreader.readinteger2
- read2dot14=streamreader.read2dot14
- readinteger=streamreader.readinteger1
- readcardinaltable=streamreader.readcardinaltable
- readintegertable=streamreader.readintegertable
+ streamreader=utilities.streams
+ setposition=streamreader.setposition
+ getposition=streamreader.getposition
+ skipbytes=streamreader.skip
+ readbyte=streamreader.readcardinal1
+ readushort=streamreader.readcardinal2
+ readulong=streamreader.readcardinal4
+ readchar=streamreader.readinteger1
+ readshort=streamreader.readinteger2
+ read2dot14=streamreader.read2dot14
+ readinteger=streamreader.readinteger1
+ readcardinaltable=streamreader.readcardinaltable
+ readintegertable=streamreader.readintegertable
end)
local short=2
local ushort=2
@@ -15525,1091 +15525,1091 @@ local ulong=4
local helpers=readers.helpers
local gotodatatable=helpers.gotodatatable
local function mergecomposites(glyphs,shapes)
- local function merge(index,shape,components)
- local contours={}
- local points={}
- local nofcontours=0
- local nofpoints=0
- local offset=0
- local deltas=shape.deltas
- for i=1,#components do
- local component=components[i]
- local subindex=component.index
- local subshape=shapes[subindex]
- local subcontours=subshape.contours
- local subpoints=subshape.points
- if not subcontours then
- local subcomponents=subshape.components
- if subcomponents then
- subcontours,subpoints=merge(subindex,subshape,subcomponents)
- end
- end
- if subpoints then
- local matrix=component.matrix
- local xscale=matrix[1]
- local xrotate=matrix[2]
- local yrotate=matrix[3]
- local yscale=matrix[4]
- local xoffset=matrix[5]
- local yoffset=matrix[6]
- local count=#subpoints
- if xscale==1 and yscale==1 and xrotate==0 and yrotate==0 then
- for i=1,count do
- local p=subpoints[i]
- nofpoints=nofpoints+1
- points[nofpoints]={
- p[1]+xoffset,
- p[2]+yoffset,
- p[3]
- }
- end
- else
- for i=1,count do
- local p=subpoints[i]
- local x=p[1]
- local y=p[2]
- nofpoints=nofpoints+1
- points[nofpoints]={
- xscale*x+xrotate*y+xoffset,
- yscale*y+yrotate*x+yoffset,
- p[3]
- }
- end
- end
- local subcount=#subcontours
- if subcount==1 then
- nofcontours=nofcontours+1
- contours[nofcontours]=offset+subcontours[1]
- else
- for i=1,#subcontours do
- nofcontours=nofcontours+1
- contours[nofcontours]=offset+subcontours[i]
- end
- end
- offset=offset+count
- else
- report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex)
- end
+ local function merge(index,shape,components)
+ local contours={}
+ local points={}
+ local nofcontours=0
+ local nofpoints=0
+ local offset=0
+ local deltas=shape.deltas
+ for i=1,#components do
+ local component=components[i]
+ local subindex=component.index
+ local subshape=shapes[subindex]
+ local subcontours=subshape.contours
+ local subpoints=subshape.points
+ if not subcontours then
+ local subcomponents=subshape.components
+ if subcomponents then
+ subcontours,subpoints=merge(subindex,subshape,subcomponents)
+ end
+ end
+ if subpoints then
+ local matrix=component.matrix
+ local xscale=matrix[1]
+ local xrotate=matrix[2]
+ local yrotate=matrix[3]
+ local yscale=matrix[4]
+ local xoffset=matrix[5]
+ local yoffset=matrix[6]
+ local count=#subpoints
+ if xscale==1 and yscale==1 and xrotate==0 and yrotate==0 then
+ for i=1,count do
+ local p=subpoints[i]
+ nofpoints=nofpoints+1
+ points[nofpoints]={
+ p[1]+xoffset,
+ p[2]+yoffset,
+ p[3]
+ }
+ end
+ else
+ for i=1,count do
+ local p=subpoints[i]
+ local x=p[1]
+ local y=p[2]
+ nofpoints=nofpoints+1
+ points[nofpoints]={
+ xscale*x+xrotate*y+xoffset,
+ yscale*y+yrotate*x+yoffset,
+ p[3]
+ }
+ end
end
- shape.points=points
- shape.contours=contours
- shape.components=nil
- return contours,points
- end
- for index=0,#glyphs-1 do
- local shape=shapes[index]
- if shape then
- local components=shape.components
- if components then
- merge(index,shape,components)
- end
+ local subcount=#subcontours
+ if subcount==1 then
+ nofcontours=nofcontours+1
+ contours[nofcontours]=offset+subcontours[1]
+ else
+ for i=1,#subcontours do
+ nofcontours=nofcontours+1
+ contours[nofcontours]=offset+subcontours[i]
+ end
end
- end
+ offset=offset+count
+ else
+ report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex)
+ end
+ end
+ shape.points=points
+ shape.contours=contours
+ shape.components=nil
+ return contours,points
+ end
+ for index=0,#glyphs-1 do
+ local shape=shapes[index]
+ if shape then
+ local components=shape.components
+ if components then
+ merge(index,shape,components)
+ end
+ end
+ end
end
local function readnothing(f)
- return {
- type="nothing",
- }
+ return {
+ type="nothing",
+ }
end
local function curveto(m_x,m_y,l_x,l_y,r_x,r_y)
- return
- l_x+2/3*(m_x-l_x),l_y+2/3*(m_y-l_y),
- r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y),
- r_x,r_y,"c"
+ return
+ l_x+2/3*(m_x-l_x),l_y+2/3*(m_y-l_y),
+ r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y),
+ r_x,r_y,"c"
end
local function applyaxis(glyph,shape,deltas,dowidth)
- local points=shape.points
- if points then
- local nofpoints=#points
- local h=nofpoints+2
- local l=nofpoints+1
- local dw=0
- local dl=0
- for i=1,#deltas do
- local deltaset=deltas[i]
- local xvalues=deltaset.xvalues
- local yvalues=deltaset.yvalues
- local dpoints=deltaset.points
- local factor=deltaset.factor
- if dpoints then
- local nofdpoints=#dpoints
- for i=1,nofdpoints do
- local d=dpoints[i]
- local p=points[d]
- if p then
- if xvalues then
- local x=xvalues[i]
- if x and x~=0 then
- p[1]=p[1]+factor*x
- end
- end
- if yvalues then
- local y=yvalues[i]
- if y and y~=0 then
- p[2]=p[2]+factor*y
- end
- end
- elseif dowidth then
- if d==h then
- local x=xvalues[i]
- if x then
- dw=dw+factor*x
- end
- elseif d==l then
- local x=xvalues[i]
- if x then
- dl=dl+factor*x
- end
- end
- end
- end
- else
- for i=1,nofpoints do
- local p=points[i]
- if xvalues then
- local x=xvalues[i]
- if x and x~=0 then
- p[1]=p[1]+factor*x
- end
- end
- if yvalues then
- local y=yvalues[i]
- if y and y~=0 then
- p[2]=p[2]+factor*y
- end
- end
- end
- if dowidth then
- local x=xvalues[h]
- if x then
- dw=dw+factor*x
- end
- local x=xvalues[l]
- if x then
- dl=dl+factor*x
- end
- end
+ local points=shape.points
+ if points then
+ local nofpoints=#points
+ local h=nofpoints+2
+ local l=nofpoints+1
+ local dw=0
+ local dl=0
+ for i=1,#deltas do
+ local deltaset=deltas[i]
+ local xvalues=deltaset.xvalues
+ local yvalues=deltaset.yvalues
+ local dpoints=deltaset.points
+ local factor=deltaset.factor
+ if dpoints then
+ local nofdpoints=#dpoints
+ for i=1,nofdpoints do
+ local d=dpoints[i]
+ local p=points[d]
+ if p then
+ if xvalues then
+ local x=xvalues[i]
+ if x and x~=0 then
+ p[1]=p[1]+factor*x
+ end
+ end
+ if yvalues then
+ local y=yvalues[i]
+ if y and y~=0 then
+ p[2]=p[2]+factor*y
+ end
end
+ elseif dowidth then
+ if d==h then
+ local x=xvalues[i]
+ if x then
+ dw=dw+factor*x
+ end
+ elseif d==l then
+ local x=xvalues[i]
+ if x then
+ dl=dl+factor*x
+ end
+ end
+ end
+ end
+ else
+ for i=1,nofpoints do
+ local p=points[i]
+ if xvalues then
+ local x=xvalues[i]
+ if x and x~=0 then
+ p[1]=p[1]+factor*x
+ end
+ end
+ if yvalues then
+ local y=yvalues[i]
+ if y and y~=0 then
+ p[2]=p[2]+factor*y
+ end
+ end
end
if dowidth then
- local width=glyph.width or 0
- glyph.width=width+dw-dl
+ local x=xvalues[h]
+ if x then
+ dw=dw+factor*x
+ end
+ local x=xvalues[l]
+ if x then
+ dl=dl+factor*x
+ end
end
- else
- report("no points for glyph %a",glyph.name)
+ end
end
+ if dowidth then
+ local width=glyph.width or 0
+ glyph.width=width+dw-dl
+ end
+ else
+ report("no points for glyph %a",glyph.name)
+ end
end
local quadratic=false
local function contours2outlines_normal(glyphs,shapes)
- for index=0,#glyphs-1 do
- local shape=shapes[index]
- if shape then
- local glyph=glyphs[index]
- local contours=shape.contours
- local points=shape.points
- if contours then
- local nofcontours=#contours
- local segments={}
- local nofsegments=0
- glyph.segments=segments
- if nofcontours>0 then
- local px,py=0,0
- local first=1
- for i=1,nofcontours do
- local last=contours[i]
- if last>=first then
- local first_pt=points[first]
- local first_on=first_pt[3]
- if first==last then
- first_pt[3]="m"
- nofsegments=nofsegments+1
- segments[nofsegments]=first_pt
- else
- local first_on=first_pt[3]
- local last_pt=points[last]
- local last_on=last_pt[3]
- local start=1
- local control_pt=false
- if first_on then
- start=2
- else
- if last_on then
- first_pt=last_pt
- else
- first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false }
- end
- control_pt=first_pt
- end
- local x,y=first_pt[1],first_pt[2]
- if not done then
- xmin,ymin,xmax,ymax=x,y,x,y
- done=true
- end
- nofsegments=nofsegments+1
- segments[nofsegments]={ x,y,"m" }
- if not quadratic then
- px,py=x,y
- end
- local previous_pt=first_pt
- for i=first,last do
- local current_pt=points[i]
- local current_on=current_pt[3]
- local previous_on=previous_pt[3]
- if previous_on then
- if current_on then
- local x,y=current_pt[1],current_pt[2]
- nofsegments=nofsegments+1
- segments[nofsegments]={ x,y,"l" }
- if not quadratic then
- px,py=x,y
- end
- else
- control_pt=current_pt
- end
- elseif current_on then
- local x1,y1=control_pt[1],control_pt[2]
- local x2,y2=current_pt[1],current_pt[2]
- nofsegments=nofsegments+1
- if quadratic then
- segments[nofsegments]={ x1,y1,x2,y2,"q" }
- else
- x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
- segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
- end
- control_pt=false
- else
- local x2,y2=(previous_pt[1]+current_pt[1])/2,(previous_pt[2]+current_pt[2])/2
- local x1,y1=control_pt[1],control_pt[2]
- nofsegments=nofsegments+1
- if quadratic then
- segments[nofsegments]={ x1,y1,x2,y2,"q" }
- else
- x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
- segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
- end
- control_pt=current_pt
- end
- previous_pt=current_pt
- end
- if first_pt==last_pt then
- else
- nofsegments=nofsegments+1
- local x2,y2=first_pt[1],first_pt[2]
- if not control_pt then
- segments[nofsegments]={ x2,y2,"l" }
- elseif quadratic then
- local x1,y1=control_pt[1],control_pt[2]
- segments[nofsegments]={ x1,y1,x2,y2,"q" }
- else
- local x1,y1=control_pt[1],control_pt[2]
- x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
- segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
- end
- end
- end
- end
- first=last+1
+ for index=0,#glyphs-1 do
+ local shape=shapes[index]
+ if shape then
+ local glyph=glyphs[index]
+ local contours=shape.contours
+ local points=shape.points
+ if contours then
+ local nofcontours=#contours
+ local segments={}
+ local nofsegments=0
+ glyph.segments=segments
+ if nofcontours>0 then
+ local px,py=0,0
+ local first=1
+ for i=1,nofcontours do
+ local last=contours[i]
+ if last>=first then
+ local first_pt=points[first]
+ local first_on=first_pt[3]
+ if first==last then
+ first_pt[3]="m"
+ nofsegments=nofsegments+1
+ segments[nofsegments]=first_pt
+ else
+ local first_on=first_pt[3]
+ local last_pt=points[last]
+ local last_on=last_pt[3]
+ local start=1
+ local control_pt=false
+ if first_on then
+ start=2
+ else
+ if last_on then
+ first_pt=last_pt
+ else
+ first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false }
+ end
+ control_pt=first_pt
+ end
+ local x,y=first_pt[1],first_pt[2]
+ if not done then
+ xmin,ymin,xmax,ymax=x,y,x,y
+ done=true
+ end
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x,y,"m" }
+ if not quadratic then
+ px,py=x,y
+ end
+ local previous_pt=first_pt
+ for i=first,last do
+ local current_pt=points[i]
+ local current_on=current_pt[3]
+ local previous_on=previous_pt[3]
+ if previous_on then
+ if current_on then
+ local x,y=current_pt[1],current_pt[2]
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x,y,"l" }
+ if not quadratic then
+ px,py=x,y
+ end
+ else
+ control_pt=current_pt
+ end
+ elseif current_on then
+ local x1,y1=control_pt[1],control_pt[2]
+ local x2,y2=current_pt[1],current_pt[2]
+ nofsegments=nofsegments+1
+ if quadratic then
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ control_pt=false
+ else
+ local x2,y2=(previous_pt[1]+current_pt[1])/2,(previous_pt[2]+current_pt[2])/2
+ local x1,y1=control_pt[1],control_pt[2]
+ nofsegments=nofsegments+1
+ if quadratic then
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
end
+ control_pt=current_pt
+ end
+ previous_pt=current_pt
+ end
+ if first_pt==last_pt then
+ else
+ nofsegments=nofsegments+1
+ local x2,y2=first_pt[1],first_pt[2]
+ if not control_pt then
+ segments[nofsegments]={ x2,y2,"l" }
+ elseif quadratic then
+ local x1,y1=control_pt[1],control_pt[2]
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ else
+ local x1,y1=control_pt[1],control_pt[2]
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
end
+ end
end
+ first=last+1
+ end
end
+ end
end
+ end
end
local function contours2outlines_shaped(glyphs,shapes,keepcurve)
- for index=0,#glyphs-1 do
- local shape=shapes[index]
- if shape then
- local glyph=glyphs[index]
- local contours=shape.contours
- local points=shape.points
- if contours then
- local nofcontours=#contours
- local segments=keepcurve and {} or nil
- local nofsegments=0
+ for index=0,#glyphs-1 do
+ local shape=shapes[index]
+ if shape then
+ local glyph=glyphs[index]
+ local contours=shape.contours
+ local points=shape.points
+ if contours then
+ local nofcontours=#contours
+ local segments=keepcurve and {} or nil
+ local nofsegments=0
+ if keepcurve then
+ glyph.segments=segments
+ end
+ if nofcontours>0 then
+ local xmin,ymin,xmax,ymax,done=0,0,0,0,false
+ local px,py=0,0
+ local first=1
+ for i=1,nofcontours do
+ local last=contours[i]
+ if last>=first then
+ local first_pt=points[first]
+ local first_on=first_pt[3]
+ if first==last then
if keepcurve then
- glyph.segments=segments
+ first_pt[3]="m"
+ nofsegments=nofsegments+1
+ segments[nofsegments]=first_pt
+ end
+ else
+ local first_on=first_pt[3]
+ local last_pt=points[last]
+ local last_on=last_pt[3]
+ local start=1
+ local control_pt=false
+ if first_on then
+ start=2
+ else
+ if last_on then
+ first_pt=last_pt
+ else
+ first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false }
+ end
+ control_pt=first_pt
+ end
+ local x,y=first_pt[1],first_pt[2]
+ if not done then
+ xmin,ymin,xmax,ymax=x,y,x,y
+ done=true
+ else
+ if x<xmin then xmin=x elseif x>xmax then xmax=x end
+ if y<ymin then ymin=y elseif y>ymax then ymax=y end
end
- if nofcontours>0 then
- local xmin,ymin,xmax,ymax,done=0,0,0,0,false
- local px,py=0,0
- local first=1
- for i=1,nofcontours do
- local last=contours[i]
- if last>=first then
- local first_pt=points[first]
- local first_on=first_pt[3]
- if first==last then
- if keepcurve then
- first_pt[3]="m"
- nofsegments=nofsegments+1
- segments[nofsegments]=first_pt
- end
- else
- local first_on=first_pt[3]
- local last_pt=points[last]
- local last_on=last_pt[3]
- local start=1
- local control_pt=false
- if first_on then
- start=2
- else
- if last_on then
- first_pt=last_pt
- else
- first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false }
- end
- control_pt=first_pt
- end
- local x,y=first_pt[1],first_pt[2]
- if not done then
- xmin,ymin,xmax,ymax=x,y,x,y
- done=true
- else
- if x<xmin then xmin=x elseif x>xmax then xmax=x end
- if y<ymin then ymin=y elseif y>ymax then ymax=y end
- end
- if keepcurve then
- nofsegments=nofsegments+1
- segments[nofsegments]={ x,y,"m" }
- end
- if not quadratic then
- px,py=x,y
- end
- local previous_pt=first_pt
- for i=first,last do
- local current_pt=points[i]
- local current_on=current_pt[3]
- local previous_on=previous_pt[3]
- if previous_on then
- if current_on then
- local x,y=current_pt[1],current_pt[2]
- if x<xmin then xmin=x elseif x>xmax then xmax=x end
- if y<ymin then ymin=y elseif y>ymax then ymax=y end
- if keepcurve then
- nofsegments=nofsegments+1
- segments[nofsegments]={ x,y,"l" }
- end
- if not quadratic then
- px,py=x,y
- end
- else
- control_pt=current_pt
- end
- elseif current_on then
- local x1,y1=control_pt[1],control_pt[2]
- local x2,y2=current_pt[1],current_pt[2]
- if quadratic then
- if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
- if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
- if keepcurve then
- nofsegments=nofsegments+1
- segments[nofsegments]={ x1,y1,x2,y2,"q" }
- end
- else
- x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
- if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
- if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
- if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
- if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
- if px<xmin then xmin=px elseif px>xmax then xmax=px end
- if py<ymin then ymin=py elseif py>ymax then ymax=py end
- if keepcurve then
- nofsegments=nofsegments+1
- segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
- end
- end
- control_pt=false
- else
- local x2,y2=(previous_pt[1]+current_pt[1])/2,(previous_pt[2]+current_pt[2])/2
- local x1,y1=control_pt[1],control_pt[2]
- if quadratic then
- if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
- if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
- if keepcurve then
- nofsegments=nofsegments+1
- segments[nofsegments]={ x1,y1,x2,y2,"q" }
- end
- else
- x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
- if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
- if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
- if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
- if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
- if px<xmin then xmin=px elseif px>xmax then xmax=px end
- if py<ymin then ymin=py elseif py>ymax then ymax=py end
- if keepcurve then
- nofsegments=nofsegments+1
- segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
- end
- end
- control_pt=current_pt
- end
- previous_pt=current_pt
- end
- if first_pt==last_pt then
- elseif not control_pt then
- if keepcurve then
- nofsegments=nofsegments+1
- segments[nofsegments]={ first_pt[1],first_pt[2],"l" }
- end
- else
- local x1,y1=control_pt[1],control_pt[2]
- local x2,y2=first_pt[1],first_pt[2]
- if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
- if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
- if quadratic then
- if keepcurve then
- nofsegments=nofsegments+1
- segments[nofsegments]={ x1,y1,x2,y2,"q" }
- end
- else
- x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
- if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
- if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
- if px<xmin then xmin=px elseif px>xmax then xmax=px end
- if py<ymin then ymin=py elseif py>ymax then ymax=py end
- if keepcurve then
- nofsegments=nofsegments+1
- segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
- end
- end
- end
- end
- end
- first=last+1
- end
- glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) }
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x,y,"m" }
+ end
+ if not quadratic then
+ px,py=x,y
+ end
+ local previous_pt=first_pt
+ for i=first,last do
+ local current_pt=points[i]
+ local current_on=current_pt[3]
+ local previous_on=previous_pt[3]
+ if previous_on then
+ if current_on then
+ local x,y=current_pt[1],current_pt[2]
+ if x<xmin then xmin=x elseif x>xmax then xmax=x end
+ if y<ymin then ymin=y elseif y>ymax then ymax=y end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x,y,"l" }
+ end
+ if not quadratic then
+ px,py=x,y
+ end
+ else
+ control_pt=current_pt
+ end
+ elseif current_on then
+ local x1,y1=control_pt[1],control_pt[2]
+ local x2,y2=current_pt[1],current_pt[2]
+ if quadratic then
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ end
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
+ if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
+ if px<xmin then xmin=px elseif px>xmax then xmax=px end
+ if py<ymin then ymin=py elseif py>ymax then ymax=py end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ end
+ control_pt=false
+ else
+ local x2,y2=(previous_pt[1]+current_pt[1])/2,(previous_pt[2]+current_pt[2])/2
+ local x1,y1=control_pt[1],control_pt[2]
+ if quadratic then
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ end
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
+ if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
+ if px<xmin then xmin=px elseif px>xmax then xmax=px end
+ if py<ymin then ymin=py elseif py>ymax then ymax=py end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ end
+ control_pt=current_pt
+ end
+ previous_pt=current_pt
+ end
+ if first_pt==last_pt then
+ elseif not control_pt then
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ first_pt[1],first_pt[2],"l" }
+ end
+ else
+ local x1,y1=control_pt[1],control_pt[2]
+ local x2,y2=first_pt[1],first_pt[2]
+ if x1<xmin then xmin=x1 elseif x1>xmax then xmax=x1 end
+ if y1<ymin then ymin=y1 elseif y1>ymax then ymax=y1 end
+ if quadratic then
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,"q" }
+ end
+ else
+ x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2)
+ if x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
+ if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
+ if px<xmin then xmin=px elseif px>xmax then xmax=px end
+ if py<ymin then ymin=py elseif py>ymax then ymax=py end
+ if keepcurve then
+ nofsegments=nofsegments+1
+ segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" }
+ end
+ end
end
+ end
end
+ first=last+1
+ end
+ glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) }
end
+ end
end
+ end
end
local c_zero=char(0)
local s_zero=char(0,0)
local function toushort(n)
- return char(band(rshift(n,8),0xFF),band(n,0xFF))
+ return char(band(rshift(n,8),0xFF),band(n,0xFF))
end
local function toshort(n)
- if n<0 then
- n=n+0x10000
- end
- return char(band(rshift(n,8),0xFF),band(n,0xFF))
+ if n<0 then
+ n=n+0x10000
+ end
+ return char(band(rshift(n,8),0xFF),band(n,0xFF))
end
local chars=setmetatableindex(function(t,k)
- for i=0,255 do local v=char(i) t[i]=v end return t[k]
+ for i=0,255 do local v=char(i) t[i]=v end return t[k]
end)
local function repackpoints(glyphs,shapes)
- local noboundingbox={ 0,0,0,0 }
- local result={}
- local xpoints={}
- local ypoints={}
- for index=0,#glyphs-1 do
- local shape=shapes[index]
- if shape then
- local r=0
- local glyph=glyphs[index]
- local contours=shape.contours
- local nofcontours=contours and #contours or 0
- local boundingbox=glyph.boundingbox or noboundingbox
- r=r+1 result[r]=toshort(nofcontours)
- r=r+1 result[r]=toshort(boundingbox[1])
- r=r+1 result[r]=toshort(boundingbox[2])
- r=r+1 result[r]=toshort(boundingbox[3])
- r=r+1 result[r]=toshort(boundingbox[4])
- if nofcontours>0 then
- for i=1,nofcontours do
- r=r+1 result[r]=toshort(contours[i]-1)
- end
- r=r+1 result[r]=s_zero
- local points=shape.points
- local currentx=0
- local currenty=0
- local x=0
- local y=0
- local lastflag=nil
- local nofflags=0
- for i=1,#points do
- local pt=points[i]
- local px=pt[1]
- local py=pt[2]
- local fl=pt[3] and 0x01 or 0x00
- if px==currentx then
- fl=fl+0x10
- else
- local dx=round(px-currentx)
- x=x+1
- if dx<-255 or dx>255 then
- xpoints[x]=toshort(dx)
- elseif dx<0 then
- fl=fl+0x02
- xpoints[x]=chars[-dx]
- elseif dx>0 then
- fl=fl+0x12
- xpoints[x]=chars[dx]
- else
- fl=fl+0x02
- xpoints[x]=c_zero
- end
- end
- if py==currenty then
- fl=fl+0x20
- else
- local dy=round(py-currenty)
- y=y+1
- if dy<-255 or dy>255 then
- ypoints[y]=toshort(dy)
- elseif dy<0 then
- fl=fl+0x04
- ypoints[y]=chars[-dy]
- elseif dy>0 then
- fl=fl+0x24
- ypoints[y]=chars[dy]
- else
- fl=fl+0x04
- ypoints[y]=c_zero
- end
- end
- currentx=px
- currenty=py
- if lastflag==fl then
- nofflags=nofflags+1
- else
- if nofflags==1 then
- r=r+1 result[r]=chars[lastflag]
- elseif nofflags==2 then
- r=r+1 result[r]=char(lastflag,lastflag)
- elseif nofflags>2 then
- lastflag=lastflag+0x08
- r=r+1 result[r]=char(lastflag,nofflags-1)
- end
- nofflags=1
- lastflag=fl
- end
- end
- if nofflags==1 then
- r=r+1 result[r]=chars[lastflag]
- elseif nofflags==2 then
- r=r+1 result[r]=char(lastflag,lastflag)
- elseif nofflags>2 then
- lastflag=lastflag+0x08
- r=r+1 result[r]=char(lastflag,nofflags-1)
- end
- r=r+1 result[r]=concat(xpoints,"",1,x)
- r=r+1 result[r]=concat(ypoints,"",1,y)
- end
- local stream=concat(result,"",1,r)
- local length=#stream
- local padding=idiv(length+3,4)*4-length
- if padding>0 then
- if padding==1 then
- padding="\0"
- elseif padding==2 then
- padding="\0\0"
- else
- padding="\0\0\0"
- end
- padding=stream..padding
- end
- glyph.stream=stream
- end
- end
-end
-local flags={}
-local function readglyph(f,nofcontours)
- local points={}
- local contours={}
- for i=1,nofcontours do
- contours[i]=readshort(f)+1
- end
- local nofpoints=contours[nofcontours]
- local nofinstructions=readushort(f)
- skipbytes(f,nofinstructions)
- local i=1
- while i<=nofpoints do
- local flag=readbyte(f)
- flags[i]=flag
- if band(flag,0x08)~=0 then
- local n=readbyte(f)
- if n==1 then
- i=i+1
- flags[i]=flag
+ local noboundingbox={ 0,0,0,0 }
+ local result={}
+ local xpoints={}
+ local ypoints={}
+ for index=0,#glyphs-1 do
+ local shape=shapes[index]
+ if shape then
+ local r=0
+ local glyph=glyphs[index]
+ local contours=shape.contours
+ local nofcontours=contours and #contours or 0
+ local boundingbox=glyph.boundingbox or noboundingbox
+ r=r+1 result[r]=toshort(nofcontours)
+ r=r+1 result[r]=toshort(boundingbox[1])
+ r=r+1 result[r]=toshort(boundingbox[2])
+ r=r+1 result[r]=toshort(boundingbox[3])
+ r=r+1 result[r]=toshort(boundingbox[4])
+ if nofcontours>0 then
+ for i=1,nofcontours do
+ r=r+1 result[r]=toshort(contours[i]-1)
+ end
+ r=r+1 result[r]=s_zero
+ local points=shape.points
+ local currentx=0
+ local currenty=0
+ local x=0
+ local y=0
+ local lastflag=nil
+ local nofflags=0
+ for i=1,#points do
+ local pt=points[i]
+ local px=pt[1]
+ local py=pt[2]
+ local fl=pt[3] and 0x01 or 0x00
+ if px==currentx then
+ fl=fl+0x10
+ else
+ local dx=round(px-currentx)
+ x=x+1
+ if dx<-255 or dx>255 then
+ xpoints[x]=toshort(dx)
+ elseif dx<0 then
+ fl=fl+0x02
+ xpoints[x]=chars[-dx]
+ elseif dx>0 then
+ fl=fl+0x12
+ xpoints[x]=chars[dx]
else
- for j=1,n do
- i=i+1
- flags[i]=flag
- end
+ fl=fl+0x02
+ xpoints[x]=c_zero
end
- end
- i=i+1
- end
- local x=0
- for i=1,nofpoints do
- local flag=flags[i]
- if band(flag,0x02)~=0 then
- if band(flag,0x10)~=0 then
- x=x+readbyte(f)
+ end
+ if py==currenty then
+ fl=fl+0x20
+ else
+ local dy=round(py-currenty)
+ y=y+1
+ if dy<-255 or dy>255 then
+ ypoints[y]=toshort(dy)
+ elseif dy<0 then
+ fl=fl+0x04
+ ypoints[y]=chars[-dy]
+ elseif dy>0 then
+ fl=fl+0x24
+ ypoints[y]=chars[dy]
else
- x=x-readbyte(f)
+ fl=fl+0x04
+ ypoints[y]=c_zero
end
- elseif band(flag,0x10)~=0 then
- else
- x=x+readshort(f)
+ end
+ currentx=px
+ currenty=py
+ if lastflag==fl then
+ nofflags=nofflags+1
+ else
+ if nofflags==1 then
+ r=r+1 result[r]=chars[lastflag]
+ elseif nofflags==2 then
+ r=r+1 result[r]=char(lastflag,lastflag)
+ elseif nofflags>2 then
+ lastflag=lastflag+0x08
+ r=r+1 result[r]=char(lastflag,nofflags-1)
+ end
+ nofflags=1
+ lastflag=fl
+ end
end
- points[i]={ x,0,band(flag,0x01)~=0 }
- end
- local y=0
- for i=1,nofpoints do
- local flag=flags[i]
- if band(flag,0x04)~=0 then
- if band(flag,0x20)~=0 then
- y=y+readbyte(f)
- else
- y=y-readbyte(f)
- end
- elseif band(flag,0x20)~=0 then
+ if nofflags==1 then
+ r=r+1 result[r]=chars[lastflag]
+ elseif nofflags==2 then
+ r=r+1 result[r]=char(lastflag,lastflag)
+ elseif nofflags>2 then
+ lastflag=lastflag+0x08
+ r=r+1 result[r]=char(lastflag,nofflags-1)
+ end
+ r=r+1 result[r]=concat(xpoints,"",1,x)
+ r=r+1 result[r]=concat(ypoints,"",1,y)
+ end
+ local stream=concat(result,"",1,r)
+ local length=#stream
+ local padding=idiv(length+3,4)*4-length
+ if padding>0 then
+ if padding==1 then
+ padding="\0"
+ elseif padding==2 then
+ padding="\0\0"
else
- y=y+readshort(f)
+ padding="\0\0\0"
end
- points[i][2]=y
+ padding=stream..padding
+ end
+ glyph.stream=stream
end
- return {
- type="glyph",
- points=points,
- contours=contours,
- nofpoints=nofpoints,
- }
+ end
end
-local function readcomposite(f)
- local components={}
- local nofcomponents=0
- local instructions=false
- while true do
- local flags=readushort(f)
- local index=readushort(f)
- local f_xyarg=band(flags,0x0002)~=0
- local f_offset=band(flags,0x0800)~=0
- local xscale=1
- local xrotate=0
- local yrotate=0
- local yscale=1
- local xoffset=0
- local yoffset=0
- local base=false
- local reference=false
- if f_xyarg then
- if band(flags,0x0001)~=0 then
- xoffset=readshort(f)
- yoffset=readshort(f)
- else
- xoffset=readchar(f)
- yoffset=readchar(f)
- end
- else
- if band(flags,0x0001)~=0 then
- base=readshort(f)
- reference=readshort(f)
- else
- base=readchar(f)
- reference=readchar(f)
- end
- end
- if band(flags,0x0008)~=0 then
- xscale=read2dot14(f)
- yscale=xscale
- if f_xyarg and f_offset then
- xoffset=xoffset*xscale
- yoffset=yoffset*yscale
- end
- elseif band(flags,0x0040)~=0 then
- xscale=read2dot14(f)
- yscale=read2dot14(f)
- if f_xyarg and f_offset then
- xoffset=xoffset*xscale
- yoffset=yoffset*yscale
- end
- elseif band(flags,0x0080)~=0 then
- xscale=read2dot14(f)
- xrotate=read2dot14(f)
- yrotate=read2dot14(f)
- yscale=read2dot14(f)
- if f_xyarg and f_offset then
- xoffset=xoffset*sqrt(xscale^2+xrotate^2)
- yoffset=yoffset*sqrt(yrotate^2+yscale^2)
- end
- end
- nofcomponents=nofcomponents+1
- components[nofcomponents]={
- index=index,
- usemine=band(flags,0x0200)~=0,
- round=band(flags,0x0006)~=0,
- base=base,
- reference=reference,
- matrix={ xscale,xrotate,yrotate,yscale,xoffset,yoffset },
- }
- if band(flags,0x0100)~=0 then
- instructions=true
- end
- if band(flags,0x0020)==0 then
- break
- end
+local flags={}
+local function readglyph(f,nofcontours)
+ local points={}
+ local contours={}
+ for i=1,nofcontours do
+ contours[i]=readshort(f)+1
+ end
+ local nofpoints=contours[nofcontours]
+ local nofinstructions=readushort(f)
+ skipbytes(f,nofinstructions)
+ local i=1
+ while i<=nofpoints do
+ local flag=readbyte(f)
+ flags[i]=flag
+ if band(flag,0x08)~=0 then
+ local n=readbyte(f)
+ if n==1 then
+ i=i+1
+ flags[i]=flag
+ else
+ for j=1,n do
+ i=i+1
+ flags[i]=flag
+ end
+ end
+ end
+ i=i+1
+ end
+ local x=0
+ for i=1,nofpoints do
+ local flag=flags[i]
+ if band(flag,0x02)~=0 then
+ if band(flag,0x10)~=0 then
+ x=x+readbyte(f)
+ else
+ x=x-readbyte(f)
+ end
+ elseif band(flag,0x10)~=0 then
+ else
+ x=x+readshort(f)
+ end
+ points[i]={ x,0,band(flag,0x01)~=0 }
+ end
+ local y=0
+ for i=1,nofpoints do
+ local flag=flags[i]
+ if band(flag,0x04)~=0 then
+ if band(flag,0x20)~=0 then
+ y=y+readbyte(f)
+ else
+ y=y-readbyte(f)
+ end
+ elseif band(flag,0x20)~=0 then
+ else
+ y=y+readshort(f)
end
- return {
- type="composite",
- components=components,
+ points[i][2]=y
+ end
+ return {
+ type="glyph",
+ points=points,
+ contours=contours,
+ nofpoints=nofpoints,
+ }
+end
+local function readcomposite(f)
+ local components={}
+ local nofcomponents=0
+ local instructions=false
+ while true do
+ local flags=readushort(f)
+ local index=readushort(f)
+ local f_xyarg=band(flags,0x0002)~=0
+ local f_offset=band(flags,0x0800)~=0
+ local xscale=1
+ local xrotate=0
+ local yrotate=0
+ local yscale=1
+ local xoffset=0
+ local yoffset=0
+ local base=false
+ local reference=false
+ if f_xyarg then
+ if band(flags,0x0001)~=0 then
+ xoffset=readshort(f)
+ yoffset=readshort(f)
+ else
+ xoffset=readchar(f)
+ yoffset=readchar(f)
+ end
+ else
+ if band(flags,0x0001)~=0 then
+ base=readshort(f)
+ reference=readshort(f)
+ else
+ base=readchar(f)
+ reference=readchar(f)
+ end
+ end
+ if band(flags,0x0008)~=0 then
+ xscale=read2dot14(f)
+ yscale=xscale
+ if f_xyarg and f_offset then
+ xoffset=xoffset*xscale
+ yoffset=yoffset*yscale
+ end
+ elseif band(flags,0x0040)~=0 then
+ xscale=read2dot14(f)
+ yscale=read2dot14(f)
+ if f_xyarg and f_offset then
+ xoffset=xoffset*xscale
+ yoffset=yoffset*yscale
+ end
+ elseif band(flags,0x0080)~=0 then
+ xscale=read2dot14(f)
+ xrotate=read2dot14(f)
+ yrotate=read2dot14(f)
+ yscale=read2dot14(f)
+ if f_xyarg and f_offset then
+ xoffset=xoffset*sqrt(xscale^2+xrotate^2)
+ yoffset=yoffset*sqrt(yrotate^2+yscale^2)
+ end
+ end
+ nofcomponents=nofcomponents+1
+ components[nofcomponents]={
+ index=index,
+ usemine=band(flags,0x0200)~=0,
+ round=band(flags,0x0006)~=0,
+ base=base,
+ reference=reference,
+ matrix={ xscale,xrotate,yrotate,yscale,xoffset,yoffset },
}
+ if band(flags,0x0100)~=0 then
+ instructions=true
+ end
+ if band(flags,0x0020)==0 then
+ break
+ end
+ end
+ return {
+ type="composite",
+ components=components,
+ }
end
function readers.loca(f,fontdata,specification)
- if specification.glyphs then
- local datatable=fontdata.tables.loca
- if datatable then
- local offset=fontdata.tables.glyf.offset
- local format=fontdata.fontheader.indextolocformat
- local profile=fontdata.maximumprofile
- local nofglyphs=profile and profile.nofglyphs
- local locations={}
- setposition(f,datatable.offset)
- if format==1 then
- if not nofglyphs then
- nofglyphs=idiv(datatable.length,4)-1
- end
- for i=0,nofglyphs do
- locations[i]=offset+readulong(f)
- end
- fontdata.nofglyphs=nofglyphs
- else
- if not nofglyphs then
- nofglyphs=idiv(datatable.length,2)-1
- end
- for i=0,nofglyphs do
- locations[i]=offset+readushort(f)*2
- end
- end
- fontdata.nofglyphs=nofglyphs
- fontdata.locations=locations
+ if specification.glyphs then
+ local datatable=fontdata.tables.loca
+ if datatable then
+ local offset=fontdata.tables.glyf.offset
+ local format=fontdata.fontheader.indextolocformat
+ local profile=fontdata.maximumprofile
+ local nofglyphs=profile and profile.nofglyphs
+ local locations={}
+ setposition(f,datatable.offset)
+ if format==1 then
+ if not nofglyphs then
+ nofglyphs=idiv(datatable.length,4)-1
+ end
+ for i=0,nofglyphs do
+ locations[i]=offset+readulong(f)
+ end
+ fontdata.nofglyphs=nofglyphs
+ else
+ if not nofglyphs then
+ nofglyphs=idiv(datatable.length,2)-1
+ end
+ for i=0,nofglyphs do
+ locations[i]=offset+readushort(f)*2
end
+ end
+ fontdata.nofglyphs=nofglyphs
+ fontdata.locations=locations
end
+ end
end
function readers.glyf(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"glyf",specification.glyphs)
- if tableoffset then
- local locations=fontdata.locations
- if locations then
- local glyphs=fontdata.glyphs
- local nofglyphs=fontdata.nofglyphs
- local filesize=fontdata.filesize
- local nothing={ 0,0,0,0 }
- local shapes={}
- local loadshapes=specification.shapes or specification.instance or specification.streams
- for index=0,nofglyphs-1 do
- local location=locations[index]
- local length=locations[index+1]-location
- if location>=filesize then
- report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1)
- fontdata.nofglyphs=index-1
- fontdata.badfont=true
- break
- elseif length>0 then
- setposition(f,location)
- local nofcontours=readshort(f)
- glyphs[index].boundingbox={
- readshort(f),
- readshort(f),
- readshort(f),
- readshort(f),
- }
- if not loadshapes then
- elseif nofcontours==0 then
- shapes[index]=readnothing(f)
- elseif nofcontours>0 then
- shapes[index]=readglyph(f,nofcontours)
- else
- shapes[index]=readcomposite(f,nofcontours)
- end
- else
- if loadshapes then
- shapes[index]=readnothing(f)
- end
- glyphs[index].boundingbox=nothing
- end
- end
- if loadshapes then
- if readers.gvar then
- readers.gvar(f,fontdata,specification,glyphs,shapes)
- end
- mergecomposites(glyphs,shapes)
- if specification.instance then
- if specification.streams then
- repackpoints(glyphs,shapes)
- else
- contours2outlines_shaped(glyphs,shapes,specification.shapes)
- end
- elseif specification.shapes then
- if specification.streams then
- repackpoints(glyphs,shapes)
- else
- contours2outlines_normal(glyphs,shapes)
- end
- elseif specification.streams then
- repackpoints(glyphs,shapes)
- end
- end
+ local tableoffset=gotodatatable(f,fontdata,"glyf",specification.glyphs)
+ if tableoffset then
+ local locations=fontdata.locations
+ if locations then
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs
+ local filesize=fontdata.filesize
+ local nothing={ 0,0,0,0 }
+ local shapes={}
+ local loadshapes=specification.shapes or specification.instance or specification.streams
+ for index=0,nofglyphs-1 do
+ local location=locations[index]
+ local length=locations[index+1]-location
+ if location>=filesize then
+ report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1)
+ fontdata.nofglyphs=index-1
+ fontdata.badfont=true
+ break
+ elseif length>0 then
+ setposition(f,location)
+ local nofcontours=readshort(f)
+ glyphs[index].boundingbox={
+ readshort(f),
+ readshort(f),
+ readshort(f),
+ readshort(f),
+ }
+ if not loadshapes then
+ elseif nofcontours==0 then
+ shapes[index]=readnothing(f)
+ elseif nofcontours>0 then
+ shapes[index]=readglyph(f,nofcontours)
+ else
+ shapes[index]=readcomposite(f,nofcontours)
+ end
+ else
+ if loadshapes then
+ shapes[index]=readnothing(f)
+ end
+ glyphs[index].boundingbox=nothing
+ end
+ end
+ if loadshapes then
+ if readers.gvar then
+ readers.gvar(f,fontdata,specification,glyphs,shapes)
end
+ mergecomposites(glyphs,shapes)
+ if specification.instance then
+ if specification.streams then
+ repackpoints(glyphs,shapes)
+ else
+ contours2outlines_shaped(glyphs,shapes,specification.shapes)
+ end
+ elseif specification.shapes then
+ if specification.streams then
+ repackpoints(glyphs,shapes)
+ else
+ contours2outlines_normal(glyphs,shapes)
+ end
+ elseif specification.streams then
+ repackpoints(glyphs,shapes)
+ end
+ end
end
+ end
end
local function readtuplerecord(f,nofaxis)
- local record={}
- for i=1,nofaxis do
- record[i]=read2dot14(f)
- end
- return record
+ local record={}
+ for i=1,nofaxis do
+ record[i]=read2dot14(f)
+ end
+ return record
end
local function readpoints(f)
- local count=readbyte(f)
- if count==0 then
- return nil,0
+ local count=readbyte(f)
+ if count==0 then
+ return nil,0
+ else
+ if count<128 then
+ elseif band(count,0x80)~=0 then
+ count=band(count,0x7F)*256+readbyte(f)
else
- if count<128 then
- elseif band(count,0x80)~=0 then
- count=band(count,0x7F)*256+readbyte(f)
- else
- end
- local points={}
- local p=0
- local n=1
- while p<count do
- local control=readbyte(f)
- local runreader=band(control,0x80)~=0 and readushort or readbyte
- local runlength=band(control,0x7F)
- for i=1,runlength+1 do
- n=n+runreader(f)
- p=p+1
- points[p]=n
- end
- end
- return points,p
end
+ local points={}
+ local p=0
+ local n=1
+ while p<count do
+ local control=readbyte(f)
+ local runreader=band(control,0x80)~=0 and readushort or readbyte
+ local runlength=band(control,0x7F)
+ for i=1,runlength+1 do
+ n=n+runreader(f)
+ p=p+1
+ points[p]=n
+ end
+ end
+ return points,p
+ end
end
local function readdeltas(f,nofpoints)
- local deltas={}
- local p=0
- local z=0
- while nofpoints>0 do
- local control=readbyte(f)
+ local deltas={}
+ local p=0
+ local z=0
+ while nofpoints>0 do
+ local control=readbyte(f)
if not control then
- break
+ break
end
- local allzero=band(control,0x80)~=0
- local runlength=band(control,0x3F)+1
- if allzero then
- z=z+runlength
- else
- local runreader=band(control,0x40)~=0 and readshort or readinteger
- if z>0 then
- for i=1,z do
- p=p+1
- deltas[p]=0
- end
- z=0
- end
- for i=1,runlength do
- p=p+1
- deltas[p]=runreader(f)
- end
- end
- nofpoints=nofpoints-runlength
- end
- if p>0 then
- return deltas
+ local allzero=band(control,0x80)~=0
+ local runlength=band(control,0x3F)+1
+ if allzero then
+ z=z+runlength
else
- end
+ local runreader=band(control,0x40)~=0 and readshort or readinteger
+ if z>0 then
+ for i=1,z do
+ p=p+1
+ deltas[p]=0
+ end
+ z=0
+ end
+ for i=1,runlength do
+ p=p+1
+ deltas[p]=runreader(f)
+ end
+ end
+ nofpoints=nofpoints-runlength
+ end
+ if p>0 then
+ return deltas
+ else
+ end
end
local function readdeltas(f,nofpoints)
- local deltas={}
- local p=0
- while nofpoints>0 do
- local control=readbyte(f)
- if control then
- local allzero=band(control,0x80)~=0
- local runlength=band(control,0x3F)+1
- if allzero then
- for i=1,runlength do
- p=p+1
- deltas[p]=0
- end
- else
- local runreader=band(control,0x40)~=0 and readshort or readinteger
- for i=1,runlength do
- p=p+1
- deltas[p]=runreader(f)
- end
- end
- nofpoints=nofpoints-runlength
- else
- break
- end
- end
- if p>0 then
- return deltas
+ local deltas={}
+ local p=0
+ while nofpoints>0 do
+ local control=readbyte(f)
+ if control then
+ local allzero=band(control,0x80)~=0
+ local runlength=band(control,0x3F)+1
+ if allzero then
+ for i=1,runlength do
+ p=p+1
+ deltas[p]=0
+ end
+ else
+ local runreader=band(control,0x40)~=0 and readshort or readinteger
+ for i=1,runlength do
+ p=p+1
+ deltas[p]=runreader(f)
+ end
+ end
+ nofpoints=nofpoints-runlength
else
+ break
end
+ end
+ if p>0 then
+ return deltas
+ else
+ end
end
function readers.gvar(f,fontdata,specification,glyphdata,shapedata)
- local instance=specification.instance
- if not instance then
- return
- end
- local factors=specification.factors
- if not factors then
- return
- end
- local tableoffset=gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes)
- if tableoffset then
- local version=readulong(f)
- local nofaxis=readushort(f)
- local noftuples=readushort(f)
- local tupleoffset=tableoffset+readulong(f)
- local nofglyphs=readushort(f)
- local flags=readushort(f)
- local dataoffset=tableoffset+readulong(f)
- local data={}
- local tuples={}
- local glyphdata=fontdata.glyphs
- local dowidth=not fontdata.variabledata.hvarwidths
- if band(flags,0x0001)~=0 then
- for i=1,nofglyphs+1 do
- data[i]=dataoffset+readulong(f)
- end
+ local instance=specification.instance
+ if not instance then
+ return
+ end
+ local factors=specification.factors
+ if not factors then
+ return
+ end
+ local tableoffset=gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes)
+ if tableoffset then
+ local version=readulong(f)
+ local nofaxis=readushort(f)
+ local noftuples=readushort(f)
+ local tupleoffset=tableoffset+readulong(f)
+ local nofglyphs=readushort(f)
+ local flags=readushort(f)
+ local dataoffset=tableoffset+readulong(f)
+ local data={}
+ local tuples={}
+ local glyphdata=fontdata.glyphs
+ local dowidth=not fontdata.variabledata.hvarwidths
+ if band(flags,0x0001)~=0 then
+ for i=1,nofglyphs+1 do
+ data[i]=dataoffset+readulong(f)
+ end
+ else
+ for i=1,nofglyphs+1 do
+ data[i]=dataoffset+2*readushort(f)
+ end
+ end
+ if noftuples>0 then
+ setposition(f,tupleoffset)
+ for i=1,noftuples do
+ tuples[i]=readtuplerecord(f,nofaxis)
+ end
+ end
+ local nextoffset=false
+ local startoffset=data[1]
+ for i=1,nofglyphs do
+ nextoffset=data[i+1]
+ local glyph=glyphdata[i-1]
+ local name=trace_deltas and glyph.name
+ if startoffset==nextoffset then
+ if name then
+ report("no deltas for glyph %a",name)
+ end
+ else
+ local shape=shapedata[i-1]
+ if not shape then
+ if name then
+ report("no shape for glyph %a",name)
+ end
else
- for i=1,nofglyphs+1 do
- data[i]=dataoffset+2*readushort(f)
+ lastoffset=startoffset
+ setposition(f,startoffset)
+ local flags=readushort(f)
+ local count=band(flags,0x0FFF)
+ local offset=startoffset+readushort(f)
+ local deltas={}
+ local allpoints=(shape.nofpoints or 0)
+ local shared=false
+ local nofshared=0
+ if band(flags,0x8000)~=0 then
+ local current=getposition(f)
+ setposition(f,offset)
+ shared,nofshared=readpoints(f)
+ offset=getposition(f)
+ setposition(f,current)
+ end
+ for j=1,count do
+ local size=readushort(f)
+ local flags=readushort(f)
+ local index=band(flags,0x0FFF)
+ local haspeak=band(flags,0x8000)~=0
+ local intermediate=band(flags,0x4000)~=0
+ local private=band(flags,0x2000)~=0
+ local peak=nil
+ local start=nil
+ local stop=nil
+ local xvalues=nil
+ local yvalues=nil
+ local points=shared
+ local nofpoints=nofshared
+ if haspeak then
+ peak=readtuplerecord(f,nofaxis)
+ else
+ if index+1>#tuples then
+ report("error, bad tuple index",index)
+ end
+ peak=tuples[index+1]
end
- end
- if noftuples>0 then
- setposition(f,tupleoffset)
- for i=1,noftuples do
- tuples[i]=readtuplerecord(f,nofaxis)
+ if intermediate then
+ start=readtuplerecord(f,nofaxis)
+ stop=readtuplerecord(f,nofaxis)
end
- end
- local nextoffset=false
- local startoffset=data[1]
- for i=1,nofglyphs do
- nextoffset=data[i+1]
- local glyph=glyphdata[i-1]
- local name=trace_deltas and glyph.name
- if startoffset==nextoffset then
- if name then
- report("no deltas for glyph %a",name)
- end
+ if size>0 then
+ local current=getposition(f)
+ setposition(f,offset)
+ if private then
+ points,nofpoints=readpoints(f)
+ end
+ if nofpoints==0 then
+ nofpoints=allpoints+4
+ end
+ if nofpoints>0 then
+ xvalues=readdeltas(f,nofpoints)
+ yvalues=readdeltas(f,nofpoints)
+ end
+ offset=offset+size
+ setposition(f,current)
+ end
+ if not xvalues and not yvalues then
+ points=nil
+ end
+ local s=1
+ for i=1,nofaxis do
+ local f=factors[i]
+ local peak=peak and peak [i] or 0
+ local start=start and start[i] or (peak<0 and peak or 0)
+ local stop=stop and stop [i] or (peak>0 and peak or 0)
+ if start>peak or peak>stop then
+ elseif start<0 and stop>0 and peak~=0 then
+ elseif peak==0 then
+ elseif f<start or f>stop then
+ s=0
+ break
+ elseif f<peak then
+ s=s*(f-start)/(peak-start)
+ elseif f>peak then
+ s=s*(stop-f)/(stop-peak)
+ else
+ end
+ end
+ if s==0 then
+ if name then
+ report("no deltas applied for glyph %a",name)
+ end
else
- local shape=shapedata[i-1]
- if not shape then
- if name then
- report("no shape for glyph %a",name)
- end
- else
- lastoffset=startoffset
- setposition(f,startoffset)
- local flags=readushort(f)
- local count=band(flags,0x0FFF)
- local offset=startoffset+readushort(f)
- local deltas={}
- local allpoints=(shape.nofpoints or 0)
- local shared=false
- local nofshared=0
- if band(flags,0x8000)~=0 then
- local current=getposition(f)
- setposition(f,offset)
- shared,nofshared=readpoints(f)
- offset=getposition(f)
- setposition(f,current)
- end
- for j=1,count do
- local size=readushort(f)
- local flags=readushort(f)
- local index=band(flags,0x0FFF)
- local haspeak=band(flags,0x8000)~=0
- local intermediate=band(flags,0x4000)~=0
- local private=band(flags,0x2000)~=0
- local peak=nil
- local start=nil
- local stop=nil
- local xvalues=nil
- local yvalues=nil
- local points=shared
- local nofpoints=nofshared
- if haspeak then
- peak=readtuplerecord(f,nofaxis)
- else
- if index+1>#tuples then
- report("error, bad tuple index",index)
- end
- peak=tuples[index+1]
- end
- if intermediate then
- start=readtuplerecord(f,nofaxis)
- stop=readtuplerecord(f,nofaxis)
- end
- if size>0 then
- local current=getposition(f)
- setposition(f,offset)
- if private then
- points,nofpoints=readpoints(f)
- end
- if nofpoints==0 then
- nofpoints=allpoints+4
- end
- if nofpoints>0 then
- xvalues=readdeltas(f,nofpoints)
- yvalues=readdeltas(f,nofpoints)
- end
- offset=offset+size
- setposition(f,current)
- end
- if not xvalues and not yvalues then
- points=nil
- end
- local s=1
- for i=1,nofaxis do
- local f=factors[i]
- local peak=peak and peak [i] or 0
- local start=start and start[i] or (peak<0 and peak or 0)
- local stop=stop and stop [i] or (peak>0 and peak or 0)
- if start>peak or peak>stop then
- elseif start<0 and stop>0 and peak~=0 then
- elseif peak==0 then
- elseif f<start or f>stop then
- s=0
- break
- elseif f<peak then
- s=s*(f-start)/(peak-start)
- elseif f>peak then
- s=s*(stop-f)/(stop-peak)
- else
- end
- end
- if s==0 then
- if name then
- report("no deltas applied for glyph %a",name)
- end
- else
- deltas[#deltas+1]={
- factor=s,
- points=points,
- xvalues=xvalues,
- yvalues=yvalues,
- }
- end
- end
- if shape.type=="glyph" then
- applyaxis(glyph,shape,deltas,dowidth)
- else
- shape.deltas=deltas
- end
- end
+ deltas[#deltas+1]={
+ factor=s,
+ points=points,
+ xvalues=xvalues,
+ yvalues=yvalues,
+ }
end
- startoffset=nextoffset
+ end
+ if shape.type=="glyph" then
+ applyaxis(glyph,shape,deltas,dowidth)
+ else
+ shape.deltas=deltas
+ end
end
+ end
+ startoffset=nextoffset
end
+ end
end
end -- closure
@@ -16617,11 +16617,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-dsp']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,tonumber=next,type,tonumber
local band=bit32.band
@@ -16672,26 +16672,26 @@ local short=2
local ushort=2
local ulong=4
directives.register("fonts.streamreader",function()
- streamreader=utilities.streams
- setposition=streamreader.setposition
- getposition=streamreader.getposition
- readuinteger=streamreader.readcardinal1
- readushort=streamreader.readcardinal2
- readulong=streamreader.readcardinal4
- readinteger=streamreader.readinteger1
- readshort=streamreader.readinteger2
- readstring=streamreader.readstring
- readtag=streamreader.readtag
- readbytes=streamreader.readbytes
- readfixed=streamreader.readfixed4
- read2dot14=streamreader.read2dot14
- skipshort=streamreader.skipshort
- skipbytes=streamreader.skip
- readbytetable=streamreader.readbytetable
- readbyte=streamreader.readbyte
- readcardinaltable=streamreader.readcardinaltable
- readintegertable=streamreader.readintegertable
- readfword=readshort
+ streamreader=utilities.streams
+ setposition=streamreader.setposition
+ getposition=streamreader.getposition
+ readuinteger=streamreader.readcardinal1
+ readushort=streamreader.readcardinal2
+ readulong=streamreader.readcardinal4
+ readinteger=streamreader.readinteger1
+ readshort=streamreader.readinteger2
+ readstring=streamreader.readstring
+ readtag=streamreader.readtag
+ readbytes=streamreader.readbytes
+ readfixed=streamreader.readfixed4
+ read2dot14=streamreader.read2dot14
+ skipshort=streamreader.skipshort
+ skipbytes=streamreader.skip
+ readbytetable=streamreader.readbytetable
+ readbyte=streamreader.readbyte
+ readcardinaltable=streamreader.readcardinaltable
+ readintegertable=streamreader.readintegertable
+ readfword=readshort
end)
local gsubhandlers={}
local gposhandlers={}
@@ -16700,3140 +16700,3140 @@ readers.gposhandlers=gposhandlers
local helpers=readers.helpers
local gotodatatable=helpers.gotodatatable
local setvariabledata=helpers.setvariabledata
-local lookupidoffset=-1
+local lookupidoffset=-1
local classes={
- "base",
- "ligature",
- "mark",
- "component",
+ "base",
+ "ligature",
+ "mark",
+ "component",
}
local gsubtypes={
- "single",
- "multiple",
- "alternate",
- "ligature",
- "context",
- "chainedcontext",
- "extension",
- "reversechainedcontextsingle",
+ "single",
+ "multiple",
+ "alternate",
+ "ligature",
+ "context",
+ "chainedcontext",
+ "extension",
+ "reversechainedcontextsingle",
}
local gpostypes={
- "single",
- "pair",
- "cursive",
- "marktobase",
- "marktoligature",
- "marktomark",
- "context",
- "chainedcontext",
- "extension",
+ "single",
+ "pair",
+ "cursive",
+ "marktobase",
+ "marktoligature",
+ "marktomark",
+ "context",
+ "chainedcontext",
+ "extension",
}
local chaindirections={
- context=0,
- chainedcontext=1,
- reversechainedcontextsingle=-1,
+ context=0,
+ chainedcontext=1,
+ reversechainedcontextsingle=-1,
}
local function setmetrics(data,where,tag,d)
- local w=data[where]
- if w then
- local v=w[tag]
- if v then
- w[tag]=v+d
- end
+ local w=data[where]
+ if w then
+ local v=w[tag]
+ if v then
+ w[tag]=v+d
end
+ end
end
local variabletags={
- hasc=function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end,
- hdsc=function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end,
- hlgp=function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end,
- hcla=function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end,
- hcld=function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end,
- vasc=function(data,d) setmetrics(data,"vhea not done","ascent",d) end,
- vdsc=function(data,d) setmetrics(data,"vhea not done","descent",d) end,
- vlgp=function(data,d) setmetrics(data,"vhea not done","linegap",d) end,
- xhgt=function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end,
- cpht=function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end,
- sbxs=function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end,
- sbys=function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end,
- sbxo=function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end,
- sbyo=function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end,
- spxs=function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end,
- spys=function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end,
- spxo=function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end,
- spyo=function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end,
- strs=function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end,
- stro=function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end,
- unds=function(data,d) setmetrics(data,"postscript","underlineposition",d) end,
- undo=function(data,d) setmetrics(data,"postscript","underlinethickness",d) end,
+ hasc=function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end,
+ hdsc=function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end,
+ hlgp=function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end,
+ hcla=function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end,
+ hcld=function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end,
+ vasc=function(data,d) setmetrics(data,"vhea not done","ascent",d) end,
+ vdsc=function(data,d) setmetrics(data,"vhea not done","descent",d) end,
+ vlgp=function(data,d) setmetrics(data,"vhea not done","linegap",d) end,
+ xhgt=function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end,
+ cpht=function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end,
+ sbxs=function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end,
+ sbys=function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end,
+ sbxo=function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end,
+ sbyo=function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end,
+ spxs=function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end,
+ spys=function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end,
+ spxo=function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end,
+ spyo=function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end,
+ strs=function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end,
+ stro=function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end,
+ unds=function(data,d) setmetrics(data,"postscript","underlineposition",d) end,
+ undo=function(data,d) setmetrics(data,"postscript","underlinethickness",d) end,
}
local read_cardinal={
- streamreader.readcardinal1,
- streamreader.readcardinal2,
- streamreader.readcardinal3,
- streamreader.readcardinal4,
+ streamreader.readcardinal1,
+ streamreader.readcardinal2,
+ streamreader.readcardinal3,
+ streamreader.readcardinal4,
}
local read_integer={
- streamreader.readinteger1,
- streamreader.readinteger2,
- streamreader.readinteger3,
- streamreader.readinteger4,
+ streamreader.readinteger1,
+ streamreader.readinteger2,
+ streamreader.readinteger3,
+ streamreader.readinteger4,
}
local lookupnames={
- gsub={
- single="gsub_single",
- multiple="gsub_multiple",
- alternate="gsub_alternate",
- ligature="gsub_ligature",
- context="gsub_context",
- chainedcontext="gsub_contextchain",
- reversechainedcontextsingle="gsub_reversecontextchain",
- },
- gpos={
- single="gpos_single",
- pair="gpos_pair",
- cursive="gpos_cursive",
- marktobase="gpos_mark2base",
- marktoligature="gpos_mark2ligature",
- marktomark="gpos_mark2mark",
- context="gpos_context",
- chainedcontext="gpos_contextchain",
- }
+ gsub={
+ single="gsub_single",
+ multiple="gsub_multiple",
+ alternate="gsub_alternate",
+ ligature="gsub_ligature",
+ context="gsub_context",
+ chainedcontext="gsub_contextchain",
+ reversechainedcontextsingle="gsub_reversecontextchain",
+ },
+ gpos={
+ single="gpos_single",
+ pair="gpos_pair",
+ cursive="gpos_cursive",
+ marktobase="gpos_mark2base",
+ marktoligature="gpos_mark2ligature",
+ marktomark="gpos_mark2mark",
+ context="gpos_context",
+ chainedcontext="gpos_contextchain",
+ }
}
local lookupflags=setmetatableindex(function(t,k)
- local v={
- band(k,0x0008)~=0 and true or false,
- band(k,0x0004)~=0 and true or false,
- band(k,0x0002)~=0 and true or false,
- band(k,0x0001)~=0 and true or false,
- }
- t[k]=v
- return v
+ local v={
+ band(k,0x0008)~=0 and true or false,
+ band(k,0x0004)~=0 and true or false,
+ band(k,0x0002)~=0 and true or false,
+ band(k,0x0001)~=0 and true or false,
+ }
+ t[k]=v
+ return v
end)
local function axistofactors(str)
- local t=settings_to_hash(str)
- for k,v in next,t do
- t[k]=tonumber(v) or v
- end
- return t
+ local t=settings_to_hash(str)
+ for k,v in next,t do
+ t[k]=tonumber(v) or v
+ end
+ return t
end
local hash=table.setmetatableindex(function(t,k)
- local v=sequenced(axistofactors(k),",")
- t[k]=v
- return v
+ local v=sequenced(axistofactors(k),",")
+ t[k]=v
+ return v
end)
helpers.normalizedaxishash=hash
local cleanname=fonts.names and fonts.names.cleanname or function(name)
- return name and (gsub(lower(name),"[^%a%d]","")) or nil
+ return name and (gsub(lower(name),"[^%a%d]","")) or nil
end
helpers.cleanname=cleanname
function helpers.normalizedaxis(str)
- return hash[str] or str
+ return hash[str] or str
end
local function getaxisscale(segments,minimum,default,maximum,user)
- if not minimum or not default or not maximum then
- return false
- end
- if user<minimum then
- user=minimum
- elseif user>maximum then
- user=maximum
- end
- if user<default then
- default=- (default-user)/(default-minimum)
- elseif user>default then
- default=(user-default)/(maximum-default)
- else
- default=0
- end
- if not segments then
+ if not minimum or not default or not maximum then
+ return false
+ end
+ if user<minimum then
+ user=minimum
+ elseif user>maximum then
+ user=maximum
+ end
+ if user<default then
+ default=- (default-user)/(default-minimum)
+ elseif user>default then
+ default=(user-default)/(maximum-default)
+ else
+ default=0
+ end
+ if not segments then
+ return default
+ end
+ local e
+ for i=1,#segments do
+ local s=segments[i]
+ if type(s)~="number" then
+ report("using default axis scale")
+ return default
+ elseif s[1]>=default then
+ if s[2]==default then
return default
- end
- local e
- for i=1,#segments do
- local s=segments[i]
- if type(s)~="number" then
- report("using default axis scale")
- return default
- elseif s[1]>=default then
- if s[2]==default then
- return default
- else
- e=i
- break
- end
- end
- end
- if e then
- local b=segments[e-1]
- local e=segments[e]
- return b[2]+(e[2]-b[2])*(default-b[1])/(e[1]-b[1])
- else
- return false
- end
+ else
+ e=i
+ break
+ end
+ end
+ end
+ if e then
+ local b=segments[e-1]
+ local e=segments[e]
+ return b[2]+(e[2]-b[2])*(default-b[1])/(e[1]-b[1])
+ else
+ return false
+ end
end
local function getfactors(data,instancespec)
+ if instancespec==true then
+ elseif type(instancespec)~="string" or instancespec=="" then
+ return
+ end
+ local variabledata=data.variabledata
+ if not variabledata then
+ return
+ end
+ local instances=variabledata.instances
+ local axis=variabledata.axis
+ local segments=variabledata.segments
+ if instances and axis then
+ local values
if instancespec==true then
- elseif type(instancespec)~="string" or instancespec=="" then
- return
- end
- local variabledata=data.variabledata
- if not variabledata then
- return
- end
- local instances=variabledata.instances
- local axis=variabledata.axis
- local segments=variabledata.segments
- if instances and axis then
- local values
- if instancespec==true then
- values={}
- for i=1,#axis do
- values[i]={
- value=axis[i].default,
- }
- end
- else
- for i=1,#instances do
- local instance=instances[i]
- if cleanname(instance.subfamily)==instancespec then
- values=instance.values
- break
- end
- end
- end
- if values then
- local factors={}
- for i=1,#axis do
- local a=axis[i]
- factors[i]=getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value)
- end
- return factors
- end
- local values=axistofactors(hash[instancespec] or instancespec)
- if values then
- local factors={}
- for i=1,#axis do
- local a=axis[i]
- local d=a.default
- factors[i]=getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d)
- end
- return factors
- end
- end
+ values={}
+ for i=1,#axis do
+ values[i]={
+ value=axis[i].default,
+ }
+ end
+ else
+ for i=1,#instances do
+ local instance=instances[i]
+ if cleanname(instance.subfamily)==instancespec then
+ values=instance.values
+ break
+ end
+ end
+ end
+ if values then
+ local factors={}
+ for i=1,#axis do
+ local a=axis[i]
+ factors[i]=getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value)
+ end
+ return factors
+ end
+ local values=axistofactors(hash[instancespec] or instancespec)
+ if values then
+ local factors={}
+ for i=1,#axis do
+ local a=axis[i]
+ local d=a.default
+ factors[i]=getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d)
+ end
+ return factors
+ end
+ end
end
local function getscales(regions,factors)
- local scales={}
- for i=1,#regions do
- local region=regions[i]
- local s=1
- for j=1,#region do
- local axis=region[j]
- local f=factors[j]
- local start=axis.start
- local peak=axis.peak
- local stop=axis.stop
- if start>peak or peak>stop then
- elseif start<0 and stop>0 and peak~=0 then
- elseif peak==0 then
- elseif f<start or f>stop then
- s=0
- break
- elseif f<peak then
- s=s*(f-start)/(peak-start)
- elseif f>peak then
- s=s*(stop-f)/(stop-peak)
- else
- end
- end
- scales[i]=s
+ local scales={}
+ for i=1,#regions do
+ local region=regions[i]
+ local s=1
+ for j=1,#region do
+ local axis=region[j]
+ local f=factors[j]
+ local start=axis.start
+ local peak=axis.peak
+ local stop=axis.stop
+ if start>peak or peak>stop then
+ elseif start<0 and stop>0 and peak~=0 then
+ elseif peak==0 then
+ elseif f<start or f>stop then
+ s=0
+ break
+ elseif f<peak then
+ s=s*(f-start)/(peak-start)
+ elseif f>peak then
+ s=s*(stop-f)/(stop-peak)
+ else
+ end
end
- return scales
+ scales[i]=s
+ end
+ return scales
end
helpers.getaxisscale=getaxisscale
helpers.getfactors=getfactors
helpers.getscales=getscales
helpers.axistofactors=axistofactors
local function readvariationdata(f,storeoffset,factors)
- local position=getposition(f)
- setposition(f,storeoffset)
- local format=readushort(f)
- local regionoffset=storeoffset+readulong(f)
- local nofdeltadata=readushort(f)
- local deltadata=readcardinaltable(f,nofdeltadata,ulong)
- setposition(f,regionoffset)
- local nofaxis=readushort(f)
- local nofregions=readushort(f)
- local regions={}
- for i=1,nofregions do
- local t={}
- for i=1,nofaxis do
- t[i]={
- start=read2dot14(f),
- peak=read2dot14(f),
- stop=read2dot14(f),
- }
- end
- regions[i]=t
- end
- if factors then
- for i=1,nofdeltadata do
- setposition(f,storeoffset+deltadata[i])
- local nofdeltasets=readushort(f)
- local nofshorts=readushort(f)
- local nofregions=readushort(f)
- local usedregions={}
- local deltas={}
- for i=1,nofregions do
- usedregions[i]=regions[readushort(f)+1]
- end
- for i=1,nofdeltasets do
- local t=readintegertable(f,nofshorts,short)
- for i=nofshorts+1,nofregions do
- t[i]=readinteger(f)
- end
- deltas[i]=t
- end
- deltadata[i]={
- regions=usedregions,
- deltas=deltas,
- scales=factors and getscales(usedregions,factors) or nil,
- }
- end
- end
- setposition(f,position)
- return regions,deltadata
+ local position=getposition(f)
+ setposition(f,storeoffset)
+ local format=readushort(f)
+ local regionoffset=storeoffset+readulong(f)
+ local nofdeltadata=readushort(f)
+ local deltadata=readcardinaltable(f,nofdeltadata,ulong)
+ setposition(f,regionoffset)
+ local nofaxis=readushort(f)
+ local nofregions=readushort(f)
+ local regions={}
+ for i=1,nofregions do
+ local t={}
+ for i=1,nofaxis do
+ t[i]={
+ start=read2dot14(f),
+ peak=read2dot14(f),
+ stop=read2dot14(f),
+ }
+ end
+ regions[i]=t
+ end
+ if factors then
+ for i=1,nofdeltadata do
+ setposition(f,storeoffset+deltadata[i])
+ local nofdeltasets=readushort(f)
+ local nofshorts=readushort(f)
+ local nofregions=readushort(f)
+ local usedregions={}
+ local deltas={}
+ for i=1,nofregions do
+ usedregions[i]=regions[readushort(f)+1]
+ end
+ for i=1,nofdeltasets do
+ local t=readintegertable(f,nofshorts,short)
+ for i=nofshorts+1,nofregions do
+ t[i]=readinteger(f)
+ end
+ deltas[i]=t
+ end
+ deltadata[i]={
+ regions=usedregions,
+ deltas=deltas,
+ scales=factors and getscales(usedregions,factors) or nil,
+ }
+ end
+ end
+ setposition(f,position)
+ return regions,deltadata
end
helpers.readvariationdata=readvariationdata
local function readcoverage(f,offset,simple)
- setposition(f,offset)
- local coverageformat=readushort(f)
- if coverageformat==1 then
- local nofcoverage=readushort(f)
- if simple then
- if nofcoverage==1 then
- return { readushort(f) }
- elseif nofcoverage==2 then
- return { readushort(f),readushort(f) }
- else
- return readcardinaltable(f,nofcoverage,ushort)
- end
- elseif nofcoverage==1 then
- return { [readushort(f)]=0 }
- elseif nofcoverage==2 then
- return { [readushort(f)]=0,[readushort(f)]=1 }
- else
- local coverage={}
- for i=0,nofcoverage-1 do
- coverage[readushort(f)]=i
- end
- return coverage
- end
- elseif coverageformat==2 then
- local nofranges=readushort(f)
- local coverage={}
- local n=simple and 1 or 0
- for i=1,nofranges do
- local firstindex=readushort(f)
- local lastindex=readushort(f)
- local coverindex=readushort(f)
- if simple then
- for i=firstindex,lastindex do
- coverage[n]=i
- n=n+1
- end
- else
- for i=firstindex,lastindex do
- coverage[i]=n
- n=n+1
- end
- end
- end
- return coverage
+ setposition(f,offset)
+ local coverageformat=readushort(f)
+ if coverageformat==1 then
+ local nofcoverage=readushort(f)
+ if simple then
+ if nofcoverage==1 then
+ return { readushort(f) }
+ elseif nofcoverage==2 then
+ return { readushort(f),readushort(f) }
+ else
+ return readcardinaltable(f,nofcoverage,ushort)
+ end
+ elseif nofcoverage==1 then
+ return { [readushort(f)]=0 }
+ elseif nofcoverage==2 then
+ return { [readushort(f)]=0,[readushort(f)]=1 }
else
- report("unknown coverage format %a ",coverageformat)
- return {}
- end
+ local coverage={}
+ for i=0,nofcoverage-1 do
+ coverage[readushort(f)]=i
+ end
+ return coverage
+ end
+ elseif coverageformat==2 then
+ local nofranges=readushort(f)
+ local coverage={}
+ local n=simple and 1 or 0
+ for i=1,nofranges do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local coverindex=readushort(f)
+ if simple then
+ for i=firstindex,lastindex do
+ coverage[n]=i
+ n=n+1
+ end
+ else
+ for i=firstindex,lastindex do
+ coverage[i]=n
+ n=n+1
+ end
+ end
+ end
+ return coverage
+ else
+ report("unknown coverage format %a ",coverageformat)
+ return {}
+ end
end
local function readclassdef(f,offset,preset)
- setposition(f,offset)
- local classdefformat=readushort(f)
- local classdef={}
- if type(preset)=="number" then
- for k=0,preset-1 do
- classdef[k]=1
- end
- end
- if classdefformat==1 then
- local index=readushort(f)
- local nofclassdef=readushort(f)
- for i=1,nofclassdef do
- classdef[index]=readushort(f)+1
- index=index+1
- end
- elseif classdefformat==2 then
- local nofranges=readushort(f)
- local n=0
- for i=1,nofranges do
- local firstindex=readushort(f)
- local lastindex=readushort(f)
- local class=readushort(f)+1
- for i=firstindex,lastindex do
- classdef[i]=class
- end
- end
- else
- report("unknown classdef format %a ",classdefformat)
- end
- if type(preset)=="table" then
- for k in next,preset do
- if not classdef[k] then
- classdef[k]=1
- end
- end
- end
- return classdef
+ setposition(f,offset)
+ local classdefformat=readushort(f)
+ local classdef={}
+ if type(preset)=="number" then
+ for k=0,preset-1 do
+ classdef[k]=1
+ end
+ end
+ if classdefformat==1 then
+ local index=readushort(f)
+ local nofclassdef=readushort(f)
+ for i=1,nofclassdef do
+ classdef[index]=readushort(f)+1
+ index=index+1
+ end
+ elseif classdefformat==2 then
+ local nofranges=readushort(f)
+ local n=0
+ for i=1,nofranges do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local class=readushort(f)+1
+ for i=firstindex,lastindex do
+ classdef[i]=class
+ end
+ end
+ else
+ report("unknown classdef format %a ",classdefformat)
+ end
+ if type(preset)=="table" then
+ for k in next,preset do
+ if not classdef[k] then
+ classdef[k]=1
+ end
+ end
+ end
+ return classdef
end
local function classtocoverage(defs)
- if defs then
- local list={}
- for index,class in next,defs do
- local c=list[class]
- if c then
- c[#c+1]=index
- else
- list[class]={ index }
- end
- end
- return list
- end
+ if defs then
+ local list={}
+ for index,class in next,defs do
+ local c=list[class]
+ if c then
+ c[#c+1]=index
+ else
+ list[class]={ index }
+ end
+ end
+ return list
+ end
end
local skips={ [0]=0,
- 1,
- 1,
- 2,
- 1,
- 2,
- 2,
- 3,
- 2,
- 2,
- 3,
- 2,
- 3,
- 3,
- 4,
+ 1,
+ 1,
+ 2,
+ 1,
+ 2,
+ 2,
+ 3,
+ 2,
+ 2,
+ 3,
+ 2,
+ 3,
+ 3,
+ 4,
}
local function readvariation(f,offset)
- local p=getposition(f)
- setposition(f,offset)
- local outer=readushort(f)
- local inner=readushort(f)
- local format=readushort(f)
- setposition(f,p)
- if format==0x8000 then
- return outer,inner
- end
+ local p=getposition(f)
+ setposition(f,offset)
+ local outer=readushort(f)
+ local inner=readushort(f)
+ local format=readushort(f)
+ setposition(f,p)
+ if format==0x8000 then
+ return outer,inner
+ end
end
local function readposition(f,format,mainoffset,getdelta)
- if format==0 then
- return false
- end
- if format==0x04 then
- local h=readshort(f)
- if h==0 then
- return true
- else
- return { 0,0,h,0 }
- end
- end
- if format==0x05 then
- local x=readshort(f)
- local h=readshort(f)
- if x==0 and h==0 then
- return true
- else
- return { x,0,h,0 }
- end
+ if format==0 then
+ return false
+ end
+ if format==0x04 then
+ local h=readshort(f)
+ if h==0 then
+ return true
+ else
+ return { 0,0,h,0 }
end
- if format==0x44 then
- local h=readshort(f)
- if getdelta then
- local d=readshort(f)
- if d>0 then
- local outer,inner=readvariation(f,mainoffset+d)
- if outer then
- h=h+getdelta(outer,inner)
- end
- end
- else
- skipshort(f,1)
- end
- if h==0 then
- return true
- else
- return { 0,0,h,0 }
- end
- end
- local x=band(format,0x1)~=0 and readshort(f) or 0
- local y=band(format,0x2)~=0 and readshort(f) or 0
- local h=band(format,0x4)~=0 and readshort(f) or 0
- local v=band(format,0x8)~=0 and readshort(f) or 0
- if format>=0x10 then
- local X=band(format,0x10)~=0 and skipshort(f) or 0
- local Y=band(format,0x20)~=0 and skipshort(f) or 0
- local H=band(format,0x40)~=0 and skipshort(f) or 0
- local V=band(format,0x80)~=0 and skipshort(f) or 0
- local s=skips[extract(format,4,4)]
- if s>0 then
- skipshort(f,s)
- end
- if getdelta then
- if X>0 then
- local outer,inner=readvariation(f,mainoffset+X)
- if outer then
- x=x+getdelta(outer,inner)
- end
- end
- if Y>0 then
- local outer,inner=readvariation(f,mainoffset+Y)
- if outer then
- y=y+getdelta(outer,inner)
- end
- end
- if H>0 then
- local outer,inner=readvariation(f,mainoffset+H)
- if outer then
- h=h+getdelta(outer,inner)
- end
- end
- if V>0 then
- local outer,inner=readvariation(f,mainoffset+V)
- if outer then
- v=v+getdelta(outer,inner)
- end
- end
- end
- return { x,y,h,v }
- elseif x==0 and y==0 and h==0 and v==0 then
- return true
+ end
+ if format==0x05 then
+ local x=readshort(f)
+ local h=readshort(f)
+ if x==0 and h==0 then
+ return true
else
- return { x,y,h,v }
+ return { x,0,h,0 }
+ end
+ end
+ if format==0x44 then
+ local h=readshort(f)
+ if getdelta then
+ local d=readshort(f)
+ if d>0 then
+ local outer,inner=readvariation(f,mainoffset+d)
+ if outer then
+ h=h+getdelta(outer,inner)
+ end
+ end
+ else
+ skipshort(f,1)
end
+ if h==0 then
+ return true
+ else
+ return { 0,0,h,0 }
+ end
+ end
+ local x=band(format,0x1)~=0 and readshort(f) or 0
+ local y=band(format,0x2)~=0 and readshort(f) or 0
+ local h=band(format,0x4)~=0 and readshort(f) or 0
+ local v=band(format,0x8)~=0 and readshort(f) or 0
+ if format>=0x10 then
+ local X=band(format,0x10)~=0 and skipshort(f) or 0
+ local Y=band(format,0x20)~=0 and skipshort(f) or 0
+ local H=band(format,0x40)~=0 and skipshort(f) or 0
+ local V=band(format,0x80)~=0 and skipshort(f) or 0
+ local s=skips[extract(format,4,4)]
+ if s>0 then
+ skipshort(f,s)
+ end
+ if getdelta then
+ if X>0 then
+ local outer,inner=readvariation(f,mainoffset+X)
+ if outer then
+ x=x+getdelta(outer,inner)
+ end
+ end
+ if Y>0 then
+ local outer,inner=readvariation(f,mainoffset+Y)
+ if outer then
+ y=y+getdelta(outer,inner)
+ end
+ end
+ if H>0 then
+ local outer,inner=readvariation(f,mainoffset+H)
+ if outer then
+ h=h+getdelta(outer,inner)
+ end
+ end
+ if V>0 then
+ local outer,inner=readvariation(f,mainoffset+V)
+ if outer then
+ v=v+getdelta(outer,inner)
+ end
+ end
+ end
+ return { x,y,h,v }
+ elseif x==0 and y==0 and h==0 and v==0 then
+ return true
+ else
+ return { x,y,h,v }
+ end
end
local function readanchor(f,offset,getdelta)
- if not offset or offset==0 then
- return nil
- end
- setposition(f,offset)
- local format=readshort(f)
- local x=readshort(f)
- local y=readshort(f)
- if format==3 then
- if getdelta then
- local X=readshort(f)
- local Y=readshort(f)
- if X>0 then
- local outer,inner=readvariation(f,offset+X)
- if outer then
- x=x+getdelta(outer,inner)
- end
- end
- if Y>0 then
- local outer,inner=readvariation(f,offset+Y)
- if outer then
- y=y+getdelta(outer,inner)
- end
- end
- else
- skipshort(f,2)
- end
- return { x,y }
+ if not offset or offset==0 then
+ return nil
+ end
+ setposition(f,offset)
+ local format=readshort(f)
+ local x=readshort(f)
+ local y=readshort(f)
+ if format==3 then
+ if getdelta then
+ local X=readshort(f)
+ local Y=readshort(f)
+ if X>0 then
+ local outer,inner=readvariation(f,offset+X)
+ if outer then
+ x=x+getdelta(outer,inner)
+ end
+ end
+ if Y>0 then
+ local outer,inner=readvariation(f,offset+Y)
+ if outer then
+ y=y+getdelta(outer,inner)
+ end
+ end
else
- return { x,y }
+ skipshort(f,2)
end
+ return { x,y }
+ else
+ return { x,y }
+ end
end
local function readfirst(f,offset)
- if offset then
- setposition(f,offset)
- end
- return { readushort(f) }
+ if offset then
+ setposition(f,offset)
+ end
+ return { readushort(f) }
end
function readarray(f,offset)
- if offset then
- setposition(f,offset)
- end
- local n=readushort(f)
- if n==1 then
- return { readushort(f) },1
- elseif n>0 then
- return readcardinaltable(f,n,ushort),n
- end
+ if offset then
+ setposition(f,offset)
+ end
+ local n=readushort(f)
+ if n==1 then
+ return { readushort(f) },1
+ elseif n>0 then
+ return readcardinaltable(f,n,ushort),n
+ end
end
local function readcoveragearray(f,offset,t,simple)
- if not t then
- return nil
- end
- local n=#t
- if n==0 then
- return nil
- end
- for i=1,n do
- t[i]=readcoverage(f,offset+t[i],simple)
- end
- return t
+ if not t then
+ return nil
+ end
+ local n=#t
+ if n==0 then
+ return nil
+ end
+ for i=1,n do
+ t[i]=readcoverage(f,offset+t[i],simple)
+ end
+ return t
end
local function covered(subset,all)
- local used,u
- for i=1,#subset do
- local s=subset[i]
- if all[s] then
- if used then
- u=u+1
- used[u]=s
- else
- u=1
- used={ s }
- end
- end
- end
- return used
+ local used,u
+ for i=1,#subset do
+ local s=subset[i]
+ if all[s] then
+ if used then
+ u=u+1
+ used[u]=s
+ else
+ u=1
+ used={ s }
+ end
+ end
+ end
+ return used
end
local function readlookuparray(f,noflookups,nofcurrent)
- local lookups={}
- if noflookups>0 then
- local length=0
- for i=1,noflookups do
- local index=readushort(f)+1
- if index>length then
- length=index
- end
- local lookup=readushort(f)+1
- local list=lookups[index]
- if list then
- list[#list+1]=lookup
- else
- lookups[index]={ lookup }
- end
- end
- for index=1,length do
- if not lookups[index] then
- lookups[index]=false
- end
- end
- end
- return lookups
+ local lookups={}
+ if noflookups>0 then
+ local length=0
+ for i=1,noflookups do
+ local index=readushort(f)+1
+ if index>length then
+ length=index
+ end
+ local lookup=readushort(f)+1
+ local list=lookups[index]
+ if list then
+ list[#list+1]=lookup
+ else
+ lookups[index]={ lookup }
+ end
+ end
+ for index=1,length do
+ if not lookups[index] then
+ lookups[index]=false
+ end
+ end
+ end
+ return lookups
end
local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
- local tableoffset=lookupoffset+offset
- setposition(f,tableoffset)
- local subtype=readushort(f)
- if subtype==1 then
- local coverage=readushort(f)
- local subclasssets=readarray(f)
- local rules={}
- if subclasssets then
- coverage=readcoverage(f,tableoffset+coverage,true)
- for i=1,#subclasssets do
- local offset=subclasssets[i]
- if offset>0 then
- local firstcoverage=coverage[i]
- local rulesoffset=tableoffset+offset
- local subclassrules=readarray(f,rulesoffset)
- for rule=1,#subclassrules do
- setposition(f,rulesoffset+subclassrules[rule])
- local nofcurrent=readushort(f)
- local noflookups=readushort(f)
- local current={ { firstcoverage } }
- for i=2,nofcurrent do
- current[i]={ readushort(f) }
- end
- local lookups=readlookuparray(f,noflookups,nofcurrent)
- rules[#rules+1]={
- current=current,
- lookups=lookups
- }
- end
- end
- end
- else
- report("empty subclassset in %a subtype %i","unchainedcontext",subtype)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local subclasssets=readarray(f)
+ local rules={}
+ if subclasssets then
+ coverage=readcoverage(f,tableoffset+coverage,true)
+ for i=1,#subclasssets do
+ local offset=subclasssets[i]
+ if offset>0 then
+ local firstcoverage=coverage[i]
+ local rulesoffset=tableoffset+offset
+ local subclassrules=readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset+subclassrules[rule])
+ local nofcurrent=readushort(f)
+ local noflookups=readushort(f)
+ local current={ { firstcoverage } }
+ for i=2,nofcurrent do
+ current[i]={ readushort(f) }
+ end
+ local lookups=readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1]={
+ current=current,
+ lookups=lookups
+ }
+ end
end
- return {
- format="glyphs",
- rules=rules,
- }
- elseif subtype==2 then
- local coverage=readushort(f)
- local currentclassdef=readushort(f)
- local subclasssets=readarray(f)
- local rules={}
- if subclasssets then
- coverage=readcoverage(f,tableoffset+coverage)
- currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage)
- local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs)
- for class=1,#subclasssets do
- local offset=subclasssets[class]
- if offset>0 then
- local firstcoverage=currentclasses[class]
- if firstcoverage then
- firstcoverage=covered(firstcoverage,coverage)
- if firstcoverage then
- local rulesoffset=tableoffset+offset
- local subclassrules=readarray(f,rulesoffset)
- for rule=1,#subclassrules do
- setposition(f,rulesoffset+subclassrules[rule])
- local nofcurrent=readushort(f)
- local noflookups=readushort(f)
- local current={ firstcoverage }
- for i=2,nofcurrent do
- current[i]=currentclasses[readushort(f)+1]
- end
- local lookups=readlookuparray(f,noflookups,nofcurrent)
- rules[#rules+1]={
- current=current,
- lookups=lookups
- }
- end
- else
- report("no coverage")
- end
- else
- report("no coverage class")
- end
- end
+ end
+ else
+ report("empty subclassset in %a subtype %i","unchainedcontext",subtype)
+ end
+ return {
+ format="glyphs",
+ rules=rules,
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local currentclassdef=readushort(f)
+ local subclasssets=readarray(f)
+ local rules={}
+ if subclasssets then
+ coverage=readcoverage(f,tableoffset+coverage)
+ currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage)
+ local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs)
+ for class=1,#subclasssets do
+ local offset=subclasssets[class]
+ if offset>0 then
+ local firstcoverage=currentclasses[class]
+ if firstcoverage then
+ firstcoverage=covered(firstcoverage,coverage)
+ if firstcoverage then
+ local rulesoffset=tableoffset+offset
+ local subclassrules=readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset+subclassrules[rule])
+ local nofcurrent=readushort(f)
+ local noflookups=readushort(f)
+ local current={ firstcoverage }
+ for i=2,nofcurrent do
+ current[i]=currentclasses[readushort(f)+1]
+ end
+ local lookups=readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1]={
+ current=current,
+ lookups=lookups
+ }
+ end
+ else
+ report("no coverage")
end
- else
- report("empty subclassset in %a subtype %i","unchainedcontext",subtype)
+ else
+ report("no coverage class")
+ end
end
- return {
- format="class",
- rules=rules,
- }
- elseif subtype==3 then
- local nofglyphs=readushort(f)
- local noflookups=readushort(f)
- local current=readcardinaltable(f,nofglyphs,ushort)
- local lookups=readlookuparray(f,noflookups,#current)
- current=readcoveragearray(f,tableoffset,current,true)
- return {
- format="coverage",
- rules={
- {
- current=current,
- lookups=lookups,
- }
- }
- }
+ end
else
- report("unsupported subtype %a in %a %s",subtype,"unchainedcontext",what)
+ report("empty subclassset in %a subtype %i","unchainedcontext",subtype)
end
+ return {
+ format="class",
+ rules=rules,
+ }
+ elseif subtype==3 then
+ local nofglyphs=readushort(f)
+ local noflookups=readushort(f)
+ local current=readcardinaltable(f,nofglyphs,ushort)
+ local lookups=readlookuparray(f,noflookups,#current)
+ current=readcoveragearray(f,tableoffset,current,true)
+ return {
+ format="coverage",
+ rules={
+ {
+ current=current,
+ lookups=lookups,
+ }
+ }
+ }
+ else
+ report("unsupported subtype %a in %a %s",subtype,"unchainedcontext",what)
+ end
end
local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
- local tableoffset=lookupoffset+offset
- setposition(f,tableoffset)
- local subtype=readushort(f)
- if subtype==1 then
- local coverage=readushort(f)
- local subclasssets=readarray(f)
- local rules={}
- if subclasssets then
- coverage=readcoverage(f,tableoffset+coverage,true)
- for i=1,#subclasssets do
- local offset=subclasssets[i]
- if offset>0 then
- local firstcoverage=coverage[i]
- local rulesoffset=tableoffset+offset
- local subclassrules=readarray(f,rulesoffset)
- for rule=1,#subclassrules do
- setposition(f,rulesoffset+subclassrules[rule])
- local nofbefore=readushort(f)
- local before
- if nofbefore>0 then
- before={}
- for i=1,nofbefore do
- before[i]={ readushort(f) }
- end
- end
- local nofcurrent=readushort(f)
- local current={ { firstcoverage } }
- for i=2,nofcurrent do
- current[i]={ readushort(f) }
- end
- local nofafter=readushort(f)
- local after
- if nofafter>0 then
- after={}
- for i=1,nofafter do
- after[i]={ readushort(f) }
- end
- end
- local noflookups=readushort(f)
- local lookups=readlookuparray(f,noflookups,nofcurrent)
- rules[#rules+1]={
- before=before,
- current=current,
- after=after,
- lookups=lookups,
- }
- end
- end
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local subclasssets=readarray(f)
+ local rules={}
+ if subclasssets then
+ coverage=readcoverage(f,tableoffset+coverage,true)
+ for i=1,#subclasssets do
+ local offset=subclasssets[i]
+ if offset>0 then
+ local firstcoverage=coverage[i]
+ local rulesoffset=tableoffset+offset
+ local subclassrules=readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset+subclassrules[rule])
+ local nofbefore=readushort(f)
+ local before
+ if nofbefore>0 then
+ before={}
+ for i=1,nofbefore do
+ before[i]={ readushort(f) }
+ end
end
- else
- report("empty subclassset in %a subtype %i","chainedcontext",subtype)
- end
- return {
- format="glyphs",
- rules=rules,
- }
- elseif subtype==2 then
- local coverage=readushort(f)
- local beforeclassdef=readushort(f)
- local currentclassdef=readushort(f)
- local afterclassdef=readushort(f)
- local subclasssets=readarray(f)
- local rules={}
- if subclasssets then
- local coverage=readcoverage(f,tableoffset+coverage)
- local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef,nofglyphs)
- local currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage)
- local afterclassdef=readclassdef(f,tableoffset+afterclassdef,nofglyphs)
- local beforeclasses=classtocoverage(beforeclassdef,fontdata.glyphs)
- local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs)
- local afterclasses=classtocoverage(afterclassdef,fontdata.glyphs)
- for class=1,#subclasssets do
- local offset=subclasssets[class]
- if offset>0 then
- local firstcoverage=currentclasses[class]
- if firstcoverage then
- firstcoverage=covered(firstcoverage,coverage)
- if firstcoverage then
- local rulesoffset=tableoffset+offset
- local subclassrules=readarray(f,rulesoffset)
- for rule=1,#subclassrules do
- setposition(f,rulesoffset+subclassrules[rule])
- local nofbefore=readushort(f)
- local before
- if nofbefore>0 then
- before={}
- for i=1,nofbefore do
- before[i]=beforeclasses[readushort(f)+1]
- end
- end
- local nofcurrent=readushort(f)
- local current={ firstcoverage }
- for i=2,nofcurrent do
- current[i]=currentclasses[readushort(f)+1]
- end
- local nofafter=readushort(f)
- local after
- if nofafter>0 then
- after={}
- for i=1,nofafter do
- after[i]=afterclasses[readushort(f)+1]
- end
- end
- local noflookups=readushort(f)
- local lookups=readlookuparray(f,noflookups,nofcurrent)
- rules[#rules+1]={
- before=before,
- current=current,
- after=after,
- lookups=lookups,
- }
- end
- else
- report("no coverage")
- end
- else
- report("class is not covered")
- end
- end
+ local nofcurrent=readushort(f)
+ local current={ { firstcoverage } }
+ for i=2,nofcurrent do
+ current[i]={ readushort(f) }
+ end
+ local nofafter=readushort(f)
+ local after
+ if nofafter>0 then
+ after={}
+ for i=1,nofafter do
+ after[i]={ readushort(f) }
+ end
end
- else
- report("empty subclassset in %a subtype %i","chainedcontext",subtype)
+ local noflookups=readushort(f)
+ local lookups=readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1]={
+ before=before,
+ current=current,
+ after=after,
+ lookups=lookups,
+ }
+ end
end
- return {
- format="class",
- rules=rules,
- }
- elseif subtype==3 then
- local before=readarray(f)
- local current=readarray(f)
- local after=readarray(f)
- local noflookups=readushort(f)
- local lookups=readlookuparray(f,noflookups,#current)
- before=readcoveragearray(f,tableoffset,before,true)
- current=readcoveragearray(f,tableoffset,current,true)
- after=readcoveragearray(f,tableoffset,after,true)
- return {
- format="coverage",
- rules={
- {
- before=before,
- current=current,
- after=after,
- lookups=lookups,
+ end
+ else
+ report("empty subclassset in %a subtype %i","chainedcontext",subtype)
+ end
+ return {
+ format="glyphs",
+ rules=rules,
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local beforeclassdef=readushort(f)
+ local currentclassdef=readushort(f)
+ local afterclassdef=readushort(f)
+ local subclasssets=readarray(f)
+ local rules={}
+ if subclasssets then
+ local coverage=readcoverage(f,tableoffset+coverage)
+ local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef,nofglyphs)
+ local currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage)
+ local afterclassdef=readclassdef(f,tableoffset+afterclassdef,nofglyphs)
+ local beforeclasses=classtocoverage(beforeclassdef,fontdata.glyphs)
+ local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs)
+ local afterclasses=classtocoverage(afterclassdef,fontdata.glyphs)
+ for class=1,#subclasssets do
+ local offset=subclasssets[class]
+ if offset>0 then
+ local firstcoverage=currentclasses[class]
+ if firstcoverage then
+ firstcoverage=covered(firstcoverage,coverage)
+ if firstcoverage then
+ local rulesoffset=tableoffset+offset
+ local subclassrules=readarray(f,rulesoffset)
+ for rule=1,#subclassrules do
+ setposition(f,rulesoffset+subclassrules[rule])
+ local nofbefore=readushort(f)
+ local before
+ if nofbefore>0 then
+ before={}
+ for i=1,nofbefore do
+ before[i]=beforeclasses[readushort(f)+1]
+ end
+ end
+ local nofcurrent=readushort(f)
+ local current={ firstcoverage }
+ for i=2,nofcurrent do
+ current[i]=currentclasses[readushort(f)+1]
+ end
+ local nofafter=readushort(f)
+ local after
+ if nofafter>0 then
+ after={}
+ for i=1,nofafter do
+ after[i]=afterclasses[readushort(f)+1]
+ end
+ end
+ local noflookups=readushort(f)
+ local lookups=readlookuparray(f,noflookups,nofcurrent)
+ rules[#rules+1]={
+ before=before,
+ current=current,
+ after=after,
+ lookups=lookups,
}
- }
- }
+ end
+ else
+ report("no coverage")
+ end
+ else
+ report("class is not covered")
+ end
+ end
+ end
else
- report("unsupported subtype %a in %a %s",subtype,"chainedcontext",what)
+ report("empty subclassset in %a subtype %i","chainedcontext",subtype)
end
+ return {
+ format="class",
+ rules=rules,
+ }
+ elseif subtype==3 then
+ local before=readarray(f)
+ local current=readarray(f)
+ local after=readarray(f)
+ local noflookups=readushort(f)
+ local lookups=readlookuparray(f,noflookups,#current)
+ before=readcoveragearray(f,tableoffset,before,true)
+ current=readcoveragearray(f,tableoffset,current,true)
+ after=readcoveragearray(f,tableoffset,after,true)
+ return {
+ format="coverage",
+ rules={
+ {
+ before=before,
+ current=current,
+ after=after,
+ lookups=lookups,
+ }
+ }
+ }
+ else
+ report("unsupported subtype %a in %a %s",subtype,"chainedcontext",what)
+ end
end
local function extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,types,handlers,what)
- local tableoffset=lookupoffset+offset
- setposition(f,tableoffset)
- local subtype=readushort(f)
- if subtype==1 then
- local lookuptype=types[readushort(f)]
- local faroffset=readulong(f)
- local handler=handlers[lookuptype]
- if handler then
- return handler(f,fontdata,lookupid,tableoffset+faroffset,0,glyphs,nofglyphs),lookuptype
- else
- report("no handler for lookuptype %a subtype %a in %s %s",lookuptype,subtype,what,"extension")
- end
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local lookuptype=types[readushort(f)]
+ local faroffset=readulong(f)
+ local handler=handlers[lookuptype]
+ if handler then
+ return handler(f,fontdata,lookupid,tableoffset+faroffset,0,glyphs,nofglyphs),lookuptype
else
- report("unsupported subtype %a in %s %s",subtype,what,"extension")
+ report("no handler for lookuptype %a subtype %a in %s %s",lookuptype,subtype,what,"extension")
end
+ else
+ report("unsupported subtype %a in %s %s",subtype,what,"extension")
+ end
end
function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- local tableoffset=lookupoffset+offset
- setposition(f,tableoffset)
- local subtype=readushort(f)
- if subtype==1 then
- local coverage=readushort(f)
- local delta=readshort(f)
- local coverage=readcoverage(f,tableoffset+coverage)
- for index in next,coverage do
- local newindex=(index+delta)%65536
- if index>nofglyphs or newindex>nofglyphs then
- report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs)
- coverage[index]=nil
- else
- coverage[index]=newindex
- end
- end
- return {
- coverage=coverage
- }
- elseif subtype==2 then
- local coverage=readushort(f)
- local nofreplacements=readushort(f)
- local replacements=readcardinaltable(f,nofreplacements,ushort)
- local coverage=readcoverage(f,tableoffset+coverage)
- for index,newindex in next,coverage do
- newindex=newindex+1
- if index>nofglyphs or newindex>nofglyphs then
- report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs)
- coverage[index]=nil
- else
- coverage[index]=replacements[newindex]
- end
- end
- return {
- coverage=coverage
- }
- else
- report("unsupported subtype %a in %a substitution",subtype,"single")
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local delta=readshort(f)
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index in next,coverage do
+ local newindex=(index+delta)%65536
+ if index>nofglyphs or newindex>nofglyphs then
+ report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs)
+ coverage[index]=nil
+ else
+ coverage[index]=newindex
+ end
end
+ return {
+ coverage=coverage
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local nofreplacements=readushort(f)
+ local replacements=readcardinaltable(f,nofreplacements,ushort)
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ newindex=newindex+1
+ if index>nofglyphs or newindex>nofglyphs then
+ report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs)
+ coverage[index]=nil
+ else
+ coverage[index]=replacements[newindex]
+ end
+ end
+ return {
+ coverage=coverage
+ }
+ else
+ report("unsupported subtype %a in %a substitution",subtype,"single")
+ end
end
local function sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what)
- local tableoffset=lookupoffset+offset
- setposition(f,tableoffset)
- local subtype=readushort(f)
- if subtype==1 then
- local coverage=readushort(f)
- local nofsequence=readushort(f)
- local sequences=readcardinaltable(f,nofsequence,ushort)
- for i=1,nofsequence do
- setposition(f,tableoffset+sequences[i])
- sequences[i]=readcardinaltable(f,readushort(f),ushort)
- end
- local coverage=readcoverage(f,tableoffset+coverage)
- for index,newindex in next,coverage do
- newindex=newindex+1
- if index>nofglyphs or newindex>nofglyphs then
- report("invalid index in %s format %i: %i -> %i (max %i)",what,subtype,index,newindex,nofglyphs)
- coverage[index]=nil
- else
- coverage[index]=sequences[newindex]
- end
- end
- return {
- coverage=coverage
- }
- else
- report("unsupported subtype %a in %a substitution",subtype,what)
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local nofsequence=readushort(f)
+ local sequences=readcardinaltable(f,nofsequence,ushort)
+ for i=1,nofsequence do
+ setposition(f,tableoffset+sequences[i])
+ sequences[i]=readcardinaltable(f,readushort(f),ushort)
+ end
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ newindex=newindex+1
+ if index>nofglyphs or newindex>nofglyphs then
+ report("invalid index in %s format %i: %i -> %i (max %i)",what,subtype,index,newindex,nofglyphs)
+ coverage[index]=nil
+ else
+ coverage[index]=sequences[newindex]
+ end
end
+ return {
+ coverage=coverage
+ }
+ else
+ report("unsupported subtype %a in %a substitution",subtype,what)
+ end
end
function gsubhandlers.multiple(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"multiple")
+ return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"multiple")
end
function gsubhandlers.alternate(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"alternate")
+ return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"alternate")
end
function gsubhandlers.ligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- local tableoffset=lookupoffset+offset
- setposition(f,tableoffset)
- local subtype=readushort(f)
- if subtype==1 then
- local coverage=readushort(f)
- local nofsets=readushort(f)
- local ligatures=readcardinaltable(f,nofsets,ushort)
- for i=1,nofsets do
- local offset=lookupoffset+offset+ligatures[i]
- setposition(f,offset)
- local n=readushort(f)
- if n==1 then
- ligatures[i]={ offset+readushort(f) }
- else
- local l={}
- for i=1,n do
- l[i]=offset+readushort(f)
- end
- ligatures[i]=l
- end
- end
- local coverage=readcoverage(f,tableoffset+coverage)
- for index,newindex in next,coverage do
- local hash={}
- local ligatures=ligatures[newindex+1]
- for i=1,#ligatures do
- local offset=ligatures[i]
- setposition(f,offset)
- local lig=readushort(f)
- local cnt=readushort(f)
- local hsh=hash
- for i=2,cnt do
- local c=readushort(f)
- local h=hsh[c]
- if not h then
- h={}
- hsh[c]=h
- end
- hsh=h
- end
- hsh.ligature=lig
- end
- coverage[index]=hash
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local coverage=readushort(f)
+ local nofsets=readushort(f)
+ local ligatures=readcardinaltable(f,nofsets,ushort)
+ for i=1,nofsets do
+ local offset=lookupoffset+offset+ligatures[i]
+ setposition(f,offset)
+ local n=readushort(f)
+ if n==1 then
+ ligatures[i]={ offset+readushort(f) }
+ else
+ local l={}
+ for i=1,n do
+ l[i]=offset+readushort(f)
end
- return {
- coverage=coverage
- }
- else
- report("unsupported subtype %a in %a substitution",subtype,"ligature")
+ ligatures[i]=l
+ end
end
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ local hash={}
+ local ligatures=ligatures[newindex+1]
+ for i=1,#ligatures do
+ local offset=ligatures[i]
+ setposition(f,offset)
+ local lig=readushort(f)
+ local cnt=readushort(f)
+ local hsh=hash
+ for i=2,cnt do
+ local c=readushort(f)
+ local h=hsh[c]
+ if not h then
+ h={}
+ hsh[c]=h
+ end
+ hsh=h
+ end
+ hsh.ligature=lig
+ end
+ coverage[index]=hash
+ end
+ return {
+ coverage=coverage
+ }
+ else
+ report("unsupported subtype %a in %a substitution",subtype,"ligature")
+ end
end
function gsubhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"context"
+ return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"context"
end
function gsubhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"chainedcontext"
+ return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"chainedcontext"
end
function gsubhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gsubtypes,gsubhandlers,"substitution")
+ return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gsubtypes,gsubhandlers,"substitution")
end
function gsubhandlers.reversechainedcontextsingle(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- local tableoffset=lookupoffset+offset
- setposition(f,tableoffset)
- local subtype=readushort(f)
- if subtype==1 then
- local current=readfirst(f)
- local before=readarray(f)
- local after=readarray(f)
- local replacements=readarray(f)
- current=readcoveragearray(f,tableoffset,current,true)
- before=readcoveragearray(f,tableoffset,before,true)
- after=readcoveragearray(f,tableoffset,after,true)
- return {
- format="reversecoverage",
- rules={
- {
- before=before,
- current=current,
- after=after,
- replacements=replacements,
- }
- }
- },"reversechainedcontextsingle"
- else
- report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle")
- end
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ if subtype==1 then
+ local current=readfirst(f)
+ local before=readarray(f)
+ local after=readarray(f)
+ local replacements=readarray(f)
+ current=readcoveragearray(f,tableoffset,current,true)
+ before=readcoveragearray(f,tableoffset,before,true)
+ after=readcoveragearray(f,tableoffset,after,true)
+ return {
+ format="reversecoverage",
+ rules={
+ {
+ before=before,
+ current=current,
+ after=after,
+ replacements=replacements,
+ }
+ }
+ },"reversechainedcontextsingle"
+ else
+ report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle")
+ end
end
local function readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta)
- local done={}
- for i=1,#sets do
- local offset=sets[i]
- local reused=done[offset]
- if not reused then
- offset=tableoffset+offset
- setposition(f,offset)
- local n=readushort(f)
- reused={}
- for i=1,n do
- reused[i]={
- readushort(f),
- readposition(f,format1,offset,getdelta),
- readposition(f,format2,offset,getdelta),
- }
- end
- done[offset]=reused
- end
- sets[i]=reused
+ local done={}
+ for i=1,#sets do
+ local offset=sets[i]
+ local reused=done[offset]
+ if not reused then
+ offset=tableoffset+offset
+ setposition(f,offset)
+ local n=readushort(f)
+ reused={}
+ for i=1,n do
+ reused[i]={
+ readushort(f),
+ readposition(f,format1,offset,getdelta),
+ readposition(f,format2,offset,getdelta),
+ }
+ end
+ done[offset]=reused
end
- return sets
+ sets[i]=reused
+ end
+ return sets
end
local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,mainoffset,getdelta)
- local classlist1={}
- for i=1,nofclasses1 do
- local classlist2={}
- classlist1[i]=classlist2
- for j=1,nofclasses2 do
- local one=readposition(f,format1,mainoffset,getdelta)
- local two=readposition(f,format2,mainoffset,getdelta)
- if one or two then
- classlist2[j]={ one,two }
- else
- classlist2[j]=false
- end
- end
- end
- return classlist1
+ local classlist1={}
+ for i=1,nofclasses1 do
+ local classlist2={}
+ classlist1[i]=classlist2
+ for j=1,nofclasses2 do
+ local one=readposition(f,format1,mainoffset,getdelta)
+ local two=readposition(f,format2,mainoffset,getdelta)
+ if one or two then
+ classlist2[j]={ one,two }
+ else
+ classlist2[j]=false
+ end
+ end
+ end
+ return classlist1
end
function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- local tableoffset=lookupoffset+offset
- setposition(f,tableoffset)
- local subtype=readushort(f)
- local getdelta=fontdata.temporary.getdelta
- if subtype==1 then
- local coverage=readushort(f)
- local format=readushort(f)
- local value=readposition(f,format,tableoffset,getdelta)
- local coverage=readcoverage(f,tableoffset+coverage)
- for index,newindex in next,coverage do
- coverage[index]=value
- end
- return {
- format="single",
- coverage=coverage,
- }
- elseif subtype==2 then
- local coverage=readushort(f)
- local format=readushort(f)
- local nofvalues=readushort(f)
- local values={}
- for i=1,nofvalues do
- values[i]=readposition(f,format,tableoffset,getdelta)
- end
- local coverage=readcoverage(f,tableoffset+coverage)
- for index,newindex in next,coverage do
- coverage[index]=values[newindex+1]
- end
- return {
- format="single",
- coverage=coverage,
- }
- else
- report("unsupported subtype %a in %a positioning",subtype,"single")
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ local getdelta=fontdata.temporary.getdelta
+ if subtype==1 then
+ local coverage=readushort(f)
+ local format=readushort(f)
+ local value=readposition(f,format,tableoffset,getdelta)
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ coverage[index]=value
end
+ return {
+ format="single",
+ coverage=coverage,
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local format=readushort(f)
+ local nofvalues=readushort(f)
+ local values={}
+ for i=1,nofvalues do
+ values[i]=readposition(f,format,tableoffset,getdelta)
+ end
+ local coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ coverage[index]=values[newindex+1]
+ end
+ return {
+ format="single",
+ coverage=coverage,
+ }
+ else
+ report("unsupported subtype %a in %a positioning",subtype,"single")
+ end
end
function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- local tableoffset=lookupoffset+offset
- setposition(f,tableoffset)
- local subtype=readushort(f)
- local getdelta=fontdata.temporary.getdelta
- if subtype==1 then
- local coverage=readushort(f)
- local format1=readushort(f)
- local format2=readushort(f)
- local sets=readarray(f)
- sets=readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta)
- coverage=readcoverage(f,tableoffset+coverage)
- for index,newindex in next,coverage do
- local set=sets[newindex+1]
- local hash={}
- for i=1,#set do
- local value=set[i]
- if value then
- local other=value[1]
- local first=value[2]
- local second=value[3]
- if first or second then
- hash[other]={ first,second or nil }
- else
- hash[other]=nil
- end
- end
- end
- coverage[index]=hash
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ local getdelta=fontdata.temporary.getdelta
+ if subtype==1 then
+ local coverage=readushort(f)
+ local format1=readushort(f)
+ local format2=readushort(f)
+ local sets=readarray(f)
+ sets=readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta)
+ coverage=readcoverage(f,tableoffset+coverage)
+ for index,newindex in next,coverage do
+ local set=sets[newindex+1]
+ local hash={}
+ for i=1,#set do
+ local value=set[i]
+ if value then
+ local other=value[1]
+ local first=value[2]
+ local second=value[3]
+ if first or second then
+ hash[other]={ first,second or nil }
+ else
+ hash[other]=nil
+ end
end
- return {
- format="pair",
- coverage=coverage,
- }
- elseif subtype==2 then
- local coverage=readushort(f)
- local format1=readushort(f)
- local format2=readushort(f)
- local classdef1=readushort(f)
- local classdef2=readushort(f)
- local nofclasses1=readushort(f)
- local nofclasses2=readushort(f)
- local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta)
- coverage=readcoverage(f,tableoffset+coverage)
- classdef1=readclassdef(f,tableoffset+classdef1,coverage)
- classdef2=readclassdef(f,tableoffset+classdef2,nofglyphs)
- local usedcoverage={}
- for g1,c1 in next,classdef1 do
- if coverage[g1] then
- local l1=classlist[c1]
- if l1 then
- local hash={}
- for paired,class in next,classdef2 do
- local offsets=l1[class]
- if offsets then
- local first=offsets[1]
- local second=offsets[2]
- if first or second then
- hash[paired]={ first,second or nil }
- else
- end
- end
- end
- usedcoverage[g1]=hash
- end
+ end
+ coverage[index]=hash
+ end
+ return {
+ format="pair",
+ coverage=coverage,
+ }
+ elseif subtype==2 then
+ local coverage=readushort(f)
+ local format1=readushort(f)
+ local format2=readushort(f)
+ local classdef1=readushort(f)
+ local classdef2=readushort(f)
+ local nofclasses1=readushort(f)
+ local nofclasses2=readushort(f)
+ local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta)
+ coverage=readcoverage(f,tableoffset+coverage)
+ classdef1=readclassdef(f,tableoffset+classdef1,coverage)
+ classdef2=readclassdef(f,tableoffset+classdef2,nofglyphs)
+ local usedcoverage={}
+ for g1,c1 in next,classdef1 do
+ if coverage[g1] then
+ local l1=classlist[c1]
+ if l1 then
+ local hash={}
+ for paired,class in next,classdef2 do
+ local offsets=l1[class]
+ if offsets then
+ local first=offsets[1]
+ local second=offsets[2]
+ if first or second then
+ hash[paired]={ first,second or nil }
+ else
+ end
end
+ end
+ usedcoverage[g1]=hash
end
- return {
- format="pair",
- coverage=usedcoverage,
- }
- elseif subtype==3 then
- report("yet unsupported subtype %a in %a positioning",subtype,"pair")
- else
- report("unsupported subtype %a in %a positioning",subtype,"pair")
+ end
end
+ return {
+ format="pair",
+ coverage=usedcoverage,
+ }
+ elseif subtype==3 then
+ report("yet unsupported subtype %a in %a positioning",subtype,"pair")
+ else
+ report("unsupported subtype %a in %a positioning",subtype,"pair")
+ end
end
function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- local tableoffset=lookupoffset+offset
- setposition(f,tableoffset)
- local subtype=readushort(f)
- local getdelta=fontdata.temporary.getdelta
- if subtype==1 then
- local coverage=tableoffset+readushort(f)
- local nofrecords=readushort(f)
- local records={}
- for i=1,nofrecords do
- local entry=readushort(f)
- local exit=readushort(f)
- records[i]={
- entry~=0 and (tableoffset+entry) or false,
- exit~=0 and (tableoffset+exit ) or nil,
- }
- end
- local cc=(fontdata.temporary.cursivecount or 0)+1
- fontdata.temporary.cursivecount=cc
- cc="cc-"..cc
- coverage=readcoverage(f,coverage)
- for i=1,nofrecords do
- local r=records[i]
- records[i]={
- cc,
- readanchor(f,r[1],getdelta) or false,
- readanchor(f,r[2],getdelta) or nil,
- }
- end
- for index,newindex in next,coverage do
- coverage[index]=records[newindex+1]
- end
- return {
- coverage=coverage,
- }
- else
- report("unsupported subtype %a in %a positioning",subtype,"cursive")
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ local getdelta=fontdata.temporary.getdelta
+ if subtype==1 then
+ local coverage=tableoffset+readushort(f)
+ local nofrecords=readushort(f)
+ local records={}
+ for i=1,nofrecords do
+ local entry=readushort(f)
+ local exit=readushort(f)
+ records[i]={
+ entry~=0 and (tableoffset+entry) or false,
+ exit~=0 and (tableoffset+exit ) or nil,
+ }
+ end
+ local cc=(fontdata.temporary.cursivecount or 0)+1
+ fontdata.temporary.cursivecount=cc
+ cc="cc-"..cc
+ coverage=readcoverage(f,coverage)
+ for i=1,nofrecords do
+ local r=records[i]
+ records[i]={
+ cc,
+ readanchor(f,r[1],getdelta) or false,
+ readanchor(f,r[2],getdelta) or nil,
+ }
+ end
+ for index,newindex in next,coverage do
+ coverage[index]=records[newindex+1]
end
+ return {
+ coverage=coverage,
+ }
+ else
+ report("unsupported subtype %a in %a positioning",subtype,"cursive")
+ end
end
local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,ligature)
- local tableoffset=lookupoffset+offset
- setposition(f,tableoffset)
- local subtype=readushort(f)
- local getdelta=fontdata.temporary.getdelta
- if subtype==1 then
- local markcoverage=tableoffset+readushort(f)
- local basecoverage=tableoffset+readushort(f)
- local nofclasses=readushort(f)
- local markoffset=tableoffset+readushort(f)
- local baseoffset=tableoffset+readushort(f)
- local markcoverage=readcoverage(f,markcoverage)
- local basecoverage=readcoverage(f,basecoverage,true)
- setposition(f,markoffset)
- local markclasses={}
- local nofmarkclasses=readushort(f)
- local lastanchor=fontdata.lastanchor or 0
- local usedanchors={}
- for i=1,nofmarkclasses do
- local class=readushort(f)+1
- local offset=readushort(f)
- if offset==0 then
- markclasses[i]=false
- else
- markclasses[i]={ class,markoffset+offset }
- end
- usedanchors[class]=true
- end
- for i=1,nofmarkclasses do
- local mc=markclasses[i]
- if mc then
- mc[2]=readanchor(f,mc[2],getdelta)
- end
- end
- setposition(f,baseoffset)
- local nofbaserecords=readushort(f)
- local baserecords={}
- if ligature then
- for i=1,nofbaserecords do
- local offset=readushort(f)
- if offset==0 then
- baserecords[i]=false
- else
- baserecords[i]=baseoffset+offset
- end
- end
- for i=1,nofbaserecords do
- local recordoffset=baserecords[i]
- if recordoffset then
- setposition(f,recordoffset)
- local nofcomponents=readushort(f)
- local components={}
- for i=1,nofcomponents do
- local classes={}
- for i=1,nofclasses do
- local offset=readushort(f)
- if offset~=0 then
- classes[i]=recordoffset+offset
- else
- classes[i]=false
- end
- end
- components[i]=classes
- end
- baserecords[i]=components
- end
- end
- local baseclasses={}
- for i=1,nofclasses do
- baseclasses[i]={}
- end
- for i=1,nofbaserecords do
- local components=baserecords[i]
- if components then
- local b=basecoverage[i]
- for c=1,#components do
- local classes=components[c]
- if classes then
- for i=1,nofclasses do
- local anchor=readanchor(f,classes[i],getdelta)
- local bclass=baseclasses[i]
- local bentry=bclass[b]
- if bentry then
- bentry[c]=anchor
- else
- bclass[b]={ [c]=anchor }
- end
- end
- end
- end
- end
- end
- for index,newindex in next,markcoverage do
- markcoverage[index]=markclasses[newindex+1] or nil
- end
- return {
- format="ligature",
- baseclasses=baseclasses,
- coverage=markcoverage,
- }
+ local tableoffset=lookupoffset+offset
+ setposition(f,tableoffset)
+ local subtype=readushort(f)
+ local getdelta=fontdata.temporary.getdelta
+ if subtype==1 then
+ local markcoverage=tableoffset+readushort(f)
+ local basecoverage=tableoffset+readushort(f)
+ local nofclasses=readushort(f)
+ local markoffset=tableoffset+readushort(f)
+ local baseoffset=tableoffset+readushort(f)
+ local markcoverage=readcoverage(f,markcoverage)
+ local basecoverage=readcoverage(f,basecoverage,true)
+ setposition(f,markoffset)
+ local markclasses={}
+ local nofmarkclasses=readushort(f)
+ local lastanchor=fontdata.lastanchor or 0
+ local usedanchors={}
+ for i=1,nofmarkclasses do
+ local class=readushort(f)+1
+ local offset=readushort(f)
+ if offset==0 then
+ markclasses[i]=false
+ else
+ markclasses[i]={ class,markoffset+offset }
+ end
+ usedanchors[class]=true
+ end
+ for i=1,nofmarkclasses do
+ local mc=markclasses[i]
+ if mc then
+ mc[2]=readanchor(f,mc[2],getdelta)
+ end
+ end
+ setposition(f,baseoffset)
+ local nofbaserecords=readushort(f)
+ local baserecords={}
+ if ligature then
+ for i=1,nofbaserecords do
+ local offset=readushort(f)
+ if offset==0 then
+ baserecords[i]=false
else
- for i=1,nofbaserecords do
- local r={}
- for j=1,nofclasses do
- local offset=readushort(f)
- if offset==0 then
- r[j]=false
- else
- r[j]=baseoffset+offset
- end
- end
- baserecords[i]=r
- end
- local baseclasses={}
+ baserecords[i]=baseoffset+offset
+ end
+ end
+ for i=1,nofbaserecords do
+ local recordoffset=baserecords[i]
+ if recordoffset then
+ setposition(f,recordoffset)
+ local nofcomponents=readushort(f)
+ local components={}
+ for i=1,nofcomponents do
+ local classes={}
for i=1,nofclasses do
- baseclasses[i]={}
+ local offset=readushort(f)
+ if offset~=0 then
+ classes[i]=recordoffset+offset
+ else
+ classes[i]=false
+ end
end
- for i=1,nofbaserecords do
- local r=baserecords[i]
- local b=basecoverage[i]
- for j=1,nofclasses do
- baseclasses[j][b]=readanchor(f,r[j],getdelta)
+ components[i]=classes
+ end
+ baserecords[i]=components
+ end
+ end
+ local baseclasses={}
+ for i=1,nofclasses do
+ baseclasses[i]={}
+ end
+ for i=1,nofbaserecords do
+ local components=baserecords[i]
+ if components then
+ local b=basecoverage[i]
+ for c=1,#components do
+ local classes=components[c]
+ if classes then
+ for i=1,nofclasses do
+ local anchor=readanchor(f,classes[i],getdelta)
+ local bclass=baseclasses[i]
+ local bentry=bclass[b]
+ if bentry then
+ bentry[c]=anchor
+ else
+ bclass[b]={ [c]=anchor }
end
+ end
end
- for index,newindex in next,markcoverage do
- markcoverage[index]=markclasses[newindex+1] or nil
- end
- return {
- format="base",
- baseclasses=baseclasses,
- coverage=markcoverage,
- }
+ end
end
+ end
+ for index,newindex in next,markcoverage do
+ markcoverage[index]=markclasses[newindex+1] or nil
+ end
+ return {
+ format="ligature",
+ baseclasses=baseclasses,
+ coverage=markcoverage,
+ }
else
- report("unsupported subtype %a in",subtype)
- end
+ for i=1,nofbaserecords do
+ local r={}
+ for j=1,nofclasses do
+ local offset=readushort(f)
+ if offset==0 then
+ r[j]=false
+ else
+ r[j]=baseoffset+offset
+ end
+ end
+ baserecords[i]=r
+ end
+ local baseclasses={}
+ for i=1,nofclasses do
+ baseclasses[i]={}
+ end
+ for i=1,nofbaserecords do
+ local r=baserecords[i]
+ local b=basecoverage[i]
+ for j=1,nofclasses do
+ baseclasses[j][b]=readanchor(f,r[j],getdelta)
+ end
+ end
+ for index,newindex in next,markcoverage do
+ markcoverage[index]=markclasses[newindex+1] or nil
+ end
+ return {
+ format="base",
+ baseclasses=baseclasses,
+ coverage=markcoverage,
+ }
+ end
+ else
+ report("unsupported subtype %a in",subtype)
+ end
end
function gposhandlers.marktobase(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
end
function gposhandlers.marktoligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,true)
+ return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,true)
end
function gposhandlers.marktomark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
+ return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
end
function gposhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"context"
+ return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"context"
end
function gposhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"chainedcontext"
+ return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"chainedcontext"
end
function gposhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs)
- return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gpostypes,gposhandlers,"positioning")
+ return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gpostypes,gposhandlers,"positioning")
end
do
- local plugins={}
- function plugins.size(f,fontdata,tableoffset,feature)
- if fontdata.designsize then
+ local plugins={}
+ function plugins.size(f,fontdata,tableoffset,feature)
+ if fontdata.designsize then
+ else
+ local function check(offset)
+ setposition(f,offset)
+ local designsize=readushort(f)
+ if designsize>0 then
+ local fontstyleid=readushort(f)
+ local guimenuid=readushort(f)
+ local minsize=readushort(f)
+ local maxsize=readushort(f)
+ if minsize==0 and maxsize==0 and fontstyleid==0 and guimenuid==0 then
+ minsize=designsize
+ maxsize=designsize
+ end
+ if designsize>=minsize and designsize<=maxsize then
+ return minsize,maxsize,designsize
+ end
+ end
+ end
+ local minsize,maxsize,designsize=check(tableoffset+feature.offset+feature.parameters)
+ if not designsize then
+ minsize,maxsize,designsize=check(tableoffset+feature.parameters)
+ if designsize then
+ report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?")
else
- local function check(offset)
- setposition(f,offset)
- local designsize=readushort(f)
- if designsize>0 then
- local fontstyleid=readushort(f)
- local guimenuid=readushort(f)
- local minsize=readushort(f)
- local maxsize=readushort(f)
- if minsize==0 and maxsize==0 and fontstyleid==0 and guimenuid==0 then
- minsize=designsize
- maxsize=designsize
- end
- if designsize>=minsize and designsize<=maxsize then
- return minsize,maxsize,designsize
- end
+ report("bad size feature in %a,",fontdata.filename or "?")
+ end
+ end
+ if designsize then
+ fontdata.minsize=minsize
+ fontdata.maxsize=maxsize
+ fontdata.designsize=designsize
+ end
+ end
+ end
+ local function reorderfeatures(fontdata,scripts,features)
+ local scriptlangs={}
+ local featurehash={}
+ local featureorder={}
+ for script,languages in next,scripts do
+ for language,record in next,languages do
+ local hash={}
+ local list=record.featureindices
+ for k=1,#list do
+ local index=list[k]
+ local feature=features[index]
+ local lookups=feature.lookups
+ local tag=feature.tag
+ if tag then
+ hash[tag]=true
+ end
+ if lookups then
+ for i=1,#lookups do
+ local lookup=lookups[i]
+ local o=featureorder[lookup]
+ if o then
+ local okay=true
+ for i=1,#o do
+ if o[i]==tag then
+ okay=false
+ break
+ end
end
- end
- local minsize,maxsize,designsize=check(tableoffset+feature.offset+feature.parameters)
- if not designsize then
- minsize,maxsize,designsize=check(tableoffset+feature.parameters)
- if designsize then
- report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?")
- else
- report("bad size feature in %a,",fontdata.filename or "?")
+ if okay then
+ o[#o+1]=tag
end
- end
- if designsize then
- fontdata.minsize=minsize
- fontdata.maxsize=maxsize
- fontdata.designsize=designsize
- end
- end
- end
- local function reorderfeatures(fontdata,scripts,features)
- local scriptlangs={}
- local featurehash={}
- local featureorder={}
- for script,languages in next,scripts do
- for language,record in next,languages do
- local hash={}
- local list=record.featureindices
- for k=1,#list do
- local index=list[k]
- local feature=features[index]
- local lookups=feature.lookups
- local tag=feature.tag
- if tag then
- hash[tag]=true
- end
- if lookups then
- for i=1,#lookups do
- local lookup=lookups[i]
- local o=featureorder[lookup]
- if o then
- local okay=true
- for i=1,#o do
- if o[i]==tag then
- okay=false
- break
- end
- end
- if okay then
- o[#o+1]=tag
- end
- else
- featureorder[lookup]={ tag }
- end
- local f=featurehash[lookup]
- if f then
- local h=f[tag]
- if h then
- local s=h[script]
- if s then
- s[language]=true
- else
- h[script]={ [language]=true }
- end
- else
- f[tag]={ [script]={ [language]=true } }
- end
- else
- featurehash[lookup]={ [tag]={ [script]={ [language]=true } } }
- end
- local h=scriptlangs[tag]
- if h then
- local s=h[script]
- if s then
- s[language]=true
- else
- h[script]={ [language]=true }
- end
- else
- scriptlangs[tag]={ [script]={ [language]=true } }
- end
- end
- end
+ else
+ featureorder[lookup]={ tag }
+ end
+ local f=featurehash[lookup]
+ if f then
+ local h=f[tag]
+ if h then
+ local s=h[script]
+ if s then
+ s[language]=true
+ else
+ h[script]={ [language]=true }
+ end
+ else
+ f[tag]={ [script]={ [language]=true } }
end
- end
- end
- return scriptlangs,featurehash,featureorder
- end
- local function readscriplan(f,fontdata,scriptoffset)
- setposition(f,scriptoffset)
- local nofscripts=readushort(f)
- local scripts={}
- for i=1,nofscripts do
- scripts[readtag(f)]=scriptoffset+readushort(f)
- end
- local languagesystems=setmetatableindex("table")
- for script,offset in next,scripts do
- setposition(f,offset)
- local defaultoffset=readushort(f)
- local noflanguages=readushort(f)
- local languages={}
- if defaultoffset>0 then
- languages.dflt=languagesystems[offset+defaultoffset]
- end
- for i=1,noflanguages do
- local language=readtag(f)
- local offset=offset+readushort(f)
- languages[language]=languagesystems[offset]
- end
- scripts[script]=languages
- end
- for offset,usedfeatures in next,languagesystems do
- if offset>0 then
- setposition(f,offset)
- local featureindices={}
- usedfeatures.featureindices=featureindices
- usedfeatures.lookuporder=readushort(f)
- usedfeatures.requiredindex=readushort(f)
- local noffeatures=readushort(f)
- for i=1,noffeatures do
- featureindices[i]=readushort(f)+1
+ else
+ featurehash[lookup]={ [tag]={ [script]={ [language]=true } } }
+ end
+ local h=scriptlangs[tag]
+ if h then
+ local s=h[script]
+ if s then
+ s[language]=true
+ else
+ h[script]={ [language]=true }
end
+ else
+ scriptlangs[tag]={ [script]={ [language]=true } }
+ end
end
+ end
end
- return scripts
- end
- local function readfeatures(f,fontdata,featureoffset)
- setposition(f,featureoffset)
- local features={}
+ end
+ end
+ return scriptlangs,featurehash,featureorder
+ end
+ local function readscriplan(f,fontdata,scriptoffset)
+ setposition(f,scriptoffset)
+ local nofscripts=readushort(f)
+ local scripts={}
+ for i=1,nofscripts do
+ scripts[readtag(f)]=scriptoffset+readushort(f)
+ end
+ local languagesystems=setmetatableindex("table")
+ for script,offset in next,scripts do
+ setposition(f,offset)
+ local defaultoffset=readushort(f)
+ local noflanguages=readushort(f)
+ local languages={}
+ if defaultoffset>0 then
+ languages.dflt=languagesystems[offset+defaultoffset]
+ end
+ for i=1,noflanguages do
+ local language=readtag(f)
+ local offset=offset+readushort(f)
+ languages[language]=languagesystems[offset]
+ end
+ scripts[script]=languages
+ end
+ for offset,usedfeatures in next,languagesystems do
+ if offset>0 then
+ setposition(f,offset)
+ local featureindices={}
+ usedfeatures.featureindices=featureindices
+ usedfeatures.lookuporder=readushort(f)
+ usedfeatures.requiredindex=readushort(f)
local noffeatures=readushort(f)
for i=1,noffeatures do
- features[i]={
- tag=readtag(f),
- offset=readushort(f)
- }
- end
- for i=1,noffeatures do
- local feature=features[i]
- local offset=featureoffset+feature.offset
- setposition(f,offset)
- local parameters=readushort(f)
- local noflookups=readushort(f)
- if noflookups>0 then
- local lookups=readcardinaltable(f,noflookups,ushort)
- feature.lookups=lookups
- for j=1,noflookups do
- lookups[j]=lookups[j]+1
- end
- end
- if parameters>0 then
- feature.parameters=parameters
- local plugin=plugins[feature.tag]
- if plugin then
- plugin(f,fontdata,featureoffset,feature)
- end
- end
- end
- return features
- end
- local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder)
- setposition(f,lookupoffset)
- local noflookups=readushort(f)
+ featureindices[i]=readushort(f)+1
+ end
+ end
+ end
+ return scripts
+ end
+ local function readfeatures(f,fontdata,featureoffset)
+ setposition(f,featureoffset)
+ local features={}
+ local noffeatures=readushort(f)
+ for i=1,noffeatures do
+ features[i]={
+ tag=readtag(f),
+ offset=readushort(f)
+ }
+ end
+ for i=1,noffeatures do
+ local feature=features[i]
+ local offset=featureoffset+feature.offset
+ setposition(f,offset)
+ local parameters=readushort(f)
+ local noflookups=readushort(f)
+ if noflookups>0 then
local lookups=readcardinaltable(f,noflookups,ushort)
- for lookupid=1,noflookups do
- local offset=lookups[lookupid]
- setposition(f,lookupoffset+offset)
- local subtables={}
- local typebits=readushort(f)
- local flagbits=readushort(f)
- local lookuptype=lookuptypes[typebits]
- local lookupflags=lookupflags[flagbits]
- local nofsubtables=readushort(f)
- for j=1,nofsubtables do
- subtables[j]=offset+readushort(f)
- end
- local markclass=band(flagbits,0x0010)~=0
- if markclass then
- markclass=readushort(f)
- end
- local markset=rshift(flagbits,8)
- if markset>0 then
- markclass=markset
- end
- lookups[lookupid]={
- type=lookuptype,
- flags=lookupflags,
- name=lookupid,
- subtables=subtables,
- markclass=markclass,
- features=featurehash[lookupid],
- order=featureorder[lookupid],
- }
- end
- return lookups
+ feature.lookups=lookups
+ for j=1,noflookups do
+ lookups[j]=lookups[j]+1
+ end
+ end
+ if parameters>0 then
+ feature.parameters=parameters
+ local plugin=plugins[feature.tag]
+ if plugin then
+ plugin(f,fontdata,featureoffset,feature)
+ end
+ end
+ end
+ return features
+ end
+ local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder)
+ setposition(f,lookupoffset)
+ local noflookups=readushort(f)
+ local lookups=readcardinaltable(f,noflookups,ushort)
+ for lookupid=1,noflookups do
+ local offset=lookups[lookupid]
+ setposition(f,lookupoffset+offset)
+ local subtables={}
+ local typebits=readushort(f)
+ local flagbits=readushort(f)
+ local lookuptype=lookuptypes[typebits]
+ local lookupflags=lookupflags[flagbits]
+ local nofsubtables=readushort(f)
+ for j=1,nofsubtables do
+ subtables[j]=offset+readushort(f)
+ end
+ local markclass=band(flagbits,0x0010)~=0
+ if markclass then
+ markclass=readushort(f)
+ end
+ local markset=rshift(flagbits,8)
+ if markset>0 then
+ markclass=markset
+ end
+ lookups[lookupid]={
+ type=lookuptype,
+ flags=lookupflags,
+ name=lookupid,
+ subtables=subtables,
+ markclass=markclass,
+ features=featurehash[lookupid],
+ order=featureorder[lookupid],
+ }
end
- local f_lookupname=formatters["%s_%s_%s"]
- local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset)
- local sequences=fontdata.sequences or {}
- local sublookuplist=fontdata.sublookups or {}
- fontdata.sequences=sequences
- fontdata.sublookups=sublookuplist
- local nofsublookups=#sublookuplist
- local nofsequences=#sequences
- local lastsublookup=nofsublookups
- local lastsequence=nofsequences
- local lookupnames=lookupnames[what]
- local sublookuphash={}
- local sublookupcheck={}
- local glyphs=fontdata.glyphs
- local nofglyphs=fontdata.nofglyphs or #glyphs
- local noflookups=#lookups
- local lookupprefix=sub(what,2,2)
- local usedlookups=false
- for lookupid=1,noflookups do
- local lookup=lookups[lookupid]
- local lookuptype=lookup.type
- local subtables=lookup.subtables
- local features=lookup.features
- local handler=lookuphandlers[lookuptype]
- if handler then
- local nofsubtables=#subtables
- local order=lookup.order
- local flags=lookup.flags
- if flags[1] then flags[1]="mark" end
- if flags[2] then flags[2]="ligature" end
- if flags[3] then flags[3]="base" end
- local markclass=lookup.markclass
- if nofsubtables>0 then
- local steps={}
- local nofsteps=0
- local oldtype=nil
- for s=1,nofsubtables do
- local step,lt=handler(f,fontdata,lookupid,lookupoffset,subtables[s],glyphs,nofglyphs)
- if lt then
- lookuptype=lt
- if oldtype and lt~=oldtype then
- report("messy %s lookup type %a and %a",what,lookuptype,oldtype)
- end
- oldtype=lookuptype
- end
- if not step then
- report("unsupported %s lookup type %a",what,lookuptype)
- else
- nofsteps=nofsteps+1
- steps[nofsteps]=step
- local rules=step.rules
- if rules then
- for i=1,#rules do
- local rule=rules[i]
- local before=rule.before
- local current=rule.current
- local after=rule.after
- local replacements=rule.replacements
- if before then
- for i=1,#before do
- before[i]=tohash(before[i])
- end
- rule.before=reversed(before)
- end
- if current then
- if replacements then
- local first=current[1]
- local hash={}
- local repl={}
- for i=1,#first do
- local c=first[i]
- hash[c]=true
- repl[c]=replacements[i]
- end
- rule.current={ hash }
- rule.replacements=repl
- else
- for i=1,#current do
- current[i]=tohash(current[i])
- end
- end
- else
- end
- if after then
- for i=1,#after do
- after[i]=tohash(after[i])
- end
- end
- if usedlookups then
- local lookups=rule.lookups
- if lookups then
- for k,v in next,lookups do
- if v then
- for k,v in next,v do
- usedlookups[v]=usedlookups[v]+1
- end
- end
- end
- end
- end
- end
- end
- end
- end
- if nofsteps~=nofsubtables then
- report("bogus subtables removed in %s lookup type %a",what,lookuptype)
- end
- lookuptype=lookupnames[lookuptype] or lookuptype
- if features then
- nofsequences=nofsequences+1
- local l={
- index=nofsequences,
- name=f_lookupname(lookupprefix,"s",lookupid+lookupidoffset),
- steps=steps,
- nofsteps=nofsteps,
- type=lookuptype,
- markclass=markclass or nil,
- flags=flags,
- order=order,
- features=features,
- }
- sequences[nofsequences]=l
- lookup.done=l
- else
- nofsublookups=nofsublookups+1
- local l={
- index=nofsublookups,
- name=f_lookupname(lookupprefix,"l",lookupid+lookupidoffset),
- steps=steps,
- nofsteps=nofsteps,
- type=lookuptype,
- markclass=markclass or nil,
- flags=flags,
- }
- sublookuplist[nofsublookups]=l
- sublookuphash[lookupid]=nofsublookups
- sublookupcheck[lookupid]=0
- lookup.done=l
- end
- else
- report("no subtables for lookup %a",lookupid)
- end
- else
- report("no handler for lookup %a with type %a",lookupid,lookuptype)
- end
- end
- if usedlookups then
- report("used %s lookups: % t",what,sortedkeys(usedlookups))
- end
- local reported={}
- local function report_issue(i,what,sequence,kind)
- local name=sequence.name
- if not reported[name] then
- report("rule %i in %s lookup %a has %s lookups",i,what,name,kind)
- reported[name]=true
+ return lookups
+ end
+ local f_lookupname=formatters["%s_%s_%s"]
+ local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset)
+ local sequences=fontdata.sequences or {}
+ local sublookuplist=fontdata.sublookups or {}
+ fontdata.sequences=sequences
+ fontdata.sublookups=sublookuplist
+ local nofsublookups=#sublookuplist
+ local nofsequences=#sequences
+ local lastsublookup=nofsublookups
+ local lastsequence=nofsequences
+ local lookupnames=lookupnames[what]
+ local sublookuphash={}
+ local sublookupcheck={}
+ local glyphs=fontdata.glyphs
+ local nofglyphs=fontdata.nofglyphs or #glyphs
+ local noflookups=#lookups
+ local lookupprefix=sub(what,2,2)
+ local usedlookups=false
+ for lookupid=1,noflookups do
+ local lookup=lookups[lookupid]
+ local lookuptype=lookup.type
+ local subtables=lookup.subtables
+ local features=lookup.features
+ local handler=lookuphandlers[lookuptype]
+ if handler then
+ local nofsubtables=#subtables
+ local order=lookup.order
+ local flags=lookup.flags
+ if flags[1] then flags[1]="mark" end
+ if flags[2] then flags[2]="ligature" end
+ if flags[3] then flags[3]="base" end
+ local markclass=lookup.markclass
+ if nofsubtables>0 then
+ local steps={}
+ local nofsteps=0
+ local oldtype=nil
+ for s=1,nofsubtables do
+ local step,lt=handler(f,fontdata,lookupid,lookupoffset,subtables[s],glyphs,nofglyphs)
+ if lt then
+ lookuptype=lt
+ if oldtype and lt~=oldtype then
+ report("messy %s lookup type %a and %a",what,lookuptype,oldtype)
+ end
+ oldtype=lookuptype
end
- end
- for i=lastsequence+1,nofsequences do
- local sequence=sequences[i]
- local steps=sequence.steps
- for i=1,#steps do
- local step=steps[i]
- local rules=step.rules
- if rules then
- for i=1,#rules do
- local rule=rules[i]
- local rlookups=rule.lookups
- if not rlookups then
- report_issue(i,what,sequence,"no")
- elseif not next(rlookups) then
- rule.lookups=nil
- else
- local length=#rlookups
- for index=1,length do
- local lookuplist=rlookups[index]
- if lookuplist then
- local length=#lookuplist
- local found={}
- local noffound=0
- for index=1,length do
- local lookupid=lookuplist[index]
- if lookupid then
- local h=sublookuphash[lookupid]
- if not h then
- local lookup=lookups[lookupid]
- if lookup then
- local d=lookup.done
- if d then
- nofsublookups=nofsublookups+1
- local l={
- index=nofsublookups,
- name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset),
- derived=true,
- steps=d.steps,
- nofsteps=d.nofsteps,
- type=d.lookuptype or "gsub_single",
- markclass=d.markclass or nil,
- flags=d.flags,
- }
- sublookuplist[nofsublookups]=copy(l)
- sublookuphash[lookupid]=nofsublookups
- sublookupcheck[lookupid]=1
- h=nofsublookups
- else
- report_issue(i,what,sequence,"missing")
- rule.lookups=nil
- break
- end
- else
- report_issue(i,what,sequence,"bad")
- rule.lookups=nil
- break
- end
- else
- sublookupcheck[lookupid]=sublookupcheck[lookupid]+1
- end
- if h then
- noffound=noffound+1
- found[noffound]=h
- end
- end
- end
- rlookups[index]=noffound>0 and found or false
- else
- rlookups[index]=false
- end
- end
+ if not step then
+ report("unsupported %s lookup type %a",what,lookuptype)
+ else
+ nofsteps=nofsteps+1
+ steps[nofsteps]=step
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local before=rule.before
+ local current=rule.current
+ local after=rule.after
+ local replacements=rule.replacements
+ if before then
+ for i=1,#before do
+ before[i]=tohash(before[i])
+ end
+ rule.before=reversed(before)
+ end
+ if current then
+ if replacements then
+ local first=current[1]
+ local hash={}
+ local repl={}
+ for i=1,#first do
+ local c=first[i]
+ hash[c]=true
+ repl[c]=replacements[i]
+ end
+ rule.current={ hash }
+ rule.replacements=repl
+ else
+ for i=1,#current do
+ current[i]=tohash(current[i])
+ end
+ end
+ else
+ end
+ if after then
+ for i=1,#after do
+ after[i]=tohash(after[i])
+ end
+ end
+ if usedlookups then
+ local lookups=rule.lookups
+ if lookups then
+ for k,v in next,lookups do
+ if v then
+ for k,v in next,v do
+ usedlookups[v]=usedlookups[v]+1
+ end
end
+ end
end
+ end
end
+ end
end
- end
- for i,n in sortedhash(sublookupcheck) do
- local l=lookups[i]
- local t=l.type
- if n==0 and t~="extension" then
- local d=l.done
- report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t)
- end
- end
- end
- local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
- setposition(f,variationsoffset)
- local version=readulong(f)
- local nofrecords=readulong(f)
- local records={}
- for i=1,nofrecords do
- records[i]={
- conditions=readulong(f),
- substitutions=readulong(f),
+ end
+ if nofsteps~=nofsubtables then
+ report("bogus subtables removed in %s lookup type %a",what,lookuptype)
+ end
+ lookuptype=lookupnames[lookuptype] or lookuptype
+ if features then
+ nofsequences=nofsequences+1
+ local l={
+ index=nofsequences,
+ name=f_lookupname(lookupprefix,"s",lookupid+lookupidoffset),
+ steps=steps,
+ nofsteps=nofsteps,
+ type=lookuptype,
+ markclass=markclass or nil,
+ flags=flags,
+ order=order,
+ features=features,
}
- end
- for i=1,nofrecords do
- local record=records[i]
- local offset=record.conditions
- if offset==0 then
- record.condition=nil
- record.matchtype="always"
- else
- local offset=variationsoffset+offset
- setposition(f,offset)
- local nofconditions=readushort(f)
- local conditions={}
- for i=1,nofconditions do
- conditions[i]=offset+readulong(f)
- end
- record.conditions=conditions
- record.matchtype="condition"
- end
- end
- for i=1,nofrecords do
- local record=records[i]
- if record.matchtype=="condition" then
- local conditions=record.conditions
- for i=1,#conditions do
- setposition(f,conditions[i])
- conditions[i]={
- format=readushort(f),
- axis=readushort(f),
- minvalue=read2dot14(f),
- maxvalue=read2dot14(f),
- }
- end
- end
- end
- for i=1,nofrecords do
- local record=records[i]
- local offset=record.substitutions
- if offset==0 then
- record.substitutions={}
+ sequences[nofsequences]=l
+ lookup.done=l
+ else
+ nofsublookups=nofsublookups+1
+ local l={
+ index=nofsublookups,
+ name=f_lookupname(lookupprefix,"l",lookupid+lookupidoffset),
+ steps=steps,
+ nofsteps=nofsteps,
+ type=lookuptype,
+ markclass=markclass or nil,
+ flags=flags,
+ }
+ sublookuplist[nofsublookups]=l
+ sublookuphash[lookupid]=nofsublookups
+ sublookupcheck[lookupid]=0
+ lookup.done=l
+ end
+ else
+ report("no subtables for lookup %a",lookupid)
+ end
+ else
+ report("no handler for lookup %a with type %a",lookupid,lookuptype)
+ end
+ end
+ if usedlookups then
+ report("used %s lookups: % t",what,sortedkeys(usedlookups))
+ end
+ local reported={}
+ local function report_issue(i,what,sequence,kind)
+ local name=sequence.name
+ if not reported[name] then
+ report("rule %i in %s lookup %a has %s lookups",i,what,name,kind)
+ reported[name]=true
+ end
+ end
+ for i=lastsequence+1,nofsequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ for i=1,#steps do
+ local step=steps[i]
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local rlookups=rule.lookups
+ if not rlookups then
+ report_issue(i,what,sequence,"no")
+ elseif not next(rlookups) then
+ rule.lookups=nil
else
- setposition(f,variationsoffset+offset)
- local version=readulong(f)
- local nofsubstitutions=readushort(f)
- local substitutions={}
- for i=1,nofsubstitutions do
- substitutions[readushort(f)]=readulong(f)
- end
- for index,alternates in sortedhash(substitutions) do
- if index==0 then
- record.substitutions=false
- else
- local tableoffset=variationsoffset+offset+alternates
- setposition(f,tableoffset)
- local parameters=readulong(f)
- local noflookups=readushort(f)
- local lookups=readcardinaltable(f,noflookups,ushort)
- record.substitutions=lookups
- end
+ local length=#rlookups
+ for index=1,length do
+ local lookuplist=rlookups[index]
+ if lookuplist then
+ local length=#lookuplist
+ local found={}
+ local noffound=0
+ for index=1,length do
+ local lookupid=lookuplist[index]
+ if lookupid then
+ local h=sublookuphash[lookupid]
+ if not h then
+ local lookup=lookups[lookupid]
+ if lookup then
+ local d=lookup.done
+ if d then
+ nofsublookups=nofsublookups+1
+ local l={
+ index=nofsublookups,
+ name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset),
+ derived=true,
+ steps=d.steps,
+ nofsteps=d.nofsteps,
+ type=d.lookuptype or "gsub_single",
+ markclass=d.markclass or nil,
+ flags=d.flags,
+ }
+ sublookuplist[nofsublookups]=copy(l)
+ sublookuphash[lookupid]=nofsublookups
+ sublookupcheck[lookupid]=1
+ h=nofsublookups
+ else
+ report_issue(i,what,sequence,"missing")
+ rule.lookups=nil
+ break
+ end
+ else
+ report_issue(i,what,sequence,"bad")
+ rule.lookups=nil
+ break
+ end
+ else
+ sublookupcheck[lookupid]=sublookupcheck[lookupid]+1
+ end
+ if h then
+ noffound=noffound+1
+ found[noffound]=h
+ end
+ end
+ end
+ rlookups[index]=noffound>0 and found or false
+ else
+ rlookups[index]=false
end
+ end
end
+ end
end
- setvariabledata(fontdata,"features",records)
- end
- local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo)
- local tableoffset=gotodatatable(f,fontdata,what,true)
- if tableoffset then
- local version=readulong(f)
- local scriptoffset=tableoffset+readushort(f)
- local featureoffset=tableoffset+readushort(f)
- local lookupoffset=tableoffset+readushort(f)
- local variationsoffset=version>0x00010000 and (tableoffset+readulong(f)) or 0
- if not scriptoffset then
- return
- end
- local scripts=readscriplan(f,fontdata,scriptoffset)
- local features=readfeatures(f,fontdata,featureoffset)
- local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features)
- if fontdata.features then
- fontdata.features[what]=scriptlangs
- else
- fontdata.features={ [what]=scriptlangs }
- end
- if not lookupstoo then
- return
- end
- local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder)
- if lookups then
- resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset)
- end
- if variationsoffset>0 then
- loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
- end
- end
+ end
end
- local function checkkerns(f,fontdata,specification)
- local datatable=fontdata.tables.kern
- if not datatable then
- return
- end
- local features=fontdata.features
- local gposfeatures=features and features.gpos
- local name
- if not gposfeatures or not gposfeatures.kern then
- name="kern"
- elseif specification.globalkerns then
- name="globalkern"
- else
- report("ignoring global kern table, using gpos kern feature")
- return
+ for i,n in sortedhash(sublookupcheck) do
+ local l=lookups[i]
+ local t=l.type
+ if n==0 and t~="extension" then
+ local d=l.done
+ report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t)
+ end
+ end
+ end
+ local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
+ setposition(f,variationsoffset)
+ local version=readulong(f)
+ local nofrecords=readulong(f)
+ local records={}
+ for i=1,nofrecords do
+ records[i]={
+ conditions=readulong(f),
+ substitutions=readulong(f),
+ }
+ end
+ for i=1,nofrecords do
+ local record=records[i]
+ local offset=record.conditions
+ if offset==0 then
+ record.condition=nil
+ record.matchtype="always"
+ else
+ local offset=variationsoffset+offset
+ setposition(f,offset)
+ local nofconditions=readushort(f)
+ local conditions={}
+ for i=1,nofconditions do
+ conditions[i]=offset+readulong(f)
+ end
+ record.conditions=conditions
+ record.matchtype="condition"
+ end
+ end
+ for i=1,nofrecords do
+ local record=records[i]
+ if record.matchtype=="condition" then
+ local conditions=record.conditions
+ for i=1,#conditions do
+ setposition(f,conditions[i])
+ conditions[i]={
+ format=readushort(f),
+ axis=readushort(f),
+ minvalue=read2dot14(f),
+ maxvalue=read2dot14(f),
+ }
+ end
+ end
+ end
+ for i=1,nofrecords do
+ local record=records[i]
+ local offset=record.substitutions
+ if offset==0 then
+ record.substitutions={}
+ else
+ setposition(f,variationsoffset+offset)
+ local version=readulong(f)
+ local nofsubstitutions=readushort(f)
+ local substitutions={}
+ for i=1,nofsubstitutions do
+ substitutions[readushort(f)]=readulong(f)
+ end
+ for index,alternates in sortedhash(substitutions) do
+ if index==0 then
+ record.substitutions=false
+ else
+ local tableoffset=variationsoffset+offset+alternates
+ setposition(f,tableoffset)
+ local parameters=readulong(f)
+ local noflookups=readushort(f)
+ local lookups=readcardinaltable(f,noflookups,ushort)
+ record.substitutions=lookups
+ end
end
- setposition(f,datatable.offset)
+ end
+ end
+ setvariabledata(fontdata,"features",records)
+ end
+ local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo)
+ local tableoffset=gotodatatable(f,fontdata,what,true)
+ if tableoffset then
+ local version=readulong(f)
+ local scriptoffset=tableoffset+readushort(f)
+ local featureoffset=tableoffset+readushort(f)
+ local lookupoffset=tableoffset+readushort(f)
+ local variationsoffset=version>0x00010000 and (tableoffset+readulong(f)) or 0
+ if not scriptoffset then
+ return
+ end
+ local scripts=readscriplan(f,fontdata,scriptoffset)
+ local features=readfeatures(f,fontdata,featureoffset)
+ local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features)
+ if fontdata.features then
+ fontdata.features[what]=scriptlangs
+ else
+ fontdata.features={ [what]=scriptlangs }
+ end
+ if not lookupstoo then
+ return
+ end
+ local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder)
+ if lookups then
+ resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset)
+ end
+ if variationsoffset>0 then
+ loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
+ end
+ end
+ end
+ local function checkkerns(f,fontdata,specification)
+ local datatable=fontdata.tables.kern
+ if not datatable then
+ return
+ end
+ local features=fontdata.features
+ local gposfeatures=features and features.gpos
+ local name
+ if not gposfeatures or not gposfeatures.kern then
+ name="kern"
+ elseif specification.globalkerns then
+ name="globalkern"
+ else
+ report("ignoring global kern table, using gpos kern feature")
+ return
+ end
+ setposition(f,datatable.offset)
+ local version=readushort(f)
+ local noftables=readushort(f)
+ if noftables>1 then
+ report("adding global kern table as gpos feature %a",name)
+ local kerns=setmetatableindex("table")
+ for i=1,noftables do
local version=readushort(f)
- local noftables=readushort(f)
- if noftables>1 then
- report("adding global kern table as gpos feature %a",name)
- local kerns=setmetatableindex("table")
- for i=1,noftables do
- local version=readushort(f)
- local length=readushort(f)
- local coverage=readushort(f)
- local format=rshift(coverage,8)
- if format==0 then
- local nofpairs=readushort(f)
- local searchrange=readushort(f)
- local entryselector=readushort(f)
- local rangeshift=readushort(f)
- for i=1,nofpairs do
- kerns[readushort(f)][readushort(f)]=readfword(f)
- end
- elseif format==2 then
- else
- end
- end
- local feature={ dflt={ dflt=true } }
- if not features then
- fontdata.features={ gpos={ [name]=feature } }
- elseif not gposfeatures then
- fontdata.features.gpos={ [name]=feature }
- else
- gposfeatures[name]=feature
- end
- local sequences=fontdata.sequences
- if not sequences then
- sequences={}
- fontdata.sequences=sequences
- end
- local nofsequences=#sequences+1
- sequences[nofsequences]={
- index=nofsequences,
- name=name,
- steps={
- {
- coverage=kerns,
- format="kern",
- },
- },
- nofsteps=1,
- type="gpos_pair",
- flags={ false,false,false,false },
- order={ name },
- features={ [name]=feature },
- }
+ local length=readushort(f)
+ local coverage=readushort(f)
+ local format=rshift(coverage,8)
+ if format==0 then
+ local nofpairs=readushort(f)
+ local searchrange=readushort(f)
+ local entryselector=readushort(f)
+ local rangeshift=readushort(f)
+ for i=1,nofpairs do
+ kerns[readushort(f)][readushort(f)]=readfword(f)
+ end
+ elseif format==2 then
else
- report("ignoring empty kern table of feature %a",name)
end
+ end
+ local feature={ dflt={ dflt=true } }
+ if not features then
+ fontdata.features={ gpos={ [name]=feature } }
+ elseif not gposfeatures then
+ fontdata.features.gpos={ [name]=feature }
+ else
+ gposfeatures[name]=feature
+ end
+ local sequences=fontdata.sequences
+ if not sequences then
+ sequences={}
+ fontdata.sequences=sequences
+ end
+ local nofsequences=#sequences+1
+ sequences[nofsequences]={
+ index=nofsequences,
+ name=name,
+ steps={
+ {
+ coverage=kerns,
+ format="kern",
+ },
+ },
+ nofsteps=1,
+ type="gpos_pair",
+ flags={ false,false,false,false },
+ order={ name },
+ features={ [name]=feature },
+ }
+ else
+ report("ignoring empty kern table of feature %a",name)
end
- function readers.gsub(f,fontdata,specification)
- if specification.details then
- readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups)
- end
+ end
+ function readers.gsub(f,fontdata,specification)
+ if specification.details then
+ readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups)
end
- function readers.gpos(f,fontdata,specification)
- if specification.details then
- readscripts(f,fontdata,"gpos",gpostypes,gposhandlers,specification.lookups)
- if specification.lookups then
- checkkerns(f,fontdata,specification)
- end
- end
+ end
+ function readers.gpos(f,fontdata,specification)
+ if specification.details then
+ readscripts(f,fontdata,"gpos",gpostypes,gposhandlers,specification.lookups)
+ if specification.lookups then
+ checkkerns(f,fontdata,specification)
+ end
end
+ end
end
function readers.gdef(f,fontdata,specification)
- if not specification.glyphs then
- return
- end
- local datatable=fontdata.tables.gdef
- if datatable then
- local tableoffset=datatable.offset
- setposition(f,tableoffset)
- local version=readulong(f)
- local classoffset=readushort(f)
- local attachmentoffset=readushort(f)
- local ligaturecarets=readushort(f)
- local markclassoffset=readushort(f)
- local marksetsoffset=version>=0x00010002 and readushort(f) or 0
- local varsetsoffset=version>=0x00010003 and readulong(f) or 0
- local glyphs=fontdata.glyphs
- local marks={}
- local markclasses=setmetatableindex("table")
- local marksets=setmetatableindex("table")
- fontdata.marks=marks
- fontdata.markclasses=markclasses
- fontdata.marksets=marksets
- if classoffset~=0 then
- setposition(f,tableoffset+classoffset)
- local classformat=readushort(f)
- if classformat==1 then
- local firstindex=readushort(f)
- local lastindex=firstindex+readushort(f)-1
- for index=firstindex,lastindex do
- local class=classes[readushort(f)]
- if class=="mark" then
- marks[index]=true
- end
- glyphs[index].class=class
- end
- elseif classformat==2 then
- local nofranges=readushort(f)
- for i=1,nofranges do
- local firstindex=readushort(f)
- local lastindex=readushort(f)
- local class=classes[readushort(f)]
- if class then
- for index=firstindex,lastindex do
- glyphs[index].class=class
- if class=="mark" then
- marks[index]=true
- end
- end
- end
- end
- end
+ if not specification.glyphs then
+ return
+ end
+ local datatable=fontdata.tables.gdef
+ if datatable then
+ local tableoffset=datatable.offset
+ setposition(f,tableoffset)
+ local version=readulong(f)
+ local classoffset=readushort(f)
+ local attachmentoffset=readushort(f)
+ local ligaturecarets=readushort(f)
+ local markclassoffset=readushort(f)
+ local marksetsoffset=version>=0x00010002 and readushort(f) or 0
+ local varsetsoffset=version>=0x00010003 and readulong(f) or 0
+ local glyphs=fontdata.glyphs
+ local marks={}
+ local markclasses=setmetatableindex("table")
+ local marksets=setmetatableindex("table")
+ fontdata.marks=marks
+ fontdata.markclasses=markclasses
+ fontdata.marksets=marksets
+ if classoffset~=0 then
+ setposition(f,tableoffset+classoffset)
+ local classformat=readushort(f)
+ if classformat==1 then
+ local firstindex=readushort(f)
+ local lastindex=firstindex+readushort(f)-1
+ for index=firstindex,lastindex do
+ local class=classes[readushort(f)]
+ if class=="mark" then
+ marks[index]=true
+ end
+ glyphs[index].class=class
end
- if markclassoffset~=0 then
- setposition(f,tableoffset+markclassoffset)
- local classformat=readushort(f)
- if classformat==1 then
- local firstindex=readushort(f)
- local lastindex=firstindex+readushort(f)-1
- for index=firstindex,lastindex do
- markclasses[readushort(f)][index]=true
- end
- elseif classformat==2 then
- local nofranges=readushort(f)
- for i=1,nofranges do
- local firstindex=readushort(f)
- local lastindex=readushort(f)
- local class=markclasses[readushort(f)]
- for index=firstindex,lastindex do
- class[index]=true
- end
- end
+ elseif classformat==2 then
+ local nofranges=readushort(f)
+ for i=1,nofranges do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local class=classes[readushort(f)]
+ if class then
+ for index=firstindex,lastindex do
+ glyphs[index].class=class
+ if class=="mark" then
+ marks[index]=true
+ end
end
+ end
end
- if marksetsoffset~=0 then
- marksetsoffset=tableoffset+marksetsoffset
- setposition(f,marksetsoffset)
- local format=readushort(f)
- if format==1 then
- local nofsets=readushort(f)
- local sets=readcardinaltable(f,nofsets,ulong)
- for i=1,nofsets do
- local offset=sets[i]
- if offset~=0 then
- marksets[i]=readcoverage(f,marksetsoffset+offset)
- end
- end
- end
+ end
+ end
+ if markclassoffset~=0 then
+ setposition(f,tableoffset+markclassoffset)
+ local classformat=readushort(f)
+ if classformat==1 then
+ local firstindex=readushort(f)
+ local lastindex=firstindex+readushort(f)-1
+ for index=firstindex,lastindex do
+ markclasses[readushort(f)][index]=true
end
- local factors=specification.factors
- if (specification.variable or factors) and varsetsoffset~=0 then
- local regions,deltas=readvariationdata(f,tableoffset+varsetsoffset,factors)
- if factors then
- fontdata.temporary.getdelta=function(outer,inner)
- local delta=deltas[outer+1]
- if delta then
- local d=delta.deltas[inner+1]
- if d then
- local scales=delta.scales
- local dd=0
- for i=1,#scales do
- local di=d[i]
- if di then
- dd=dd+scales[i]*di
- else
- break
- end
- end
- return round(dd)
- end
- end
- return 0
+ elseif classformat==2 then
+ local nofranges=readushort(f)
+ for i=1,nofranges do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local class=markclasses[readushort(f)]
+ for index=firstindex,lastindex do
+ class[index]=true
+ end
+ end
+ end
+ end
+ if marksetsoffset~=0 then
+ marksetsoffset=tableoffset+marksetsoffset
+ setposition(f,marksetsoffset)
+ local format=readushort(f)
+ if format==1 then
+ local nofsets=readushort(f)
+ local sets=readcardinaltable(f,nofsets,ulong)
+ for i=1,nofsets do
+ local offset=sets[i]
+ if offset~=0 then
+ marksets[i]=readcoverage(f,marksetsoffset+offset)
+ end
+ end
+ end
+ end
+ local factors=specification.factors
+ if (specification.variable or factors) and varsetsoffset~=0 then
+ local regions,deltas=readvariationdata(f,tableoffset+varsetsoffset,factors)
+ if factors then
+ fontdata.temporary.getdelta=function(outer,inner)
+ local delta=deltas[outer+1]
+ if delta then
+ local d=delta.deltas[inner+1]
+ if d then
+ local scales=delta.scales
+ local dd=0
+ for i=1,#scales do
+ local di=d[i]
+ if di then
+ dd=dd+scales[i]*di
+ else
+ break
end
+ end
+ return round(dd)
end
+ end
+ return 0
end
+ end
end
+ end
end
local function readmathvalue(f)
- local v=readshort(f)
- skipshort(f,1)
- return v
+ local v=readshort(f)
+ skipshort(f,1)
+ return v
end
local function readmathconstants(f,fontdata,offset)
- setposition(f,offset)
- fontdata.mathconstants={
- ScriptPercentScaleDown=readshort(f),
- ScriptScriptPercentScaleDown=readshort(f),
- DelimitedSubFormulaMinHeight=readushort(f),
- DisplayOperatorMinHeight=readushort(f),
- MathLeading=readmathvalue(f),
- AxisHeight=readmathvalue(f),
- AccentBaseHeight=readmathvalue(f),
- FlattenedAccentBaseHeight=readmathvalue(f),
- SubscriptShiftDown=readmathvalue(f),
- SubscriptTopMax=readmathvalue(f),
- SubscriptBaselineDropMin=readmathvalue(f),
- SuperscriptShiftUp=readmathvalue(f),
- SuperscriptShiftUpCramped=readmathvalue(f),
- SuperscriptBottomMin=readmathvalue(f),
- SuperscriptBaselineDropMax=readmathvalue(f),
- SubSuperscriptGapMin=readmathvalue(f),
- SuperscriptBottomMaxWithSubscript=readmathvalue(f),
- SpaceAfterScript=readmathvalue(f),
- UpperLimitGapMin=readmathvalue(f),
- UpperLimitBaselineRiseMin=readmathvalue(f),
- LowerLimitGapMin=readmathvalue(f),
- LowerLimitBaselineDropMin=readmathvalue(f),
- StackTopShiftUp=readmathvalue(f),
- StackTopDisplayStyleShiftUp=readmathvalue(f),
- StackBottomShiftDown=readmathvalue(f),
- StackBottomDisplayStyleShiftDown=readmathvalue(f),
- StackGapMin=readmathvalue(f),
- StackDisplayStyleGapMin=readmathvalue(f),
- StretchStackTopShiftUp=readmathvalue(f),
- StretchStackBottomShiftDown=readmathvalue(f),
- StretchStackGapAboveMin=readmathvalue(f),
- StretchStackGapBelowMin=readmathvalue(f),
- FractionNumeratorShiftUp=readmathvalue(f),
- FractionNumeratorDisplayStyleShiftUp=readmathvalue(f),
- FractionDenominatorShiftDown=readmathvalue(f),
- FractionDenominatorDisplayStyleShiftDown=readmathvalue(f),
- FractionNumeratorGapMin=readmathvalue(f),
- FractionNumeratorDisplayStyleGapMin=readmathvalue(f),
- FractionRuleThickness=readmathvalue(f),
- FractionDenominatorGapMin=readmathvalue(f),
- FractionDenominatorDisplayStyleGapMin=readmathvalue(f),
- SkewedFractionHorizontalGap=readmathvalue(f),
- SkewedFractionVerticalGap=readmathvalue(f),
- OverbarVerticalGap=readmathvalue(f),
- OverbarRuleThickness=readmathvalue(f),
- OverbarExtraAscender=readmathvalue(f),
- UnderbarVerticalGap=readmathvalue(f),
- UnderbarRuleThickness=readmathvalue(f),
- UnderbarExtraDescender=readmathvalue(f),
- RadicalVerticalGap=readmathvalue(f),
- RadicalDisplayStyleVerticalGap=readmathvalue(f),
- RadicalRuleThickness=readmathvalue(f),
- RadicalExtraAscender=readmathvalue(f),
- RadicalKernBeforeDegree=readmathvalue(f),
- RadicalKernAfterDegree=readmathvalue(f),
- RadicalDegreeBottomRaisePercent=readshort(f),
- }
+ setposition(f,offset)
+ fontdata.mathconstants={
+ ScriptPercentScaleDown=readshort(f),
+ ScriptScriptPercentScaleDown=readshort(f),
+ DelimitedSubFormulaMinHeight=readushort(f),
+ DisplayOperatorMinHeight=readushort(f),
+ MathLeading=readmathvalue(f),
+ AxisHeight=readmathvalue(f),
+ AccentBaseHeight=readmathvalue(f),
+ FlattenedAccentBaseHeight=readmathvalue(f),
+ SubscriptShiftDown=readmathvalue(f),
+ SubscriptTopMax=readmathvalue(f),
+ SubscriptBaselineDropMin=readmathvalue(f),
+ SuperscriptShiftUp=readmathvalue(f),
+ SuperscriptShiftUpCramped=readmathvalue(f),
+ SuperscriptBottomMin=readmathvalue(f),
+ SuperscriptBaselineDropMax=readmathvalue(f),
+ SubSuperscriptGapMin=readmathvalue(f),
+ SuperscriptBottomMaxWithSubscript=readmathvalue(f),
+ SpaceAfterScript=readmathvalue(f),
+ UpperLimitGapMin=readmathvalue(f),
+ UpperLimitBaselineRiseMin=readmathvalue(f),
+ LowerLimitGapMin=readmathvalue(f),
+ LowerLimitBaselineDropMin=readmathvalue(f),
+ StackTopShiftUp=readmathvalue(f),
+ StackTopDisplayStyleShiftUp=readmathvalue(f),
+ StackBottomShiftDown=readmathvalue(f),
+ StackBottomDisplayStyleShiftDown=readmathvalue(f),
+ StackGapMin=readmathvalue(f),
+ StackDisplayStyleGapMin=readmathvalue(f),
+ StretchStackTopShiftUp=readmathvalue(f),
+ StretchStackBottomShiftDown=readmathvalue(f),
+ StretchStackGapAboveMin=readmathvalue(f),
+ StretchStackGapBelowMin=readmathvalue(f),
+ FractionNumeratorShiftUp=readmathvalue(f),
+ FractionNumeratorDisplayStyleShiftUp=readmathvalue(f),
+ FractionDenominatorShiftDown=readmathvalue(f),
+ FractionDenominatorDisplayStyleShiftDown=readmathvalue(f),
+ FractionNumeratorGapMin=readmathvalue(f),
+ FractionNumeratorDisplayStyleGapMin=readmathvalue(f),
+ FractionRuleThickness=readmathvalue(f),
+ FractionDenominatorGapMin=readmathvalue(f),
+ FractionDenominatorDisplayStyleGapMin=readmathvalue(f),
+ SkewedFractionHorizontalGap=readmathvalue(f),
+ SkewedFractionVerticalGap=readmathvalue(f),
+ OverbarVerticalGap=readmathvalue(f),
+ OverbarRuleThickness=readmathvalue(f),
+ OverbarExtraAscender=readmathvalue(f),
+ UnderbarVerticalGap=readmathvalue(f),
+ UnderbarRuleThickness=readmathvalue(f),
+ UnderbarExtraDescender=readmathvalue(f),
+ RadicalVerticalGap=readmathvalue(f),
+ RadicalDisplayStyleVerticalGap=readmathvalue(f),
+ RadicalRuleThickness=readmathvalue(f),
+ RadicalExtraAscender=readmathvalue(f),
+ RadicalKernBeforeDegree=readmathvalue(f),
+ RadicalKernAfterDegree=readmathvalue(f),
+ RadicalDegreeBottomRaisePercent=readshort(f),
+ }
end
local function readmathglyphinfo(f,fontdata,offset)
- setposition(f,offset)
- local italics=readushort(f)
- local accents=readushort(f)
- local extensions=readushort(f)
- local kerns=readushort(f)
- local glyphs=fontdata.glyphs
- if italics~=0 then
- setposition(f,offset+italics)
- local coverage=readushort(f)
- local nofglyphs=readushort(f)
- coverage=readcoverage(f,offset+italics+coverage,true)
- setposition(f,offset+italics+4)
- for i=1,nofglyphs do
- local italic=readmathvalue(f)
- if italic~=0 then
- local glyph=glyphs[coverage[i]]
- local math=glyph.math
- if not math then
- glyph.math={ italic=italic }
- else
- math.italic=italic
- end
+ setposition(f,offset)
+ local italics=readushort(f)
+ local accents=readushort(f)
+ local extensions=readushort(f)
+ local kerns=readushort(f)
+ local glyphs=fontdata.glyphs
+ if italics~=0 then
+ setposition(f,offset+italics)
+ local coverage=readushort(f)
+ local nofglyphs=readushort(f)
+ coverage=readcoverage(f,offset+italics+coverage,true)
+ setposition(f,offset+italics+4)
+ for i=1,nofglyphs do
+ local italic=readmathvalue(f)
+ if italic~=0 then
+ local glyph=glyphs[coverage[i]]
+ local math=glyph.math
+ if not math then
+ glyph.math={ italic=italic }
+ else
+ math.italic=italic
+ end
+ end
+ end
+ fontdata.hasitalics=true
+ end
+ if accents~=0 then
+ setposition(f,offset+accents)
+ local coverage=readushort(f)
+ local nofglyphs=readushort(f)
+ coverage=readcoverage(f,offset+accents+coverage,true)
+ setposition(f,offset+accents+4)
+ for i=1,nofglyphs do
+ local accent=readmathvalue(f)
+ if accent~=0 then
+ local glyph=glyphs[coverage[i]]
+ local math=glyph.math
+ if not math then
+ glyph.math={ accent=accent }
+ else
+ math.accent=accent
+ end
+ end
+ end
+ end
+ if extensions~=0 then
+ setposition(f,offset+extensions)
+ end
+ if kerns~=0 then
+ local kernoffset=offset+kerns
+ setposition(f,kernoffset)
+ local coverage=readushort(f)
+ local nofglyphs=readushort(f)
+ if nofglyphs>0 then
+ local function get(offset)
+ setposition(f,kernoffset+offset)
+ local n=readushort(f)
+ if n==0 then
+ local k=readmathvalue(f)
+ if k==0 then
+ else
+ return { { kern=k } }
+ end
+ else
+ local l={}
+ for i=1,n do
+ l[i]={ height=readmathvalue(f) }
+ end
+ for i=1,n do
+ l[i].kern=readmathvalue(f)
+ end
+ l[n+1]={ kern=readmathvalue(f) }
+ return l
+ end
+ end
+ local kernsets={}
+ for i=1,nofglyphs do
+ local topright=readushort(f)
+ local topleft=readushort(f)
+ local bottomright=readushort(f)
+ local bottomleft=readushort(f)
+ kernsets[i]={
+ topright=topright~=0 and topright or nil,
+ topleft=topleft~=0 and topleft or nil,
+ bottomright=bottomright~=0 and bottomright or nil,
+ bottomleft=bottomleft~=0 and bottomleft or nil,
+ }
+ end
+ coverage=readcoverage(f,kernoffset+coverage,true)
+ for i=1,nofglyphs do
+ local kernset=kernsets[i]
+ if next(kernset) then
+ local k=kernset.topright if k then kernset.topright=get(k) end
+ local k=kernset.topleft if k then kernset.topleft=get(k) end
+ local k=kernset.bottomright if k then kernset.bottomright=get(k) end
+ local k=kernset.bottomleft if k then kernset.bottomleft=get(k) end
+ if next(kernset) then
+ local glyph=glyphs[coverage[i]]
+ local math=glyph.math
+ if math then
+ math.kerns=kernset
+ else
+ glyph.math={ kerns=kernset }
end
+ end
end
- fontdata.hasitalics=true
+ end
end
- if accents~=0 then
- setposition(f,offset+accents)
- local coverage=readushort(f)
- local nofglyphs=readushort(f)
- coverage=readcoverage(f,offset+accents+coverage,true)
- setposition(f,offset+accents+4)
- for i=1,nofglyphs do
- local accent=readmathvalue(f)
- if accent~=0 then
- local glyph=glyphs[coverage[i]]
- local math=glyph.math
- if not math then
- glyph.math={ accent=accent }
- else
- math.accent=accent
- end
+ end
+end
+local function readmathvariants(f,fontdata,offset)
+ setposition(f,offset)
+ local glyphs=fontdata.glyphs
+ local minoverlap=readushort(f)
+ local vcoverage=readushort(f)
+ local hcoverage=readushort(f)
+ local vnofglyphs=readushort(f)
+ local hnofglyphs=readushort(f)
+ local vconstruction=readcardinaltable(f,vnofglyphs,ushort)
+ local hconstruction=readcardinaltable(f,hnofglyphs,ushort)
+ fontdata.mathconstants.MinConnectorOverlap=minoverlap
+ local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic)
+ if coverage~=0 and nofglyphs>0 then
+ local coverage=readcoverage(f,offset+coverage,true)
+ for i=1,nofglyphs do
+ local c=construction[i]
+ if c~=0 then
+ local index=coverage[i]
+ local glyph=glyphs[index]
+ local math=glyph.math
+ setposition(f,offset+c)
+ local assembly=readushort(f)
+ local nofvariants=readushort(f)
+ if nofvariants>0 then
+ local variants,v=nil,0
+ for i=1,nofvariants do
+ local variant=readushort(f)
+ if variant==index then
+ elseif variants then
+ v=v+1
+ variants[v]=variant
+ else
+ v=1
+ variants={ variant }
+ end
+ skipshort(f)
end
- end
- end
- if extensions~=0 then
- setposition(f,offset+extensions)
- end
- if kerns~=0 then
- local kernoffset=offset+kerns
- setposition(f,kernoffset)
- local coverage=readushort(f)
- local nofglyphs=readushort(f)
- if nofglyphs>0 then
- local function get(offset)
- setposition(f,kernoffset+offset)
- local n=readushort(f)
- if n==0 then
- local k=readmathvalue(f)
- if k==0 then
- else
- return { { kern=k } }
- end
- else
- local l={}
- for i=1,n do
- l[i]={ height=readmathvalue(f) }
- end
- for i=1,n do
- l[i].kern=readmathvalue(f)
- end
- l[n+1]={ kern=readmathvalue(f) }
- return l
- end
+ if not variants then
+ elseif not math then
+ math={ [kvariants]=variants }
+ glyph.math=math
+ else
+ math[kvariants]=variants
end
- local kernsets={}
- for i=1,nofglyphs do
- local topright=readushort(f)
- local topleft=readushort(f)
- local bottomright=readushort(f)
- local bottomleft=readushort(f)
- kernsets[i]={
- topright=topright~=0 and topright or nil,
- topleft=topleft~=0 and topleft or nil,
- bottomright=bottomright~=0 and bottomright or nil,
- bottomleft=bottomleft~=0 and bottomleft or nil,
- }
+ end
+ if assembly~=0 then
+ setposition(f,offset+c+assembly)
+ local italic=readmathvalue(f)
+ local nofparts=readushort(f)
+ local parts={}
+ for i=1,nofparts do
+ local p={
+ glyph=readushort(f),
+ start=readushort(f),
+ ["end"]=readushort(f),
+ advance=readushort(f),
+ }
+ local flags=readushort(f)
+ if band(flags,0x0001)~=0 then
+ p.extender=1
+ end
+ parts[i]=p
end
- coverage=readcoverage(f,kernoffset+coverage,true)
- for i=1,nofglyphs do
- local kernset=kernsets[i]
- if next(kernset) then
- local k=kernset.topright if k then kernset.topright=get(k) end
- local k=kernset.topleft if k then kernset.topleft=get(k) end
- local k=kernset.bottomright if k then kernset.bottomright=get(k) end
- local k=kernset.bottomleft if k then kernset.bottomleft=get(k) end
- if next(kernset) then
- local glyph=glyphs[coverage[i]]
- local math=glyph.math
- if math then
- math.kerns=kernset
- else
- glyph.math={ kerns=kernset }
- end
- end
- end
+ if not math then
+ math={
+ [kparts]=parts
+ }
+ glyph.math=math
+ else
+ math[kparts]=parts
end
- end
- end
-end
-local function readmathvariants(f,fontdata,offset)
- setposition(f,offset)
- local glyphs=fontdata.glyphs
- local minoverlap=readushort(f)
- local vcoverage=readushort(f)
- local hcoverage=readushort(f)
- local vnofglyphs=readushort(f)
- local hnofglyphs=readushort(f)
- local vconstruction=readcardinaltable(f,vnofglyphs,ushort)
- local hconstruction=readcardinaltable(f,hnofglyphs,ushort)
- fontdata.mathconstants.MinConnectorOverlap=minoverlap
- local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic)
- if coverage~=0 and nofglyphs>0 then
- local coverage=readcoverage(f,offset+coverage,true)
- for i=1,nofglyphs do
- local c=construction[i]
- if c~=0 then
- local index=coverage[i]
- local glyph=glyphs[index]
- local math=glyph.math
- setposition(f,offset+c)
- local assembly=readushort(f)
- local nofvariants=readushort(f)
- if nofvariants>0 then
- local variants,v=nil,0
- for i=1,nofvariants do
- local variant=readushort(f)
- if variant==index then
- elseif variants then
- v=v+1
- variants[v]=variant
- else
- v=1
- variants={ variant }
- end
- skipshort(f)
- end
- if not variants then
- elseif not math then
- math={ [kvariants]=variants }
- glyph.math=math
- else
- math[kvariants]=variants
- end
- end
- if assembly~=0 then
- setposition(f,offset+c+assembly)
- local italic=readmathvalue(f)
- local nofparts=readushort(f)
- local parts={}
- for i=1,nofparts do
- local p={
- glyph=readushort(f),
- start=readushort(f),
- ["end"]=readushort(f),
- advance=readushort(f),
- }
- local flags=readushort(f)
- if band(flags,0x0001)~=0 then
- p.extender=1
- end
- parts[i]=p
- end
- if not math then
- math={
- [kparts]=parts
- }
- glyph.math=math
- else
- math[kparts]=parts
- end
- if italic and italic~=0 then
- math[kitalic]=italic
- end
- end
- end
+ if italic and italic~=0 then
+ math[kitalic]=italic
end
+ end
end
+ end
end
- get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic")
- get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic")
+ end
+ get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic")
+ get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic")
end
function readers.math(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"math",specification.glyphs)
- if tableoffset then
- local version=readulong(f)
- local constants=readushort(f)
- local glyphinfo=readushort(f)
- local variants=readushort(f)
- if constants==0 then
- report("the math table of %a has no constants",fontdata.filename)
- else
- readmathconstants(f,fontdata,tableoffset+constants)
- end
- if glyphinfo~=0 then
- readmathglyphinfo(f,fontdata,tableoffset+glyphinfo)
- end
- if variants~=0 then
- readmathvariants(f,fontdata,tableoffset+variants)
- end
+ local tableoffset=gotodatatable(f,fontdata,"math",specification.glyphs)
+ if tableoffset then
+ local version=readulong(f)
+ local constants=readushort(f)
+ local glyphinfo=readushort(f)
+ local variants=readushort(f)
+ if constants==0 then
+ report("the math table of %a has no constants",fontdata.filename)
+ else
+ readmathconstants(f,fontdata,tableoffset+constants)
+ end
+ if glyphinfo~=0 then
+ readmathglyphinfo(f,fontdata,tableoffset+glyphinfo)
end
+ if variants~=0 then
+ readmathvariants(f,fontdata,tableoffset+variants)
+ end
+ end
end
function readers.colr(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"colr",specification.glyphs)
- if tableoffset then
- local version=readushort(f)
- if version~=0 then
- report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename)
- return
- end
- if not fontdata.tables.cpal then
- report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal")
- fontdata.colorpalettes={}
- end
- local glyphs=fontdata.glyphs
- local nofglyphs=readushort(f)
- local baseoffset=readulong(f)
- local layeroffset=readulong(f)
- local noflayers=readushort(f)
- local layerrecords={}
- local maxclass=0
- setposition(f,tableoffset+layeroffset)
- for i=1,noflayers do
- local slot=readushort(f)
- local class=readushort(f)
- if class<0xFFFF then
- class=class+1
- if class>maxclass then
- maxclass=class
- end
- end
- layerrecords[i]={
- slot=slot,
- class=class,
- }
- end
- fontdata.maxcolorclass=maxclass
- setposition(f,tableoffset+baseoffset)
- for i=0,nofglyphs-1 do
- local glyphindex=readushort(f)
- local firstlayer=readushort(f)
- local noflayers=readushort(f)
- local t={}
- for i=1,noflayers do
- t[i]=layerrecords[firstlayer+i]
- end
- glyphs[glyphindex].colors=t
- end
+ local tableoffset=gotodatatable(f,fontdata,"colr",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ if version~=0 then
+ report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename)
+ return
end
- fontdata.hascolor=true
+ if not fontdata.tables.cpal then
+ report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal")
+ fontdata.colorpalettes={}
+ end
+ local glyphs=fontdata.glyphs
+ local nofglyphs=readushort(f)
+ local baseoffset=readulong(f)
+ local layeroffset=readulong(f)
+ local noflayers=readushort(f)
+ local layerrecords={}
+ local maxclass=0
+ setposition(f,tableoffset+layeroffset)
+ for i=1,noflayers do
+ local slot=readushort(f)
+ local class=readushort(f)
+ if class<0xFFFF then
+ class=class+1
+ if class>maxclass then
+ maxclass=class
+ end
+ end
+ layerrecords[i]={
+ slot=slot,
+ class=class,
+ }
+ end
+ fontdata.maxcolorclass=maxclass
+ setposition(f,tableoffset+baseoffset)
+ for i=0,nofglyphs-1 do
+ local glyphindex=readushort(f)
+ local firstlayer=readushort(f)
+ local noflayers=readushort(f)
+ local t={}
+ for i=1,noflayers do
+ t[i]=layerrecords[firstlayer+i]
+ end
+ glyphs[glyphindex].colors=t
+ end
+ end
+ fontdata.hascolor=true
end
function readers.cpal(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"cpal",specification.glyphs)
- if tableoffset then
- local version=readushort(f)
- local nofpaletteentries=readushort(f)
- local nofpalettes=readushort(f)
- local nofcolorrecords=readushort(f)
- local firstcoloroffset=readulong(f)
- local colorrecords={}
- local palettes=readcardinaltable(f,nofpalettes,ushort)
- if version==1 then
- local palettettypesoffset=readulong(f)
- local palettelabelsoffset=readulong(f)
- local paletteentryoffset=readulong(f)
- end
- setposition(f,tableoffset+firstcoloroffset)
- for i=1,nofcolorrecords do
- local b,g,r,a=readbytes(f,4)
- colorrecords[i]={
- r,g,b,a~=255 and a or nil,
- }
- end
- for i=1,nofpalettes do
- local p={}
- local o=palettes[i]
- for j=1,nofpaletteentries do
- p[j]=colorrecords[o+j]
- end
- palettes[i]=p
- end
- fontdata.colorpalettes=palettes
- end
+ local tableoffset=gotodatatable(f,fontdata,"cpal",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local nofpaletteentries=readushort(f)
+ local nofpalettes=readushort(f)
+ local nofcolorrecords=readushort(f)
+ local firstcoloroffset=readulong(f)
+ local colorrecords={}
+ local palettes=readcardinaltable(f,nofpalettes,ushort)
+ if version==1 then
+ local palettettypesoffset=readulong(f)
+ local palettelabelsoffset=readulong(f)
+ local paletteentryoffset=readulong(f)
+ end
+ setposition(f,tableoffset+firstcoloroffset)
+ for i=1,nofcolorrecords do
+ local b,g,r,a=readbytes(f,4)
+ colorrecords[i]={
+ r,g,b,a~=255 and a or nil,
+ }
+ end
+ for i=1,nofpalettes do
+ local p={}
+ local o=palettes[i]
+ for j=1,nofpaletteentries do
+ p[j]=colorrecords[o+j]
+ end
+ palettes[i]=p
+ end
+ fontdata.colorpalettes=palettes
+ end
end
function readers.svg(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs)
- if tableoffset then
- local version=readushort(f)
- local glyphs=fontdata.glyphs
- local indexoffset=tableoffset+readulong(f)
- local reserved=readulong(f)
- setposition(f,indexoffset)
- local nofentries=readushort(f)
- local entries={}
- for i=1,nofentries do
- entries[i]={
- first=readushort(f),
- last=readushort(f),
- offset=indexoffset+readulong(f),
- length=readulong(f),
- }
- end
- for i=1,nofentries do
- local entry=entries[i]
- setposition(f,entry.offset)
- entries[i]={
- first=entry.first,
- last=entry.last,
- data=readstring(f,entry.length)
- }
- end
- fontdata.svgshapes=entries
- end
- fontdata.hascolor=true
+ local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local glyphs=fontdata.glyphs
+ local indexoffset=tableoffset+readulong(f)
+ local reserved=readulong(f)
+ setposition(f,indexoffset)
+ local nofentries=readushort(f)
+ local entries={}
+ for i=1,nofentries do
+ entries[i]={
+ first=readushort(f),
+ last=readushort(f),
+ offset=indexoffset+readulong(f),
+ length=readulong(f),
+ }
+ end
+ for i=1,nofentries do
+ local entry=entries[i]
+ setposition(f,entry.offset)
+ entries[i]={
+ first=entry.first,
+ last=entry.last,
+ data=readstring(f,entry.length)
+ }
+ end
+ fontdata.svgshapes=entries
+ end
+ fontdata.hascolor=true
end
function readers.sbix(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"sbix",specification.glyphs)
- if tableoffset then
- local version=readushort(f)
- local flags=readushort(f)
- local nofstrikes=readulong(f)
- local strikes={}
- local nofglyphs=fontdata.nofglyphs
- for i=1,nofstrikes do
- strikes[i]=readulong(f)
- end
- local shapes={}
- local done=0
- for i=1,nofstrikes do
- local strikeoffset=strikes[i]+tableoffset
- setposition(f,strikeoffset)
- strikes[i]={
- ppem=readushort(f),
- ppi=readushort(f),
- offset=strikeoffset
+ local tableoffset=gotodatatable(f,fontdata,"sbix",specification.glyphs)
+ if tableoffset then
+ local version=readushort(f)
+ local flags=readushort(f)
+ local nofstrikes=readulong(f)
+ local strikes={}
+ local nofglyphs=fontdata.nofglyphs
+ for i=1,nofstrikes do
+ strikes[i]=readulong(f)
+ end
+ local shapes={}
+ local done=0
+ for i=1,nofstrikes do
+ local strikeoffset=strikes[i]+tableoffset
+ setposition(f,strikeoffset)
+ strikes[i]={
+ ppem=readushort(f),
+ ppi=readushort(f),
+ offset=strikeoffset
+ }
+ end
+ sort(strikes,function(a,b)
+ if b.ppem==a.ppem then
+ return b.ppi<a.ppi
+ else
+ return b.ppem<a.ppem
+ end
+ end)
+ local glyphs={}
+ for i=1,nofstrikes do
+ local strike=strikes[i]
+ local strikeppem=strike.ppem
+ local strikeppi=strike.ppi
+ local strikeoffset=strike.offset
+ setposition(f,strikeoffset)
+ for i=0,nofglyphs do
+ glyphs[i]=readulong(f)
+ end
+ local glyphoffset=glyphs[0]
+ for i=0,nofglyphs-1 do
+ local nextoffset=glyphs[i+1]
+ if not shapes[i] then
+ local datasize=nextoffset-glyphoffset
+ if datasize>0 then
+ setposition(f,strikeoffset+glyphoffset)
+ shapes[i]={
+ x=readshort(f),
+ y=readshort(f),
+ tag=readtag(f),
+ data=readstring(f,datasize-8),
+ ppem=strikeppem,
+ ppi=strikeppi,
}
- end
- sort(strikes,function(a,b)
- if b.ppem==a.ppem then
- return b.ppi<a.ppi
- else
- return b.ppem<a.ppem
- end
- end)
- local glyphs={}
- for i=1,nofstrikes do
- local strike=strikes[i]
- local strikeppem=strike.ppem
- local strikeppi=strike.ppi
- local strikeoffset=strike.offset
- setposition(f,strikeoffset)
- for i=0,nofglyphs do
- glyphs[i]=readulong(f)
- end
- local glyphoffset=glyphs[0]
- for i=0,nofglyphs-1 do
- local nextoffset=glyphs[i+1]
- if not shapes[i] then
- local datasize=nextoffset-glyphoffset
- if datasize>0 then
- setposition(f,strikeoffset+glyphoffset)
- shapes[i]={
- x=readshort(f),
- y=readshort(f),
- tag=readtag(f),
- data=readstring(f,datasize-8),
- ppem=strikeppem,
- ppi=strikeppi,
- }
- done=done+1
- if done==nofglyphs then
- break
- end
- end
- end
- glyphoffset=nextoffset
+ done=done+1
+ if done==nofglyphs then
+ break
end
+ end
end
- fontdata.pngshapes=shapes
+ glyphoffset=nextoffset
+ end
end
+ fontdata.pngshapes=shapes
+ end
end
do
- local function getmetrics(f)
- return {
- ascender=readinteger(f),
- descender=readinteger(f),
- widthmax=readuinteger(f),
- caretslopedumerator=readinteger(f),
- caretslopedenominator=readinteger(f),
- caretoffset=readinteger(f),
- minorigin=readinteger(f),
- minadvance=readinteger(f),
- maxbefore=readinteger(f),
- minafter=readinteger(f),
- pad1=readinteger(f),
- pad2=readinteger(f),
- }
- end
- local function getbigmetrics(f)
- return {
- height=readuinteger(f),
- width=readuinteger(f),
- horiBearingX=readinteger(f),
- horiBearingY=readinteger(f),
- horiAdvance=readuinteger(f),
- vertBearingX=readinteger(f),
- vertBearingY=readinteger(f),
- vertAdvance=readuinteger(f),
- }
- end
- local function getsmallmetrics(f)
- return {
- height=readuinteger(f),
- width=readuinteger(f),
- bearingX=readinteger(f),
- bearingY=readinteger(f),
- advance=readuinteger(f),
+ local function getmetrics(f)
+ return {
+ ascender=readinteger(f),
+ descender=readinteger(f),
+ widthmax=readuinteger(f),
+ caretslopedumerator=readinteger(f),
+ caretslopedenominator=readinteger(f),
+ caretoffset=readinteger(f),
+ minorigin=readinteger(f),
+ minadvance=readinteger(f),
+ maxbefore=readinteger(f),
+ minafter=readinteger(f),
+ pad1=readinteger(f),
+ pad2=readinteger(f),
+ }
+ end
+ local function getbigmetrics(f)
+ return {
+ height=readuinteger(f),
+ width=readuinteger(f),
+ horiBearingX=readinteger(f),
+ horiBearingY=readinteger(f),
+ horiAdvance=readuinteger(f),
+ vertBearingX=readinteger(f),
+ vertBearingY=readinteger(f),
+ vertAdvance=readuinteger(f),
+ }
+ end
+ local function getsmallmetrics(f)
+ return {
+ height=readuinteger(f),
+ width=readuinteger(f),
+ bearingX=readinteger(f),
+ bearingY=readinteger(f),
+ advance=readuinteger(f),
+ }
+ end
+ function readers.cblc(f,fontdata,specification)
+ local ctdttableoffset=gotodatatable(f,fontdata,"cbdt",specification.glyphs)
+ if not ctdttableoffset then
+ return
+ end
+ local cblctableoffset=gotodatatable(f,fontdata,"cblc",specification.glyphs)
+ if cblctableoffset then
+ local majorversion=readushort(f)
+ local minorversion=readushort(f)
+ local nofsizetables=readulong(f)
+ local sizetables={}
+ local shapes={}
+ local subtables={}
+ for i=1,nofsizetables do
+ sizetables[i]={
+ subtables=readulong(f),
+ indexsize=readulong(f),
+ nofsubtables=readulong(f),
+ colorref=readulong(f),
+ hormetrics=getmetrics(f),
+ vermetrics=getmetrics(f),
+ firstindex=readushort(f),
+ lastindex=readushort(f),
+ ppemx=readbyte(f),
+ ppemy=readbyte(f),
+ bitdepth=readbyte(f),
+ flags=readbyte(f),
}
- end
- function readers.cblc(f,fontdata,specification)
- local ctdttableoffset=gotodatatable(f,fontdata,"cbdt",specification.glyphs)
- if not ctdttableoffset then
- return
- end
- local cblctableoffset=gotodatatable(f,fontdata,"cblc",specification.glyphs)
- if cblctableoffset then
- local majorversion=readushort(f)
- local minorversion=readushort(f)
- local nofsizetables=readulong(f)
- local sizetables={}
- local shapes={}
- local subtables={}
- for i=1,nofsizetables do
- sizetables[i]={
- subtables=readulong(f),
- indexsize=readulong(f),
- nofsubtables=readulong(f),
- colorref=readulong(f),
- hormetrics=getmetrics(f),
- vermetrics=getmetrics(f),
- firstindex=readushort(f),
- lastindex=readushort(f),
- ppemx=readbyte(f),
- ppemy=readbyte(f),
- bitdepth=readbyte(f),
- flags=readbyte(f),
- }
- end
- sort(sizetables,function(a,b)
- if b.ppemx==a.ppemx then
- return b.bitdepth<a.bitdepth
- else
- return b.ppemx<a.ppemx
- end
- end)
- for i=1,nofsizetables do
- local s=sizetables[i]
- local d=false
- for j=s.firstindex,s.lastindex do
- if not shapes[j] then
- shapes[j]=i
- d=true
- end
- end
- if d then
- s.used=true
- end
- end
- for i=1,nofsizetables do
- local s=sizetables[i]
- if s.used then
- local offset=s.subtables
- setposition(f,cblctableoffset+offset)
- for j=1,s.nofsubtables do
- local firstindex=readushort(f)
- local lastindex=readushort(f)
- local tableoffset=readulong(f)+offset
- for k=firstindex,lastindex do
- if shapes[k]==i then
- local s=subtables[tableoffset]
- if not s then
- s={
- firstindex=firstindex,
- lastindex=lastindex,
- }
- subtables[tableoffset]=s
- end
- shapes[k]=s
- end
- end
- end
- end
- end
- for offset,subtable in sortedhash(subtables) do
- local tabletype=readushort(f)
- subtable.format=readushort(f)
- local baseoffset=readulong(f)+ctdttableoffset
- local offsets={}
- local metrics=nil
- if tabletype==1 then
- for i=subtable.firstindex,subtable.lastindex do
- offsets[i]=readulong(f)+baseoffset
- end
- skipbytes(f,4)
- elseif tabletype==2 then
- local size=readulong(f)
- local done=baseoffset
- metrics=getbigmetrics(f)
- for i=subtable.firstindex,subtable.lastindex do
- offsets[i]=done
- done=done+size
- end
- elseif tabletype==3 then
- local n=subtable.lastindex-subtable.firstindex+2
- for i=subtable.firstindex,subtable.lastindex do
- offsets[i]=readushort(f)+baseoffset
- end
- if math.odd(n) then
- skipbytes(f,4)
- else
- skipbytes(f,2)
- end
- elseif tabletype==4 then
- for i=1,readulong(f) do
- offsets[readushort(f)]=readushort(f)+baseoffset
- end
- elseif tabletype==5 then
- local size=readulong(f)
- local done=baseoffset
- metrics=getbigmetrics(f)
- local n=readulong(f)
- for i=1,n do
- offsets[readushort(f)]=done
- done=done+size
- end
- if math.odd(n) then
- skipbytes(f,2)
- end
- else
- return
- end
- subtable.offsets=offsets
- subtable.metrics=metrics
- end
- local default={ width=0,height=0 }
- local glyphs=fontdata.glyphs
- for index,subtable in sortedhash(shapes) do
- if type(subtable)=="table" then
- local data=nil
- local metrics=default
- local format=subtable.format
- local offset=subtable.offsets[index]
- setposition(f,offset)
- if format==17 then
- metrics=getsmallmetrics(f)
- data=readstring(f,readulong(f))
- elseif format==18 then
- metrics=getbigmetrics(f)
- data=readstring(f,readulong(f))
- elseif format==19 then
- metrics=subtable.metrics
- data=readstring(f,readulong(f))
- else
- end
- local x=metrics.width
- local y=metrics.height
- shapes[index]={
- x=x,
- y=y,
- data=data,
- }
- local glyph=glyphs[index]
- if not glyph.boundingbox then
- local width=glyph.width
- local height=width*y/x
- glyph.boundingbox={ 0,0,width,height }
- end
- else
- shapes[index]={
- x=0,
- y=0,
- data="",
- }
+ end
+ sort(sizetables,function(a,b)
+ if b.ppemx==a.ppemx then
+ return b.bitdepth<a.bitdepth
+ else
+ return b.ppemx<a.ppemx
+ end
+ end)
+ for i=1,nofsizetables do
+ local s=sizetables[i]
+ local d=false
+ for j=s.firstindex,s.lastindex do
+ if not shapes[j] then
+ shapes[j]=i
+ d=true
+ end
+ end
+ if d then
+ s.used=true
+ end
+ end
+ for i=1,nofsizetables do
+ local s=sizetables[i]
+ if s.used then
+ local offset=s.subtables
+ setposition(f,cblctableoffset+offset)
+ for j=1,s.nofsubtables do
+ local firstindex=readushort(f)
+ local lastindex=readushort(f)
+ local tableoffset=readulong(f)+offset
+ for k=firstindex,lastindex do
+ if shapes[k]==i then
+ local s=subtables[tableoffset]
+ if not s then
+ s={
+ firstindex=firstindex,
+ lastindex=lastindex,
+ }
+ subtables[tableoffset]=s
end
+ shapes[k]=s
+ end
end
- fontdata.pngshapes=shapes
+ end
end
+ end
+ for offset,subtable in sortedhash(subtables) do
+ local tabletype=readushort(f)
+ subtable.format=readushort(f)
+ local baseoffset=readulong(f)+ctdttableoffset
+ local offsets={}
+ local metrics=nil
+ if tabletype==1 then
+ for i=subtable.firstindex,subtable.lastindex do
+ offsets[i]=readulong(f)+baseoffset
+ end
+ skipbytes(f,4)
+ elseif tabletype==2 then
+ local size=readulong(f)
+ local done=baseoffset
+ metrics=getbigmetrics(f)
+ for i=subtable.firstindex,subtable.lastindex do
+ offsets[i]=done
+ done=done+size
+ end
+ elseif tabletype==3 then
+ local n=subtable.lastindex-subtable.firstindex+2
+ for i=subtable.firstindex,subtable.lastindex do
+ offsets[i]=readushort(f)+baseoffset
+ end
+ if math.odd(n) then
+ skipbytes(f,4)
+ else
+ skipbytes(f,2)
+ end
+ elseif tabletype==4 then
+ for i=1,readulong(f) do
+ offsets[readushort(f)]=readushort(f)+baseoffset
+ end
+ elseif tabletype==5 then
+ local size=readulong(f)
+ local done=baseoffset
+ metrics=getbigmetrics(f)
+ local n=readulong(f)
+ for i=1,n do
+ offsets[readushort(f)]=done
+ done=done+size
+ end
+ if math.odd(n) then
+ skipbytes(f,2)
+ end
+ else
+ return
+ end
+ subtable.offsets=offsets
+ subtable.metrics=metrics
+ end
+ local default={ width=0,height=0 }
+ local glyphs=fontdata.glyphs
+ for index,subtable in sortedhash(shapes) do
+ if type(subtable)=="table" then
+ local data=nil
+ local metrics=default
+ local format=subtable.format
+ local offset=subtable.offsets[index]
+ setposition(f,offset)
+ if format==17 then
+ metrics=getsmallmetrics(f)
+ data=readstring(f,readulong(f))
+ elseif format==18 then
+ metrics=getbigmetrics(f)
+ data=readstring(f,readulong(f))
+ elseif format==19 then
+ metrics=subtable.metrics
+ data=readstring(f,readulong(f))
+ else
+ end
+ local x=metrics.width
+ local y=metrics.height
+ shapes[index]={
+ x=x,
+ y=y,
+ data=data,
+ }
+ local glyph=glyphs[index]
+ if not glyph.boundingbox then
+ local width=glyph.width
+ local height=width*y/x
+ glyph.boundingbox={ 0,0,width,height }
+ end
+ else
+ shapes[index]={
+ x=0,
+ y=0,
+ data="",
+ }
+ end
+ end
+ fontdata.pngshapes=shapes
end
- function readers.cbdt(f,fontdata,specification)
- end
+ end
+ function readers.cbdt(f,fontdata,specification)
+ end
end
function readers.stat(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"stat",true)
- if tableoffset then
- local extras=fontdata.extras
- local version=readulong(f)
- local axissize=readushort(f)
- local nofaxis=readushort(f)
- local axisoffset=readulong(f)
- local nofvalues=readushort(f)
- local valuesoffset=readulong(f)
- local fallbackname=extras[readushort(f)]
- local axis={}
- local values={}
- setposition(f,tableoffset+axisoffset)
- for i=1,nofaxis do
- local tag=readtag(f)
- axis[i]={
- tag=tag,
- name=lower(extras[readushort(f)] or tag),
- ordering=readushort(f),
- variants={}
- }
- end
- setposition(f,tableoffset+valuesoffset)
- for i=1,nofvalues do
- values[i]=readushort(f)
- end
- for i=1,nofvalues do
- setposition(f,tableoffset+valuesoffset+values[i])
- local format=readushort(f)
- local index=readushort(f)+1
- local flags=readushort(f)
- local name=lower(extras[readushort(f)] or "no name")
- local value=readfixed(f)
- local variant
- if format==1 then
- variant={
- flags=flags,
- name=name,
- value=value,
- }
- elseif format==2 then
- variant={
- flags=flags,
- name=name,
- value=value,
- minimum=readfixed(f),
- maximum=readfixed(f),
- }
- elseif format==3 then
- variant={
- flags=flags,
- name=name,
- value=value,
- link=readfixed(f),
- }
- end
- insert(axis[index].variants,variant)
- end
- sort(axis,function(a,b)
- return a.ordering<b.ordering
- end)
- for i=1,#axis do
- local a=axis[i]
- sort(a.variants,function(a,b)
- return a.name<b.name
- end)
- a.ordering=nil
- end
- setvariabledata(fontdata,"designaxis",axis)
- setvariabledata(fontdata,"fallbackname",fallbackname)
+ local tableoffset=gotodatatable(f,fontdata,"stat",true)
+ if tableoffset then
+ local extras=fontdata.extras
+ local version=readulong(f)
+ local axissize=readushort(f)
+ local nofaxis=readushort(f)
+ local axisoffset=readulong(f)
+ local nofvalues=readushort(f)
+ local valuesoffset=readulong(f)
+ local fallbackname=extras[readushort(f)]
+ local axis={}
+ local values={}
+ setposition(f,tableoffset+axisoffset)
+ for i=1,nofaxis do
+ local tag=readtag(f)
+ axis[i]={
+ tag=tag,
+ name=lower(extras[readushort(f)] or tag),
+ ordering=readushort(f),
+ variants={}
+ }
+ end
+ setposition(f,tableoffset+valuesoffset)
+ for i=1,nofvalues do
+ values[i]=readushort(f)
+ end
+ for i=1,nofvalues do
+ setposition(f,tableoffset+valuesoffset+values[i])
+ local format=readushort(f)
+ local index=readushort(f)+1
+ local flags=readushort(f)
+ local name=lower(extras[readushort(f)] or "no name")
+ local value=readfixed(f)
+ local variant
+ if format==1 then
+ variant={
+ flags=flags,
+ name=name,
+ value=value,
+ }
+ elseif format==2 then
+ variant={
+ flags=flags,
+ name=name,
+ value=value,
+ minimum=readfixed(f),
+ maximum=readfixed(f),
+ }
+ elseif format==3 then
+ variant={
+ flags=flags,
+ name=name,
+ value=value,
+ link=readfixed(f),
+ }
+ end
+ insert(axis[index].variants,variant)
end
+ sort(axis,function(a,b)
+ return a.ordering<b.ordering
+ end)
+ for i=1,#axis do
+ local a=axis[i]
+ sort(a.variants,function(a,b)
+ return a.name<b.name
+ end)
+ a.ordering=nil
+ end
+ setvariabledata(fontdata,"designaxis",axis)
+ setvariabledata(fontdata,"fallbackname",fallbackname)
+ end
end
function readers.avar(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"avar",true)
- if tableoffset then
- local function collect()
- local nofvalues=readushort(f)
- local values={}
- local lastfrom=false
- local lastto=false
- for i=1,nofvalues do
- local f,t=read2dot14(f),read2dot14(f)
- if lastfrom and f<=lastfrom then
- elseif lastto and t>=lastto then
- else
- values[#values+1]={ f,t }
- lastfrom,lastto=f,t
- end
- end
- nofvalues=#values
- if nofvalues>2 then
- local some=values[1]
- if some[1]==-1 and some[2]==-1 then
- some=values[nofvalues]
- if some[1]==1 and some[2]==1 then
- for i=2,nofvalues-1 do
- some=values[i]
- if some[1]==0 and some[2]==0 then
- return values
- end
- end
- end
- end
+ local tableoffset=gotodatatable(f,fontdata,"avar",true)
+ if tableoffset then
+ local function collect()
+ local nofvalues=readushort(f)
+ local values={}
+ local lastfrom=false
+ local lastto=false
+ for i=1,nofvalues do
+ local f,t=read2dot14(f),read2dot14(f)
+ if lastfrom and f<=lastfrom then
+ elseif lastto and t>=lastto then
+ else
+ values[#values+1]={ f,t }
+ lastfrom,lastto=f,t
+ end
+ end
+ nofvalues=#values
+ if nofvalues>2 then
+ local some=values[1]
+ if some[1]==-1 and some[2]==-1 then
+ some=values[nofvalues]
+ if some[1]==1 and some[2]==1 then
+ for i=2,nofvalues-1 do
+ some=values[i]
+ if some[1]==0 and some[2]==0 then
+ return values
+ end
end
- return false
- end
- local version=readulong(f)
- local reserved=readushort(f)
- local nofaxis=readushort(f)
- local segments={}
- for i=1,nofaxis do
- segments[i]=collect()
+ end
end
- setvariabledata(fontdata,"segments",segments)
+ end
+ return false
end
+ local version=readulong(f)
+ local reserved=readushort(f)
+ local nofaxis=readushort(f)
+ local segments={}
+ for i=1,nofaxis do
+ segments[i]=collect()
+ end
+ setvariabledata(fontdata,"segments",segments)
+ end
end
function readers.fvar(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"fvar",true)
- if tableoffset then
- local version=readulong(f)
- local offsettoaxis=tableoffset+readushort(f)
- local reserved=skipshort(f)
- local nofaxis=readushort(f)
- local sizeofaxis=readushort(f)
- local nofinstances=readushort(f)
- local sizeofinstances=readushort(f)
- local extras=fontdata.extras
- local axis={}
- local instances={}
- setposition(f,offsettoaxis)
- for i=1,nofaxis do
- axis[i]={
- tag=readtag(f),
- minimum=readfixed(f),
- default=readfixed(f),
- maximum=readfixed(f),
- flags=readushort(f),
- name=lower(extras[readushort(f)] or "bad name"),
- }
- local n=sizeofaxis-20
- if n>0 then
- skipbytes(f,n)
- elseif n<0 then
- end
- end
- local nofbytes=2+2+2+nofaxis*4
- local readpsname=nofbytes<=sizeofinstances
- local skippable=sizeofinstances-nofbytes
- for i=1,nofinstances do
- local subfamid=readushort(f)
- local flags=readushort(f)
- local values={}
- for i=1,nofaxis do
- values[i]={
- axis=axis[i].tag,
- value=readfixed(f),
- }
- end
- local psnameid=readpsname and readushort(f) or 0xFFFF
- if subfamid==2 or subfamid==17 then
- elseif subfamid==0xFFFF then
- subfamid=nil
- elseif subfamid<=256 or subfamid>=32768 then
- subfamid=nil
- end
- if psnameid==6 then
- elseif psnameid==0xFFFF then
- psnameid=nil
- elseif psnameid<=256 or psnameid>=32768 then
- psnameid=nil
- end
- instances[i]={
- subfamily=extras[subfamid],
- psname=psnameid and extras[psnameid] or nil,
- values=values,
- }
- if skippable>0 then
- skipbytes(f,skippable)
- end
- end
- setvariabledata(fontdata,"axis",axis)
- setvariabledata(fontdata,"instances",instances)
- end
+ local tableoffset=gotodatatable(f,fontdata,"fvar",true)
+ if tableoffset then
+ local version=readulong(f)
+ local offsettoaxis=tableoffset+readushort(f)
+ local reserved=skipshort(f)
+ local nofaxis=readushort(f)
+ local sizeofaxis=readushort(f)
+ local nofinstances=readushort(f)
+ local sizeofinstances=readushort(f)
+ local extras=fontdata.extras
+ local axis={}
+ local instances={}
+ setposition(f,offsettoaxis)
+ for i=1,nofaxis do
+ axis[i]={
+ tag=readtag(f),
+ minimum=readfixed(f),
+ default=readfixed(f),
+ maximum=readfixed(f),
+ flags=readushort(f),
+ name=lower(extras[readushort(f)] or "bad name"),
+ }
+ local n=sizeofaxis-20
+ if n>0 then
+ skipbytes(f,n)
+ elseif n<0 then
+ end
+ end
+ local nofbytes=2+2+2+nofaxis*4
+ local readpsname=nofbytes<=sizeofinstances
+ local skippable=sizeofinstances-nofbytes
+ for i=1,nofinstances do
+ local subfamid=readushort(f)
+ local flags=readushort(f)
+ local values={}
+ for i=1,nofaxis do
+ values[i]={
+ axis=axis[i].tag,
+ value=readfixed(f),
+ }
+ end
+ local psnameid=readpsname and readushort(f) or 0xFFFF
+ if subfamid==2 or subfamid==17 then
+ elseif subfamid==0xFFFF then
+ subfamid=nil
+ elseif subfamid<=256 or subfamid>=32768 then
+ subfamid=nil
+ end
+ if psnameid==6 then
+ elseif psnameid==0xFFFF then
+ psnameid=nil
+ elseif psnameid<=256 or psnameid>=32768 then
+ psnameid=nil
+ end
+ instances[i]={
+ subfamily=extras[subfamid],
+ psname=psnameid and extras[psnameid] or nil,
+ values=values,
+ }
+ if skippable>0 then
+ skipbytes(f,skippable)
+ end
+ end
+ setvariabledata(fontdata,"axis",axis)
+ setvariabledata(fontdata,"instances",instances)
+ end
end
function readers.hvar(f,fontdata,specification)
- local factors=specification.factors
- if not factors then
- return
- end
- local tableoffset=gotodatatable(f,fontdata,"hvar",specification.variable)
- if not tableoffset then
- return
- end
- local version=readulong(f)
- local variationoffset=tableoffset+readulong(f)
- local advanceoffset=tableoffset+readulong(f)
- local lsboffset=tableoffset+readulong(f)
- local rsboffset=tableoffset+readulong(f)
- local regions={}
- local variations={}
- local innerindex={}
- local outerindex={}
- if variationoffset>0 then
- regions,deltas=readvariationdata(f,variationoffset,factors)
- end
- if not regions then
- return
- end
- if advanceoffset>0 then
- setposition(f,advanceoffset)
- local format=readushort(f)
- local mapcount=readushort(f)
- local entrysize=rshift(band(format,0x0030),4)+1
- local nofinnerbits=band(format,0x000F)+1
- local innermask=lshift(1,nofinnerbits)-1
- local readcardinal=read_cardinal[entrysize]
- for i=0,mapcount-1 do
- local mapdata=readcardinal(f)
- outerindex[i]=rshift(mapdata,nofinnerbits)
- innerindex[i]=band(mapdata,innermask)
- end
- setvariabledata(fontdata,"hvarwidths",true)
- local glyphs=fontdata.glyphs
- for i=0,fontdata.nofglyphs-1 do
- local glyph=glyphs[i]
- local width=glyph.width
- if width then
- local outer=outerindex[i] or 0
- local inner=innerindex[i] or i
- if outer and inner then
- local delta=deltas[outer+1]
- if delta then
- local d=delta.deltas[inner+1]
- if d then
- local scales=delta.scales
- local deltaw=0
- for i=1,#scales do
- local di=d[i]
- if di then
- deltaw=deltaw+scales[i]*di
- else
- break
- end
- end
- glyph.width=width+round(deltaw)
- end
- end
+ local factors=specification.factors
+ if not factors then
+ return
+ end
+ local tableoffset=gotodatatable(f,fontdata,"hvar",specification.variable)
+ if not tableoffset then
+ return
+ end
+ local version=readulong(f)
+ local variationoffset=tableoffset+readulong(f)
+ local advanceoffset=tableoffset+readulong(f)
+ local lsboffset=tableoffset+readulong(f)
+ local rsboffset=tableoffset+readulong(f)
+ local regions={}
+ local variations={}
+ local innerindex={}
+ local outerindex={}
+ if variationoffset>0 then
+ regions,deltas=readvariationdata(f,variationoffset,factors)
+ end
+ if not regions then
+ return
+ end
+ if advanceoffset>0 then
+ setposition(f,advanceoffset)
+ local format=readushort(f)
+ local mapcount=readushort(f)
+ local entrysize=rshift(band(format,0x0030),4)+1
+ local nofinnerbits=band(format,0x000F)+1
+ local innermask=lshift(1,nofinnerbits)-1
+ local readcardinal=read_cardinal[entrysize]
+ for i=0,mapcount-1 do
+ local mapdata=readcardinal(f)
+ outerindex[i]=rshift(mapdata,nofinnerbits)
+ innerindex[i]=band(mapdata,innermask)
+ end
+ setvariabledata(fontdata,"hvarwidths",true)
+ local glyphs=fontdata.glyphs
+ for i=0,fontdata.nofglyphs-1 do
+ local glyph=glyphs[i]
+ local width=glyph.width
+ if width then
+ local outer=outerindex[i] or 0
+ local inner=innerindex[i] or i
+ if outer and inner then
+ local delta=deltas[outer+1]
+ if delta then
+ local d=delta.deltas[inner+1]
+ if d then
+ local scales=delta.scales
+ local deltaw=0
+ for i=1,#scales do
+ local di=d[i]
+ if di then
+ deltaw=deltaw+scales[i]*di
+ else
+ break
end
+ end
+ glyph.width=width+round(deltaw)
end
+ end
end
+ end
end
+ end
end
function readers.vvar(f,fontdata,specification)
- if not specification.variable then
- return
- end
+ if not specification.variable then
+ return
+ end
end
function readers.mvar(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"mvar",specification.variable)
- if tableoffset then
- local version=readulong(f)
- local reserved=skipshort(f,1)
- local recordsize=readushort(f)
- local nofrecords=readushort(f)
- local offsettostore=tableoffset+readushort(f)
- local dimensions={}
- local factors=specification.factors
- if factors then
- local regions,deltas=readvariationdata(f,offsettostore,factors)
- for i=1,nofrecords do
- local tag=readtag(f)
- local var=variabletags[tag]
- if var then
- local outer=readushort(f)
- local inner=readushort(f)
- local delta=deltas[outer+1]
- if delta then
- local d=delta.deltas[inner+1]
- if d then
- local scales=delta.scales
- local dd=0
- for i=1,#scales do
- dd=dd+scales[i]*d[i]
- end
- var(fontdata,round(dd))
- end
- end
- else
- skipshort(f,2)
- end
- if recordsize>8 then
- skipbytes(recordsize-8)
- end
+ local tableoffset=gotodatatable(f,fontdata,"mvar",specification.variable)
+ if tableoffset then
+ local version=readulong(f)
+ local reserved=skipshort(f,1)
+ local recordsize=readushort(f)
+ local nofrecords=readushort(f)
+ local offsettostore=tableoffset+readushort(f)
+ local dimensions={}
+ local factors=specification.factors
+ if factors then
+ local regions,deltas=readvariationdata(f,offsettostore,factors)
+ for i=1,nofrecords do
+ local tag=readtag(f)
+ local var=variabletags[tag]
+ if var then
+ local outer=readushort(f)
+ local inner=readushort(f)
+ local delta=deltas[outer+1]
+ if delta then
+ local d=delta.deltas[inner+1]
+ if d then
+ local scales=delta.scales
+ local dd=0
+ for i=1,#scales do
+ dd=dd+scales[i]*d[i]
+ end
+ var(fontdata,round(dd))
end
+ end
+ else
+ skipshort(f,2)
+ end
+ if recordsize>8 then
+ skipbytes(recordsize-8)
end
+ end
end
+ end
end
end -- closure
@@ -19841,11 +19841,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-oup']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type=next,type
local P,R,S=lpeg.P,lpeg.R,lpeg.S
@@ -19861,10 +19861,10 @@ local report_markwidth=logs.reporter("otf reader","markwidth")
local report_cleanup=logs.reporter("otf reader","cleanup")
local report_optimizations=logs.reporter("otf reader","merges")
local report_unicodes=logs.reporter("otf reader","unicodes")
-local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end)
-local trace_cleanup=false trackers.register("otf.cleanups",function(v) trace_cleanups=v end)
-local trace_optimizations=false trackers.register("otf.optimizations",function(v) trace_optimizations=v end)
-local trace_unicodes=false trackers.register("otf.unicodes",function(v) trace_unicodes=v end)
+local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end)
+local trace_cleanup=false trackers.register("otf.cleanups",function(v) trace_cleanups=v end)
+local trace_optimizations=false trackers.register("otf.optimizations",function(v) trace_optimizations=v end)
+local trace_unicodes=false trackers.register("otf.unicodes",function(v) trace_unicodes=v end)
local readers=fonts.handlers.otf.readers
local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
local f_private=formatters["P%05X"]
@@ -19875,2239 +19875,2239 @@ local f_character_n=formatters["[ %C ]"]
local check_duplicates=true
local check_soft_hyphen=true
directives.register("otf.checksofthyphen",function(v)
- check_soft_hyphen=v
+ check_soft_hyphen=v
end)
local function replaced(list,index,replacement)
- if type(list)=="number" then
- return replacement
- elseif type(replacement)=="table" then
- local t={}
- local n=index-1
- for i=1,n do
- t[i]=list[i]
- end
- for i=1,#replacement do
- n=n+1
- t[n]=replacement[i]
- end
- for i=index+1,#list do
- n=n+1
- t[n]=list[i]
- end
- else
- list[index]=replacement
- return list
+ if type(list)=="number" then
+ return replacement
+ elseif type(replacement)=="table" then
+ local t={}
+ local n=index-1
+ for i=1,n do
+ t[i]=list[i]
end
-end
-local function unifyresources(fontdata,indices)
- local descriptions=fontdata.descriptions
- local resources=fontdata.resources
- if not descriptions or not resources then
- return
+ for i=1,#replacement do
+ n=n+1
+ t[n]=replacement[i]
end
- local nofindices=#indices
- local variants=fontdata.resources.variants
- if variants then
- for selector,unicodes in next,variants do
- for unicode,index in next,unicodes do
- unicodes[unicode]=indices[index]
- end
- end
- end
- local function remark(marks)
- if marks then
- local newmarks={}
- for k,v in next,marks do
- local u=indices[k]
- if u then
- newmarks[u]=v
- elseif trace_optimizations then
- report_optimizations("discarding mark %i",k)
- end
- end
- return newmarks
- end
+ for i=index+1,#list do
+ n=n+1
+ t[n]=list[i]
end
- local marks=resources.marks
+ else
+ list[index]=replacement
+ return list
+ end
+end
+local function unifyresources(fontdata,indices)
+ local descriptions=fontdata.descriptions
+ local resources=fontdata.resources
+ if not descriptions or not resources then
+ return
+ end
+ local nofindices=#indices
+ local variants=fontdata.resources.variants
+ if variants then
+ for selector,unicodes in next,variants do
+ for unicode,index in next,unicodes do
+ unicodes[unicode]=indices[index]
+ end
+ end
+ end
+ local function remark(marks)
if marks then
- resources.marks=remark(marks)
- end
- local markclasses=resources.markclasses
- if markclasses then
- for class,marks in next,markclasses do
- markclasses[class]=remark(marks)
+ local newmarks={}
+ for k,v in next,marks do
+ local u=indices[k]
+ if u then
+ newmarks[u]=v
+ elseif trace_optimizations then
+ report_optimizations("discarding mark %i",k)
+ end
+ end
+ return newmarks
+ end
+ end
+ local marks=resources.marks
+ if marks then
+ resources.marks=remark(marks)
+ end
+ local markclasses=resources.markclasses
+ if markclasses then
+ for class,marks in next,markclasses do
+ markclasses[class]=remark(marks)
+ end
+ end
+ local marksets=resources.marksets
+ if marksets then
+ for class,marks in next,marksets do
+ marksets[class]=remark(marks)
+ end
+ end
+ local done={}
+ local duplicates=check_duplicates and resources.duplicates
+ if duplicates and not next(duplicates) then
+ duplicates=false
+ end
+ local function recover(cover)
+ for i=1,#cover do
+ local c=cover[i]
+ if not done[c] then
+ local t={}
+ for k,v in next,c do
+ local ug=indices[k]
+ if ug then
+ t[ug]=v
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices)
+ end
end
+ cover[i]=t
+ done[c]=d
+ end
end
- local marksets=resources.marksets
- if marksets then
- for class,marks in next,marksets do
- marksets[class]=remark(marks)
+ end
+ local function recursed(c,kind)
+ local t={}
+ for g,d in next,c do
+ if type(d)=="table" then
+ local ug=indices[g]
+ if ug then
+ t[ug]=recursed(d,kind)
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices)
end
+ else
+ t[g]=indices[d]
+ end
end
- local done={}
- local duplicates=check_duplicates and resources.duplicates
- if duplicates and not next(duplicates) then
- duplicates=false
- end
- local function recover(cover)
- for i=1,#cover do
- local c=cover[i]
- if not done[c] then
- local t={}
- for k,v in next,c do
- local ug=indices[k]
- if ug then
- t[ug]=v
+ return t
+ end
+ local function unifythem(sequences)
+ if not sequences then
+ return
+ end
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local features=sequence.features
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gsub_single" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ local ud1=indices[d1]
+ if ud1 then
+ t1[ug1]=ud1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=ud1
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices)
+ end
else
- report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices)
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
end
- end
- cover[i]=t
- done[c]=d
- end
- end
- end
- local function recursed(c,kind)
- local t={}
- for g,d in next,c do
- if type(d)=="table" then
- local ug=indices[g]
- if ug then
- t[ug]=recursed(d,kind)
+ end
else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices)
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=indices[d1]
+ else
+ report_error("fuzzy case %i in unifying %s: %i",2,kind,g1)
+ end
+ end
end
- else
- t[g]=indices[d]
+ done[c]=t1
+ end
+ step.coverage=t1
end
- end
- return t
- end
- local function unifythem(sequences)
- if not sequences then
- return
- end
- for i=1,#sequences do
- local sequence=sequences[i]
- local kind=sequence.type
- local steps=sequence.steps
- local features=sequence.features
- if steps then
- for i=1,#steps do
- local step=steps[i]
- if kind=="gsub_single" then
- local c=step.coverage
- if c then
- local t1=done[c]
- if not t1 then
- t1={}
- if duplicates then
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- local ud1=indices[d1]
- if ud1 then
- t1[ug1]=ud1
- local dg1=duplicates[ug1]
- if dg1 then
- for u in next,dg1 do
- t1[u]=ud1
- end
- end
- else
- report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices)
- end
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
- end
- end
- else
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=indices[d1]
- else
- report_error("fuzzy case %i in unifying %s: %i",2,kind,g1)
- end
- end
- end
- done[c]=t1
- end
- step.coverage=t1
- end
- elseif kind=="gpos_pair" then
- local c=step.coverage
- if c then
- local t1=done[c]
- if not t1 then
- t1={}
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- local t2=done[d1]
- if not t2 then
- t2={}
- for g2,d2 in next,d1 do
- local ug2=indices[g2]
- if ug2 then
- t2[ug2]=d2
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices)
- end
- end
- done[d1]=t2
- end
- t1[ug1]=t2
- else
- report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
- end
- end
- done[c]=t1
- end
- step.coverage=t1
- end
- elseif kind=="gsub_ligature" then
- local c=step.coverage
- if c then
- step.coverage=recursed(c,kind)
- end
- elseif kind=="gsub_alternate" or kind=="gsub_multiple" then
- local c=step.coverage
- if c then
- local t1=done[c]
- if not t1 then
- t1={}
- if duplicates then
- for g1,d1 in next,c do
- for i=1,#d1 do
- local d1i=d1[i]
- local d1u=indices[d1i]
- if d1u then
- d1[i]=d1u
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices)
- end
- end
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=d1
- local dg1=duplicates[ug1]
- if dg1 then
- for u in next,dg1 do
- t1[u]=copy(d1)
- end
- end
- else
- report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
- end
- end
- else
- for g1,d1 in next,c do
- for i=1,#d1 do
- local d1i=d1[i]
- local d1u=indices[d1i]
- if d1u then
- d1[i]=d1u
- else
- report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices)
- end
- end
- t1[indices[g1]]=d1
- end
- end
- done[c]=t1
- end
- step.coverage=t1
- end
- elseif kind=="gpos_single" then
- local c=step.coverage
- if c then
- local t1=done[c]
- if not t1 then
- t1={}
- if duplicates then
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=d1
- local dg1=duplicates[ug1]
- if dg1 then
- for u in next,dg1 do
- t1[u]=d1
- end
- end
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
- end
- end
- else
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=d1
- else
- report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
- end
- end
- end
- done[c]=t1
- end
- step.coverage=t1
- end
- elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then
- local c=step.coverage
- if c then
- local t1=done[c]
- if not t1 then
- t1={}
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=d1
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
- end
- end
- done[c]=t1
- end
- step.coverage=t1
- end
- local c=step.baseclasses
- if c then
- local t1=done[c]
- if not t1 then
- for g1,d1 in next,c do
- local t2=done[d1]
- if not t2 then
- t2={}
- for g2,d2 in next,d1 do
- local ug2=indices[g2]
- if ug2 then
- t2[ug2]=d2
- else
- report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices)
- end
- end
- done[d1]=t2
- end
- c[g1]=t2
- end
- done[c]=c
- end
- end
- elseif kind=="gpos_cursive" then
- local c=step.coverage
- if c then
- local t1=done[c]
- if not t1 then
- t1={}
- if duplicates then
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=d1
- local dg1=duplicates[ug1]
- if dg1 then
- for u in next,dg1 do
- t1[u]=copy(d1)
- end
- end
- else
- report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
- end
- end
- else
- for g1,d1 in next,c do
- local ug1=indices[g1]
- if ug1 then
- t1[ug1]=d1
- else
- report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
- end
- end
- end
- done[c]=t1
- end
- step.coverage=t1
- end
- end
- local rules=step.rules
- if rules then
- for i=1,#rules do
- local rule=rules[i]
- local before=rule.before if before then recover(before) end
- local after=rule.after if after then recover(after) end
- local current=rule.current if current then recover(current) end
- local replacements=rule.replacements
- if replacements then
- if not done[replacements] then
- local r={}
- for k,v in next,replacements do
- r[indices[k]]=indices[v]
- end
- rule.replacements=r
- done[replacements]=r
- end
- end
+ elseif kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ local t2=done[d1]
+ if not t2 then
+ t2={}
+ for g2,d2 in next,d1 do
+ local ug2=indices[g2]
+ if ug2 then
+ t2[ug2]=d2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices)
end
+ end
+ done[d1]=t2
end
+ t1[ug1]=t2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
end
+ done[c]=t1
+ end
+ step.coverage=t1
end
- end
- end
- unifythem(resources.sequences)
- unifythem(resources.sublookups)
-end
-local function copyduplicates(fontdata)
- if check_duplicates then
- local descriptions=fontdata.descriptions
- local resources=fontdata.resources
- local duplicates=resources.duplicates
- if check_soft_hyphen then
- local ds=descriptions[0xAD]
- if not ds or ds.width==0 then
- if ds then
- descriptions[0xAD]=nil
- if trace_unicodes then
- report_unicodes("patching soft hyphen")
+ elseif kind=="gsub_ligature" then
+ local c=step.coverage
+ if c then
+ step.coverage=recursed(c,kind)
+ end
+ elseif kind=="gsub_alternate" or kind=="gsub_multiple" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ for i=1,#d1 do
+ local d1i=d1[i]
+ local d1u=indices[d1i]
+ if d1u then
+ d1[i]=d1u
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices)
+ end
+ end
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=copy(d1)
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
end
+ end
else
- if trace_unicodes then
- report_unicodes("adding soft hyphen")
+ for g1,d1 in next,c do
+ for i=1,#d1 do
+ local d1i=d1[i]
+ local d1u=indices[d1i]
+ if d1u then
+ d1[i]=d1u
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices)
+ end
+ end
+ t1[indices[g1]]=d1
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ elseif kind=="gpos_single" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=d1
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
end
- end
- if not duplicates then
- duplicates={}
- resources.duplicates=duplicates
- end
- local dh=duplicates[0x2D]
- if dh then
- dh[#dh+1]={ [0xAD]=true }
+ end
else
- duplicates[0x2D]={ [0xAD]=true }
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
end
+ done[c]=t1
+ end
+ step.coverage=t1
end
- end
- if duplicates then
- for u,d in next,duplicates do
- local du=descriptions[u]
- if du then
- local t={ f_character_y(u),"@",f_index(du.index),"->" }
- local n=0
- local m=25
- for u in next,d do
- if descriptions[u] then
- if n<m then
- t[n+4]=f_character_n(u)
- end
- else
- local c=copy(du)
- c.unicode=u
- descriptions[u]=c
- if n<m then
- t[n+4]=f_character_y(u)
- end
- end
- n=n+1
- end
- if trace_unicodes then
- if n<=m then
- report_unicodes("%i : % t",n,t)
- else
- report_unicodes("%i : % t ...",n,t)
- end
+ elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
+ end
+ end
+ done[c]=t1
+ end
+ step.coverage=t1
+ end
+ local c=step.baseclasses
+ if c then
+ local t1=done[c]
+ if not t1 then
+ for g1,d1 in next,c do
+ local t2=done[d1]
+ if not t2 then
+ t2={}
+ for g2,d2 in next,d1 do
+ local ug2=indices[g2]
+ if ug2 then
+ t2[ug2]=d2
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices)
+ end
+ end
+ done[d1]=t2
+ end
+ c[g1]=t2
+ end
+ done[c]=c
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ local t1=done[c]
+ if not t1 then
+ t1={}
+ if duplicates then
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ local dg1=duplicates[ug1]
+ if dg1 then
+ for u in next,dg1 do
+ t1[u]=copy(d1)
+ end
+ end
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices)
end
+ end
else
+ for g1,d1 in next,c do
+ local ug1=indices[g1]
+ if ug1 then
+ t1[ug1]=d1
+ else
+ report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices)
+ end
+ end
end
+ done[c]=t1
+ end
+ step.coverage=t1
end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local before=rule.before if before then recover(before) end
+ local after=rule.after if after then recover(after) end
+ local current=rule.current if current then recover(current) end
+ local replacements=rule.replacements
+ if replacements then
+ if not done[replacements] then
+ local r={}
+ for k,v in next,replacements do
+ r[indices[k]]=indices[v]
+ end
+ rule.replacements=r
+ done[replacements]=r
+ end
+ end
+ end
+ end
end
- end
+ end
+ end
+ end
+ unifythem(resources.sequences)
+ unifythem(resources.sublookups)
end
-local ignore={
- ["notdef"]=true,
- [".notdef"]=true,
- ["null"]=true,
- [".null"]=true,
- ["nonmarkingreturn"]=true,
-}
-local function checklookups(fontdata,missing,nofmissing)
+local function copyduplicates(fontdata)
+ if check_duplicates then
local descriptions=fontdata.descriptions
local resources=fontdata.resources
- if missing and nofmissing and nofmissing<=0 then
- return
- end
- local singles={}
- local alternates={}
- local ligatures={}
- if not missing then
- missing={}
- nofmissing=0
- for u,d in next,descriptions do
- if not d.unicode then
- nofmissing=nofmissing+1
- missing[u]=true
- end
+ local duplicates=resources.duplicates
+ if check_soft_hyphen then
+ local ds=descriptions[0xAD]
+ if not ds or ds.width==0 then
+ if ds then
+ descriptions[0xAD]=nil
+ if trace_unicodes then
+ report_unicodes("patching soft hyphen")
+ end
+ else
+ if trace_unicodes then
+ report_unicodes("adding soft hyphen")
+ end
end
- end
- local function collectthem(sequences)
- if not sequences then
- return
+ if not duplicates then
+ duplicates={}
+ resources.duplicates=duplicates
end
- for i=1,#sequences do
- local sequence=sequences[i]
- local kind=sequence.type
- local steps=sequence.steps
- if steps then
- for i=1,#steps do
- local step=steps[i]
- if kind=="gsub_single" then
- local c=step.coverage
- if c then
- singles[#singles+1]=c
- end
- elseif kind=="gsub_alternate" then
- local c=step.coverage
- if c then
- alternates[#alternates+1]=c
- end
- elseif kind=="gsub_ligature" then
- local c=step.coverage
- if c then
- ligatures[#ligatures+1]=c
- end
- end
- end
+ local dh=duplicates[0x2D]
+ if dh then
+ dh[#dh+1]={ [0xAD]=true }
+ else
+ duplicates[0x2D]={ [0xAD]=true }
+ end
+ end
+ end
+ if duplicates then
+ for u,d in next,duplicates do
+ local du=descriptions[u]
+ if du then
+ local t={ f_character_y(u),"@",f_index(du.index),"->" }
+ local n=0
+ local m=25
+ for u in next,d do
+ if descriptions[u] then
+ if n<m then
+ t[n+4]=f_character_n(u)
+ end
+ else
+ local c=copy(du)
+ c.unicode=u
+ descriptions[u]=c
+ if n<m then
+ t[n+4]=f_character_y(u)
+ end
end
+ n=n+1
+ end
+ if trace_unicodes then
+ if n<=m then
+ report_unicodes("%i : % t",n,t)
+ else
+ report_unicodes("%i : % t ...",n,t)
+ end
+ end
+ else
end
+ end
end
- collectthem(resources.sequences)
- collectthem(resources.sublookups)
- local loops=0
- while true do
- loops=loops+1
- local old=nofmissing
- for i=1,#singles do
- local c=singles[i]
- for g1,g2 in next,c do
- if missing[g1] then
- local u2=descriptions[g2].unicode
- if u2 then
- missing[g1]=false
- descriptions[g1].unicode=u2
- nofmissing=nofmissing-1
- end
- end
- if missing[g2] then
- local u1=descriptions[g1].unicode
- if u1 then
- missing[g2]=false
- descriptions[g2].unicode=u1
- nofmissing=nofmissing-1
- end
- end
+ end
+end
+local ignore={
+ ["notdef"]=true,
+ [".notdef"]=true,
+ ["null"]=true,
+ [".null"]=true,
+ ["nonmarkingreturn"]=true,
+}
+local function checklookups(fontdata,missing,nofmissing)
+ local descriptions=fontdata.descriptions
+ local resources=fontdata.resources
+ if missing and nofmissing and nofmissing<=0 then
+ return
+ end
+ local singles={}
+ local alternates={}
+ local ligatures={}
+ if not missing then
+ missing={}
+ nofmissing=0
+ for u,d in next,descriptions do
+ if not d.unicode then
+ nofmissing=nofmissing+1
+ missing[u]=true
+ end
+ end
+ end
+ local function collectthem(sequences)
+ if not sequences then
+ return
+ end
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gsub_single" then
+ local c=step.coverage
+ if c then
+ singles[#singles+1]=c
end
- end
- for i=1,#alternates do
- local c=alternates[i]
- for g1,d1 in next,c do
- if missing[g1] then
- for i=1,#d1 do
- local g2=d1[i]
- local u2=descriptions[g2].unicode
- if u2 then
- missing[g1]=false
- descriptions[g1].unicode=u2
- nofmissing=nofmissing-1
- end
- end
- end
- if not missing[g1] then
- for i=1,#d1 do
- local g2=d1[i]
- if missing[g2] then
- local u1=descriptions[g1].unicode
- if u1 then
- missing[g2]=false
- descriptions[g2].unicode=u1
- nofmissing=nofmissing-1
- end
- end
- end
- end
+ elseif kind=="gsub_alternate" then
+ local c=step.coverage
+ if c then
+ alternates[#alternates+1]=c
end
- end
- if nofmissing<=0 then
- if trace_unicodes then
- report_unicodes("all missings done in %s loops",loops)
+ elseif kind=="gsub_ligature" then
+ local c=step.coverage
+ if c then
+ ligatures[#ligatures+1]=c
end
- return
- elseif old==nofmissing then
- break
+ end
+ end
+ end
+ end
+ end
+ collectthem(resources.sequences)
+ collectthem(resources.sublookups)
+ local loops=0
+ while true do
+ loops=loops+1
+ local old=nofmissing
+ for i=1,#singles do
+ local c=singles[i]
+ for g1,g2 in next,c do
+ if missing[g1] then
+ local u2=descriptions[g2].unicode
+ if u2 then
+ missing[g1]=false
+ descriptions[g1].unicode=u2
+ nofmissing=nofmissing-1
+ end
+ end
+ if missing[g2] then
+ local u1=descriptions[g1].unicode
+ if u1 then
+ missing[g2]=false
+ descriptions[g2].unicode=u1
+ nofmissing=nofmissing-1
+ end
end
+ end
end
- local t,n
- local function recursed(c)
- for g,d in next,c do
- if g~="ligature" then
- local u=descriptions[g].unicode
- if u then
- n=n+1
- t[n]=u
- recursed(d)
- n=n-1
- end
- elseif missing[d] then
- local l={}
- local m=0
- for i=1,n do
- local u=t[i]
- if type(u)=="table" then
- for i=1,#u do
- m=m+1
- l[m]=u[i]
- end
- else
- m=m+1
- l[m]=u
- end
- end
- missing[d]=false
- descriptions[d].unicode=l
+ for i=1,#alternates do
+ local c=alternates[i]
+ for g1,d1 in next,c do
+ if missing[g1] then
+ for i=1,#d1 do
+ local g2=d1[i]
+ local u2=descriptions[g2].unicode
+ if u2 then
+ missing[g1]=false
+ descriptions[g1].unicode=u2
+ nofmissing=nofmissing-1
+ end
+ end
+ end
+ if not missing[g1] then
+ for i=1,#d1 do
+ local g2=d1[i]
+ if missing[g2] then
+ local u1=descriptions[g1].unicode
+ if u1 then
+ missing[g2]=false
+ descriptions[g2].unicode=u1
nofmissing=nofmissing-1
+ end
end
+ end
end
- end
- if nofmissing>0 then
- t={}
- n=0
- local loops=0
- while true do
- loops=loops+1
- local old=nofmissing
- for i=1,#ligatures do
- recursed(ligatures[i])
- end
- if nofmissing<=0 then
- if trace_unicodes then
- report_unicodes("all missings done in %s loops",loops)
- end
- return
- elseif old==nofmissing then
- break
+ end
+ end
+ if nofmissing<=0 then
+ if trace_unicodes then
+ report_unicodes("all missings done in %s loops",loops)
+ end
+ return
+ elseif old==nofmissing then
+ break
+ end
+ end
+ local t,n
+ local function recursed(c)
+ for g,d in next,c do
+ if g~="ligature" then
+ local u=descriptions[g].unicode
+ if u then
+ n=n+1
+ t[n]=u
+ recursed(d)
+ n=n-1
+ end
+ elseif missing[d] then
+ local l={}
+ local m=0
+ for i=1,n do
+ local u=t[i]
+ if type(u)=="table" then
+ for i=1,#u do
+ m=m+1
+ l[m]=u[i]
end
+ else
+ m=m+1
+ l[m]=u
+ end
end
- t=nil
- n=0
+ missing[d]=false
+ descriptions[d].unicode=l
+ nofmissing=nofmissing-1
+ end
end
- if trace_unicodes and nofmissing>0 then
- local done={}
- for i,r in next,missing do
- if r then
- local data=descriptions[i]
- local name=data and data.name or f_index(i)
- if not ignore[name] then
- done[name]=true
- end
- end
+ end
+ if nofmissing>0 then
+ t={}
+ n=0
+ local loops=0
+ while true do
+ loops=loops+1
+ local old=nofmissing
+ for i=1,#ligatures do
+ recursed(ligatures[i])
+ end
+ if nofmissing<=0 then
+ if trace_unicodes then
+ report_unicodes("all missings done in %s loops",loops)
end
- if next(done) then
- report_unicodes("not unicoded: % t",sortedkeys(done))
+ return
+ elseif old==nofmissing then
+ break
+ end
+ end
+ t=nil
+ n=0
+ end
+ if trace_unicodes and nofmissing>0 then
+ local done={}
+ for i,r in next,missing do
+ if r then
+ local data=descriptions[i]
+ local name=data and data.name or f_index(i)
+ if not ignore[name] then
+ done[name]=true
end
+ end
+ end
+ if next(done) then
+ report_unicodes("not unicoded: % t",sortedkeys(done))
end
+ end
end
local function unifymissing(fontdata)
- if not fonts.mappings then
- require("font-map")
- require("font-agl")
- end
- local unicodes={}
- local resources=fontdata.resources
- resources.unicodes=unicodes
- for unicode,d in next,fontdata.descriptions do
- if unicode<privateoffset then
- local name=d.name
- if name then
- unicodes[name]=unicode
- end
- end
- end
- fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups)
- resources.unicodes=nil
+ if not fonts.mappings then
+ require("font-map")
+ require("font-agl")
+ end
+ local unicodes={}
+ local resources=fontdata.resources
+ resources.unicodes=unicodes
+ for unicode,d in next,fontdata.descriptions do
+ if unicode<privateoffset then
+ local name=d.name
+ if name then
+ unicodes[name]=unicode
+ end
+ end
+ end
+ fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups)
+ resources.unicodes=nil
end
local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000
local puafirst=0xE000
local pualast=0xF8FF
local function unifyglyphs(fontdata,usenames)
- local private=fontdata.private or privateoffset
- local glyphs=fontdata.glyphs
- local indices={}
- local descriptions={}
- local names=usenames and {}
- local resources=fontdata.resources
- local zero=glyphs[0]
- local zerocode=zero.unicode
- if not zerocode then
- zerocode=private
- zero.unicode=zerocode
+ local private=fontdata.private or privateoffset
+ local glyphs=fontdata.glyphs
+ local indices={}
+ local descriptions={}
+ local names=usenames and {}
+ local resources=fontdata.resources
+ local zero=glyphs[0]
+ local zerocode=zero.unicode
+ if not zerocode then
+ zerocode=private
+ zero.unicode=zerocode
+ private=private+1
+ end
+ descriptions[zerocode]=zero
+ if names then
+ local name=glyphs[0].name or f_private(zerocode)
+ indices[0]=name
+ names[name]=zerocode
+ else
+ indices[0]=zerocode
+ end
+ if names then
+ for index=1,#glyphs do
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
private=private+1
- end
- descriptions[zerocode]=zero
- if names then
- local name=glyphs[0].name or f_private(zerocode)
- indices[0]=name
- names[name]=zerocode
- else
- indices[0]=zerocode
- end
- if names then
- for index=1,#glyphs do
- local glyph=glyphs[index]
- local unicode=glyph.unicode
- if not unicode then
- unicode=private
- local name=glyph.name or f_private(unicode)
- indices[index]=name
- names[name]=unicode
- private=private+1
- elseif unicode>=firstprivate then
- unicode=private
- local name=glyph.name or f_private(unicode)
- indices[index]=name
- names[name]=unicode
- private=private+1
- elseif unicode>=puafirst and unicode<=pualast then
- local name=glyph.name or f_private(unicode)
- indices[index]=name
- names[name]=unicode
- elseif descriptions[unicode] then
- unicode=private
- local name=glyph.name or f_private(unicode)
- indices[index]=name
- names[name]=unicode
- private=private+1
- else
- local name=glyph.name or f_unicode(unicode)
- indices[index]=name
- names[name]=unicode
- end
- descriptions[unicode]=glyph
- end
- elseif trace_unicodes then
- for index=1,#glyphs do
- local glyph=glyphs[index]
- local unicode=glyph.unicode
- if not unicode then
- unicode=private
- indices[index]=unicode
- private=private+1
- elseif unicode>=firstprivate then
- local name=glyph.name
- if name then
- report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private)
- else
- report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private)
- end
- unicode=private
- indices[index]=unicode
- private=private+1
- elseif unicode>=puafirst and unicode<=pualast then
- local name=glyph.name
- if name then
- report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index)
- else
- report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index)
- end
- indices[index]=unicode
- elseif descriptions[unicode] then
- local name=glyph.name
- if name then
- report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index)
- else
- report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index)
- end
- unicode=private
- indices[index]=unicode
- private=private+1
- else
- indices[index]=unicode
- end
- descriptions[unicode]=glyph
- end
- else
- for index=1,#glyphs do
- local glyph=glyphs[index]
- local unicode=glyph.unicode
- if not unicode then
- unicode=private
- indices[index]=unicode
- private=private+1
- elseif unicode>=firstprivate then
- local name=glyph.name
- unicode=private
- indices[index]=unicode
- private=private+1
- elseif unicode>=puafirst and unicode<=pualast then
- local name=glyph.name
- indices[index]=unicode
- elseif descriptions[unicode] then
- local name=glyph.name
- unicode=private
- indices[index]=unicode
- private=private+1
- else
- indices[index]=unicode
- end
- descriptions[unicode]=glyph
- end
- end
+ elseif unicode>=firstprivate then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ private=private+1
+ elseif unicode>=puafirst and unicode<=pualast then
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ elseif descriptions[unicode] then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
+ private=private+1
+ else
+ local name=glyph.name or f_unicode(unicode)
+ indices[index]=name
+ names[name]=unicode
+ end
+ descriptions[unicode]=glyph
+ end
+ elseif trace_unicodes then
for index=1,#glyphs do
- local math=glyphs[index].math
- if math then
- local list=math.vparts
- if list then
- for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
- end
- local list=math.hparts
- if list then
- for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
- end
- local list=math.vvariants
- if list then
- for i=1,#list do list[i]=indices[list[i]] end
- end
- local list=math.hvariants
- if list then
- for i=1,#list do list[i]=indices[list[i]] end
- end
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=firstprivate then
+ local name=glyph.name
+ if name then
+ report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private)
+ else
+ report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private)
end
- end
- local colorpalettes=resources.colorpalettes
- if colorpalettes then
- for index=1,#glyphs do
- local colors=glyphs[index].colors
- if colors then
- for i=1,#colors do
- local c=colors[i]
- c.slot=indices[c.slot]
- end
- end
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=puafirst and unicode<=pualast then
+ local name=glyph.name
+ if name then
+ report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index)
+ else
+ report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index)
+ end
+ indices[index]=unicode
+ elseif descriptions[unicode] then
+ local name=glyph.name
+ if name then
+ report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index)
+ else
+ report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index)
end
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ else
+ indices[index]=unicode
+ end
+ descriptions[unicode]=glyph
end
- fontdata.private=private
- fontdata.glyphs=nil
- fontdata.names=names
- fontdata.descriptions=descriptions
- fontdata.hashmethod=hashmethod
- return indices,names
-end
-local p_crappyname do
- local p_hex=R("af","AF","09")
- local p_digit=R("09")
- local p_done=S("._-")^0+P(-1)
- local p_alpha=R("az","AZ")
- local p_ALPHA=R("AZ")
- p_crappyname=(
- lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1
+ else
+ for index=1,#glyphs do
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=firstprivate then
+ local name=glyph.name
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ elseif unicode>=puafirst and unicode<=pualast then
+ local name=glyph.name
+ indices[index]=unicode
+ elseif descriptions[unicode] then
+ local name=glyph.name
+ unicode=private
+ indices[index]=unicode
+ private=private+1
+ else
+ indices[index]=unicode
+ end
+ descriptions[unicode]=glyph
+ end
+ end
+ for index=1,#glyphs do
+ local math=glyphs[index].math
+ if math then
+ local list=math.vparts
+ if list then
+ for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
+ end
+ local list=math.hparts
+ if list then
+ for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
+ end
+ local list=math.vvariants
+ if list then
+ for i=1,#list do list[i]=indices[list[i]] end
+ end
+ local list=math.hvariants
+ if list then
+ for i=1,#list do list[i]=indices[list[i]] end
+ end
+ end
+ end
+ local colorpalettes=resources.colorpalettes
+ if colorpalettes then
+ for index=1,#glyphs do
+ local colors=glyphs[index].colors
+ if colors then
+ for i=1,#colors do
+ local c=colors[i]
+ c.slot=indices[c.slot]
+ end
+ end
+ end
+ end
+ fontdata.private=private
+ fontdata.glyphs=nil
+ fontdata.names=names
+ fontdata.descriptions=descriptions
+ fontdata.hashmethod=hashmethod
+ return indices,names
+end
+local p_crappyname do
+ local p_hex=R("af","AF","09")
+ local p_digit=R("09")
+ local p_done=S("._-")^0+P(-1)
+ local p_alpha=R("az","AZ")
+ local p_ALPHA=R("AZ")
+ p_crappyname=(
+ lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1
+lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1
+lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1
+p_digit*p_hex^3+p_alpha*p_digit^1
+P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1
- )*p_done
+ )*p_done
end
local forcekeep=false
directives.register("otf.keepnames",function(v)
- report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
- forcekeep=v
+ report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
+ forcekeep=v
end)
local function stripredundant(fontdata)
- local descriptions=fontdata.descriptions
- if descriptions then
- local n=0
- local c=0
- if (not context and fonts.privateoffsets.keepnames) or forcekeep then
- for unicode,d in next,descriptions do
- if d.class=="base" then
- d.class=nil
- c=c+1
- end
- end
- else
- for unicode,d in next,descriptions do
- local name=d.name
- if name and lpegmatch(p_crappyname,name) then
- d.name=nil
- n=n+1
- end
- if d.class=="base" then
- d.class=nil
- c=c+1
- end
- end
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ local n=0
+ local c=0
+ if (not context and fonts.privateoffsets.keepnames) or forcekeep then
+ for unicode,d in next,descriptions do
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ else
+ for unicode,d in next,descriptions do
+ local name=d.name
+ if name and lpegmatch(p_crappyname,name) then
+ d.name=nil
+ n=n+1
end
- if trace_cleanup then
- if n>0 then
- report_cleanup("%s bogus names removed (verbose unicode)",n)
- end
- if c>0 then
- report_cleanup("%s base class tags removed (default is base)",c)
- end
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
end
+ end
end
+ if trace_cleanup then
+ if n>0 then
+ report_cleanup("%s bogus names removed (verbose unicode)",n)
+ end
+ if c>0 then
+ report_cleanup("%s base class tags removed (default is base)",c)
+ end
+ end
+ end
end
readers.stripredundant=stripredundant
function readers.getcomponents(fontdata)
- local resources=fontdata.resources
- if resources then
- local sequences=resources.sequences
- if sequences then
- local collected={}
- for i=1,#sequences do
- local sequence=sequences[i]
- if sequence.type=="gsub_ligature" then
- local steps=sequence.steps
- if steps then
- local l={}
- local function traverse(p,k,v)
- if k=="ligature" then
- collected[v]={ unpack(l) }
- else
- insert(l,k)
- for k,vv in next,v do
- traverse(p,k,vv)
- end
- remove(l)
- end
- end
- for i=1,#steps do
- local c=steps[i].coverage
- if c then
- for k,v in next,c do
- traverse(k,k,v)
- end
- end
- end
- end
+ local resources=fontdata.resources
+ if resources then
+ local sequences=resources.sequences
+ if sequences then
+ local collected={}
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ if sequence.type=="gsub_ligature" then
+ local steps=sequence.steps
+ if steps then
+ local l={}
+ local function traverse(p,k,v)
+ if k=="ligature" then
+ collected[v]={ unpack(l) }
+ else
+ insert(l,k)
+ for k,vv in next,v do
+ traverse(p,k,vv)
+ end
+ remove(l)
+ end
+ end
+ for i=1,#steps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ traverse(k,k,v)
end
+ end
end
- if next(collected) then
- while true do
- local done=false
- for k,v in next,collected do
- for i=1,#v do
- local vi=v[i]
- if vi==k then
- collected[k]=nil
- break
- else
- local c=collected[vi]
- if c then
- done=true
- local t={}
- local n=i-1
- for j=1,n do
- t[j]=v[j]
- end
- for j=1,#c do
- n=n+1
- t[n]=c[j]
- end
- for j=i+1,#v do
- n=n+1
- t[n]=v[j]
- end
- collected[k]=t
- break
- end
- end
- end
- end
- if not done then
- break
- end
+ end
+ end
+ end
+ if next(collected) then
+ while true do
+ local done=false
+ for k,v in next,collected do
+ for i=1,#v do
+ local vi=v[i]
+ if vi==k then
+ collected[k]=nil
+ break
+ else
+ local c=collected[vi]
+ if c then
+ done=true
+ local t={}
+ local n=i-1
+ for j=1,n do
+ t[j]=v[j]
+ end
+ for j=1,#c do
+ n=n+1
+ t[n]=c[j]
+ end
+ for j=i+1,#v do
+ n=n+1
+ t[n]=v[j]
+ end
+ collected[k]=t
+ break
end
- return collected
+ end
end
+ end
+ if not done then
+ break
+ end
end
+ return collected
+ end
end
+ end
end
readers.unifymissing=unifymissing
function readers.rehash(fontdata,hashmethod)
- if not (fontdata and fontdata.glyphs) then
- return
- end
- if hashmethod=="indices" then
- fontdata.hashmethod="indices"
- elseif hashmethod=="names" then
- fontdata.hashmethod="names"
- local indices=unifyglyphs(fontdata,true)
- unifyresources(fontdata,indices)
- copyduplicates(fontdata)
- unifymissing(fontdata)
- else
- fontdata.hashmethod="unicodes"
- local indices=unifyglyphs(fontdata)
- unifyresources(fontdata,indices)
- copyduplicates(fontdata)
- unifymissing(fontdata)
- stripredundant(fontdata)
- end
+ if not (fontdata and fontdata.glyphs) then
+ return
+ end
+ if hashmethod=="indices" then
+ fontdata.hashmethod="indices"
+ elseif hashmethod=="names" then
+ fontdata.hashmethod="names"
+ local indices=unifyglyphs(fontdata,true)
+ unifyresources(fontdata,indices)
+ copyduplicates(fontdata)
+ unifymissing(fontdata)
+ else
+ fontdata.hashmethod="unicodes"
+ local indices=unifyglyphs(fontdata)
+ unifyresources(fontdata,indices)
+ copyduplicates(fontdata)
+ unifymissing(fontdata)
+ stripredundant(fontdata)
+ end
end
function readers.checkhash(fontdata)
- local hashmethod=fontdata.hashmethod
- if hashmethod=="unicodes" then
- fontdata.names=nil
- elseif hashmethod=="names" and fontdata.names then
- unifyresources(fontdata,fontdata.names)
- copyduplicates(fontdata)
- fontdata.hashmethod="unicodes"
- fontdata.names=nil
- else
- readers.rehash(fontdata,"unicodes")
- end
+ local hashmethod=fontdata.hashmethod
+ if hashmethod=="unicodes" then
+ fontdata.names=nil
+ elseif hashmethod=="names" and fontdata.names then
+ unifyresources(fontdata,fontdata.names)
+ copyduplicates(fontdata)
+ fontdata.hashmethod="unicodes"
+ fontdata.names=nil
+ else
+ readers.rehash(fontdata,"unicodes")
+ end
end
function readers.addunicodetable(fontdata)
- local resources=fontdata.resources
- local unicodes=resources.unicodes
- if not unicodes then
- local descriptions=fontdata.descriptions
- if descriptions then
- unicodes={}
- resources.unicodes=unicodes
- for u,d in next,descriptions do
- local n=d.name
- if n then
- unicodes[n]=u
- end
- end
+ local resources=fontdata.resources
+ local unicodes=resources.unicodes
+ if not unicodes then
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ unicodes={}
+ resources.unicodes=unicodes
+ for u,d in next,descriptions do
+ local n=d.name
+ if n then
+ unicodes[n]=u
end
+ end
end
+ end
end
local concat,sort=table.concat,table.sort
local next,type,tostring=next,type,tostring
local criterium=1
local threshold=0
-local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end)
-local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
+local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end)
+local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
local report_otf=logs.reporter("fonts","otf loading")
local function tabstr_normal(t)
- local s={}
- local n=0
- for k,v in next,t do
- n=n+1
- if type(v)=="table" then
- s[n]=k..">"..tabstr_normal(v)
- elseif v==true then
- s[n]=k.."+"
- elseif v then
- s[n]=k.."="..v
- else
- s[n]=k.."-"
- end
- end
- if n==0 then
- return ""
- elseif n==1 then
- return s[1]
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ if type(v)=="table" then
+ s[n]=k..">"..tabstr_normal(v)
+ elseif v==true then
+ s[n]=k.."+"
+ elseif v then
+ s[n]=k.."="..v
else
- sort(s)
- return concat(s,",")
+ s[n]=k.."-"
end
+ end
+ if n==0 then
+ return ""
+ elseif n==1 then
+ return s[1]
+ else
+ sort(s)
+ return concat(s,",")
+ end
end
local function tabstr_flat(t)
- local s={}
- local n=0
- for k,v in next,t do
- n=n+1
- s[n]=k.."="..v
- end
- if n==0 then
- return ""
- elseif n==1 then
- return s[1]
- else
- sort(s)
- return concat(s,",")
- end
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ s[n]=k.."="..v
+ end
+ if n==0 then
+ return ""
+ elseif n==1 then
+ return s[1]
+ else
+ sort(s)
+ return concat(s,",")
+ end
end
local function tabstr_mixed(t)
- local s={}
- local n=#t
- if n==0 then
- return ""
- elseif n==1 then
- local k=t[1]
- if k==true then
- return "++"
- elseif k==false then
- return "--"
- else
- return tostring(k)
- end
+ local s={}
+ local n=#t
+ if n==0 then
+ return ""
+ elseif n==1 then
+ local k=t[1]
+ if k==true then
+ return "++"
+ elseif k==false then
+ return "--"
else
- for i=1,n do
- local k=t[i]
- if k==true then
- s[i]="++"
- elseif k==false then
- s[i]="--"
- else
- s[i]=k
- end
- end
- return concat(s,",")
+ return tostring(k)
end
+ else
+ for i=1,n do
+ local k=t[i]
+ if k==true then
+ s[i]="++"
+ elseif k==false then
+ s[i]="--"
+ else
+ s[i]=k
+ end
+ end
+ return concat(s,",")
+ end
end
local function tabstr_boolean(t)
- local s={}
- local n=0
- for k,v in next,t do
- n=n+1
- if v then
- s[n]=k.."+"
- else
- s[n]=k.."-"
- end
- end
- if n==0 then
- return ""
- elseif n==1 then
- return s[1]
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ if v then
+ s[n]=k.."+"
else
- sort(s)
- return concat(s,",")
+ s[n]=k.."-"
end
+ end
+ if n==0 then
+ return ""
+ elseif n==1 then
+ return s[1]
+ else
+ sort(s)
+ return concat(s,",")
+ end
end
function readers.pack(data)
- if data then
- local h,t,c={},{},{}
- local hh,tt,cc={},{},{}
- local nt,ntt=0,0
- local function pack_normal(v)
- local tag=tabstr_normal(v)
- local ht=h[tag]
- if ht then
- c[ht]=c[ht]+1
- return ht
- else
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
- end
- end
- local function pack_normal_cc(v)
- local tag=tabstr_normal(v)
- local ht=h[tag]
- if ht then
- c[ht]=c[ht]+1
- return ht
- else
- v[1]=0
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
- end
- end
- local function pack_flat(v)
- local tag=tabstr_flat(v)
- local ht=h[tag]
- if ht then
- c[ht]=c[ht]+1
- return ht
- else
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
- end
- end
- local function pack_indexed(v)
- local tag=concat(v," ")
- local ht=h[tag]
- if ht then
- c[ht]=c[ht]+1
- return ht
- else
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
- end
- end
- local function pack_mixed(v)
- local tag=tabstr_mixed(v)
- local ht=h[tag]
- if ht then
- c[ht]=c[ht]+1
- return ht
- else
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
- end
- end
- local function pack_boolean(v)
- local tag=tabstr_boolean(v)
- local ht=h[tag]
- if ht then
- c[ht]=c[ht]+1
- return ht
+ if data then
+ local h,t,c={},{},{}
+ local hh,tt,cc={},{},{}
+ local nt,ntt=0,0
+ local function pack_normal(v)
+ local tag=tabstr_normal(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_normal_cc(v)
+ local tag=tabstr_normal(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ v[1]=0
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_flat(v)
+ local tag=tabstr_flat(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_indexed(v)
+ local tag=concat(v," ")
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_mixed(v)
+ local tag=tabstr_mixed(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_boolean(v)
+ local tag=tabstr_boolean(v)
+ local ht=h[tag]
+ if ht then
+ c[ht]=c[ht]+1
+ return ht
+ else
+ nt=nt+1
+ t[nt]=v
+ h[tag]=nt
+ c[nt]=1
+ return nt
+ end
+ end
+ local function pack_final(v)
+ if c[v]<=criterium then
+ return t[v]
+ else
+ local hv=hh[v]
+ if hv then
+ return hv
+ else
+ ntt=ntt+1
+ tt[ntt]=t[v]
+ hh[v]=ntt
+ cc[ntt]=c[v]
+ return ntt
+ end
+ end
+ end
+ local function pack_final_cc(v)
+ if c[v]<=criterium then
+ return t[v]
+ else
+ local hv=hh[v]
+ if hv then
+ return hv
+ else
+ ntt=ntt+1
+ tt[ntt]=t[v]
+ hh[v]=ntt
+ cc[ntt]=c[v]
+ return ntt
+ end
+ end
+ end
+ local function success(stage,pass)
+ if nt==0 then
+ if trace_loading or trace_packing then
+ report_otf("pack quality: nothing to pack")
+ end
+ return false
+ elseif nt>=threshold then
+ local one,two,rest=0,0,0
+ if pass==1 then
+ for k,v in next,c do
+ if v==1 then
+ one=one+1
+ elseif v==2 then
+ two=two+1
else
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
+ rest=rest+1
end
- end
- local function pack_final(v)
- if c[v]<=criterium then
- return t[v]
+ end
+ else
+ for k,v in next,cc do
+ if v>20 then
+ rest=rest+1
+ elseif v>10 then
+ two=two+1
else
- local hv=hh[v]
- if hv then
- return hv
- else
- ntt=ntt+1
- tt[ntt]=t[v]
- hh[v]=ntt
- cc[ntt]=c[v]
- return ntt
- end
+ one=one+1
end
+ end
+ data.tables=tt
end
- local function pack_final_cc(v)
- if c[v]<=criterium then
- return t[v]
- else
- local hv=hh[v]
- if hv then
- return hv
- else
- ntt=ntt+1
- tt[ntt]=t[v]
- hh[v]=ntt
- cc[ntt]=c[v]
- return ntt
- end
+ if trace_loading or trace_packing then
+ report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)",
+ stage,pass,one+two+rest,one,two,rest,criterium)
+ end
+ return true
+ else
+ if trace_loading or trace_packing then
+ report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)",
+ stage,pass,nt,threshold)
+ end
+ return false
+ end
+ end
+ local function packers(pass)
+ if pass==1 then
+ return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc
+ else
+ return pack_final,pack_final,pack_final,pack_final,pack_final,pack_final_cc
+ end
+ end
+ local resources=data.resources
+ local sequences=resources.sequences
+ local sublookups=resources.sublookups
+ local features=resources.features
+ local palettes=resources.colorpalettes
+ local variable=resources.variabledata
+ local chardata=characters and characters.data
+ local descriptions=data.descriptions or data.glyphs
+ if not descriptions then
+ return
+ end
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 1, pass %s",pass)
+ end
+ local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
+ for unicode,description in next,descriptions do
+ local boundingbox=description.boundingbox
+ if boundingbox then
+ description.boundingbox=pack_indexed(boundingbox)
+ end
+ local math=description.math
+ if math then
+ local kerns=math.kerns
+ if kerns then
+ for tag,kern in next,kerns do
+ kerns[tag]=pack_normal(kern)
end
+ end
end
- local function success(stage,pass)
- if nt==0 then
- if trace_loading or trace_packing then
- report_otf("pack quality: nothing to pack")
- end
- return false
- elseif nt>=threshold then
- local one,two,rest=0,0,0
- if pass==1 then
- for k,v in next,c do
- if v==1 then
- one=one+1
- elseif v==2 then
- two=two+1
- else
- rest=rest+1
- end
+ end
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local order=sequence.order
+ local features=sequence.features
+ local flags=sequence.flags
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end
+ local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end
+ end
end
- else
- for k,v in next,cc do
- if v>20 then
- rest=rest+1
- elseif v>10 then
- two=two+1
- else
- one=one+1
- end
+ else
+ for g1,d1 in next,c do
+ c[g1]=pack_normal(d1)
end
- data.tables=tt
+ end
end
- if trace_loading or trace_packing then
- report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)",
- stage,pass,one+two+rest,one,two,rest,criterium)
+ elseif kind=="gpos_single" then
+ local c=step.coverage
+ if c then
+ if step.format=="single" then
+ for g1,d1 in next,c do
+ if d1 and d1~=true then
+ c[g1]=pack_indexed(d1)
+ end
+ end
+ else
+ step.coverage=pack_normal(c)
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local f=d1[2] if f then d1[2]=pack_indexed(f) end
+ local s=d1[3] if s then d1[3]=pack_indexed(s) end
+ end
end
- return true
- else
- if trace_loading or trace_packing then
- report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)",
- stage,pass,nt,threshold)
+ elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ d1[g2]=pack_indexed(d2)
+ end
+ end
end
- return false
- end
- end
- local function packers(pass)
- if pass==1 then
- return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc
- else
- return pack_final,pack_final,pack_final,pack_final,pack_final,pack_final_cc
- end
- end
- local resources=data.resources
- local sequences=resources.sequences
- local sublookups=resources.sublookups
- local features=resources.features
- local palettes=resources.colorpalettes
- local variable=resources.variabledata
- local chardata=characters and characters.data
- local descriptions=data.descriptions or data.glyphs
- if not descriptions then
- return
- end
- for pass=1,2 do
- if trace_packing then
- report_otf("start packing: stage 1, pass %s",pass)
- end
- local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
- for unicode,description in next,descriptions do
- local boundingbox=description.boundingbox
- if boundingbox then
- description.boundingbox=pack_indexed(boundingbox)
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ d1[2]=pack_indexed(d1[2])
+ end
end
- local math=description.math
- if math then
- local kerns=math.kerns
- if kerns then
- for tag,kern in next,kerns do
- kerns[tag]=pack_normal(kern)
- end
+ elseif kind=="gpos_mark2ligature" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ for g3,d3 in next,d2 do
+ d2[g3]=pack_indexed(d3)
+ end
end
+ end
end
- end
- local function packthem(sequences)
- for i=1,#sequences do
- local sequence=sequences[i]
- local kind=sequence.type
- local steps=sequence.steps
- local order=sequence.order
- local features=sequence.features
- local flags=sequence.flags
- if steps then
- for i=1,#steps do
- local step=steps[i]
- if kind=="gpos_pair" then
- local c=step.coverage
- if c then
- if step.format=="pair" then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end
- local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end
- end
- end
- else
- for g1,d1 in next,c do
- c[g1]=pack_normal(d1)
- end
- end
- end
- elseif kind=="gpos_single" then
- local c=step.coverage
- if c then
- if step.format=="single" then
- for g1,d1 in next,c do
- if d1 and d1~=true then
- c[g1]=pack_indexed(d1)
- end
- end
- else
- step.coverage=pack_normal(c)
- end
- end
- elseif kind=="gpos_cursive" then
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- local f=d1[2] if f then d1[2]=pack_indexed(f) end
- local s=d1[3] if s then d1[3]=pack_indexed(s) end
- end
- end
- elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
- local c=step.baseclasses
- if c then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- d1[g2]=pack_indexed(d2)
- end
- end
- end
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- d1[2]=pack_indexed(d1[2])
- end
- end
- elseif kind=="gpos_mark2ligature" then
- local c=step.baseclasses
- if c then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- for g3,d3 in next,d2 do
- d2[g3]=pack_indexed(d3)
- end
- end
- end
- end
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- d1[2]=pack_indexed(d1[2])
- end
- end
- end
- local rules=step.rules
- if rules then
- for i=1,#rules do
- local rule=rules[i]
- local r=rule.before if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
- local r=rule.after if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
- local r=rule.current if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
- local r=rule.replacements if r then rule.replacements=pack_flat (r) end
- end
- end
- end
- end
- if order then
- sequence.order=pack_indexed(order)
- end
- if features then
- for script,feature in next,features do
- features[script]=pack_normal(feature)
- end
- end
- if flags then
- sequence.flags=pack_normal(flags)
- end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ d1[2]=pack_indexed(d1[2])
+ end
+ end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local r=rule.before if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
+ local r=rule.after if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
+ local r=rule.current if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
+ local r=rule.replacements if r then rule.replacements=pack_flat (r) end
end
+ end
end
- if sequences then
- packthem(sequences)
+ end
+ if order then
+ sequence.order=pack_indexed(order)
+ end
+ if features then
+ for script,feature in next,features do
+ features[script]=pack_normal(feature)
end
- if sublookups then
- packthem(sublookups)
+ end
+ if flags then
+ sequence.flags=pack_normal(flags)
+ end
end
- if features then
- for k,list in next,features do
- for feature,spec in next,list do
- list[feature]=pack_normal(spec)
- end
- end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+ if features then
+ for k,list in next,features do
+ for feature,spec in next,list do
+ list[feature]=pack_normal(spec)
+ end
+ end
+ end
+ if palettes then
+ for i=1,#palettes do
+ local p=palettes[i]
+ for j=1,#p do
+ p[j]=pack_indexed(p[j])
+ end
+ end
+ end
+ if variable then
+ local instances=variable.instances
+ if instances then
+ for i=1,#instances do
+ local v=instances[i].values
+ for j=1,#v do
+ v[j]=pack_normal(v[j])
end
- if palettes then
- for i=1,#palettes do
- local p=palettes[i]
- for j=1,#p do
- p[j]=pack_indexed(p[j])
- end
- end
+ end
+ end
+ local function packdeltas(main)
+ if main then
+ local deltas=main.deltas
+ if deltas then
+ for i=1,#deltas do
+ local di=deltas[i]
+ local d=di.deltas
+ for j=1,#d do
+ d[j]=pack_indexed(d[j])
+ end
+ di.regions=pack_indexed(di.regions)
+ end
end
- if variable then
- local instances=variable.instances
- if instances then
- for i=1,#instances do
- local v=instances[i].values
- for j=1,#v do
- v[j]=pack_normal(v[j])
- end
- end
+ local regions=main.regions
+ if regions then
+ for i=1,#regions do
+ local r=regions[i]
+ for j=1,#r do
+ r[j]=pack_normal(r[j])
end
- local function packdeltas(main)
- if main then
- local deltas=main.deltas
- if deltas then
- for i=1,#deltas do
- local di=deltas[i]
- local d=di.deltas
- for j=1,#d do
- d[j]=pack_indexed(d[j])
- end
- di.regions=pack_indexed(di.regions)
- end
- end
- local regions=main.regions
- if regions then
- for i=1,#regions do
- local r=regions[i]
- for j=1,#r do
- r[j]=pack_normal(r[j])
- end
- end
- end
- end
- end
- packdeltas(variable.global)
- packdeltas(variable.horizontal)
- packdeltas(variable.vertical)
- packdeltas(variable.metrics)
+ end
end
- if not success(1,pass) then
- return
+ end
+ end
+ packdeltas(variable.global)
+ packdeltas(variable.horizontal)
+ packdeltas(variable.vertical)
+ packdeltas(variable.metrics)
+ end
+ if not success(1,pass) then
+ return
+ end
+ end
+ if nt>0 then
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 2, pass %s",pass)
+ end
+ local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
+ for unicode,description in next,descriptions do
+ local math=description.math
+ if math then
+ local kerns=math.kerns
+ if kerns then
+ math.kerns=pack_normal(kerns)
end
+ end
end
- if nt>0 then
- for pass=1,2 do
- if trace_packing then
- report_otf("start packing: stage 2, pass %s",pass)
- end
- local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
- for unicode,description in next,descriptions do
- local math=description.math
- if math then
- local kerns=math.kerns
- if kerns then
- math.kerns=pack_normal(kerns)
- end
- end
- end
- local function packthem(sequences)
- for i=1,#sequences do
- local sequence=sequences[i]
- local kind=sequence.type
- local steps=sequence.steps
- local features=sequence.features
- if steps then
- for i=1,#steps do
- local step=steps[i]
- if kind=="gpos_pair" then
- local c=step.coverage
- if c then
- if step.format=="pair" then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- d1[g2]=pack_normal(d2)
- end
- end
- end
- end
- elseif kind=="gpos_mark2ligature" then
- local c=step.baseclasses
- if c then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- d1[g2]=pack_normal(d2)
- end
- end
- end
- end
- local rules=step.rules
- if rules then
- for i=1,#rules do
- local rule=rules[i]
- local r=rule.before if r then rule.before=pack_normal(r) end
- local r=rule.after if r then rule.after=pack_normal(r) end
- local r=rule.current if r then rule.current=pack_normal(r) end
- end
- end
- end
- end
- if features then
- sequence.features=pack_normal(features)
- end
- end
- end
- if sequences then
- packthem(sequences)
- end
- if sublookups then
- packthem(sublookups)
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local features=sequence.features
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ d1[g2]=pack_normal(d2)
+ end
+ end
+ end
+ end
+ elseif kind=="gpos_mark2ligature" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ d1[g2]=pack_normal(d2)
+ end
+ end
+ end
end
- if variable then
- local function unpackdeltas(main)
- if main then
- local regions=main.regions
- if regions then
- main.regions=pack_normal(regions)
- end
- end
- end
- unpackdeltas(variable.global)
- unpackdeltas(variable.horizontal)
- unpackdeltas(variable.vertical)
- unpackdeltas(variable.metrics)
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local r=rule.before if r then rule.before=pack_normal(r) end
+ local r=rule.after if r then rule.after=pack_normal(r) end
+ local r=rule.current if r then rule.current=pack_normal(r) end
+ end
end
+ end
end
- for pass=1,2 do
- if trace_packing then
- report_otf("start packing: stage 3, pass %s",pass)
- end
- local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
- local function packthem(sequences)
- for i=1,#sequences do
- local sequence=sequences[i]
- local kind=sequence.type
- local steps=sequence.steps
- local features=sequence.features
- if steps then
- for i=1,#steps do
- local step=steps[i]
- if kind=="gpos_pair" then
- local c=step.coverage
- if c then
- if step.format=="pair" then
- for g1,d1 in next,c do
- c[g1]=pack_normal(d1)
- end
- end
- end
- elseif kind=="gpos_cursive" then
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- c[g1]=pack_normal_cc(d1)
- end
- end
- end
- end
- end
- end
- end
- if sequences then
- packthem(sequences)
- end
- if sublookups then
- packthem(sublookups)
+ if features then
+ sequence.features=pack_normal(features)
+ end
+ end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
+ end
+ if variable then
+ local function unpackdeltas(main)
+ if main then
+ local regions=main.regions
+ if regions then
+ main.regions=pack_normal(regions)
+ end
+ end
+ end
+ unpackdeltas(variable.global)
+ unpackdeltas(variable.horizontal)
+ unpackdeltas(variable.vertical)
+ unpackdeltas(variable.metrics)
+ end
+ end
+ for pass=1,2 do
+ if trace_packing then
+ report_otf("start packing: stage 3, pass %s",pass)
+ end
+ local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass)
+ local function packthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local features=sequence.features
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ c[g1]=pack_normal(d1)
+ end
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ c[g1]=pack_normal_cc(d1)
+ end
+ end
end
+ end
end
+ end
+ end
+ if sequences then
+ packthem(sequences)
+ end
+ if sublookups then
+ packthem(sublookups)
end
+ end
end
+ end
end
local unpacked_mt={
- __index=function(t,k)
- t[k]=false
- return k
- end
+ __index=function(t,k)
+ t[k]=false
+ return k
+ end
}
function readers.unpack(data)
- if data then
- local tables=data.tables
- if tables then
- local resources=data.resources
- local descriptions=data.descriptions or data.glyphs
- local sequences=resources.sequences
- local sublookups=resources.sublookups
- local features=resources.features
- local palettes=resources.colorpalettes
- local variable=resources.variabledata
- local unpacked={}
- setmetatable(unpacked,unpacked_mt)
- for unicode,description in next,descriptions do
- local tv=tables[description.boundingbox]
+ if data then
+ local tables=data.tables
+ if tables then
+ local resources=data.resources
+ local descriptions=data.descriptions or data.glyphs
+ local sequences=resources.sequences
+ local sublookups=resources.sublookups
+ local features=resources.features
+ local palettes=resources.colorpalettes
+ local variable=resources.variabledata
+ local unpacked={}
+ setmetatable(unpacked,unpacked_mt)
+ for unicode,description in next,descriptions do
+ local tv=tables[description.boundingbox]
+ if tv then
+ description.boundingbox=tv
+ end
+ local math=description.math
+ if math then
+ local kerns=math.kerns
+ if kerns then
+ local tm=tables[kerns]
+ if tm then
+ math.kerns=tm
+ kerns=unpacked[tm]
+ end
+ if kerns then
+ for k,kern in next,kerns do
+ local tv=tables[kern]
if tv then
- description.boundingbox=tv
- end
- local math=description.math
- if math then
- local kerns=math.kerns
- if kerns then
- local tm=tables[kerns]
- if tm then
- math.kerns=tm
- kerns=unpacked[tm]
- end
- if kerns then
- for k,kern in next,kerns do
- local tv=tables[kern]
- if tv then
- kerns[k]=tv
- end
- end
- end
- end
+ kerns[k]=tv
end
+ end
end
- local function unpackthem(sequences)
- for i=1,#sequences do
- local sequence=sequences[i]
- local kind=sequence.type
- local steps=sequence.steps
- local order=sequence.order
- local features=sequence.features
- local flags=sequence.flags
- local markclass=sequence.markclass
- if features then
- local tv=tables[features]
+ end
+ end
+ end
+ local function unpackthem(sequences)
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local kind=sequence.type
+ local steps=sequence.steps
+ local order=sequence.order
+ local features=sequence.features
+ local flags=sequence.flags
+ local markclass=sequence.markclass
+ if features then
+ local tv=tables[features]
+ if tv then
+ sequence.features=tv
+ features=tv
+ end
+ for script,feature in next,features do
+ local tv=tables[feature]
+ if tv then
+ features[script]=tv
+ end
+ end
+ end
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ if kind=="gpos_pair" then
+ local c=step.coverage
+ if c then
+ if step.format=="pair" then
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ d1=tv
+ end
+ for g2,d2 in next,d1 do
+ local tv=tables[d2]
if tv then
- sequence.features=tv
- features=tv
- end
- for script,feature in next,features do
- local tv=tables[feature]
- if tv then
- features[script]=tv
- end
+ d1[g2]=tv
+ d2=tv
end
+ local f=tables[d2[1]] if f then d2[1]=f end
+ local s=tables[d2[2]] if s then d2[2]=s end
+ end
end
- if steps then
- for i=1,#steps do
- local step=steps[i]
- if kind=="gpos_pair" then
- local c=step.coverage
- if c then
- if step.format=="pair" then
- for g1,d1 in next,c do
- local tv=tables[d1]
- if tv then
- c[g1]=tv
- d1=tv
- end
- for g2,d2 in next,d1 do
- local tv=tables[d2]
- if tv then
- d1[g2]=tv
- d2=tv
- end
- local f=tables[d2[1]] if f then d2[1]=f end
- local s=tables[d2[2]] if s then d2[2]=s end
- end
- end
- else
- for g1,d1 in next,c do
- local tv=tables[d1]
- if tv then
- c[g1]=tv
- end
- end
- end
- end
- elseif kind=="gpos_single" then
- local c=step.coverage
- if c then
- if step.format=="single" then
- for g1,d1 in next,c do
- local tv=tables[d1]
- if tv then
- c[g1]=tv
- end
- end
- else
- local tv=tables[c]
- if tv then
- step.coverage=tv
- end
- end
- end
- elseif kind=="gpos_cursive" then
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- local tv=tables[d1]
- if tv then
- d1=tv
- c[g1]=d1
- end
- local f=tables[d1[2]] if f then d1[2]=f end
- local s=tables[d1[3]] if s then d1[3]=s end
- end
- end
- elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
- local c=step.baseclasses
- if c then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- local tv=tables[d2]
- if tv then
- d1[g2]=tv
- end
- end
- end
- end
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- local tv=tables[d1[2]]
- if tv then
- d1[2]=tv
- end
- end
- end
- elseif kind=="gpos_mark2ligature" then
- local c=step.baseclasses
- if c then
- for g1,d1 in next,c do
- for g2,d2 in next,d1 do
- local tv=tables[d2]
- if tv then
- d2=tv
- d1[g2]=d2
- end
- for g3,d3 in next,d2 do
- local tv=tables[d2[g3]]
- if tv then
- d2[g3]=tv
- end
- end
- end
- end
- end
- local c=step.coverage
- if c then
- for g1,d1 in next,c do
- local tv=tables[d1[2]]
- if tv then
- d1[2]=tv
- end
- end
- end
- end
- local rules=step.rules
- if rules then
- for i=1,#rules do
- local rule=rules[i]
- local before=rule.before
- if before then
- local tv=tables[before]
- if tv then
- rule.before=tv
- before=tv
- end
- for i=1,#before do
- local tv=tables[before[i]]
- if tv then
- before[i]=tv
- end
- end
- end
- local after=rule.after
- if after then
- local tv=tables[after]
- if tv then
- rule.after=tv
- after=tv
- end
- for i=1,#after do
- local tv=tables[after[i]]
- if tv then
- after[i]=tv
- end
- end
- end
- local current=rule.current
- if current then
- local tv=tables[current]
- if tv then
- rule.current=tv
- current=tv
- end
- for i=1,#current do
- local tv=tables[current[i]]
- if tv then
- current[i]=tv
- end
- end
- end
- local replacements=rule.replacements
- if replacements then
- local tv=tables[replacements]
- if tv then
- rule.replacements=tv
- end
- end
- end
- end
- end
+ else
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ end
end
- if order then
- local tv=tables[order]
- if tv then
- sequence.order=tv
- end
+ end
+ end
+ elseif kind=="gpos_single" then
+ local c=step.coverage
+ if c then
+ if step.format=="single" then
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ end
+ end
+ else
+ local tv=tables[c]
+ if tv then
+ step.coverage=tv
+ end
+ end
+ end
+ elseif kind=="gpos_cursive" then
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ d1=tv
+ c[g1]=d1
+ end
+ local f=tables[d1[2]] if f then d1[2]=f end
+ local s=tables[d1[3]] if s then d1[3]=s end
+ end
+ end
+ elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ local tv=tables[d2]
+ if tv then
+ d1[g2]=tv
+ end
end
- if flags then
- local tv=tables[flags]
- if tv then
- sequence.flags=tv
- end
+ end
+ end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local tv=tables[d1[2]]
+ if tv then
+ d1[2]=tv
end
+ end
end
- end
- if sequences then
- unpackthem(sequences)
- end
- if sublookups then
- unpackthem(sublookups)
- end
- if features then
- for k,list in next,features do
- for feature,spec in next,list do
- local tv=tables[spec]
+ elseif kind=="gpos_mark2ligature" then
+ local c=step.baseclasses
+ if c then
+ for g1,d1 in next,c do
+ for g2,d2 in next,d1 do
+ local tv=tables[d2]
+ if tv then
+ d2=tv
+ d1[g2]=d2
+ end
+ for g3,d3 in next,d2 do
+ local tv=tables[d2[g3]]
if tv then
- list[feature]=tv
+ d2[g3]=tv
end
+ end
end
+ end
end
- end
- if palettes then
- for i=1,#palettes do
- local p=palettes[i]
- for j=1,#p do
- local tv=tables[p[j]]
- if tv then
- p[j]=tv
- end
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ local tv=tables[d1[2]]
+ if tv then
+ d1[2]=tv
end
+ end
end
+ end
+ local rules=step.rules
+ if rules then
+ for i=1,#rules do
+ local rule=rules[i]
+ local before=rule.before
+ if before then
+ local tv=tables[before]
+ if tv then
+ rule.before=tv
+ before=tv
+ end
+ for i=1,#before do
+ local tv=tables[before[i]]
+ if tv then
+ before[i]=tv
+ end
+ end
+ end
+ local after=rule.after
+ if after then
+ local tv=tables[after]
+ if tv then
+ rule.after=tv
+ after=tv
+ end
+ for i=1,#after do
+ local tv=tables[after[i]]
+ if tv then
+ after[i]=tv
+ end
+ end
+ end
+ local current=rule.current
+ if current then
+ local tv=tables[current]
+ if tv then
+ rule.current=tv
+ current=tv
+ end
+ for i=1,#current do
+ local tv=tables[current[i]]
+ if tv then
+ current[i]=tv
+ end
+ end
+ end
+ local replacements=rule.replacements
+ if replacements then
+ local tv=tables[replacements]
+ if tv then
+ rule.replacements=tv
+ end
+ end
+ end
+ end
end
- if variable then
- local instances=variable.instances
- if instances then
- for i=1,#instances do
- local v=instances[i].values
- for j=1,#v do
- local tv=tables[v[j]]
- if tv then
- v[j]=tv
- end
- end
- end
+ end
+ if order then
+ local tv=tables[order]
+ if tv then
+ sequence.order=tv
+ end
+ end
+ if flags then
+ local tv=tables[flags]
+ if tv then
+ sequence.flags=tv
+ end
+ end
+ end
+ end
+ if sequences then
+ unpackthem(sequences)
+ end
+ if sublookups then
+ unpackthem(sublookups)
+ end
+ if features then
+ for k,list in next,features do
+ for feature,spec in next,list do
+ local tv=tables[spec]
+ if tv then
+ list[feature]=tv
+ end
+ end
+ end
+ end
+ if palettes then
+ for i=1,#palettes do
+ local p=palettes[i]
+ for j=1,#p do
+ local tv=tables[p[j]]
+ if tv then
+ p[j]=tv
+ end
+ end
+ end
+ end
+ if variable then
+ local instances=variable.instances
+ if instances then
+ for i=1,#instances do
+ local v=instances[i].values
+ for j=1,#v do
+ local tv=tables[v[j]]
+ if tv then
+ v[j]=tv
+ end
+ end
+ end
+ end
+ local function unpackdeltas(main)
+ if main then
+ local deltas=main.deltas
+ if deltas then
+ for i=1,#deltas do
+ local di=deltas[i]
+ local d=di.deltas
+ local r=di.regions
+ for j=1,#d do
+ local tv=tables[d[j]]
+ if tv then
+ d[j]=tv
+ end
+ end
+ local tv=di.regions
+ if tv then
+ di.regions=tv
end
- local function unpackdeltas(main)
- if main then
- local deltas=main.deltas
- if deltas then
- for i=1,#deltas do
- local di=deltas[i]
- local d=di.deltas
- local r=di.regions
- for j=1,#d do
- local tv=tables[d[j]]
- if tv then
- d[j]=tv
- end
- end
- local tv=di.regions
- if tv then
- di.regions=tv
- end
- end
- end
- local regions=main.regions
- if regions then
- local tv=tables[regions]
- if tv then
- main.regions=tv
- regions=tv
- end
- for i=1,#regions do
- local r=regions[i]
- for j=1,#r do
- local tv=tables[r[j]]
- if tv then
- r[j]=tv
- end
- end
- end
- end
- end
+ end
+ end
+ local regions=main.regions
+ if regions then
+ local tv=tables[regions]
+ if tv then
+ main.regions=tv
+ regions=tv
+ end
+ for i=1,#regions do
+ local r=regions[i]
+ for j=1,#r do
+ local tv=tables[r[j]]
+ if tv then
+ r[j]=tv
+ end
end
- unpackdeltas(variable.global)
- unpackdeltas(variable.horizontal)
- unpackdeltas(variable.vertical)
- unpackdeltas(variable.metrics)
+ end
end
- data.tables=nil
+ end
end
+ unpackdeltas(variable.global)
+ unpackdeltas(variable.horizontal)
+ unpackdeltas(variable.vertical)
+ unpackdeltas(variable.metrics)
+ end
+ data.tables=nil
end
+ end
end
local mt={
- __index=function(t,k)
- if k=="height" then
- local ht=t.boundingbox[4]
- return ht<0 and 0 or ht
- elseif k=="depth" then
- local dp=-t.boundingbox[2]
- return dp<0 and 0 or dp
- elseif k=="width" then
- return 0
- elseif k=="name" then
- return forcenotdef and ".notdef"
- end
- end
+ __index=function(t,k)
+ if k=="height" then
+ local ht=t.boundingbox[4]
+ return ht<0 and 0 or ht
+ elseif k=="depth" then
+ local dp=-t.boundingbox[2]
+ return dp<0 and 0 or dp
+ elseif k=="width" then
+ return 0
+ elseif k=="name" then
+ return forcenotdef and ".notdef"
+ end
+ end
}
local function sameformat(sequence,steps,first,nofsteps,kind)
- return true
+ return true
end
local function mergesteps_1(lookup,strict)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- local first=steps[1]
- if strict then
- local f=first.format
- for i=2,nofsteps do
- if steps[i].format~=f then
- if trace_optimizations then
- report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
- end
- return 0
- end
- end
- end
- if trace_optimizations then
- report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
- end
- local target=first.coverage
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if strict then
+ local f=first.format
for i=2,nofsteps do
- local c=steps[i].coverage
- if c then
- for k,v in next,c do
- if not target[k] then
- target[k]=v
- end
- end
+ if steps[i].format~=f then
+ if trace_optimizations then
+ report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
end
- end
- lookup.nofsteps=1
- lookup.merged=true
- lookup.steps={ first }
- return nofsteps-1
+ return 0
+ end
+ end
+ end
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ if not target[k] then
+ target[k]=v
+ end
+ end
+ end
+ end
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
end
local function mergesteps_2(lookup)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- local first=steps[1]
- if strict then
- local f=first.format
- for i=2,nofsteps do
- if steps[i].format~=f then
- if trace_optimizations then
- report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
- end
- return 0
- end
- end
- end
- if trace_optimizations then
- report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
- end
- local target=first.coverage
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if strict then
+ local f=first.format
for i=2,nofsteps do
- local c=steps[i].coverage
- if c then
- for k,v in next,c do
- local tk=target[k]
- if tk then
- for kk,vv in next,v do
- if tk[kk]==nil then
- tk[kk]=vv
- end
- end
- else
- target[k]=v
- end
+ if steps[i].format~=f then
+ if trace_optimizations then
+ report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name)
+ end
+ return 0
+ end
+ end
+ end
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=target[k]
+ if tk then
+ for kk,vv in next,v do
+ if tk[kk]==nil then
+ tk[kk]=vv
end
+ end
+ else
+ target[k]=v
end
+ end
end
- lookup.nofsteps=1
- lookup.merged=true
- lookup.steps={ first }
- return nofsteps-1
+ end
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
end
local function mergesteps_3(lookup,strict)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- if trace_optimizations then
- report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
- end
- local coverage={}
- for i=1,nofsteps do
- local c=steps[i].coverage
- if c then
- for k,v in next,c do
- local tk=coverage[k]
- if tk then
- if trace_optimizations then
- report_optimizations("quitting merge due to multiple checks")
- end
- return nofsteps
- else
- coverage[k]=v
- end
- end
- end
- end
- local first=steps[1]
- local baseclasses={}
- for i=1,nofsteps do
- local offset=i*10
- local step=steps[i]
- for k,v in sortedhash(step.baseclasses) do
- baseclasses[offset+k]=v
- end
- for k,v in next,step.coverage do
- v[1]=offset+v[1]
- end
- end
- first.baseclasses=baseclasses
- first.coverage=coverage
- lookup.nofsteps=1
- lookup.merged=true
- lookup.steps={ first }
- return nofsteps-1
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local coverage={}
+ for i=1,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=coverage[k]
+ if tk then
+ if trace_optimizations then
+ report_optimizations("quitting merge due to multiple checks")
+ end
+ return nofsteps
+ else
+ coverage[k]=v
+ end
+ end
+ end
+ end
+ local first=steps[1]
+ local baseclasses={}
+ for i=1,nofsteps do
+ local offset=i*10
+ local step=steps[i]
+ for k,v in sortedhash(step.baseclasses) do
+ baseclasses[offset+k]=v
+ end
+ for k,v in next,step.coverage do
+ v[1]=offset+v[1]
+ end
+ end
+ first.baseclasses=baseclasses
+ first.coverage=coverage
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
end
local function nested(old,new)
- for k,v in next,old do
- if k=="ligature" then
- if not new.ligature then
- new.ligature=v
- end
- else
- local n=new[k]
- if n then
- nested(v,n)
- else
- new[k]=v
- end
- end
+ for k,v in next,old do
+ if k=="ligature" then
+ if not new.ligature then
+ new.ligature=v
+ end
+ else
+ local n=new[k]
+ if n then
+ nested(v,n)
+ else
+ new[k]=v
+ end
end
+ end
end
local function mergesteps_4(lookup)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- local first=steps[1]
- if trace_optimizations then
- report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
- end
- local target=first.coverage
- for i=2,nofsteps do
- local c=steps[i].coverage
- if c then
- for k,v in next,c do
- local tk=target[k]
- if tk then
- nested(v,tk)
- else
- target[k]=v
- end
- end
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=target[k]
+ if tk then
+ nested(v,tk)
+ else
+ target[k]=v
end
+ end
end
- lookup.nofsteps=1
- lookup.steps={ first }
- return nofsteps-1
+ end
+ lookup.nofsteps=1
+ lookup.steps={ first }
+ return nofsteps-1
end
local function mergesteps_5(lookup)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- local first=steps[1]
- if trace_optimizations then
- report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
- end
- local target=first.coverage
- local hash=nil
- for k,v in next,target do
- hash=v[1]
- break
- end
- for i=2,nofsteps do
- local c=steps[i].coverage
- if c then
- for k,v in next,c do
- local tk=target[k]
- if tk then
- if not tk[2] then
- tk[2]=v[2]
- end
- if not tk[3] then
- tk[3]=v[3]
- end
- else
- target[k]=v
- v[1]=hash
- end
- end
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local first=steps[1]
+ if trace_optimizations then
+ report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name)
+ end
+ local target=first.coverage
+ local hash=nil
+ for k,v in next,target do
+ hash=v[1]
+ break
+ end
+ for i=2,nofsteps do
+ local c=steps[i].coverage
+ if c then
+ for k,v in next,c do
+ local tk=target[k]
+ if tk then
+ if not tk[2] then
+ tk[2]=v[2]
+ end
+ if not tk[3] then
+ tk[3]=v[3]
+ end
+ else
+ target[k]=v
+ v[1]=hash
end
+ end
end
- lookup.nofsteps=1
- lookup.merged=true
- lookup.steps={ first }
- return nofsteps-1
+ end
+ lookup.nofsteps=1
+ lookup.merged=true
+ lookup.steps={ first }
+ return nofsteps-1
end
local function checkkerns(lookup)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- local kerned=0
- for i=1,nofsteps do
- local step=steps[i]
- if step.format=="pair" then
- local coverage=step.coverage
- local kerns=true
- for g1,d1 in next,coverage do
- if d1==true then
- elseif not d1 then
- elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then
- kerns=false
- break
- end
- end
- if kerns then
- if trace_optimizations then
- report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
- end
- local c={}
- for g1,d1 in next,coverage do
- if d1 and d1~=true then
- c[g1]=d1[3]
- end
- end
- step.coverage=c
- step.format="move"
- kerned=kerned+1
- end
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local kerned=0
+ for i=1,nofsteps do
+ local step=steps[i]
+ if step.format=="pair" then
+ local coverage=step.coverage
+ local kerns=true
+ for g1,d1 in next,coverage do
+ if d1==true then
+ elseif not d1 then
+ elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then
+ kerns=false
+ break
+ end
+ end
+ if kerns then
+ if trace_optimizations then
+ report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
+ end
+ local c={}
+ for g1,d1 in next,coverage do
+ if d1 and d1~=true then
+ c[g1]=d1[3]
+ end
end
+ step.coverage=c
+ step.format="move"
+ kerned=kerned+1
+ end
end
- return kerned
+ end
+ return kerned
end
local function checkpairs(lookup)
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- local kerned=0
- local function onlykerns(step)
- local coverage=step.coverage
- for g1,d1 in next,coverage do
- for g2,d2 in next,d1 do
- if d2[2] then
- return false
- else
- local v=d2[1]
- if v==true then
- elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then
- return false
- end
- end
- end
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ local kerned=0
+ local function onlykerns(step)
+ local coverage=step.coverage
+ for g1,d1 in next,coverage do
+ for g2,d2 in next,d1 do
+ if d2[2] then
+ return false
+ else
+ local v=d2[1]
+ if v==true then
+ elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then
+ return false
+ end
end
- return coverage
+ end
end
- for i=1,nofsteps do
- local step=steps[i]
- if step.format=="pair" then
- local coverage=onlykerns(step)
- if coverage then
- if trace_optimizations then
- report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
- end
- for g1,d1 in next,coverage do
- local d={}
- for g2,d2 in next,d1 do
- local v=d2[1]
- if v==true then
- elseif v then
- d[g2]=v[3]
- end
- end
- coverage[g1]=d
- end
- step.format="move"
- kerned=kerned+1
+ return coverage
+ end
+ for i=1,nofsteps do
+ local step=steps[i]
+ if step.format=="pair" then
+ local coverage=onlykerns(step)
+ if coverage then
+ if trace_optimizations then
+ report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name)
+ end
+ for g1,d1 in next,coverage do
+ local d={}
+ for g2,d2 in next,d1 do
+ local v=d2[1]
+ if v==true then
+ elseif v then
+ d[g2]=v[3]
end
+ end
+ coverage[g1]=d
end
+ step.format="move"
+ kerned=kerned+1
+ end
end
- return kerned
+ end
+ return kerned
end
local compact_pairs=true
local compact_singles=true
@@ -22130,333 +22130,333 @@ directives.register("otf.merge.ligatures",function(v) merge_ligatures=v end)
directives.register("otf.merge.cursives",function(v) merge_cursives=v end)
directives.register("otf.merge.marks",function(v) merge_marks=v end)
function readers.compact(data)
- if not data or data.compacted then
- return
- else
- data.compacted=true
- end
- local resources=data.resources
- local merged=0
- local kerned=0
- local allsteps=0
- local function compact(what)
- local lookups=resources[what]
- if lookups then
- for i=1,#lookups do
- local lookup=lookups[i]
- local nofsteps=lookup.nofsteps
- local kind=lookup.type
- allsteps=allsteps+nofsteps
- if nofsteps>1 then
- local merg=merged
- if kind=="gsub_single" then
- if merge_substitutions then
- merged=merged+mergesteps_1(lookup)
- end
- elseif kind=="gsub_alternate" then
- if merge_alternates then
- merged=merged+mergesteps_1(lookup)
- end
- elseif kind=="gsub_multiple" then
- if merge_multiples then
- merged=merged+mergesteps_1(lookup)
- end
- elseif kind=="gsub_ligature" then
- if merge_ligatures then
- merged=merged+mergesteps_4(lookup)
- end
- elseif kind=="gpos_single" then
- if merge_singles then
- merged=merged+mergesteps_1(lookup,true)
- end
- if compact_singles then
- kerned=kerned+checkkerns(lookup)
- end
- elseif kind=="gpos_pair" then
- if merge_pairs then
- merged=merged+mergesteps_2(lookup)
- end
- if compact_pairs then
- kerned=kerned+checkpairs(lookup)
- end
- elseif kind=="gpos_cursive" then
- if merge_cursives then
- merged=merged+mergesteps_5(lookup)
- end
- elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then
- if merge_marks then
- merged=merged+mergesteps_3(lookup)
- end
- end
- if merg~=merged then
- lookup.merged=true
- end
- elseif nofsteps==1 then
- local kern=kerned
- if kind=="gpos_single" then
- if compact_singles then
- kerned=kerned+checkkerns(lookup)
- end
- elseif kind=="gpos_pair" then
- if compact_pairs then
- kerned=kerned+checkpairs(lookup)
- end
- end
- if kern~=kerned then
- end
- end
+ if not data or data.compacted then
+ return
+ else
+ data.compacted=true
+ end
+ local resources=data.resources
+ local merged=0
+ local kerned=0
+ local allsteps=0
+ local function compact(what)
+ local lookups=resources[what]
+ if lookups then
+ for i=1,#lookups do
+ local lookup=lookups[i]
+ local nofsteps=lookup.nofsteps
+ local kind=lookup.type
+ allsteps=allsteps+nofsteps
+ if nofsteps>1 then
+ local merg=merged
+ if kind=="gsub_single" then
+ if merge_substitutions then
+ merged=merged+mergesteps_1(lookup)
end
- elseif trace_optimizations then
- report_optimizations("no lookups in %a",what)
+ elseif kind=="gsub_alternate" then
+ if merge_alternates then
+ merged=merged+mergesteps_1(lookup)
+ end
+ elseif kind=="gsub_multiple" then
+ if merge_multiples then
+ merged=merged+mergesteps_1(lookup)
+ end
+ elseif kind=="gsub_ligature" then
+ if merge_ligatures then
+ merged=merged+mergesteps_4(lookup)
+ end
+ elseif kind=="gpos_single" then
+ if merge_singles then
+ merged=merged+mergesteps_1(lookup,true)
+ end
+ if compact_singles then
+ kerned=kerned+checkkerns(lookup)
+ end
+ elseif kind=="gpos_pair" then
+ if merge_pairs then
+ merged=merged+mergesteps_2(lookup)
+ end
+ if compact_pairs then
+ kerned=kerned+checkpairs(lookup)
+ end
+ elseif kind=="gpos_cursive" then
+ if merge_cursives then
+ merged=merged+mergesteps_5(lookup)
+ end
+ elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then
+ if merge_marks then
+ merged=merged+mergesteps_3(lookup)
+ end
+ end
+ if merg~=merged then
+ lookup.merged=true
+ end
+ elseif nofsteps==1 then
+ local kern=kerned
+ if kind=="gpos_single" then
+ if compact_singles then
+ kerned=kerned+checkkerns(lookup)
+ end
+ elseif kind=="gpos_pair" then
+ if compact_pairs then
+ kerned=kerned+checkpairs(lookup)
+ end
+ end
+ if kern~=kerned then
+ end
end
+ end
+ elseif trace_optimizations then
+ report_optimizations("no lookups in %a",what)
end
- compact("sequences")
- compact("sublookups")
- if trace_optimizations then
- if merged>0 then
- report_optimizations("%i steps of %i removed due to merging",merged,allsteps)
- end
- if kerned>0 then
- report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps)
- end
+ end
+ compact("sequences")
+ compact("sublookups")
+ if trace_optimizations then
+ if merged>0 then
+ report_optimizations("%i steps of %i removed due to merging",merged,allsteps)
end
+ if kerned>0 then
+ report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps)
+ end
+ end
end
local function mergesteps(t,k)
- if k=="merged" then
- local merged={}
- for i=1,#t do
- local step=t[i]
- local coverage=step.coverage
- for k in next,coverage do
- local m=merged[k]
- if m then
- m[2]=i
- else
- merged[k]={ i,i }
- end
- end
+ if k=="merged" then
+ local merged={}
+ for i=1,#t do
+ local step=t[i]
+ local coverage=step.coverage
+ for k in next,coverage do
+ local m=merged[k]
+ if m then
+ m[2]=i
+ else
+ merged[k]={ i,i }
end
- t.merged=merged
- return merged
+ end
end
+ t.merged=merged
+ return merged
+ end
end
local function checkmerge(sequence)
- local steps=sequence.steps
- if steps then
- setmetatableindex(steps,mergesteps)
- end
+ local steps=sequence.steps
+ if steps then
+ setmetatableindex(steps,mergesteps)
+ end
end
local function checkflags(sequence,resources)
- if not sequence.skiphash then
- local flags=sequence.flags
- if flags then
- local skipmark=flags[1]
- local skipligature=flags[2]
- local skipbase=flags[3]
- local markclass=sequence.markclass
- local skipsome=skipmark or skipligature or skipbase or markclass or false
- if skipsome then
- sequence.skiphash=setmetatableindex(function(t,k)
- local c=resources.classes[k]
- local v=c==skipmark
- or (markclass and c=="mark" and not markclass[k])
- or c==skipligature
- or c==skipbase
- or false
- t[k]=v
- return v
- end)
- else
- sequence.skiphash=false
- end
- else
- sequence.skiphash=false
- end
+ if not sequence.skiphash then
+ local flags=sequence.flags
+ if flags then
+ local skipmark=flags[1]
+ local skipligature=flags[2]
+ local skipbase=flags[3]
+ local markclass=sequence.markclass
+ local skipsome=skipmark or skipligature or skipbase or markclass or false
+ if skipsome then
+ sequence.skiphash=setmetatableindex(function(t,k)
+ local c=resources.classes[k]
+ local v=c==skipmark
+ or (markclass and c=="mark" and not markclass[k])
+ or c==skipligature
+ or c==skipbase
+ or false
+ t[k]=v
+ return v
+ end)
+ else
+ sequence.skiphash=false
+ end
+ else
+ sequence.skiphash=false
end
+ end
end
local function checksteps(sequence)
- local steps=sequence.steps
- if steps then
- for i=1,#steps do
- steps[i].index=i
- end
+ local steps=sequence.steps
+ if steps then
+ for i=1,#steps do
+ steps[i].index=i
end
+ end
end
if fonts.helpers then
- fonts.helpers.checkmerge=checkmerge
- fonts.helpers.checkflags=checkflags
- fonts.helpers.checksteps=checksteps
+ fonts.helpers.checkmerge=checkmerge
+ fonts.helpers.checkflags=checkflags
+ fonts.helpers.checksteps=checksteps
end
function readers.expand(data)
- if not data or data.expanded then
- return
- else
- data.expanded=true
+ if not data or data.expanded then
+ return
+ else
+ data.expanded=true
+ end
+ local resources=data.resources
+ local sublookups=resources.sublookups
+ local sequences=resources.sequences
+ local markclasses=resources.markclasses
+ local descriptions=data.descriptions
+ if descriptions then
+ local defaultwidth=resources.defaultwidth or 0
+ local defaultheight=resources.defaultheight or 0
+ local defaultdepth=resources.defaultdepth or 0
+ local basename=trace_markwidth and file.basename(resources.filename)
+ for u,d in next,descriptions do
+ local bb=d.boundingbox
+ local wd=d.width
+ if not wd then
+ d.width=defaultwidth
+ elseif trace_markwidth and wd~=0 and d.class=="mark" then
+ report_markwidth("mark %a with width %b found in %a",d.name or "<noname>",wd,basename)
+ end
+ if bb then
+ local ht=bb[4]
+ local dp=-bb[2]
+ if ht==0 or ht<0 then
+ else
+ d.height=ht
+ end
+ if dp==0 or dp<0 then
+ else
+ d.depth=dp
+ end
+ end
end
- local resources=data.resources
- local sublookups=resources.sublookups
- local sequences=resources.sequences
- local markclasses=resources.markclasses
- local descriptions=data.descriptions
- if descriptions then
- local defaultwidth=resources.defaultwidth or 0
- local defaultheight=resources.defaultheight or 0
- local defaultdepth=resources.defaultdepth or 0
- local basename=trace_markwidth and file.basename(resources.filename)
- for u,d in next,descriptions do
- local bb=d.boundingbox
- local wd=d.width
- if not wd then
- d.width=defaultwidth
- elseif trace_markwidth and wd~=0 and d.class=="mark" then
- report_markwidth("mark %a with width %b found in %a",d.name or "<noname>",wd,basename)
- end
- if bb then
- local ht=bb[4]
- local dp=-bb[2]
- if ht==0 or ht<0 then
- else
- d.height=ht
+ end
+ local function expandlookups(sequences)
+ if sequences then
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ if steps then
+ local nofsteps=sequence.nofsteps
+ local kind=sequence.type
+ local markclass=sequence.markclass
+ if markclass then
+ if not markclasses then
+ report_warning("missing markclasses")
+ sequence.markclass=false
+ else
+ sequence.markclass=markclasses[markclass]
+ end
+ end
+ for i=1,nofsteps do
+ local step=steps[i]
+ local baseclasses=step.baseclasses
+ if baseclasses then
+ local coverage=step.coverage
+ for k,v in next,coverage do
+ v[1]=baseclasses[v[1]]
+ end
+ elseif kind=="gpos_cursive" then
+ local coverage=step.coverage
+ for k,v in next,coverage do
+ v[1]=coverage
+ end
+ end
+ local rules=step.rules
+ if rules then
+ local rulehash={ n=0 }
+ local rulesize=0
+ local coverage={}
+ local lookuptype=sequence.type
+ local nofrules=#rules
+ step.coverage=coverage
+ for currentrule=1,nofrules do
+ local rule=rules[currentrule]
+ local current=rule.current
+ local before=rule.before
+ local after=rule.after
+ local replacements=rule.replacements or false
+ local sequence={}
+ local nofsequences=0
+ if before then
+ for n=1,#before do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=before[n]
+ end
end
- if dp==0 or dp<0 then
- else
- d.depth=dp
+ local start=nofsequences+1
+ for n=1,#current do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=current[n]
end
- end
- end
- end
- local function expandlookups(sequences)
- if sequences then
- for i=1,#sequences do
- local sequence=sequences[i]
- local steps=sequence.steps
- if steps then
- local nofsteps=sequence.nofsteps
- local kind=sequence.type
- local markclass=sequence.markclass
- if markclass then
- if not markclasses then
- report_warning("missing markclasses")
- sequence.markclass=false
+ local stop=nofsequences
+ if after then
+ for n=1,#after do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=after[n]
+ end
+ end
+ local lookups=rule.lookups or false
+ local subtype=nil
+ if lookups then
+ for i=1,#lookups do
+ local lookups=lookups[i]
+ if lookups then
+ for k,v in next,lookups do
+ local lookup=sublookups[v]
+ if lookup then
+ lookups[k]=lookup
+ if not subtype then
+ subtype=lookup.type
+ end
else
- sequence.markclass=markclasses[markclass]
end
- end
- for i=1,nofsteps do
- local step=steps[i]
- local baseclasses=step.baseclasses
- if baseclasses then
- local coverage=step.coverage
- for k,v in next,coverage do
- v[1]=baseclasses[v[1]]
- end
- elseif kind=="gpos_cursive" then
- local coverage=step.coverage
- for k,v in next,coverage do
- v[1]=coverage
- end
- end
- local rules=step.rules
- if rules then
- local rulehash={ n=0 }
- local rulesize=0
- local coverage={}
- local lookuptype=sequence.type
- local nofrules=#rules
- step.coverage=coverage
- for currentrule=1,nofrules do
- local rule=rules[currentrule]
- local current=rule.current
- local before=rule.before
- local after=rule.after
- local replacements=rule.replacements or false
- local sequence={}
- local nofsequences=0
- if before then
- for n=1,#before do
- nofsequences=nofsequences+1
- sequence[nofsequences]=before[n]
- end
- end
- local start=nofsequences+1
- for n=1,#current do
- nofsequences=nofsequences+1
- sequence[nofsequences]=current[n]
- end
- local stop=nofsequences
- if after then
- for n=1,#after do
- nofsequences=nofsequences+1
- sequence[nofsequences]=after[n]
- end
- end
- local lookups=rule.lookups or false
- local subtype=nil
- if lookups then
- for i=1,#lookups do
- local lookups=lookups[i]
- if lookups then
- for k,v in next,lookups do
- local lookup=sublookups[v]
- if lookup then
- lookups[k]=lookup
- if not subtype then
- subtype=lookup.type
- end
- else
- end
- end
- end
- end
- end
- if sequence[1] then
- sequence.n=#sequence
- local ruledata={
- currentrule,
- lookuptype,
- sequence,
- start,
- stop,
- lookups,
- replacements,
- subtype,
- }
- rulesize=rulesize+1
- rulehash[rulesize]=ruledata
- rulehash.n=rulesize
- if true then
- for unic in next,sequence[start] do
- local cu=coverage[unic]
- if cu then
- local n=#cu+1
- cu[n]=ruledata
- cu.n=n
- else
- coverage[unic]={ ruledata,n=1 }
- end
- end
- else
- for unic in next,sequence[start] do
- local cu=coverage[unic]
- if cu then
- else
- coverage[unic]=rulehash
- end
- end
- end
- end
- end
- end
- end
- checkmerge(sequence)
- checkflags(sequence,resources)
- checksteps(sequence)
+ end
+ end
+ end
+ end
+ if sequence[1] then
+ sequence.n=#sequence
+ local ruledata={
+ currentrule,
+ lookuptype,
+ sequence,
+ start,
+ stop,
+ lookups,
+ replacements,
+ subtype,
+ }
+ rulesize=rulesize+1
+ rulehash[rulesize]=ruledata
+ rulehash.n=rulesize
+ if true then
+ for unic in next,sequence[start] do
+ local cu=coverage[unic]
+ if cu then
+ local n=#cu+1
+ cu[n]=ruledata
+ cu.n=n
+ else
+ coverage[unic]={ ruledata,n=1 }
+ end
+ end
+ else
+ for unic in next,sequence[start] do
+ local cu=coverage[unic]
+ if cu then
+ else
+ coverage[unic]=rulehash
+ end
+ end
+ end
end
+ end
end
+ end
+ checkmerge(sequence)
+ checkflags(sequence,resources)
+ checksteps(sequence)
end
+ end
end
- expandlookups(sequences)
- expandlookups(sublookups)
+ end
+ expandlookups(sequences)
+ expandlookups(sublookups)
end
end -- closure
@@ -22464,11 +22464,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-otl']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local lower=string.lower
local type,next,tonumber,tostring,unpack=type,next,tonumber,tostring,unpack
@@ -22483,9 +22483,9 @@ local starttiming=statistics.starttiming
local stoptiming=statistics.stoptiming
local elapsedtime=statistics.elapsedtime
local findbinfile=resolvers.findbinfile
-local trace_loading=false registertracker("otf.loading",function(v) trace_loading=v end)
-local trace_features=false registertracker("otf.features",function(v) trace_features=v end)
-local trace_defining=false registertracker("fonts.defining",function(v) trace_defining=v end)
+local trace_loading=false registertracker("otf.loading",function(v) trace_loading=v end)
+local trace_features=false registertracker("otf.features",function(v) trace_features=v end)
+local trace_defining=false registertracker("fonts.defining",function(v) trace_defining=v end)
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
@@ -22506,7 +22506,7 @@ local registerotffeature=otffeatures.register
local otfenhancers=constructors.enhancers.otf
local registerotfenhancer=otfenhancers.register
local forceload=false
-local cleanup=0
+local cleanup=0
local syncspace=true
local forcenotdef=false
local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000
@@ -22527,641 +22527,641 @@ local threshold=100
local tracememory=false
registertracker("fonts.otf.loader.memory",function(v) tracememory=v end)
if not checkmemory then
- local collectgarbage=collectgarbage
- checkmemory=function(previous,threshold)
- local current=collectgarbage("count")
- if previous then
- local checked=(threshold or 64)*1024
- if current-previous>checked then
- collectgarbage("collect")
- current=collectgarbage("count")
- end
- end
- return current
- end
+ local collectgarbage=collectgarbage
+ checkmemory=function(previous,threshold)
+ local current=collectgarbage("count")
+ if previous then
+ local checked=(threshold or 64)*1024
+ if current-previous>checked then
+ collectgarbage("collect")
+ current=collectgarbage("count")
+ end
+ end
+ return current
+ end
end
function otf.load(filename,sub,instance)
- local base=file.basename(file.removesuffix(filename))
- local name=file.removesuffix(base)
- local attr=lfs.attributes(filename)
- local size=attr and attr.size or 0
- local time=attr and attr.modification or 0
- if sub=="" then
- sub=false
- end
- local hash=name
- if sub then
- hash=hash.."-"..sub
- end
- if instance then
- hash=hash.."-"..instance
- end
- hash=containers.cleanname(hash)
- local data=containers.read(otf.cache,hash)
- local reload=not data or data.size~=size or data.time~=time or data.tableversion~=otfreaders.tableversion
- if forceload then
- report_otf("forced reload of %a due to hard coded flag",filename)
- reload=true
- end
- if reload then
- report_otf("loading %a, hash %a",filename,hash)
- starttiming(otfreaders,true)
- data=otfreaders.loadfont(filename,sub or 1,instance)
- if data then
- local used=checkmemory()
- local resources=data.resources
- local svgshapes=resources.svgshapes
- local pngshapes=resources.pngshapes
- if cleanup==0 then
- checkmemory(used,threshold,tracememory)
- end
- if svgshapes then
- resources.svgshapes=nil
- if otf.svgenabled then
- local timestamp=os.date()
- containers.write(otf.svgcache,hash,{
- svgshapes=svgshapes,
- timestamp=timestamp,
- })
- data.properties.svg={
- hash=hash,
- timestamp=timestamp,
- }
- end
- if cleanup>1 then
- collectgarbage("collect")
- else
- checkmemory(used,threshold,tracememory)
- end
- end
- if pngshapes then
- resources.pngshapes=nil
- if otf.pngenabled then
- local timestamp=os.date()
- containers.write(otf.pngcache,hash,{
- pngshapes=pngshapes,
- timestamp=timestamp,
- })
- data.properties.png={
- hash=hash,
- timestamp=timestamp,
- }
- end
- if cleanup>1 then
- collectgarbage("collect")
- else
- checkmemory(used,threshold,tracememory)
- end
- end
- otfreaders.compact(data)
- if cleanup==0 then
- checkmemory(used,threshold,tracememory)
- end
- otfreaders.rehash(data,"unicodes")
- otfreaders.addunicodetable(data)
- otfreaders.extend(data)
- if cleanup==0 then
- checkmemory(used,threshold,tracememory)
- end
- otfreaders.pack(data)
- report_otf("loading done")
- report_otf("saving %a in cache",filename)
- data=containers.write(otf.cache,hash,data)
- if cleanup>1 then
- collectgarbage("collect")
- else
- checkmemory(used,threshold,tracememory)
- end
- stoptiming(otfreaders)
- if elapsedtime then
- report_otf("loading, optimizing, packing and caching time %s",elapsedtime(otfreaders))
- end
- if cleanup>3 then
- collectgarbage("collect")
- else
- checkmemory(used,threshold,tracememory)
- end
- data=containers.read(otf.cache,hash)
- if cleanup>2 then
- collectgarbage("collect")
- else
- checkmemory(used,threshold,tracememory)
- end
+ local base=file.basename(file.removesuffix(filename))
+ local name=file.removesuffix(base)
+ local attr=lfs.attributes(filename)
+ local size=attr and attr.size or 0
+ local time=attr and attr.modification or 0
+ if sub=="" then
+ sub=false
+ end
+ local hash=name
+ if sub then
+ hash=hash.."-"..sub
+ end
+ if instance then
+ hash=hash.."-"..instance
+ end
+ hash=containers.cleanname(hash)
+ local data=containers.read(otf.cache,hash)
+ local reload=not data or data.size~=size or data.time~=time or data.tableversion~=otfreaders.tableversion
+ if forceload then
+ report_otf("forced reload of %a due to hard coded flag",filename)
+ reload=true
+ end
+ if reload then
+ report_otf("loading %a, hash %a",filename,hash)
+ starttiming(otfreaders,true)
+ data=otfreaders.loadfont(filename,sub or 1,instance)
+ if data then
+ local used=checkmemory()
+ local resources=data.resources
+ local svgshapes=resources.svgshapes
+ local pngshapes=resources.pngshapes
+ if cleanup==0 then
+ checkmemory(used,threshold,tracememory)
+ end
+ if svgshapes then
+ resources.svgshapes=nil
+ if otf.svgenabled then
+ local timestamp=os.date()
+ containers.write(otf.svgcache,hash,{
+ svgshapes=svgshapes,
+ timestamp=timestamp,
+ })
+ data.properties.svg={
+ hash=hash,
+ timestamp=timestamp,
+ }
+ end
+ if cleanup>1 then
+ collectgarbage("collect")
else
- stoptiming(otfreaders)
- data=nil
- report_otf("loading failed due to read error")
- end
+ checkmemory(used,threshold,tracememory)
+ end
+ end
+ if pngshapes then
+ resources.pngshapes=nil
+ if otf.pngenabled then
+ local timestamp=os.date()
+ containers.write(otf.pngcache,hash,{
+ pngshapes=pngshapes,
+ timestamp=timestamp,
+ })
+ data.properties.png={
+ hash=hash,
+ timestamp=timestamp,
+ }
+ end
+ if cleanup>1 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ end
+ otfreaders.compact(data)
+ if cleanup==0 then
+ checkmemory(used,threshold,tracememory)
+ end
+ otfreaders.rehash(data,"unicodes")
+ otfreaders.addunicodetable(data)
+ otfreaders.extend(data)
+ if cleanup==0 then
+ checkmemory(used,threshold,tracememory)
+ end
+ otfreaders.pack(data)
+ report_otf("loading done")
+ report_otf("saving %a in cache",filename)
+ data=containers.write(otf.cache,hash,data)
+ if cleanup>1 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ stoptiming(otfreaders)
+ if elapsedtime then
+ report_otf("loading, optimizing, packing and caching time %s",elapsedtime(otfreaders))
+ end
+ if cleanup>3 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ data=containers.read(otf.cache,hash)
+ if cleanup>2 then
+ collectgarbage("collect")
+ else
+ checkmemory(used,threshold,tracememory)
+ end
+ else
+ stoptiming(otfreaders)
+ data=nil
+ report_otf("loading failed due to read error")
end
- if data then
- if trace_defining then
- report_otf("loading from cache using hash %a",hash)
- end
- otfreaders.unpack(data)
- otfreaders.expand(data)
- otfreaders.addunicodetable(data)
- otfenhancers.apply(data,filename,data)
- if applyruntimefixes then
- applyruntimefixes(filename,data)
- end
- data.metadata.math=data.resources.mathconstants
- local classes=data.resources.classes
- if not classes then
- local descriptions=data.descriptions
- classes=setmetatableindex(function(t,k)
- local d=descriptions[k]
- local v=(d and d.class or "base") or false
- t[k]=v
- return v
- end)
- data.resources.classes=classes
- end
+ end
+ if data then
+ if trace_defining then
+ report_otf("loading from cache using hash %a",hash)
+ end
+ otfreaders.unpack(data)
+ otfreaders.expand(data)
+ otfreaders.addunicodetable(data)
+ otfenhancers.apply(data,filename,data)
+ if applyruntimefixes then
+ applyruntimefixes(filename,data)
+ end
+ data.metadata.math=data.resources.mathconstants
+ local classes=data.resources.classes
+ if not classes then
+ local descriptions=data.descriptions
+ classes=setmetatableindex(function(t,k)
+ local d=descriptions[k]
+ local v=(d and d.class or "base") or false
+ t[k]=v
+ return v
+ end)
+ data.resources.classes=classes
end
- return data
+ end
+ return data
end
function otf.setfeatures(tfmdata,features)
- local okay=constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf)
- if okay then
- return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf)
- else
- return {}
- end
+ local okay=constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf)
+ if okay then
+ return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf)
+ else
+ return {}
+ end
end
local function copytotfm(data,cache_id)
- if data then
- local metadata=data.metadata
- local properties=derivetable(data.properties)
- local descriptions=derivetable(data.descriptions)
- local goodies=derivetable(data.goodies)
- local characters={}
- local parameters={}
- local mathparameters={}
- local resources=data.resources
- local unicodes=resources.unicodes
- local spaceunits=500
- local spacer="space"
- local designsize=metadata.designsize or 100
- local minsize=metadata.minsize or designsize
- local maxsize=metadata.maxsize or designsize
- local mathspecs=metadata.math
- if designsize==0 then
- designsize=100
- minsize=100
- maxsize=100
- end
- if mathspecs then
- for name,value in next,mathspecs do
- mathparameters[name]=value
- end
- end
- for unicode in next,data.descriptions do
- characters[unicode]={}
- end
- if mathspecs then
- for unicode,character in next,characters do
- local d=descriptions[unicode]
- local m=d.math
- if m then
- local italic=m.italic
- local vitalic=m.vitalic
- local variants=m.hvariants
- local parts=m.hparts
- if variants then
- local c=character
- for i=1,#variants do
- local un=variants[i]
- c.next=un
- c=characters[un]
- end
- c.horiz_variants=parts
- elseif parts then
- character.horiz_variants=parts
- italic=m.hitalic
- end
- local variants=m.vvariants
- local parts=m.vparts
- if variants then
- local c=character
- for i=1,#variants do
- local un=variants[i]
- c.next=un
- c=characters[un]
- end
- c.vert_variants=parts
- elseif parts then
- character.vert_variants=parts
- end
- if italic and italic~=0 then
- character.italic=italic
- end
- if vitalic and vitalic~=0 then
- character.vert_italic=vitalic
- end
- local accent=m.accent
- if accent then
- character.accent=accent
- end
- local kerns=m.kerns
- if kerns then
- character.mathkerns=kerns
- end
- end
- end
- end
- local filename=constructors.checkedfilename(resources)
- local fontname=metadata.fontname
- local fullname=metadata.fullname or fontname
- local psname=fontname or fullname
- local subfont=metadata.subfontindex
- local units=metadata.units or 1000
- if units==0 then
- units=1000
- metadata.units=1000
- report_otf("changing %a units to %a",0,units)
- end
- local monospaced=metadata.monospaced
- local charwidth=metadata.averagewidth
- local charxheight=metadata.xheight
- local italicangle=metadata.italicangle
- local hasitalics=metadata.hasitalics
- properties.monospaced=monospaced
- properties.hasitalics=hasitalics
- parameters.italicangle=italicangle
- parameters.charwidth=charwidth
- parameters.charxheight=charxheight
- local space=0x0020
- local emdash=0x2014
- if monospaced then
- if descriptions[space] then
- spaceunits,spacer=descriptions[space].width,"space"
- end
- if not spaceunits and descriptions[emdash] then
- spaceunits,spacer=descriptions[emdash].width,"emdash"
- end
- if not spaceunits and charwidth then
- spaceunits,spacer=charwidth,"charwidth"
- end
- else
- if descriptions[space] then
- spaceunits,spacer=descriptions[space].width,"space"
- end
- if not spaceunits and descriptions[emdash] then
- spaceunits,spacer=descriptions[emdash].width/2,"emdash/2"
- end
- if not spaceunits and charwidth then
- spaceunits,spacer=charwidth,"charwidth"
- end
- end
- spaceunits=tonumber(spaceunits) or units/2
- parameters.slant=0
- parameters.space=spaceunits
- parameters.space_stretch=1*units/2
- parameters.space_shrink=1*units/3
- parameters.x_height=2*units/5
- parameters.quad=units
- if spaceunits<2*units/5 then
- end
- if italicangle and italicangle~=0 then
- parameters.italicangle=italicangle
- parameters.italicfactor=math.cos(math.rad(90+italicangle))
- parameters.slant=- math.tan(italicangle*math.pi/180)
- end
- if monospaced then
- parameters.space_stretch=0
- parameters.space_shrink=0
- elseif syncspace then
- parameters.space_stretch=spaceunits/2
- parameters.space_shrink=spaceunits/3
- end
- parameters.extra_space=parameters.space_shrink
- if charxheight then
- parameters.x_height=charxheight
- else
- local x=0x0078
- if x then
- local x=descriptions[x]
- if x then
- parameters.x_height=x.height
- end
- end
+ if data then
+ local metadata=data.metadata
+ local properties=derivetable(data.properties)
+ local descriptions=derivetable(data.descriptions)
+ local goodies=derivetable(data.goodies)
+ local characters={}
+ local parameters={}
+ local mathparameters={}
+ local resources=data.resources
+ local unicodes=resources.unicodes
+ local spaceunits=500
+ local spacer="space"
+ local designsize=metadata.designsize or 100
+ local minsize=metadata.minsize or designsize
+ local maxsize=metadata.maxsize or designsize
+ local mathspecs=metadata.math
+ if designsize==0 then
+ designsize=100
+ minsize=100
+ maxsize=100
+ end
+ if mathspecs then
+ for name,value in next,mathspecs do
+ mathparameters[name]=value
+ end
+ end
+ for unicode in next,data.descriptions do
+ characters[unicode]={}
+ end
+ if mathspecs then
+ for unicode,character in next,characters do
+ local d=descriptions[unicode]
+ local m=d.math
+ if m then
+ local italic=m.italic
+ local vitalic=m.vitalic
+ local variants=m.hvariants
+ local parts=m.hparts
+ if variants then
+ local c=character
+ for i=1,#variants do
+ local un=variants[i]
+ c.next=un
+ c=characters[un]
+ end
+ c.horiz_variants=parts
+ elseif parts then
+ character.horiz_variants=parts
+ italic=m.hitalic
+ end
+ local variants=m.vvariants
+ local parts=m.vparts
+ if variants then
+ local c=character
+ for i=1,#variants do
+ local un=variants[i]
+ c.next=un
+ c=characters[un]
+ end
+ c.vert_variants=parts
+ elseif parts then
+ character.vert_variants=parts
+ end
+ if italic and italic~=0 then
+ character.italic=italic
+ end
+ if vitalic and vitalic~=0 then
+ character.vert_italic=vitalic
+ end
+ local accent=m.accent
+ if accent then
+ character.accent=accent
+ end
+ local kerns=m.kerns
+ if kerns then
+ character.mathkerns=kerns
+ end
end
- parameters.designsize=(designsize/10)*65536
- parameters.minsize=(minsize/10)*65536
- parameters.maxsize=(maxsize/10)*65536
- parameters.ascender=abs(metadata.ascender or 0)
- parameters.descender=abs(metadata.descender or 0)
- parameters.units=units
- properties.space=spacer
- properties.encodingbytes=2
- properties.format=data.format or formats.otf
- properties.noglyphnames=true
- properties.filename=filename
- properties.fontname=fontname
- properties.fullname=fullname
- properties.psname=psname
- properties.name=filename or fullname
- properties.subfont=subfont
- properties.private=properties.private or data.private or privateoffset
- return {
- characters=characters,
- descriptions=descriptions,
- parameters=parameters,
- mathparameters=mathparameters,
- resources=resources,
- properties=properties,
- goodies=goodies,
- }
- end
+ end
+ end
+ local filename=constructors.checkedfilename(resources)
+ local fontname=metadata.fontname
+ local fullname=metadata.fullname or fontname
+ local psname=fontname or fullname
+ local subfont=metadata.subfontindex
+ local units=metadata.units or 1000
+ if units==0 then
+ units=1000
+ metadata.units=1000
+ report_otf("changing %a units to %a",0,units)
+ end
+ local monospaced=metadata.monospaced
+ local charwidth=metadata.averagewidth
+ local charxheight=metadata.xheight
+ local italicangle=metadata.italicangle
+ local hasitalics=metadata.hasitalics
+ properties.monospaced=monospaced
+ properties.hasitalics=hasitalics
+ parameters.italicangle=italicangle
+ parameters.charwidth=charwidth
+ parameters.charxheight=charxheight
+ local space=0x0020
+ local emdash=0x2014
+ if monospaced then
+ if descriptions[space] then
+ spaceunits,spacer=descriptions[space].width,"space"
+ end
+ if not spaceunits and descriptions[emdash] then
+ spaceunits,spacer=descriptions[emdash].width,"emdash"
+ end
+ if not spaceunits and charwidth then
+ spaceunits,spacer=charwidth,"charwidth"
+ end
+ else
+ if descriptions[space] then
+ spaceunits,spacer=descriptions[space].width,"space"
+ end
+ if not spaceunits and descriptions[emdash] then
+ spaceunits,spacer=descriptions[emdash].width/2,"emdash/2"
+ end
+ if not spaceunits and charwidth then
+ spaceunits,spacer=charwidth,"charwidth"
+ end
+ end
+ spaceunits=tonumber(spaceunits) or units/2
+ parameters.slant=0
+ parameters.space=spaceunits
+ parameters.space_stretch=1*units/2
+ parameters.space_shrink=1*units/3
+ parameters.x_height=2*units/5
+ parameters.quad=units
+ if spaceunits<2*units/5 then
+ end
+ if italicangle and italicangle~=0 then
+ parameters.italicangle=italicangle
+ parameters.italicfactor=math.cos(math.rad(90+italicangle))
+ parameters.slant=- math.tan(italicangle*math.pi/180)
+ end
+ if monospaced then
+ parameters.space_stretch=0
+ parameters.space_shrink=0
+ elseif syncspace then
+ parameters.space_stretch=spaceunits/2
+ parameters.space_shrink=spaceunits/3
+ end
+ parameters.extra_space=parameters.space_shrink
+ if charxheight then
+ parameters.x_height=charxheight
+ else
+ local x=0x0078
+ if x then
+ local x=descriptions[x]
+ if x then
+ parameters.x_height=x.height
+ end
+ end
+ end
+ parameters.designsize=(designsize/10)*65536
+ parameters.minsize=(minsize/10)*65536
+ parameters.maxsize=(maxsize/10)*65536
+ parameters.ascender=abs(metadata.ascender or 0)
+ parameters.descender=abs(metadata.descender or 0)
+ parameters.units=units
+ properties.space=spacer
+ properties.encodingbytes=2
+ properties.format=data.format or formats.otf
+ properties.noglyphnames=true
+ properties.filename=filename
+ properties.fontname=fontname
+ properties.fullname=fullname
+ properties.psname=psname
+ properties.name=filename or fullname
+ properties.subfont=subfont
+ properties.private=properties.private or data.private or privateoffset
+ return {
+ characters=characters,
+ descriptions=descriptions,
+ parameters=parameters,
+ mathparameters=mathparameters,
+ resources=resources,
+ properties=properties,
+ goodies=goodies,
+ }
+ end
end
local converters={
- woff={
- cachename="webfonts",
- action=otf.readers.woff2otf,
- }
+ woff={
+ cachename="webfonts",
+ action=otf.readers.woff2otf,
+ }
}
local function checkconversion(specification)
- local filename=specification.filename
- local converter=converters[lower(file.suffix(filename))]
- if converter then
- local base=file.basename(filename)
- local name=file.removesuffix(base)
- local attr=lfs.attributes(filename)
- local size=attr and attr.size or 0
- local time=attr and attr.modification or 0
- if size>0 then
- local cleanname=containers.cleanname(name)
- local cachename=caches.setfirstwritablefile(cleanname,converter.cachename)
- if not io.exists(cachename) or (time~=lfs.attributes(cachename).modification) then
- report_otf("caching font %a in %a",filename,cachename)
- converter.action(filename,cachename)
- lfs.touch(cachename,time,time)
- end
- specification.filename=cachename
- end
+ local filename=specification.filename
+ local converter=converters[lower(file.suffix(filename))]
+ if converter then
+ local base=file.basename(filename)
+ local name=file.removesuffix(base)
+ local attr=lfs.attributes(filename)
+ local size=attr and attr.size or 0
+ local time=attr and attr.modification or 0
+ if size>0 then
+ local cleanname=containers.cleanname(name)
+ local cachename=caches.setfirstwritablefile(cleanname,converter.cachename)
+ if not io.exists(cachename) or (time~=lfs.attributes(cachename).modification) then
+ report_otf("caching font %a in %a",filename,cachename)
+ converter.action(filename,cachename)
+ lfs.touch(cachename,time,time)
+ end
+ specification.filename=cachename
end
+ end
end
local function otftotfm(specification)
- local cache_id=specification.hash
- local tfmdata=containers.read(constructors.cache,cache_id)
- if not tfmdata then
- checkconversion(specification)
- local name=specification.name
- local sub=specification.sub
- local subindex=specification.subindex
- local filename=specification.filename
- local features=specification.features.normal
- local instance=specification.instance or (features and features.axis)
- local rawdata=otf.load(filename,sub,instance)
- if rawdata and next(rawdata) then
- local descriptions=rawdata.descriptions
- rawdata.lookuphash={}
- tfmdata=copytotfm(rawdata,cache_id)
- if tfmdata and next(tfmdata) then
- local features=constructors.checkedfeatures("otf",features)
- local shared=tfmdata.shared
- if not shared then
- shared={}
- tfmdata.shared=shared
- end
- shared.rawdata=rawdata
- shared.dynamics={}
- tfmdata.changed={}
- shared.features=features
- shared.processes=otf.setfeatures(tfmdata,features)
- end
+ local cache_id=specification.hash
+ local tfmdata=containers.read(constructors.cache,cache_id)
+ if not tfmdata then
+ checkconversion(specification)
+ local name=specification.name
+ local sub=specification.sub
+ local subindex=specification.subindex
+ local filename=specification.filename
+ local features=specification.features.normal
+ local instance=specification.instance or (features and features.axis)
+ local rawdata=otf.load(filename,sub,instance)
+ if rawdata and next(rawdata) then
+ local descriptions=rawdata.descriptions
+ rawdata.lookuphash={}
+ tfmdata=copytotfm(rawdata,cache_id)
+ if tfmdata and next(tfmdata) then
+ local features=constructors.checkedfeatures("otf",features)
+ local shared=tfmdata.shared
+ if not shared then
+ shared={}
+ tfmdata.shared=shared
end
- containers.write(constructors.cache,cache_id,tfmdata)
+ shared.rawdata=rawdata
+ shared.dynamics={}
+ tfmdata.changed={}
+ shared.features=features
+ shared.processes=otf.setfeatures(tfmdata,features)
+ end
end
- return tfmdata
+ containers.write(constructors.cache,cache_id,tfmdata)
+ end
+ return tfmdata
end
local function read_from_otf(specification)
- local tfmdata=otftotfm(specification)
- if tfmdata then
- tfmdata.properties.name=specification.name
- tfmdata.properties.sub=specification.sub
- tfmdata=constructors.scale(tfmdata,specification)
- local allfeatures=tfmdata.shared.features or specification.features.normal
- constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf)
- constructors.setname(tfmdata,specification)
- fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification)
- end
- return tfmdata
+ local tfmdata=otftotfm(specification)
+ if tfmdata then
+ tfmdata.properties.name=specification.name
+ tfmdata.properties.sub=specification.sub
+ tfmdata=constructors.scale(tfmdata,specification)
+ local allfeatures=tfmdata.shared.features or specification.features.normal
+ constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf)
+ constructors.setname(tfmdata,specification)
+ fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification)
+ end
+ return tfmdata
end
local function checkmathsize(tfmdata,mathsize)
- local mathdata=tfmdata.shared.rawdata.metadata.math
- local mathsize=tonumber(mathsize)
- if mathdata then
- local parameters=tfmdata.parameters
- parameters.scriptpercentage=mathdata.ScriptPercentScaleDown
- parameters.scriptscriptpercentage=mathdata.ScriptScriptPercentScaleDown
- parameters.mathsize=mathsize
- end
+ local mathdata=tfmdata.shared.rawdata.metadata.math
+ local mathsize=tonumber(mathsize)
+ if mathdata then
+ local parameters=tfmdata.parameters
+ parameters.scriptpercentage=mathdata.ScriptPercentScaleDown
+ parameters.scriptscriptpercentage=mathdata.ScriptScriptPercentScaleDown
+ parameters.mathsize=mathsize
+ end
end
registerotffeature {
- name="mathsize",
- description="apply mathsize specified in the font",
- initializers={
- base=checkmathsize,
- node=checkmathsize,
- }
+ name="mathsize",
+ description="apply mathsize specified in the font",
+ initializers={
+ base=checkmathsize,
+ node=checkmathsize,
+ }
}
function otf.collectlookups(rawdata,kind,script,language)
- if not kind then
- return
- end
- if not script then
- script=default
- end
- if not language then
- language=default
- end
- local lookupcache=rawdata.lookupcache
- if not lookupcache then
- lookupcache={}
- rawdata.lookupcache=lookupcache
- end
- local kindlookup=lookupcache[kind]
- if not kindlookup then
- kindlookup={}
- lookupcache[kind]=kindlookup
- end
- local scriptlookup=kindlookup[script]
- if not scriptlookup then
- scriptlookup={}
- kindlookup[script]=scriptlookup
- end
- local languagelookup=scriptlookup[language]
- if not languagelookup then
- local sequences=rawdata.resources.sequences
- local featuremap={}
- local featurelist={}
- if sequences then
- for s=1,#sequences do
- local sequence=sequences[s]
- local features=sequence.features
- if features then
- features=features[kind]
- if features then
- features=features[script] or features[wildcard]
- if features then
- features=features[language] or features[wildcard]
- if features then
- if not featuremap[sequence] then
- featuremap[sequence]=true
- featurelist[#featurelist+1]=sequence
- end
- end
- end
- end
+ if not kind then
+ return
+ end
+ if not script then
+ script=default
+ end
+ if not language then
+ language=default
+ end
+ local lookupcache=rawdata.lookupcache
+ if not lookupcache then
+ lookupcache={}
+ rawdata.lookupcache=lookupcache
+ end
+ local kindlookup=lookupcache[kind]
+ if not kindlookup then
+ kindlookup={}
+ lookupcache[kind]=kindlookup
+ end
+ local scriptlookup=kindlookup[script]
+ if not scriptlookup then
+ scriptlookup={}
+ kindlookup[script]=scriptlookup
+ end
+ local languagelookup=scriptlookup[language]
+ if not languagelookup then
+ local sequences=rawdata.resources.sequences
+ local featuremap={}
+ local featurelist={}
+ if sequences then
+ for s=1,#sequences do
+ local sequence=sequences[s]
+ local features=sequence.features
+ if features then
+ features=features[kind]
+ if features then
+ features=features[script] or features[wildcard]
+ if features then
+ features=features[language] or features[wildcard]
+ if features then
+ if not featuremap[sequence] then
+ featuremap[sequence]=true
+ featurelist[#featurelist+1]=sequence
end
+ end
end
- if #featurelist==0 then
- featuremap,featurelist=false,false
- end
- else
- featuremap,featurelist=false,false
+ end
end
- languagelookup={ featuremap,featurelist }
- scriptlookup[language]=languagelookup
+ end
+ if #featurelist==0 then
+ featuremap,featurelist=false,false
+ end
+ else
+ featuremap,featurelist=false,false
end
- return unpack(languagelookup)
+ languagelookup={ featuremap,featurelist }
+ scriptlookup[language]=languagelookup
+ end
+ return unpack(languagelookup)
end
local function getgsub(tfmdata,k,kind,value)
- local shared=tfmdata.shared
- local rawdata=shared and shared.rawdata
- if rawdata then
- local sequences=rawdata.resources.sequences
- if sequences then
- local properties=tfmdata.properties
- local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language)
- if validlookups then
- for i=1,#lookuplist do
- local lookup=lookuplist[i]
- local steps=lookup.steps
- local nofsteps=lookup.nofsteps
- for i=1,nofsteps do
- local coverage=steps[i].coverage
- if coverage then
- local found=coverage[k]
- if found then
- return found,lookup.type
- end
- end
- end
- end
+ local shared=tfmdata.shared
+ local rawdata=shared and shared.rawdata
+ if rawdata then
+ local sequences=rawdata.resources.sequences
+ if sequences then
+ local properties=tfmdata.properties
+ local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language)
+ if validlookups then
+ for i=1,#lookuplist do
+ local lookup=lookuplist[i]
+ local steps=lookup.steps
+ local nofsteps=lookup.nofsteps
+ for i=1,nofsteps do
+ local coverage=steps[i].coverage
+ if coverage then
+ local found=coverage[k]
+ if found then
+ return found,lookup.type
+ end
end
+ end
end
+ end
end
+ end
end
otf.getgsub=getgsub
function otf.getsubstitution(tfmdata,k,kind,value)
- local found,kind=getgsub(tfmdata,k,kind,value)
- if not found then
- elseif kind=="gsub_single" then
- return found
- elseif kind=="gsub_alternate" then
- local choice=tonumber(value) or 1
- return found[choice] or found[1] or k
- end
- return k
+ local found,kind=getgsub(tfmdata,k,kind,value)
+ if not found then
+ elseif kind=="gsub_single" then
+ return found
+ elseif kind=="gsub_alternate" then
+ local choice=tonumber(value) or 1
+ return found[choice] or found[1] or k
+ end
+ return k
end
otf.getalternate=otf.getsubstitution
function otf.getmultiple(tfmdata,k,kind)
- local found,kind=getgsub(tfmdata,k,kind)
- if found and kind=="gsub_multiple" then
- return found
- end
- return { k }
+ local found,kind=getgsub(tfmdata,k,kind)
+ if found and kind=="gsub_multiple" then
+ return found
+ end
+ return { k }
end
function otf.getkern(tfmdata,left,right,kind)
- local kerns=getgsub(tfmdata,left,kind or "kern",true)
- if kerns then
- local found=kerns[right]
- local kind=type(found)
- if kind=="table" then
- found=found[1][3]
- elseif kind~="number" then
- found=false
- end
- if found then
- return found*tfmdata.parameters.factor
- end
+ local kerns=getgsub(tfmdata,left,kind or "kern",true)
+ if kerns then
+ local found=kerns[right]
+ local kind=type(found)
+ if kind=="table" then
+ found=found[1][3]
+ elseif kind~="number" then
+ found=false
end
- return 0
+ if found then
+ return found*tfmdata.parameters.factor
+ end
+ end
+ return 0
end
local function check_otf(forced,specification,suffix)
- local name=specification.name
- if forced then
- name=specification.forcedname
- end
- local fullname=findbinfile(name,suffix) or ""
- if fullname=="" then
- fullname=fonts.names.getfilename(name,suffix) or ""
- end
- if fullname~="" and not fonts.names.ignoredfile(fullname) then
- specification.filename=fullname
- return read_from_otf(specification)
- end
+ local name=specification.name
+ if forced then
+ name=specification.forcedname
+ end
+ local fullname=findbinfile(name,suffix) or ""
+ if fullname=="" then
+ fullname=fonts.names.getfilename(name,suffix) or ""
+ end
+ if fullname~="" and not fonts.names.ignoredfile(fullname) then
+ specification.filename=fullname
+ return read_from_otf(specification)
+ end
end
local function opentypereader(specification,suffix)
- local forced=specification.forced or ""
- if formats[forced] then
- return check_otf(true,specification,forced)
- else
- return check_otf(false,specification,suffix)
- end
+ local forced=specification.forced or ""
+ if formats[forced] then
+ return check_otf(true,specification,forced)
+ else
+ return check_otf(false,specification,suffix)
+ end
end
readers.opentype=opentypereader
function readers.otf(specification) return opentypereader(specification,"otf") end
function readers.ttf(specification) return opentypereader(specification,"ttf") end
function readers.ttc(specification) return opentypereader(specification,"ttf") end
function readers.woff(specification)
- checkconversion(specification)
- opentypereader(specification,"")
+ checkconversion(specification)
+ opentypereader(specification,"")
end
function otf.scriptandlanguage(tfmdata,attr)
- local properties=tfmdata.properties
- return properties.script or "dflt",properties.language or "dflt"
+ local properties=tfmdata.properties
+ return properties.script or "dflt",properties.language or "dflt"
end
local function justset(coverage,unicode,replacement)
- coverage[unicode]=replacement
+ coverage[unicode]=replacement
end
otf.coverup={
- stepkey="steps",
- actions={
- chainsubstitution=justset,
- chainposition=justset,
- substitution=justset,
- alternate=justset,
- multiple=justset,
- kern=justset,
- pair=justset,
- single=justset,
- ligature=function(coverage,unicode,ligature)
- local first=ligature[1]
- local tree=coverage[first]
- if not tree then
- tree={}
- coverage[first]=tree
- end
- for i=2,#ligature do
- local l=ligature[i]
- local t=tree[l]
- if not t then
- t={}
- tree[l]=t
- end
- tree=t
- end
- tree.ligature=unicode
- end,
- },
- register=function(coverage,featuretype,format)
- return {
- format=format,
- coverage=coverage,
- }
- end
+ stepkey="steps",
+ actions={
+ chainsubstitution=justset,
+ chainposition=justset,
+ substitution=justset,
+ alternate=justset,
+ multiple=justset,
+ kern=justset,
+ pair=justset,
+ single=justset,
+ ligature=function(coverage,unicode,ligature)
+ local first=ligature[1]
+ local tree=coverage[first]
+ if not tree then
+ tree={}
+ coverage[first]=tree
+ end
+ for i=2,#ligature do
+ local l=ligature[i]
+ local t=tree[l]
+ if not t then
+ t={}
+ tree[l]=t
+ end
+ tree=t
+ end
+ tree.ligature=unicode
+ end,
+ },
+ register=function(coverage,featuretype,format)
+ return {
+ format=format,
+ coverage=coverage,
+ }
+ end
}
end -- closure
@@ -23169,23 +23169,23 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-oto']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local concat,unpack=table.concat,table.unpack
local insert,remove=table.insert,table.remove
local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip
local type,next,tonumber,tostring,rawget=type,next,tonumber,tostring,rawget
-local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end)
-local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end)
-local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end)
-local trace_alternatives=false trackers.register("otf.alternatives",function(v) trace_alternatives=v end)
-local trace_ligatures=false trackers.register("otf.ligatures",function(v) trace_ligatures=v end)
-local trace_kerns=false trackers.register("otf.kerns",function(v) trace_kerns=v end)
-local trace_preparing=false trackers.register("otf.preparing",function(v) trace_preparing=v end)
+local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end)
+local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end)
+local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end)
+local trace_alternatives=false trackers.register("otf.alternatives",function(v) trace_alternatives=v end)
+local trace_ligatures=false trackers.register("otf.ligatures",function(v) trace_ligatures=v end)
+local trace_kerns=false trackers.register("otf.kerns",function(v) trace_kerns=v end)
+local trace_preparing=false trackers.register("otf.preparing",function(v) trace_preparing=v end)
local report_prepare=logs.reporter("fonts","otf prepare")
local fonts=fonts
local otf=fonts.handlers.otf
@@ -23200,422 +23200,422 @@ local f_unicode=formatters["%U"]
local f_uniname=formatters["%U (%s)"]
local f_unilist=formatters["% t (% t)"]
local function gref(descriptions,n)
- if type(n)=="number" then
- local name=descriptions[n].name
- if name then
- return f_uniname(n,name)
- else
- return f_unicode(n)
- end
- elseif n then
- local num,nam,j={},{},0
- for i=1,#n do
- local ni=n[i]
- if tonumber(ni) then
- j=j+1
- local di=descriptions[ni]
- num[j]=f_unicode(ni)
- nam[j]=di and di.name or "-"
- end
- end
- return f_unilist(num,nam)
+ if type(n)=="number" then
+ local name=descriptions[n].name
+ if name then
+ return f_uniname(n,name)
else
- return "<error in base mode tracing>"
- end
+ return f_unicode(n)
+ end
+ elseif n then
+ local num,nam,j={},{},0
+ for i=1,#n do
+ local ni=n[i]
+ if tonumber(ni) then
+ j=j+1
+ local di=descriptions[ni]
+ num[j]=f_unicode(ni)
+ nam[j]=di and di.name or "-"
+ end
+ end
+ return f_unilist(num,nam)
+ else
+ return "<error in base mode tracing>"
+ end
end
local function cref(feature,sequence)
- return formatters["feature %a, type %a, chain lookup %a"](feature,sequence.type,sequence.name)
+ return formatters["feature %a, type %a, chain lookup %a"](feature,sequence.type,sequence.name)
end
local function report_substitution(feature,sequence,descriptions,unicode,substitution)
- if unicode==substitution then
- report_prepare("%s: base substitution %s maps onto itself",
- cref(feature,sequence),
- gref(descriptions,unicode))
- else
- report_prepare("%s: base substitution %s => %S",
- cref(feature,sequence),
- gref(descriptions,unicode),
- gref(descriptions,substitution))
- end
+ if unicode==substitution then
+ report_prepare("%s: base substitution %s maps onto itself",
+ cref(feature,sequence),
+ gref(descriptions,unicode))
+ else
+ report_prepare("%s: base substitution %s => %S",
+ cref(feature,sequence),
+ gref(descriptions,unicode),
+ gref(descriptions,substitution))
+ end
end
local function report_alternate(feature,sequence,descriptions,unicode,replacement,value,comment)
- if unicode==replacement then
- report_prepare("%s: base alternate %s maps onto itself",
- cref(feature,sequence),
- gref(descriptions,unicode))
- else
- report_prepare("%s: base alternate %s => %s (%S => %S)",
- cref(feature,sequence),
- gref(descriptions,unicode),
- replacement and gref(descriptions,replacement),
- value,
- comment)
- end
+ if unicode==replacement then
+ report_prepare("%s: base alternate %s maps onto itself",
+ cref(feature,sequence),
+ gref(descriptions,unicode))
+ else
+ report_prepare("%s: base alternate %s => %s (%S => %S)",
+ cref(feature,sequence),
+ gref(descriptions,unicode),
+ replacement and gref(descriptions,replacement),
+ value,
+ comment)
+ end
end
local function report_ligature(feature,sequence,descriptions,unicode,ligature)
- report_prepare("%s: base ligature %s => %S",
- cref(feature,sequence),
- gref(descriptions,ligature),
- gref(descriptions,unicode))
+ report_prepare("%s: base ligature %s => %S",
+ cref(feature,sequence),
+ gref(descriptions,ligature),
+ gref(descriptions,unicode))
end
local function report_kern(feature,sequence,descriptions,unicode,otherunicode,value)
- report_prepare("%s: base kern %s + %s => %S",
- cref(feature,sequence),
- gref(descriptions,unicode),
- gref(descriptions,otherunicode),
- value)
+ report_prepare("%s: base kern %s + %s => %S",
+ cref(feature,sequence),
+ gref(descriptions,unicode),
+ gref(descriptions,otherunicode),
+ value)
end
local basehash,basehashes,applied={},1,{}
local function registerbasehash(tfmdata)
- local properties=tfmdata.properties
- local hash=concat(applied," ")
- local base=basehash[hash]
- if not base then
- basehashes=basehashes+1
- base=basehashes
- basehash[hash]=base
- end
- properties.basehash=base
- properties.fullname=(properties.fullname or properties.name).."-"..base
- applied={}
+ local properties=tfmdata.properties
+ local hash=concat(applied," ")
+ local base=basehash[hash]
+ if not base then
+ basehashes=basehashes+1
+ base=basehashes
+ basehash[hash]=base
+ end
+ properties.basehash=base
+ properties.fullname=(properties.fullname or properties.name).."-"..base
+ applied={}
end
local function registerbasefeature(feature,value)
- applied[#applied+1]=feature.."="..tostring(value)
+ applied[#applied+1]=feature.."="..tostring(value)
end
local function makefake(tfmdata,name,present)
- local private=getprivate(tfmdata)
- local character={ intermediate=true,ligatures={} }
- resources.unicodes[name]=private
- tfmdata.characters[private]=character
- tfmdata.descriptions[private]={ name=name }
- present[name]=private
- return character
+ local private=getprivate(tfmdata)
+ local character={ intermediate=true,ligatures={} }
+ resources.unicodes[name]=private
+ tfmdata.characters[private]=character
+ tfmdata.descriptions[private]={ name=name }
+ present[name]=private
+ return character
end
local function make_1(present,tree,name)
- for k,v in next,tree do
- if k=="ligature" then
- present[name]=v
- else
- make_1(present,v,name.."_"..k)
- end
+ for k,v in next,tree do
+ if k=="ligature" then
+ present[name]=v
+ else
+ make_1(present,v,name.."_"..k)
end
+ end
end
local function make_2(present,tfmdata,characters,tree,name,preceding,unicode,done)
- for k,v in next,tree do
- if k=="ligature" then
- local character=characters[preceding]
- if not character then
- if trace_baseinit then
- report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding)
- end
- character=makefake(tfmdata,name,present)
- end
- local ligatures=character.ligatures
- if ligatures then
- ligatures[unicode]={ char=v }
- else
- character.ligatures={ [unicode]={ char=v } }
- end
- if done then
- local d=done[name]
- if not d then
- done[name]={ "dummy",v }
- else
- d[#d+1]=v
- end
- end
+ for k,v in next,tree do
+ if k=="ligature" then
+ local character=characters[preceding]
+ if not character then
+ if trace_baseinit then
+ report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding)
+ end
+ character=makefake(tfmdata,name,present)
+ end
+ local ligatures=character.ligatures
+ if ligatures then
+ ligatures[unicode]={ char=v }
+ else
+ character.ligatures={ [unicode]={ char=v } }
+ end
+ if done then
+ local d=done[name]
+ if not d then
+ done[name]={ "dummy",v }
else
- local code=present[name] or unicode
- local name=name.."_"..k
- make_2(present,tfmdata,characters,v,name,code,k,done)
+ d[#d+1]=v
end
+ end
+ else
+ local code=present[name] or unicode
+ local name=name.."_"..k
+ make_2(present,tfmdata,characters,v,name,code,k,done)
end
+ end
end
local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist)
- local characters=tfmdata.characters
- local descriptions=tfmdata.descriptions
- local resources=tfmdata.resources
- local changed=tfmdata.changed
- local ligatures={}
- local alternate=tonumber(value) or true and 1
- local defaultalt=otf.defaultbasealternate
- local trace_singles=trace_baseinit and trace_singles
- local trace_alternatives=trace_baseinit and trace_alternatives
- local trace_ligatures=trace_baseinit and trace_ligatures
- if not changed then
- changed={}
- tfmdata.changed=changed
- end
- for i=1,#lookuplist do
- local sequence=lookuplist[i]
- local steps=sequence.steps
- local kind=sequence.type
- if kind=="gsub_single" then
- for i=1,#steps do
- for unicode,data in next,steps[i].coverage do
- if unicode~=data then
- changed[unicode]=data
- end
- if trace_singles then
- report_substitution(feature,sequence,descriptions,unicode,data)
- end
- end
+ local characters=tfmdata.characters
+ local descriptions=tfmdata.descriptions
+ local resources=tfmdata.resources
+ local changed=tfmdata.changed
+ local ligatures={}
+ local alternate=tonumber(value) or true and 1
+ local defaultalt=otf.defaultbasealternate
+ local trace_singles=trace_baseinit and trace_singles
+ local trace_alternatives=trace_baseinit and trace_alternatives
+ local trace_ligatures=trace_baseinit and trace_ligatures
+ if not changed then
+ changed={}
+ tfmdata.changed=changed
+ end
+ for i=1,#lookuplist do
+ local sequence=lookuplist[i]
+ local steps=sequence.steps
+ local kind=sequence.type
+ if kind=="gsub_single" then
+ for i=1,#steps do
+ for unicode,data in next,steps[i].coverage do
+ if unicode~=data then
+ changed[unicode]=data
+ end
+ if trace_singles then
+ report_substitution(feature,sequence,descriptions,unicode,data)
+ end
+ end
+ end
+ elseif kind=="gsub_alternate" then
+ for i=1,#steps do
+ for unicode,data in next,steps[i].coverage do
+ local replacement=data[alternate]
+ if replacement then
+ if unicode~=replacement then
+ changed[unicode]=replacement
end
- elseif kind=="gsub_alternate" then
- for i=1,#steps do
- for unicode,data in next,steps[i].coverage do
- local replacement=data[alternate]
- if replacement then
- if unicode~=replacement then
- changed[unicode]=replacement
- end
- if trace_alternatives then
- report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal")
- end
- elseif defaultalt=="first" then
- replacement=data[1]
- if unicode~=replacement then
- changed[unicode]=replacement
- end
- if trace_alternatives then
- report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
- end
- elseif defaultalt=="last" then
- replacement=data[#data]
- if unicode~=replacement then
- changed[unicode]=replacement
- end
- if trace_alternatives then
- report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
- end
- else
- if trace_alternatives then
- report_alternate(feature,sequence,descriptions,unicode,replacement,value,"unknown")
- end
- end
- end
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal")
end
- elseif kind=="gsub_ligature" then
- for i=1,#steps do
- for unicode,data in next,steps[i].coverage do
- ligatures[#ligatures+1]={ unicode,data,"" }
- if trace_ligatures then
- report_ligature(feature,sequence,descriptions,unicode,data)
- end
- end
+ elseif defaultalt=="first" then
+ replacement=data[1]
+ if unicode~=replacement then
+ changed[unicode]=replacement
end
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
+ end
+ elseif defaultalt=="last" then
+ replacement=data[#data]
+ if unicode~=replacement then
+ changed[unicode]=replacement
+ end
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
+ end
+ else
+ if trace_alternatives then
+ report_alternate(feature,sequence,descriptions,unicode,replacement,value,"unknown")
+ end
+ end
end
- end
- local nofligatures=#ligatures
- if nofligatures>0 then
- local characters=tfmdata.characters
- local present={}
- local done=trace_baseinit and trace_ligatures and {}
- for i=1,nofligatures do
- local ligature=ligatures[i]
- local unicode,tree=ligature[1],ligature[2]
- make_1(present,tree,"ctx_"..unicode)
- end
- for i=1,nofligatures do
- local ligature=ligatures[i]
- local unicode,tree,lookupname=ligature[1],ligature[2],ligature[3]
- make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence)
+ end
+ elseif kind=="gsub_ligature" then
+ for i=1,#steps do
+ for unicode,data in next,steps[i].coverage do
+ ligatures[#ligatures+1]={ unicode,data,"" }
+ if trace_ligatures then
+ report_ligature(feature,sequence,descriptions,unicode,data)
+ end
end
+ end
end
+ end
+ local nofligatures=#ligatures
+ if nofligatures>0 then
+ local characters=tfmdata.characters
+ local present={}
+ local done=trace_baseinit and trace_ligatures and {}
+ for i=1,nofligatures do
+ local ligature=ligatures[i]
+ local unicode,tree=ligature[1],ligature[2]
+ make_1(present,tree,"ctx_"..unicode)
+ end
+ for i=1,nofligatures do
+ local ligature=ligatures[i]
+ local unicode,tree,lookupname=ligature[1],ligature[2],ligature[3]
+ make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence)
+ end
+ end
end
local function preparepositionings(tfmdata,feature,value,validlookups,lookuplist)
- local characters=tfmdata.characters
- local descriptions=tfmdata.descriptions
- local resources=tfmdata.resources
- local properties=tfmdata.properties
- local traceindeed=trace_baseinit and trace_kerns
- for i=1,#lookuplist do
- local sequence=lookuplist[i]
- local steps=sequence.steps
- local kind=sequence.type
- local format=sequence.format
- if kind=="gpos_pair" then
- for i=1,#steps do
- local step=steps[i]
- local format=step.format
- if format=="kern" or format=="move" then
- for unicode,data in next,steps[i].coverage do
- local character=characters[unicode]
- local kerns=character.kerns
- if not kerns then
- kerns={}
- character.kerns=kerns
- end
- if traceindeed then
- for otherunicode,kern in next,data do
- if not kerns[otherunicode] and kern~=0 then
- kerns[otherunicode]=kern
- report_kern(feature,sequence,descriptions,unicode,otherunicode,kern)
- end
- end
- else
- for otherunicode,kern in next,data do
- if not kerns[otherunicode] and kern~=0 then
- kerns[otherunicode]=kern
- end
- end
- end
- end
+ local characters=tfmdata.characters
+ local descriptions=tfmdata.descriptions
+ local resources=tfmdata.resources
+ local properties=tfmdata.properties
+ local traceindeed=trace_baseinit and trace_kerns
+ for i=1,#lookuplist do
+ local sequence=lookuplist[i]
+ local steps=sequence.steps
+ local kind=sequence.type
+ local format=sequence.format
+ if kind=="gpos_pair" then
+ for i=1,#steps do
+ local step=steps[i]
+ local format=step.format
+ if format=="kern" or format=="move" then
+ for unicode,data in next,steps[i].coverage do
+ local character=characters[unicode]
+ local kerns=character.kerns
+ if not kerns then
+ kerns={}
+ character.kerns=kerns
+ end
+ if traceindeed then
+ for otherunicode,kern in next,data do
+ if not kerns[otherunicode] and kern~=0 then
+ kerns[otherunicode]=kern
+ report_kern(feature,sequence,descriptions,unicode,otherunicode,kern)
+ end
+ end
+ else
+ for otherunicode,kern in next,data do
+ if not kerns[otherunicode] and kern~=0 then
+ kerns[otherunicode]=kern
+ end
+ end
+ end
+ end
+ else
+ for unicode,data in next,steps[i].coverage do
+ local character=characters[unicode]
+ local kerns=character.kerns
+ for otherunicode,kern in next,data do
+ local other=kern[2]
+ if other==true or (not other and not (kerns and kerns[otherunicode])) then
+ local kern=kern[1]
+ if kern==true then
+ elseif kern[1]~=0 or kern[2]~=0 or kern[4]~=0 then
else
- for unicode,data in next,steps[i].coverage do
- local character=characters[unicode]
- local kerns=character.kerns
- for otherunicode,kern in next,data do
- local other=kern[2]
- if other==true or (not other and not (kerns and kerns[otherunicode])) then
- local kern=kern[1]
- if kern==true then
- elseif kern[1]~=0 or kern[2]~=0 or kern[4]~=0 then
- else
- kern=kern[3]
- if kern~=0 then
- if kerns then
- kerns[otherunicode]=kern
- else
- kerns={ [otherunicode]=kern }
- character.kerns=kerns
- end
- if traceindeed then
- report_kern(feature,sequence,descriptions,unicode,otherunicode,kern)
- end
- end
- end
- end
- end
+ kern=kern[3]
+ if kern~=0 then
+ if kerns then
+ kerns[otherunicode]=kern
+ else
+ kerns={ [otherunicode]=kern }
+ character.kerns=kerns
end
+ if traceindeed then
+ report_kern(feature,sequence,descriptions,unicode,otherunicode,kern)
+ end
+ end
end
+ end
end
+ end
end
+ end
end
+ end
end
local function initializehashes(tfmdata)
end
local function checkmathreplacements(tfmdata,fullname,fixitalics)
- if tfmdata.mathparameters then
- local characters=tfmdata.characters
- local changed=tfmdata.changed
- if next(changed) then
- if trace_preparing or trace_baseinit then
- report_prepare("checking math replacements for %a",fullname)
- end
- for unicode,replacement in next,changed do
- local u=characters[unicode]
- local r=characters[replacement]
- if u and r then
- local n=u.next
- local v=u.vert_variants
- local h=u.horiz_variants
- if fixitalics then
- local ui=u.italic
- if ui and not r.italic then
- if trace_preparing then
- report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement)
- end
- r.italic=ui
- end
- end
- if n and not r.next then
- if trace_preparing then
- report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement)
- end
- r.next=n
- end
- if v and not r.vert_variants then
- if trace_preparing then
- report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement)
- end
- r.vert_variants=v
- end
- if h and not r.horiz_variants then
- if trace_preparing then
- report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement)
- end
- r.horiz_variants=h
- end
- else
- if trace_preparing then
- report_prepare("error replacing %C by %U",unicode,replacement)
- end
- end
+ if tfmdata.mathparameters then
+ local characters=tfmdata.characters
+ local changed=tfmdata.changed
+ if next(changed) then
+ if trace_preparing or trace_baseinit then
+ report_prepare("checking math replacements for %a",fullname)
+ end
+ for unicode,replacement in next,changed do
+ local u=characters[unicode]
+ local r=characters[replacement]
+ if u and r then
+ local n=u.next
+ local v=u.vert_variants
+ local h=u.horiz_variants
+ if fixitalics then
+ local ui=u.italic
+ if ui and not r.italic then
+ if trace_preparing then
+ report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement)
+ end
+ r.italic=ui
+ end
+ end
+ if n and not r.next then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement)
+ end
+ r.next=n
+ end
+ if v and not r.vert_variants then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement)
+ end
+ r.vert_variants=v
+ end
+ if h and not r.horiz_variants then
+ if trace_preparing then
+ report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement)
end
+ r.horiz_variants=h
+ end
+ else
+ if trace_preparing then
+ report_prepare("error replacing %C by %U",unicode,replacement)
+ end
end
+ end
end
+ end
end
local function featuresinitializer(tfmdata,value)
- if true then
- local starttime=trace_preparing and os.clock()
- local features=tfmdata.shared.features
- local fullname=tfmdata.properties.fullname or "?"
- if features then
- initializehashes(tfmdata)
- local collectlookups=otf.collectlookups
- local rawdata=tfmdata.shared.rawdata
- local properties=tfmdata.properties
- local script=properties.script
- local language=properties.language
- local rawresources=rawdata.resources
- local rawfeatures=rawresources and rawresources.features
- local basesubstitutions=rawfeatures and rawfeatures.gsub
- local basepositionings=rawfeatures and rawfeatures.gpos
- local substitutionsdone=false
- local positioningsdone=false
- if basesubstitutions or basepositionings then
- local sequences=tfmdata.resources.sequences
- for s=1,#sequences do
- local sequence=sequences[s]
- local sfeatures=sequence.features
- if sfeatures then
- local order=sequence.order
- if order then
- for i=1,#order do
- local feature=order[i]
- local value=features[feature]
- if value then
- local validlookups,lookuplist=collectlookups(rawdata,feature,script,language)
- if not validlookups then
- elseif basesubstitutions and basesubstitutions[feature] then
- if trace_preparing then
- report_prepare("filtering base %s feature %a for %a with value %a","sub",feature,fullname,value)
- end
- preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist)
- registerbasefeature(feature,value)
- substitutionsdone=true
- elseif basepositionings and basepositionings[feature] then
- if trace_preparing then
- report_prepare("filtering base %a feature %a for %a with value %a","pos",feature,fullname,value)
- end
- preparepositionings(tfmdata,feature,value,validlookups,lookuplist)
- registerbasefeature(feature,value)
- positioningsdone=true
- end
- end
- end
- end
+ if true then
+ local starttime=trace_preparing and os.clock()
+ local features=tfmdata.shared.features
+ local fullname=tfmdata.properties.fullname or "?"
+ if features then
+ initializehashes(tfmdata)
+ local collectlookups=otf.collectlookups
+ local rawdata=tfmdata.shared.rawdata
+ local properties=tfmdata.properties
+ local script=properties.script
+ local language=properties.language
+ local rawresources=rawdata.resources
+ local rawfeatures=rawresources and rawresources.features
+ local basesubstitutions=rawfeatures and rawfeatures.gsub
+ local basepositionings=rawfeatures and rawfeatures.gpos
+ local substitutionsdone=false
+ local positioningsdone=false
+ if basesubstitutions or basepositionings then
+ local sequences=tfmdata.resources.sequences
+ for s=1,#sequences do
+ local sequence=sequences[s]
+ local sfeatures=sequence.features
+ if sfeatures then
+ local order=sequence.order
+ if order then
+ for i=1,#order do
+ local feature=order[i]
+ local value=features[feature]
+ if value then
+ local validlookups,lookuplist=collectlookups(rawdata,feature,script,language)
+ if not validlookups then
+ elseif basesubstitutions and basesubstitutions[feature] then
+ if trace_preparing then
+ report_prepare("filtering base %s feature %a for %a with value %a","sub",feature,fullname,value)
+ end
+ preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist)
+ registerbasefeature(feature,value)
+ substitutionsdone=true
+ elseif basepositionings and basepositionings[feature] then
+ if trace_preparing then
+ report_prepare("filtering base %a feature %a for %a with value %a","pos",feature,fullname,value)
end
+ preparepositionings(tfmdata,feature,value,validlookups,lookuplist)
+ registerbasefeature(feature,value)
+ positioningsdone=true
+ end
end
+ end
end
- if substitutionsdone then
- checkmathreplacements(tfmdata,fullname,features.fixitalics)
- end
- registerbasehash(tfmdata)
- end
- if trace_preparing then
- report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname)
+ end
end
+ end
+ if substitutionsdone then
+ checkmathreplacements(tfmdata,fullname,features.fixitalics)
+ end
+ registerbasehash(tfmdata)
end
+ if trace_preparing then
+ report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname)
+ end
+ end
end
registerotffeature {
- name="features",
- description="features",
- default=true,
- initializers={
- base=featuresinitializer,
- }
+ name="features",
+ description="features",
+ default=true,
+ initializers={
+ base=featuresinitializer,
+ }
}
otf.basemodeinitializer=featuresinitializer
@@ -23624,21 +23624,21 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-otj']={
- version=1.001,
- comment="companion to font-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to font-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
if not nodes.properties then return end
local next,rawget,tonumber=next,rawget,tonumber
local fastcopy=table.fastcopy
local registertracker=trackers.register
local registerdirective=directives.register
-local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end)
-local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end)
-local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end)
-local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end)
+local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end)
+local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end)
+local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end)
+local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end)
local report_injections=logs.reporter("fonts","injections")
local report_spaces=logs.reporter("fonts","spaces")
local attributes,nodes,node=attributes,nodes,node
@@ -23682,34 +23682,34 @@ local nextglue=nuts.traversers.glue
local insert_node_before=nuts.insert_before
local insert_node_after=nuts.insert_after
local properties=nodes.properties.data
-local fontkern=nuts.pool and nuts.pool.fontkern
+local fontkern=nuts.pool and nuts.pool.fontkern
local italickern=nuts.pool and nuts.pool.italickern
local useitalickerns=false
directives.register("fonts.injections.useitalics",function(v)
- if v then
- report_injections("using italics for space kerns (tracing only)")
- end
- useitalickerns=v
+ if v then
+ report_injections("using italics for space kerns (tracing only)")
+ end
+ useitalickerns=v
end)
do if not fontkern then
- local thekern=nuts.new("kern",0)
- local setkern=nuts.setkern
- local copy_node=nuts.copy_node
- fontkern=function(k)
- local n=copy_node(thekern)
- setkern(n,k)
- return n
- end
+ local thekern=nuts.new("kern",0)
+ local setkern=nuts.setkern
+ local copy_node=nuts.copy_node
+ fontkern=function(k)
+ local n=copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
end end
do if not italickern then
- local thekern=nuts.new("kern",3)
- local setkern=nuts.setkern
- local copy_node=nuts.copy_node
- italickern=function(k)
- local n=copy_node(thekern)
- setkern(n,k)
- return n
- end
+ local thekern=nuts.new("kern",3)
+ local setkern=nuts.setkern
+ local copy_node=nuts.copy_node
+ italickern=function(k)
+ local n=copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
end end
function injections.installnewkern() end
local nofregisteredkerns=0
@@ -23718,1199 +23718,1199 @@ local nofregisteredmarks=0
local nofregisteredcursives=0
local keepregisteredcounts=false
function injections.keepcounts()
- keepregisteredcounts=true
+ keepregisteredcounts=true
end
function injections.resetcounts()
- nofregisteredkerns=0
- nofregisteredpositions=0
- nofregisteredmarks=0
- nofregisteredcursives=0
- keepregisteredcounts=false
+ nofregisteredkerns=0
+ nofregisteredpositions=0
+ nofregisteredmarks=0
+ nofregisteredcursives=0
+ keepregisteredcounts=false
end
function injections.reset(n)
- local p=rawget(properties,n)
- if p then
- p.injections=false
- else
- properties[n]=false
- end
+ local p=rawget(properties,n)
+ if p then
+ p.injections=false
+ else
+ properties[n]=false
+ end
end
function injections.copy(target,source)
- local sp=rawget(properties,source)
- if sp then
- local tp=rawget(properties,target)
- local si=sp.injections
- if si then
- si=fastcopy(si)
- if tp then
- tp.injections=si
- else
- properties[target]={
- injections=si,
- }
- end
- elseif tp then
- tp.injections=false
- else
- properties[target]={ injections={} }
- end
+ local sp=rawget(properties,source)
+ if sp then
+ local tp=rawget(properties,target)
+ local si=sp.injections
+ if si then
+ si=fastcopy(si)
+ if tp then
+ tp.injections=si
+ else
+ properties[target]={
+ injections=si,
+ }
+ end
+ elseif tp then
+ tp.injections=false
else
- local tp=rawget(properties,target)
- if tp then
- tp.injections=false
- else
- properties[target]=false
- end
+ properties[target]={ injections={} }
end
+ else
+ local tp=rawget(properties,target)
+ if tp then
+ tp.injections=false
+ else
+ properties[target]=false
+ end
+ end
end
function injections.setligaindex(n,index)
- local p=rawget(properties,n)
- if p then
- local i=p.injections
- if i then
- i.ligaindex=index
- else
- p.injections={
- ligaindex=index
- }
- end
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections
+ if i then
+ i.ligaindex=index
else
- properties[n]={
- injections={
- ligaindex=index
- }
- }
- end
+ p.injections={
+ ligaindex=index
+ }
+ end
+ else
+ properties[n]={
+ injections={
+ ligaindex=index
+ }
+ }
+ end
end
function injections.getligaindex(n,default)
- local p=rawget(properties,n)
- if p then
- local i=p.injections
- if i then
- return i.ligaindex or default
- end
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections
+ if i then
+ return i.ligaindex or default
end
- return default
+ end
+ return default
end
function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext,r2lflag)
- local dx=factor*(exit[1]-entry[1])
- local dy=-factor*(exit[2]-entry[2])
- local ws=tfmstart.width
- local wn=tfmnext.width
- nofregisteredcursives=nofregisteredcursives+1
- if rlmode<0 then
- dx=-(dx+wn)
+ local dx=factor*(exit[1]-entry[1])
+ local dy=-factor*(exit[2]-entry[2])
+ local ws=tfmstart.width
+ local wn=tfmnext.width
+ nofregisteredcursives=nofregisteredcursives+1
+ if rlmode<0 then
+ dx=-(dx+wn)
+ else
+ dx=dx-ws
+ end
+ if dx==0 then
+ dx=0
+ end
+ local p=rawget(properties,start)
+ if p then
+ local i=p.injections
+ if i then
+ i.cursiveanchor=true
else
- dx=dx-ws
- end
- if dx==0 then
- dx=0
- end
- local p=rawget(properties,start)
- if p then
- local i=p.injections
- if i then
- i.cursiveanchor=true
- else
- p.injections={
- cursiveanchor=true,
- }
- end
- else
- properties[start]={
- injections={
- cursiveanchor=true,
- },
- }
- end
- local p=rawget(properties,nxt)
- if p then
- local i=p.injections
- if i then
- i.cursivex=dx
- i.cursivey=dy
- else
- p.injections={
- cursivex=dx,
- cursivey=dy,
- }
- end
+ p.injections={
+ cursiveanchor=true,
+ }
+ end
+ else
+ properties[start]={
+ injections={
+ cursiveanchor=true,
+ },
+ }
+ end
+ local p=rawget(properties,nxt)
+ if p then
+ local i=p.injections
+ if i then
+ i.cursivex=dx
+ i.cursivey=dy
else
- properties[nxt]={
- injections={
- cursivex=dx,
- cursivey=dy,
- },
- }
- end
- return dx,dy,nofregisteredcursives
+ p.injections={
+ cursivex=dx,
+ cursivey=dy,
+ }
+ end
+ else
+ properties[nxt]={
+ injections={
+ cursivex=dx,
+ cursivey=dy,
+ },
+ }
+ end
+ return dx,dy,nofregisteredcursives
end
function injections.setposition(kind,current,factor,rlmode,spec,injection)
- local x=factor*(spec[1] or 0)
- local y=factor*(spec[2] or 0)
- local w=factor*(spec[3] or 0)
- local h=factor*(spec[4] or 0)
- if x~=0 or w~=0 or y~=0 or h~=0 then
- local yoffset=y-h
- local leftkern=x
- local rightkern=w-x
- if leftkern~=0 or rightkern~=0 or yoffset~=0 then
- nofregisteredpositions=nofregisteredpositions+1
- if rlmode and rlmode<0 then
- leftkern,rightkern=rightkern,leftkern
- end
- if not injection then
- injection="injections"
- end
- local p=rawget(properties,current)
- if p then
- local i=p[injection]
- if i then
- if leftkern~=0 then
- i.leftkern=(i.leftkern or 0)+leftkern
- end
- if rightkern~=0 then
- i.rightkern=(i.rightkern or 0)+rightkern
- end
- if yoffset~=0 then
- i.yoffset=(i.yoffset or 0)+yoffset
- end
- elseif leftkern~=0 or rightkern~=0 then
- p[injection]={
- leftkern=leftkern,
- rightkern=rightkern,
- yoffset=yoffset,
- }
- else
- p[injection]={
- yoffset=yoffset,
- }
- end
- elseif leftkern~=0 or rightkern~=0 then
- properties[current]={
- [injection]={
- leftkern=leftkern,
- rightkern=rightkern,
- yoffset=yoffset,
- },
- }
- else
- properties[current]={
- [injection]={
- yoffset=yoffset,
- },
- }
- end
- return x,y,w,h,nofregisteredpositions
+ local x=factor*(spec[1] or 0)
+ local y=factor*(spec[2] or 0)
+ local w=factor*(spec[3] or 0)
+ local h=factor*(spec[4] or 0)
+ if x~=0 or w~=0 or y~=0 or h~=0 then
+ local yoffset=y-h
+ local leftkern=x
+ local rightkern=w-x
+ if leftkern~=0 or rightkern~=0 or yoffset~=0 then
+ nofregisteredpositions=nofregisteredpositions+1
+ if rlmode and rlmode<0 then
+ leftkern,rightkern=rightkern,leftkern
+ end
+ if not injection then
+ injection="injections"
+ end
+ local p=rawget(properties,current)
+ if p then
+ local i=p[injection]
+ if i then
+ if leftkern~=0 then
+ i.leftkern=(i.leftkern or 0)+leftkern
end
- end
- return x,y,w,h
+ if rightkern~=0 then
+ i.rightkern=(i.rightkern or 0)+rightkern
+ end
+ if yoffset~=0 then
+ i.yoffset=(i.yoffset or 0)+yoffset
+ end
+ elseif leftkern~=0 or rightkern~=0 then
+ p[injection]={
+ leftkern=leftkern,
+ rightkern=rightkern,
+ yoffset=yoffset,
+ }
+ else
+ p[injection]={
+ yoffset=yoffset,
+ }
+ end
+ elseif leftkern~=0 or rightkern~=0 then
+ properties[current]={
+ [injection]={
+ leftkern=leftkern,
+ rightkern=rightkern,
+ yoffset=yoffset,
+ },
+ }
+ else
+ properties[current]={
+ [injection]={
+ yoffset=yoffset,
+ },
+ }
+ end
+ return x,y,w,h,nofregisteredpositions
+ end
+ end
+ return x,y,w,h
end
function injections.setkern(current,factor,rlmode,x,injection)
- local dx=factor*x
- if dx~=0 then
- nofregisteredkerns=nofregisteredkerns+1
- local p=rawget(properties,current)
- if not injection then
- injection="injections"
- end
- if p then
- local i=p[injection]
- if i then
- i.leftkern=dx+(i.leftkern or 0)
- else
- p[injection]={
- leftkern=dx,
- }
- end
- else
- properties[current]={
- [injection]={
- leftkern=dx,
- },
- }
- end
- return dx,nofregisteredkerns
+ local dx=factor*x
+ if dx~=0 then
+ nofregisteredkerns=nofregisteredkerns+1
+ local p=rawget(properties,current)
+ if not injection then
+ injection="injections"
+ end
+ if p then
+ local i=p[injection]
+ if i then
+ i.leftkern=dx+(i.leftkern or 0)
+ else
+ p[injection]={
+ leftkern=dx,
+ }
+ end
else
- return 0,0
+ properties[current]={
+ [injection]={
+ leftkern=dx,
+ },
+ }
end
+ return dx,nofregisteredkerns
+ else
+ return 0,0
+ end
end
function injections.setmove(current,factor,rlmode,x,injection)
- local dx=factor*x
- if dx~=0 then
- nofregisteredkerns=nofregisteredkerns+1
- local p=rawget(properties,current)
- if not injection then
- injection="injections"
- end
- if rlmode and rlmode<0 then
- if p then
- local i=p[injection]
- if i then
- i.rightkern=dx+(i.rightkern or 0)
- else
- p[injection]={
- rightkern=dx,
- }
- end
- else
- properties[current]={
- [injection]={
- rightkern=dx,
- },
- }
- end
+ local dx=factor*x
+ if dx~=0 then
+ nofregisteredkerns=nofregisteredkerns+1
+ local p=rawget(properties,current)
+ if not injection then
+ injection="injections"
+ end
+ if rlmode and rlmode<0 then
+ if p then
+ local i=p[injection]
+ if i then
+ i.rightkern=dx+(i.rightkern or 0)
else
- if p then
- local i=p[injection]
- if i then
- i.leftkern=dx+(i.leftkern or 0)
- else
- p[injection]={
- leftkern=dx,
- }
- end
- else
- properties[current]={
- [injection]={
- leftkern=dx,
- },
- }
- end
- end
- return dx,nofregisteredkerns
+ p[injection]={
+ rightkern=dx,
+ }
+ end
+ else
+ properties[current]={
+ [injection]={
+ rightkern=dx,
+ },
+ }
+ end
else
- return 0,0
- end
-end
-function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark)
- local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2])
- nofregisteredmarks=nofregisteredmarks+1
- if rlmode>=0 then
- dx=tfmbase.width-dx
- end
- local p=rawget(properties,start)
- if p then
- local i=p.injections
+ if p then
+ local i=p[injection]
if i then
- if i.markmark then
- else
- if dx~=0 then
- i.markx=dx
- end
- if y~=0 then
- i.marky=dy
- end
- if rlmode then
- i.markdir=rlmode
- end
- i.markbase=nofregisteredmarks
- i.markbasenode=base
- i.markmark=mkmk
- i.checkmark=checkmark
- end
+ i.leftkern=dx+(i.leftkern or 0)
else
- p.injections={
- markx=dx,
- marky=dy,
- markdir=rlmode or 0,
- markbase=nofregisteredmarks,
- markbasenode=base,
- markmark=mkmk,
- checkmark=checkmark,
- }
- end
- else
- properties[start]={
- injections={
- markx=dx,
- marky=dy,
- markdir=rlmode or 0,
- markbase=nofregisteredmarks,
- markbasenode=base,
- markmark=mkmk,
- checkmark=checkmark,
- },
+ p[injection]={
+ leftkern=dx,
+ }
+ end
+ else
+ properties[current]={
+ [injection]={
+ leftkern=dx,
+ },
}
+ end
end
- return dx,dy,nofregisteredmarks
+ return dx,nofregisteredkerns
+ else
+ return 0,0
+ end
+end
+function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark)
+ local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2])
+ nofregisteredmarks=nofregisteredmarks+1
+ if rlmode>=0 then
+ dx=tfmbase.width-dx
+ end
+ local p=rawget(properties,start)
+ if p then
+ local i=p.injections
+ if i then
+ if i.markmark then
+ else
+ if dx~=0 then
+ i.markx=dx
+ end
+ if y~=0 then
+ i.marky=dy
+ end
+ if rlmode then
+ i.markdir=rlmode
+ end
+ i.markbase=nofregisteredmarks
+ i.markbasenode=base
+ i.markmark=mkmk
+ i.checkmark=checkmark
+ end
+ else
+ p.injections={
+ markx=dx,
+ marky=dy,
+ markdir=rlmode or 0,
+ markbase=nofregisteredmarks,
+ markbasenode=base,
+ markmark=mkmk,
+ checkmark=checkmark,
+ }
+ end
+ else
+ properties[start]={
+ injections={
+ markx=dx,
+ marky=dy,
+ markdir=rlmode or 0,
+ markbase=nofregisteredmarks,
+ markbasenode=base,
+ markmark=mkmk,
+ checkmark=checkmark,
+ },
+ }
+ end
+ return dx,dy,nofregisteredmarks
end
local function dir(n)
- return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset"
+ return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset"
end
local function showchar(n,nested)
- local char=getchar(n)
- report_injections("%wfont %s, char %U, glyph %c",nested and 2 or 0,getfont(n),char,char)
+ local char=getchar(n)
+ report_injections("%wfont %s, char %U, glyph %c",nested and 2 or 0,getfont(n),char,char)
end
local function show(n,what,nested,symbol)
- if n then
- local p=rawget(properties,n)
- if p then
- local i=p[what]
- if i then
- local leftkern=i.leftkern or 0
- local rightkern=i.rightkern or 0
- local yoffset=i.yoffset or 0
- local markx=i.markx or 0
- local marky=i.marky or 0
- local markdir=i.markdir or 0
- local markbase=i.markbase or 0
- local cursivex=i.cursivex or 0
- local cursivey=i.cursivey or 0
- local ligaindex=i.ligaindex or 0
- local cursbase=i.cursiveanchor
- local margin=nested and 4 or 2
- if rightkern~=0 or yoffset~=0 then
- report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset)
- elseif leftkern~=0 then
- report_injections("%w%s kern: dx %p",margin,symbol,leftkern)
- end
- if markx~=0 or marky~=0 or markbase~=0 then
- report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase~=0 and "yes" or "no")
- end
- if cursivex~=0 or cursivey~=0 then
- if cursbase then
- report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey)
- else
- report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey)
- end
- elseif cursbase then
- report_injections("%w%s curs: base",margin,symbol)
- end
- if ligaindex~=0 then
- report_injections("%w%s liga: index %i",margin,symbol,ligaindex)
- end
- end
+ if n then
+ local p=rawget(properties,n)
+ if p then
+ local i=p[what]
+ if i then
+ local leftkern=i.leftkern or 0
+ local rightkern=i.rightkern or 0
+ local yoffset=i.yoffset or 0
+ local markx=i.markx or 0
+ local marky=i.marky or 0
+ local markdir=i.markdir or 0
+ local markbase=i.markbase or 0
+ local cursivex=i.cursivex or 0
+ local cursivey=i.cursivey or 0
+ local ligaindex=i.ligaindex or 0
+ local cursbase=i.cursiveanchor
+ local margin=nested and 4 or 2
+ if rightkern~=0 or yoffset~=0 then
+ report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset)
+ elseif leftkern~=0 then
+ report_injections("%w%s kern: dx %p",margin,symbol,leftkern)
+ end
+ if markx~=0 or marky~=0 or markbase~=0 then
+ report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase~=0 and "yes" or "no")
+ end
+ if cursivex~=0 or cursivey~=0 then
+ if cursbase then
+ report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ else
+ report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ end
+ elseif cursbase then
+ report_injections("%w%s curs: base",margin,symbol)
+ end
+ if ligaindex~=0 then
+ report_injections("%w%s liga: index %i",margin,symbol,ligaindex)
end
+ end
end
+ end
end
local function showsub(n,what,where)
- report_injections("begin subrun: %s",where)
- for n in nextchar,n do
- showchar(n,where)
- show(n,what,where," ")
- end
- report_injections("end subrun")
+ report_injections("begin subrun: %s",where)
+ for n in nextchar,n do
+ showchar(n,where)
+ show(n,what,where," ")
+ end
+ report_injections("end subrun")
end
local function trace(head,where)
- report_injections()
- report_injections("begin run %s: %s kerns, %s positions, %s marks and %s cursives registered",
- where or "",nofregisteredkerns,nofregisteredpositions,nofregisteredmarks,nofregisteredcursives)
- local n=head
- while n do
- local id=getid(n)
- if id==glyph_code then
- showchar(n)
- show(n,"injections",false," ")
- show(n,"preinjections",false,"<")
- show(n,"postinjections",false,">")
- show(n,"replaceinjections",false,"=")
- show(n,"emptyinjections",false,"*")
- elseif id==disc_code then
- local pre,post,replace=getdisc(n)
- if pre then
- showsub(pre,"preinjections","pre")
- end
- if post then
- showsub(post,"postinjections","post")
- end
- if replace then
- showsub(replace,"replaceinjections","replace")
- end
- show(n,"emptyinjections",false,"*")
- end
- n=getnext(n)
- end
- report_injections("end run")
+ report_injections()
+ report_injections("begin run %s: %s kerns, %s positions, %s marks and %s cursives registered",
+ where or "",nofregisteredkerns,nofregisteredpositions,nofregisteredmarks,nofregisteredcursives)
+ local n=head
+ while n do
+ local id=getid(n)
+ if id==glyph_code then
+ showchar(n)
+ show(n,"injections",false," ")
+ show(n,"preinjections",false,"<")
+ show(n,"postinjections",false,">")
+ show(n,"replaceinjections",false,"=")
+ show(n,"emptyinjections",false,"*")
+ elseif id==disc_code then
+ local pre,post,replace=getdisc(n)
+ if pre then
+ showsub(pre,"preinjections","pre")
+ end
+ if post then
+ showsub(post,"postinjections","post")
+ end
+ if replace then
+ showsub(replace,"replaceinjections","replace")
+ end
+ show(n,"emptyinjections",false,"*")
+ end
+ n=getnext(n)
+ end
+ report_injections("end run")
end
local function show_result(head)
- local current=head
- local skipping=false
- while current do
- local id=getid(current)
- if id==glyph_code then
- local w=getwidth(current)
- local x,y=getoffsets(current)
- report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y)
- skipping=false
- elseif id==kern_code then
- report_injections("kern: %p",getkern(current))
- skipping=false
- elseif not skipping then
- report_injections()
- skipping=true
- end
- current=getnext(current)
- end
- report_injections()
+ local current=head
+ local skipping=false
+ while current do
+ local id=getid(current)
+ if id==glyph_code then
+ local w=getwidth(current)
+ local x,y=getoffsets(current)
+ report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y)
+ skipping=false
+ elseif id==kern_code then
+ report_injections("kern: %p",getkern(current))
+ skipping=false
+ elseif not skipping then
+ report_injections()
+ skipping=true
+ end
+ current=getnext(current)
+ end
+ report_injections()
end
local function inject_kerns_only(head,where)
- if trace_injections then
- trace(head,"kerns")
- end
- local current=head
- local prev=nil
- local next=nil
- local prevdisc=nil
- local pre=nil
- local post=nil
- local replace=nil
- local pretail=nil
- local posttail=nil
- local replacetail=nil
- while current do
- local next=getnext(current)
- local char,id=ischar(current)
- if char then
- local p=rawget(properties,current)
- if p then
- local i=p.injections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- head=insert_node_before(head,current,fontkern(leftkern))
- end
- end
- if prevdisc then
- local done=false
- if post then
- local i=p.postinjections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- setlink(posttail,fontkern(leftkern))
- done=true
- end
- end
- end
- if replace then
- local i=p.replaceinjections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- setlink(replacetail,fontkern(leftkern))
- done=true
- end
- end
- else
- local i=p.emptyinjections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- setfield(prev,"replace",fontkern(leftkern))
- end
- end
- end
- if done then
- setdisc(prevdisc,pre,post,replace)
- end
- end
+ if trace_injections then
+ trace(head,"kerns")
+ end
+ local current=head
+ local prev=nil
+ local next=nil
+ local prevdisc=nil
+ local pre=nil
+ local post=nil
+ local replace=nil
+ local pretail=nil
+ local posttail=nil
+ local replacetail=nil
+ while current do
+ local next=getnext(current)
+ local char,id=ischar(current)
+ if char then
+ local p=rawget(properties,current)
+ if p then
+ local i=p.injections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ head=insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if prevdisc then
+ local done=false
+ if post then
+ local i=p.postinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(posttail,fontkern(leftkern))
+ done=true
+ end
end
- prevdisc=nil
- elseif char==false then
- prevdisc=nil
- elseif id==disc_code then
- pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
- local done=false
- if pre then
- for n in nextchar,pre do
- local p=rawget(properties,n)
- if p then
- local i=p.injections or p.preinjections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- pre=insert_node_before(pre,n,fontkern(leftkern))
- done=true
- end
- end
- end
- end
+ end
+ if replace then
+ local i=p.replaceinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(replacetail,fontkern(leftkern))
+ done=true
+ end
end
- if post then
- for n in nextchar,post do
- local p=rawget(properties,n)
- if p then
- local i=p.injections or p.postinjections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- post=insert_node_before(post,n,fontkern(leftkern))
- done=true
- end
- end
- end
- end
+ else
+ local i=p.emptyinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setfield(prev,"replace",fontkern(leftkern))
+ end
end
- if replace then
- for n in nextchar,replace do
- local p=rawget(properties,n)
- if p then
- local i=p.injections or p.replaceinjections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- replace=insert_node_before(replace,n,fontkern(leftkern))
- done=true
- end
- end
- end
- end
+ end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
+ end
+ end
+ end
+ prevdisc=nil
+ elseif char==false then
+ prevdisc=nil
+ elseif id==disc_code then
+ pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
+ local done=false
+ if pre then
+ for n in nextchar,pre do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.preinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ pre=insert_node_before(pre,n,fontkern(leftkern))
+ done=true
+ end
end
- if done then
- setdisc(current,pre,post,replace)
+ end
+ end
+ end
+ if post then
+ for n in nextchar,post do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.postinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ post=insert_node_before(post,n,fontkern(leftkern))
+ done=true
+ end
end
- prevdisc=current
- else
- prevdisc=nil
+ end
end
- prev=current
- current=next
- end
- if keepregisteredcounts then
- keepregisteredcounts=false
+ end
+ if replace then
+ for n in nextchar,replace do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.replaceinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=insert_node_before(replace,n,fontkern(leftkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if done then
+ setdisc(current,pre,post,replace)
+ end
+ prevdisc=current
else
- nofregisteredkerns=0
- end
- if trace_injections then
- show_result(head)
+ prevdisc=nil
end
- return head
+ prev=current
+ current=next
+ end
+ if keepregisteredcounts then
+ keepregisteredcounts=false
+ else
+ nofregisteredkerns=0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
end
local function inject_positions_only(head,where)
- if trace_injections then
- trace(head,"positions")
- end
- local current=head
- local prev=nil
- local next=nil
- local prevdisc=nil
- local prevglyph=nil
- local pre=nil
- local post=nil
- local replace=nil
- local pretail=nil
- local posttail=nil
- local replacetail=nil
- while current do
- local next=getnext(current)
- local char,id=ischar(current)
- if char then
- local p=rawget(properties,current)
- if p then
- local i=p.injections
- if i then
- local yoffset=i.yoffset
- if yoffset and yoffset~=0 then
- setoffsets(current,false,yoffset)
- end
- local leftkern=i.leftkern
- local rightkern=i.rightkern
- if leftkern and leftkern~=0 then
- if rightkern and leftkern==-rightkern then
- setoffsets(current,leftkern,false)
- rightkern=0
- else
- head=insert_node_before(head,current,fontkern(leftkern))
- end
- end
- if rightkern and rightkern~=0 then
- insert_node_after(head,current,fontkern(rightkern))
- end
+ if trace_injections then
+ trace(head,"positions")
+ end
+ local current=head
+ local prev=nil
+ local next=nil
+ local prevdisc=nil
+ local prevglyph=nil
+ local pre=nil
+ local post=nil
+ local replace=nil
+ local pretail=nil
+ local posttail=nil
+ local replacetail=nil
+ while current do
+ local next=getnext(current)
+ local char,id=ischar(current)
+ if char then
+ local p=rawget(properties,current)
+ if p then
+ local i=p.injections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(current,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ local rightkern=i.rightkern
+ if leftkern and leftkern~=0 then
+ if rightkern and leftkern==-rightkern then
+ setoffsets(current,leftkern,false)
+ rightkern=0
+ else
+ head=insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if rightkern and rightkern~=0 then
+ insert_node_after(head,current,fontkern(rightkern))
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ if next and getid(next)==disc_code then
+ if replace then
else
- local i=p.emptyinjections
- if i then
- local rightkern=i.rightkern
- if rightkern and rightkern~=0 then
- if next and getid(next)==disc_code then
- if replace then
- else
- setfield(next,"replace",fontkern(rightkern))
- end
- end
- end
- end
- end
- if prevdisc then
- local done=false
- if post then
- local i=p.postinjections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- setlink(posttail,fontkern(leftkern))
- done=true
- end
- end
- end
- if replace then
- local i=p.replaceinjections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- setlink(replacetail,fontkern(leftkern))
- done=true
- end
- end
- else
- local i=p.emptyinjections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- setfield(prev,"replace",fontkern(leftkern))
- end
- end
- end
- if done then
- setdisc(prevdisc,pre,post,replace)
- end
+ setfield(next,"replace",fontkern(rightkern))
end
+ end
end
- prevdisc=nil
- prevglyph=current
- elseif char==false then
- prevdisc=nil
- prevglyph=current
- elseif id==disc_code then
- pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
- local done=false
- if pre then
- for n in nextchar,pre do
- local p=rawget(properties,n)
- if p then
- local i=p.injections or p.preinjections
- if i then
- local yoffset=i.yoffset
- if yoffset and yoffset~=0 then
- setoffsets(n,false,yoffset)
- end
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- pre=insert_node_before(pre,n,fontkern(leftkern))
- done=true
- end
- local rightkern=i.rightkern
- if rightkern and rightkern~=0 then
- insert_node_after(pre,n,fontkern(rightkern))
- done=true
- end
- end
- end
- end
+ end
+ end
+ if prevdisc then
+ local done=false
+ if post then
+ local i=p.postinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(posttail,fontkern(leftkern))
+ done=true
+ end
end
- if post then
- for n in nextchar,post do
- local p=rawget(properties,n)
- if p then
- local i=p.injections or p.postinjections
- if i then
- local yoffset=i.yoffset
- if yoffset and yoffset~=0 then
- setoffsets(n,false,yoffset)
- end
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- post=insert_node_before(post,n,fontkern(leftkern))
- done=true
- end
- local rightkern=i.rightkern
- if rightkern and rightkern~=0 then
- insert_node_after(post,n,fontkern(rightkern))
- done=true
- end
- end
- end
- end
+ end
+ if replace then
+ local i=p.replaceinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(replacetail,fontkern(leftkern))
+ done=true
+ end
end
- if replace then
- for n in nextchar,replace do
- local p=rawget(properties,n)
- if p then
- local i=p.injections or p.replaceinjections
- if i then
- local yoffset=i.yoffset
- if yoffset and yoffset~=0 then
- setoffsets(n,false,yoffset)
- end
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- replace=insert_node_before(replace,n,fontkern(leftkern))
- done=true
- end
- local rightkern=i.rightkern
- if rightkern and rightkern~=0 then
- insert_node_after(replace,n,fontkern(rightkern))
- done=true
- end
- end
- end
- end
+ else
+ local i=p.emptyinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setfield(prev,"replace",fontkern(leftkern))
+ end
end
- if prevglyph then
- if pre then
- local p=rawget(properties,prevglyph)
- if p then
- local i=p.preinjections
- if i then
- local rightkern=i.rightkern
- if rightkern and rightkern~=0 then
- pre=insert_node_before(pre,pre,fontkern(rightkern))
- done=true
- end
- end
- end
- end
- if replace then
- local p=rawget(properties,prevglyph)
- if p then
- local i=p.replaceinjections
- if i then
- local rightkern=i.rightkern
- if rightkern and rightkern~=0 then
- replace=insert_node_before(replace,replace,fontkern(rightkern))
- done=true
- end
- end
- end
- end
+ end
+ if done then
+ setdisc(prevdisc,pre,post,replace)
+ end
+ end
+ end
+ prevdisc=nil
+ prevglyph=current
+ elseif char==false then
+ prevdisc=nil
+ prevglyph=current
+ elseif id==disc_code then
+ pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
+ local done=false
+ if pre then
+ for n in nextchar,pre do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.preinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ pre=insert_node_before(pre,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(pre,n,fontkern(rightkern))
+ done=true
+ end
end
- if done then
- setdisc(current,pre,post,replace)
+ end
+ end
+ end
+ if post then
+ for n in nextchar,post do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.postinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ post=insert_node_before(post,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(post,n,fontkern(rightkern))
+ done=true
+ end
end
- prevglyph=nil
- prevdisc=current
- else
- prevglyph=nil
- prevdisc=nil
+ end
end
- prev=current
- current=next
- end
- if keepregisteredcounts then
- keepregisteredcounts=false
+ end
+ if replace then
+ for n in nextchar,replace do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.replaceinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=insert_node_before(replace,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(replace,n,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if prevglyph then
+ if pre then
+ local p=rawget(properties,prevglyph)
+ if p then
+ local i=p.preinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ pre=insert_node_before(pre,pre,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ if replace then
+ local p=rawget(properties,prevglyph)
+ if p then
+ local i=p.replaceinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ replace=insert_node_before(replace,replace,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if done then
+ setdisc(current,pre,post,replace)
+ end
+ prevglyph=nil
+ prevdisc=current
else
- nofregisteredpositions=0
+ prevglyph=nil
+ prevdisc=nil
end
- if trace_injections then
- show_result(head)
- end
- return head
+ prev=current
+ current=next
+ end
+ if keepregisteredcounts then
+ keepregisteredcounts=false
+ else
+ nofregisteredpositions=0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
end
local function showoffset(n,flag)
- local x,y=getoffsets(n)
- if x~=0 or y~=0 then
- setcolor(n,"darkgray")
- end
+ local x,y=getoffsets(n)
+ if x~=0 or y~=0 then
+ setcolor(n,"darkgray")
+ end
end
local function inject_everything(head,where)
- if trace_injections then
- trace(head,"everything")
- end
- local hascursives=nofregisteredcursives>0
- local hasmarks=nofregisteredmarks>0
- local current=head
- local last=nil
- local prev=nil
- local next=nil
- local prevdisc=nil
- local prevglyph=nil
- local pre=nil
- local post=nil
- local replace=nil
- local pretail=nil
- local posttail=nil
- local replacetail=nil
- local cursiveanchor=nil
- local minc=0
- local maxc=0
- local glyphs={}
- local marks={}
- local nofmarks=0
- local function processmark(p,n,pn)
- local px,py=getoffsets(p)
- local nx,ny=getoffsets(n)
- local ox=0
- local rightkern=nil
- local pp=rawget(properties,p)
- if pp then
- pp=pp.injections
- if pp then
- rightkern=pp.rightkern
- end
- end
- local markdir=pn.markdir
- if rightkern then
- ox=px-(pn.markx or 0)-rightkern
- if markdir and markdir<0 then
- if not pn.markmark then
- ox=ox+(pn.leftkern or 0)
- end
- else
- if false then
- local leftkern=pp.leftkern
- if leftkern then
- ox=ox-leftkern
- end
- end
- end
- else
- ox=px-(pn.markx or 0)
- if markdir and markdir<0 then
- if not pn.markmark then
- local leftkern=pn.leftkern
- if leftkern then
- ox=ox+leftkern
- end
- end
- end
- if pn.checkmark then
- local wn=getwidth(n)
- if wn and wn~=0 then
- wn=wn/2
- if trace_injections then
- report_injections("correcting non zero width mark %C",getchar(n))
- end
- insert_node_before(n,n,fontkern(-wn))
- insert_node_after(n,n,fontkern(-wn))
- end
- end
- end
- local oy=ny+py+(pn.marky or 0)
+ if trace_injections then
+ trace(head,"everything")
+ end
+ local hascursives=nofregisteredcursives>0
+ local hasmarks=nofregisteredmarks>0
+ local current=head
+ local last=nil
+ local prev=nil
+ local next=nil
+ local prevdisc=nil
+ local prevglyph=nil
+ local pre=nil
+ local post=nil
+ local replace=nil
+ local pretail=nil
+ local posttail=nil
+ local replacetail=nil
+ local cursiveanchor=nil
+ local minc=0
+ local maxc=0
+ local glyphs={}
+ local marks={}
+ local nofmarks=0
+ local function processmark(p,n,pn)
+ local px,py=getoffsets(p)
+ local nx,ny=getoffsets(n)
+ local ox=0
+ local rightkern=nil
+ local pp=rawget(properties,p)
+ if pp then
+ pp=pp.injections
+ if pp then
+ rightkern=pp.rightkern
+ end
+ end
+ local markdir=pn.markdir
+ if rightkern then
+ ox=px-(pn.markx or 0)-rightkern
+ if markdir and markdir<0 then
if not pn.markmark then
- local yoffset=pn.yoffset
- if yoffset then
- oy=oy+yoffset
- end
+ ox=ox+(pn.leftkern or 0)
end
- setoffsets(n,ox,oy)
- if trace_marks then
- showoffset(n,true)
+ else
+ if false then
+ local leftkern=pp.leftkern
+ if leftkern then
+ ox=ox-leftkern
+ end
end
- end
- while current do
- local next=getnext(current)
- local char,id=ischar(current)
- if char then
- local p=rawget(properties,current)
- if p then
- local i=p.injections
- if i then
- local pm=i.markbasenode
- if pm then
- nofmarks=nofmarks+1
- marks[nofmarks]=current
- else
- local yoffset=i.yoffset
- if yoffset and yoffset~=0 then
- setoffsets(current,false,yoffset)
- end
- if hascursives then
- local cursivex=i.cursivex
- if cursivex then
- if cursiveanchor then
- if cursivex~=0 then
- i.leftkern=(i.leftkern or 0)+cursivex
- end
- if maxc==0 then
- minc=1
- maxc=1
- glyphs[1]=cursiveanchor
- else
- maxc=maxc+1
- glyphs[maxc]=cursiveanchor
- end
- properties[cursiveanchor].cursivedy=i.cursivey
- last=current
- else
- maxc=0
- end
- elseif maxc>0 then
- local nx,ny=getoffsets(current)
- for i=maxc,minc,-1 do
- local ti=glyphs[i]
- ny=ny+properties[ti].cursivedy
- setoffsets(ti,false,ny)
- if trace_cursive then
- showoffset(ti)
- end
- end
- maxc=0
- cursiveanchor=nil
- end
- if i.cursiveanchor then
- cursiveanchor=current
- else
- if maxc>0 then
- local nx,ny=getoffsets(current)
- for i=maxc,minc,-1 do
- local ti=glyphs[i]
- ny=ny+properties[ti].cursivedy
- setoffsets(ti,false,ny)
- if trace_cursive then
- showoffset(ti)
- end
- end
- maxc=0
- end
- cursiveanchor=nil
- end
- end
- local leftkern=i.leftkern
- local rightkern=i.rightkern
- if leftkern and leftkern~=0 then
- if rightkern and leftkern==-rightkern then
- setoffsets(current,leftkern,false)
- rightkern=0
- else
- head=insert_node_before(head,current,fontkern(leftkern))
- end
- end
- if rightkern and rightkern~=0 then
- insert_node_after(head,current,fontkern(rightkern))
- end
- end
+ end
+ else
+ ox=px-(pn.markx or 0)
+ if markdir and markdir<0 then
+ if not pn.markmark then
+ local leftkern=pn.leftkern
+ if leftkern then
+ ox=ox+leftkern
+ end
+ end
+ end
+ if pn.checkmark then
+ local wn=getwidth(n)
+ if wn and wn~=0 then
+ wn=wn/2
+ if trace_injections then
+ report_injections("correcting non zero width mark %C",getchar(n))
+ end
+ insert_node_before(n,n,fontkern(-wn))
+ insert_node_after(n,n,fontkern(-wn))
+ end
+ end
+ end
+ local oy=ny+py+(pn.marky or 0)
+ if not pn.markmark then
+ local yoffset=pn.yoffset
+ if yoffset then
+ oy=oy+yoffset
+ end
+ end
+ setoffsets(n,ox,oy)
+ if trace_marks then
+ showoffset(n,true)
+ end
+ end
+ while current do
+ local next=getnext(current)
+ local char,id=ischar(current)
+ if char then
+ local p=rawget(properties,current)
+ if p then
+ local i=p.injections
+ if i then
+ local pm=i.markbasenode
+ if pm then
+ nofmarks=nofmarks+1
+ marks[nofmarks]=current
+ else
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(current,false,yoffset)
+ end
+ if hascursives then
+ local cursivex=i.cursivex
+ if cursivex then
+ if cursiveanchor then
+ if cursivex~=0 then
+ i.leftkern=(i.leftkern or 0)+cursivex
+ end
+ if maxc==0 then
+ minc=1
+ maxc=1
+ glyphs[1]=cursiveanchor
+ else
+ maxc=maxc+1
+ glyphs[maxc]=cursiveanchor
+ end
+ properties[cursiveanchor].cursivedy=i.cursivey
+ last=current
else
- local i=p.emptyinjections
- if i then
- local rightkern=i.rightkern
- if rightkern and rightkern~=0 then
- if next and getid(next)==disc_code then
- if replace then
- else
- setfield(next,"replace",fontkern(rightkern))
- end
- end
- end
- end
- end
- if prevdisc then
- if p then
- local done=false
- if post then
- local i=p.postinjections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- setlink(posttail,fontkern(leftkern))
- done=true
- end
- end
- end
- if replace then
- local i=p.replaceinjections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- setlink(replacetail,fontkern(leftkern))
- done=true
- end
- end
- else
- local i=p.emptyinjections
- if i then
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- setfield(prev,"replace",fontkern(leftkern))
- end
- end
- end
- if done then
- setdisc(prevdisc,pre,post,replace)
- end
- end
- end
- else
- if hascursives and maxc>0 then
- local nx,ny=getoffsets(current)
- for i=maxc,minc,-1 do
- local ti=glyphs[i]
- ny=ny+properties[ti].cursivedy
- local xi,yi=getoffsets(ti)
- setoffsets(ti,xi,yi+ny)
- end
- maxc=0
- cursiveanchor=nil
- end
+ maxc=0
+ end
+ elseif maxc>0 then
+ local nx,ny=getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti=glyphs[i]
+ ny=ny+properties[ti].cursivedy
+ setoffsets(ti,false,ny)
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ maxc=0
+ cursiveanchor=nil
+ end
+ if i.cursiveanchor then
+ cursiveanchor=current
+ else
+ if maxc>0 then
+ local nx,ny=getoffsets(current)
+ for i=maxc,minc,-1 do
+ local ti=glyphs[i]
+ ny=ny+properties[ti].cursivedy
+ setoffsets(ti,false,ny)
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ maxc=0
+ end
+ cursiveanchor=nil
+ end
end
- prevdisc=nil
- prevglyph=current
- elseif char==false then
- prevdisc=nil
- prevglyph=current
- elseif id==disc_code then
- pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
- local done=false
- if pre then
- for n in nextchar,pre do
- local p=rawget(properties,n)
- if p then
- local i=p.injections or p.preinjections
- if i then
- local yoffset=i.yoffset
- if yoffset and yoffset~=0 then
- setoffsets(n,false,yoffset)
- end
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- pre=insert_node_before(pre,n,fontkern(leftkern))
- done=true
- end
- local rightkern=i.rightkern
- if rightkern and rightkern~=0 then
- insert_node_after(pre,n,fontkern(rightkern))
- done=true
- end
- if hasmarks then
- local pm=i.markbasenode
- if pm then
- processmark(pm,n,i)
- end
- end
- end
- end
+ local leftkern=i.leftkern
+ local rightkern=i.rightkern
+ if leftkern and leftkern~=0 then
+ if rightkern and leftkern==-rightkern then
+ setoffsets(current,leftkern,false)
+ rightkern=0
+ else
+ head=insert_node_before(head,current,fontkern(leftkern))
+ end
+ end
+ if rightkern and rightkern~=0 then
+ insert_node_after(head,current,fontkern(rightkern))
+ end
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ if next and getid(next)==disc_code then
+ if replace then
+ else
+ setfield(next,"replace",fontkern(rightkern))
end
+ end
end
+ end
+ end
+ if prevdisc then
+ if p then
+ local done=false
if post then
- for n in nextchar,post do
- local p=rawget(properties,n)
- if p then
- local i=p.injections or p.postinjections
- if i then
- local yoffset=i.yoffset
- if yoffset and yoffset~=0 then
- setoffsets(n,false,yoffset)
- end
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- post=insert_node_before(post,n,fontkern(leftkern))
- done=true
- end
- local rightkern=i.rightkern
- if rightkern and rightkern~=0 then
- insert_node_after(post,n,fontkern(rightkern))
- done=true
- end
- if hasmarks then
- local pm=i.markbasenode
- if pm then
- processmark(pm,n,i)
- end
- end
- end
- end
+ local i=p.postinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(posttail,fontkern(leftkern))
+ done=true
end
+ end
end
if replace then
- for n in nextchar,replace do
- local p=rawget(properties,n)
- if p then
- local i=p.injections or p.replaceinjections
- if i then
- local yoffset=i.yoffset
- if yoffset and yoffset~=0 then
- setoffsets(n,false,yoffset)
- end
- local leftkern=i.leftkern
- if leftkern and leftkern~=0 then
- replace=insert_node_before(replace,n,fontkern(leftkern))
- done=true
- end
- local rightkern=i.rightkern
- if rightkern and rightkern~=0 then
- insert_node_after(replace,n,fontkern(rightkern))
- done=true
- end
- if hasmarks then
- local pm=i.markbasenode
- if pm then
- processmark(pm,n,i)
- end
- end
- end
- end
- end
- end
- if prevglyph then
- if pre then
- local p=rawget(properties,prevglyph)
- if p then
- local i=p.preinjections
- if i then
- local rightkern=i.rightkern
- if rightkern and rightkern~=0 then
- pre=insert_node_before(pre,pre,fontkern(rightkern))
- done=true
- end
- end
- end
+ local i=p.replaceinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setlink(replacetail,fontkern(leftkern))
+ done=true
end
- if replace then
- local p=rawget(properties,prevglyph)
- if p then
- local i=p.replaceinjections
- if i then
- local rightkern=i.rightkern
- if rightkern and rightkern~=0 then
- replace=insert_node_before(replace,replace,fontkern(rightkern))
- done=true
- end
- end
- end
+ end
+ else
+ local i=p.emptyinjections
+ if i then
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ setfield(prev,"replace",fontkern(leftkern))
end
+ end
end
if done then
- setdisc(current,pre,post,replace)
+ setdisc(prevdisc,pre,post,replace)
end
- prevglyph=nil
- prevdisc=current
- else
- prevglyph=nil
- prevdisc=nil
+ end
end
- prev=current
- current=next
- end
- if hascursives and maxc>0 then
- local nx,ny=getoffsets(last)
- for i=maxc,minc,-1 do
+ else
+ if hascursives and maxc>0 then
+ local nx,ny=getoffsets(current)
+ for i=maxc,minc,-1 do
local ti=glyphs[i]
ny=ny+properties[ti].cursivedy
- setoffsets(ti,false,ny)
- if trace_cursive then
- showoffset(ti)
+ local xi,yi=getoffsets(ti)
+ setoffsets(ti,xi,yi+ny)
+ end
+ maxc=0
+ cursiveanchor=nil
+ end
+ end
+ prevdisc=nil
+ prevglyph=current
+ elseif char==false then
+ prevdisc=nil
+ prevglyph=current
+ elseif id==disc_code then
+ pre,post,replace,pretail,posttail,replacetail=getdisc(current,true)
+ local done=false
+ if pre then
+ for n in nextchar,pre do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.preinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ pre=insert_node_before(pre,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(pre,n,fontkern(rightkern))
+ done=true
+ end
+ if hasmarks then
+ local pm=i.markbasenode
+ if pm then
+ processmark(pm,n,i)
+ end
+ end
end
+ end
end
- end
- if nofmarks>0 then
- for i=1,nofmarks do
- local m=marks[i]
- local p=rawget(properties,m)
- local i=p.injections
- local b=i.markbasenode
- processmark(b,m,i)
+ end
+ if post then
+ for n in nextchar,post do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.postinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ post=insert_node_before(post,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(post,n,fontkern(rightkern))
+ done=true
+ end
+ if hasmarks then
+ local pm=i.markbasenode
+ if pm then
+ processmark(pm,n,i)
+ end
+ end
+ end
+ end
end
- elseif hasmarks then
- end
- if keepregisteredcounts then
- keepregisteredcounts=false
+ end
+ if replace then
+ for n in nextchar,replace do
+ local p=rawget(properties,n)
+ if p then
+ local i=p.injections or p.replaceinjections
+ if i then
+ local yoffset=i.yoffset
+ if yoffset and yoffset~=0 then
+ setoffsets(n,false,yoffset)
+ end
+ local leftkern=i.leftkern
+ if leftkern and leftkern~=0 then
+ replace=insert_node_before(replace,n,fontkern(leftkern))
+ done=true
+ end
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ insert_node_after(replace,n,fontkern(rightkern))
+ done=true
+ end
+ if hasmarks then
+ local pm=i.markbasenode
+ if pm then
+ processmark(pm,n,i)
+ end
+ end
+ end
+ end
+ end
+ end
+ if prevglyph then
+ if pre then
+ local p=rawget(properties,prevglyph)
+ if p then
+ local i=p.preinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ pre=insert_node_before(pre,pre,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ if replace then
+ local p=rawget(properties,prevglyph)
+ if p then
+ local i=p.replaceinjections
+ if i then
+ local rightkern=i.rightkern
+ if rightkern and rightkern~=0 then
+ replace=insert_node_before(replace,replace,fontkern(rightkern))
+ done=true
+ end
+ end
+ end
+ end
+ end
+ if done then
+ setdisc(current,pre,post,replace)
+ end
+ prevglyph=nil
+ prevdisc=current
else
- nofregisteredkerns=0
- nofregisteredpositions=0
- nofregisteredmarks=0
- nofregisteredcursives=0
- end
- if trace_injections then
- show_result(head)
- end
- return head
+ prevglyph=nil
+ prevdisc=nil
+ end
+ prev=current
+ current=next
+ end
+ if hascursives and maxc>0 then
+ local nx,ny=getoffsets(last)
+ for i=maxc,minc,-1 do
+ local ti=glyphs[i]
+ ny=ny+properties[ti].cursivedy
+ setoffsets(ti,false,ny)
+ if trace_cursive then
+ showoffset(ti)
+ end
+ end
+ end
+ if nofmarks>0 then
+ for i=1,nofmarks do
+ local m=marks[i]
+ local p=rawget(properties,m)
+ local i=p.injections
+ local b=i.markbasenode
+ processmark(b,m,i)
+ end
+ elseif hasmarks then
+ end
+ if keepregisteredcounts then
+ keepregisteredcounts=false
+ else
+ nofregisteredkerns=0
+ nofregisteredpositions=0
+ nofregisteredmarks=0
+ nofregisteredcursives=0
+ end
+ if trace_injections then
+ show_result(head)
+ end
+ return head
end
local triggers=false
function nodes.injections.setspacekerns(font,sequence)
- if triggers then
- triggers[font]=sequence
- else
- triggers={ [font]=sequence }
- end
+ if triggers then
+ triggers[font]=sequence
+ else
+ triggers={ [font]=sequence }
+ end
end
local getthreshold
if context then
@@ -24918,157 +24918,157 @@ if context then
--removed
else
- injections.threshold=0
- getthreshold=function(font)
- local p=fontdata[font].parameters
- local f=p.factor
- local s=p.spacing
- local t=injections.threshold*(s and s.width or p.space or 0)-2
- return t>0 and t or 0,f
- end
+ injections.threshold=0
+ getthreshold=function(font)
+ local p=fontdata[font].parameters
+ local f=p.factor
+ local s=p.spacing
+ local t=injections.threshold*(s and s.width or p.space or 0)-2
+ return t>0 and t or 0,f
+ end
end
injections.getthreshold=getthreshold
function injections.isspace(n,threshold,id)
- if (id or getid(n))==glue_code then
- local w=getwidth(n)
- if threshold and w>threshold then
- return 32
- end
+ if (id or getid(n))==glue_code then
+ local w=getwidth(n)
+ if threshold and w>threshold then
+ return 32
end
+ end
end
local getspaceboth=getboth
function injections.installgetspaceboth(gb)
- getspaceboth=gb or getboth
+ getspaceboth=gb or getboth
end
local function injectspaces(head)
- if not triggers then
- return head
- end
- local lastfont=nil
- local spacekerns=nil
- local leftkerns=nil
- local rightkerns=nil
- local factor=0
- local threshold=0
- local leftkern=false
- local rightkern=false
- local function updatefont(font,trig)
- leftkerns=trig.left
- rightkerns=trig.right
- lastfont=font
- threshold,
- factor=getthreshold(font)
- end
- for n in nextglue,head do
- local prev,next=getspaceboth(n)
- local prevchar=prev and ischar(prev)
- local nextchar=next and ischar(next)
- if nextchar then
- local font=getfont(next)
- local trig=triggers[font]
- if trig then
- if lastfont~=font then
- updatefont(font,trig)
- end
- if rightkerns then
- rightkern=rightkerns[nextchar]
- end
- end
- end
- if prevchar then
- local font=getfont(prev)
- local trig=triggers[font]
- if trig then
- if lastfont~=font then
- updatefont(font,trig)
- end
- if leftkerns then
- leftkern=leftkerns[prevchar]
- end
+ if not triggers then
+ return head
+ end
+ local lastfont=nil
+ local spacekerns=nil
+ local leftkerns=nil
+ local rightkerns=nil
+ local factor=0
+ local threshold=0
+ local leftkern=false
+ local rightkern=false
+ local function updatefont(font,trig)
+ leftkerns=trig.left
+ rightkerns=trig.right
+ lastfont=font
+ threshold,
+ factor=getthreshold(font)
+ end
+ for n in nextglue,head do
+ local prev,next=getspaceboth(n)
+ local prevchar=prev and ischar(prev)
+ local nextchar=next and ischar(next)
+ if nextchar then
+ local font=getfont(next)
+ local trig=triggers[font]
+ if trig then
+ if lastfont~=font then
+ updatefont(font,trig)
+ end
+ if rightkerns then
+ rightkern=rightkerns[nextchar]
+ end
+ end
+ end
+ if prevchar then
+ local font=getfont(prev)
+ local trig=triggers[font]
+ if trig then
+ if lastfont~=font then
+ updatefont(font,trig)
+ end
+ if leftkerns then
+ leftkern=leftkerns[prevchar]
+ end
+ end
+ end
+ if leftkern then
+ local old=getwidth(n)
+ if old>threshold then
+ if rightkern then
+ if useitalickerns then
+ local lnew=leftkern*factor
+ local rnew=rightkern*factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar)
+ end
+ head=insert_node_before(head,n,italickern(lnew))
+ insert_node_after(head,n,italickern(rnew))
+ else
+ local new=old+(leftkern+rightkern)*factor
+ if trace_spaces then
+ report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar)
end
- end
- if leftkern then
- local old=getwidth(n)
- if old>threshold then
- if rightkern then
- if useitalickerns then
- local lnew=leftkern*factor
- local rnew=rightkern*factor
- if trace_spaces then
- report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar)
- end
- head=insert_node_before(head,n,italickern(lnew))
- insert_node_after(head,n,italickern(rnew))
- else
- local new=old+(leftkern+rightkern)*factor
- if trace_spaces then
- report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar)
- end
- setwidth(n,new)
- end
- rightkern=false
- else
- if useitalickerns then
- local new=leftkern*factor
- if trace_spaces then
- report_spaces("%C [%p + %p]",prevchar,old,new)
- end
- insert_node_after(head,n,italickern(new))
- else
- local new=old+leftkern*factor
- if trace_spaces then
- report_spaces("%C [%p -> %p]",prevchar,old,new)
- end
- setwidth(n,new)
- end
- end
+ setwidth(n,new)
+ end
+ rightkern=false
+ else
+ if useitalickerns then
+ local new=leftkern*factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p]",prevchar,old,new)
end
- leftkern=false
- elseif rightkern then
- local old=getwidth(n)
- if old>threshold then
- if useitalickerns then
- local new=rightkern*factor
- if trace_spaces then
- report_spaces("%C [%p + %p]",nextchar,old,new)
- end
- insert_node_after(head,n,italickern(new))
- else
- local new=old+rightkern*factor
- if trace_spaces then
- report_spaces("[%p -> %p] %C",nextchar,old,new)
- end
- setwidth(n,new)
- end
+ insert_node_after(head,n,italickern(new))
+ else
+ local new=old+leftkern*factor
+ if trace_spaces then
+ report_spaces("%C [%p -> %p]",prevchar,old,new)
end
- rightkern=false
+ setwidth(n,new)
+ end
+ end
+ end
+ leftkern=false
+ elseif rightkern then
+ local old=getwidth(n)
+ if old>threshold then
+ if useitalickerns then
+ local new=rightkern*factor
+ if trace_spaces then
+ report_spaces("%C [%p + %p]",nextchar,old,new)
+ end
+ insert_node_after(head,n,italickern(new))
+ else
+ local new=old+rightkern*factor
+ if trace_spaces then
+ report_spaces("[%p -> %p] %C",nextchar,old,new)
+ end
+ setwidth(n,new)
end
+ end
+ rightkern=false
end
- triggers=false
- return head
+ end
+ triggers=false
+ return head
end
function injections.handler(head,where)
- if triggers then
- head=injectspaces(head)
+ if triggers then
+ head=injectspaces(head)
+ end
+ if nofregisteredmarks>0 or nofregisteredcursives>0 then
+ if trace_injections then
+ report_injections("injection variant %a","everything")
end
- if nofregisteredmarks>0 or nofregisteredcursives>0 then
- if trace_injections then
- report_injections("injection variant %a","everything")
- end
- return inject_everything(head,where)
- elseif nofregisteredpositions>0 then
- if trace_injections then
- report_injections("injection variant %a","positions")
- end
- return inject_positions_only(head,where)
- elseif nofregisteredkerns>0 then
- if trace_injections then
- report_injections("injection variant %a","kerns")
- end
- return inject_kerns_only(head,where)
- else
- return head
+ return inject_everything(head,where)
+ elseif nofregisteredpositions>0 then
+ if trace_injections then
+ report_injections("injection variant %a","positions")
+ end
+ return inject_positions_only(head,where)
+ elseif nofregisteredkerns>0 then
+ if trace_injections then
+ report_injections("injection variant %a","kerns")
end
+ return inject_kerns_only(head,where)
+ else
+ return head
+ end
end
end -- closure
@@ -25076,11 +25076,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-ota']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type=type
if not trackers then trackers={ register=function() end } end
@@ -25112,342 +25112,342 @@ local categories=characters and characters.categories or {}
local chardata=characters and characters.data
local otffeatures=fonts.constructors.features.otf
local registerotffeature=otffeatures.register
-local s_init=1 local s_rphf=7
-local s_medi=2 local s_half=8
-local s_fina=3 local s_pref=9
-local s_isol=4 local s_blwf=10
-local s_mark=5 local s_pstf=11
+local s_init=1 local s_rphf=7
+local s_medi=2 local s_half=8
+local s_fina=3 local s_pref=9
+local s_isol=4 local s_blwf=10
+local s_mark=5 local s_pstf=11
local s_rest=6
local states=allocate {
- init=s_init,
- medi=s_medi,
- med2=s_medi,
- fina=s_fina,
- fin2=s_fina,
- fin3=s_fina,
- isol=s_isol,
- mark=s_mark,
- rest=s_rest,
- rphf=s_rphf,
- half=s_half,
- pref=s_pref,
- blwf=s_blwf,
- pstf=s_pstf,
+ init=s_init,
+ medi=s_medi,
+ med2=s_medi,
+ fina=s_fina,
+ fin2=s_fina,
+ fin3=s_fina,
+ isol=s_isol,
+ mark=s_mark,
+ rest=s_rest,
+ rphf=s_rphf,
+ half=s_half,
+ pref=s_pref,
+ blwf=s_blwf,
+ pstf=s_pstf,
}
local features=allocate {
- init=s_init,
- medi=s_medi,
- med2=s_medi,
- fina=s_fina,
- fin2=s_fina,
- fin3=s_fina,
- isol=s_isol,
- rphf=s_rphf,
- half=s_half,
- pref=s_pref,
- blwf=s_blwf,
- pstf=s_pstf,
+ init=s_init,
+ medi=s_medi,
+ med2=s_medi,
+ fina=s_fina,
+ fin2=s_fina,
+ fin3=s_fina,
+ isol=s_isol,
+ rphf=s_rphf,
+ half=s_half,
+ pref=s_pref,
+ blwf=s_blwf,
+ pstf=s_pstf,
}
analyzers.states=states
analyzers.features=features
analyzers.useunicodemarks=false
function analyzers.setstate(head,font)
- local useunicodemarks=analyzers.useunicodemarks
- local tfmdata=fontdata[font]
- local descriptions=tfmdata.descriptions
- local first,last,current,n,done=nil,nil,head,0,false
- current=tonut(current)
- while current do
- local char,id=ischar(current,font)
- if char and not getprop(current,a_state) then
- done=true
- local d=descriptions[char]
- if d then
- if d.class=="mark" then
- done=true
- setprop(current,a_state,s_mark)
- elseif useunicodemarks and categories[char]=="mn" then
- done=true
- setprop(current,a_state,s_mark)
- elseif n==0 then
- first,last,n=current,current,1
- setprop(current,a_state,s_init)
- else
- last,n=current,n+1
- setprop(current,a_state,s_medi)
- end
- else
- if first and first==last then
- setprop(last,a_state,s_isol)
- elseif last then
- setprop(last,a_state,s_fina)
- end
- first,last,n=nil,nil,0
- end
- elseif char==false then
- if first and first==last then
- setprop(last,a_state,s_isol)
- elseif last then
- setprop(last,a_state,s_fina)
- end
- first,last,n=nil,nil,0
- if id==math_code then
- current=end_of_math(current)
- end
- elseif id==disc_code then
- setprop(current,a_state,s_medi)
- last=current
- else
- if first and first==last then
- setprop(last,a_state,s_isol)
- elseif last then
- setprop(last,a_state,s_fina)
- end
- first,last,n=nil,nil,0
- if id==math_code then
- current=end_of_math(current)
- end
- end
- current=getnext(current)
- end
- if first and first==last then
+ local useunicodemarks=analyzers.useunicodemarks
+ local tfmdata=fontdata[font]
+ local descriptions=tfmdata.descriptions
+ local first,last,current,n,done=nil,nil,head,0,false
+ current=tonut(current)
+ while current do
+ local char,id=ischar(current,font)
+ if char and not getprop(current,a_state) then
+ done=true
+ local d=descriptions[char]
+ if d then
+ if d.class=="mark" then
+ done=true
+ setprop(current,a_state,s_mark)
+ elseif useunicodemarks and categories[char]=="mn" then
+ done=true
+ setprop(current,a_state,s_mark)
+ elseif n==0 then
+ first,last,n=current,current,1
+ setprop(current,a_state,s_init)
+ else
+ last,n=current,n+1
+ setprop(current,a_state,s_medi)
+ end
+ else
+ if first and first==last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ first,last,n=nil,nil,0
+ end
+ elseif char==false then
+ if first and first==last then
setprop(last,a_state,s_isol)
- elseif last then
+ elseif last then
setprop(last,a_state,s_fina)
- end
- return head,done
+ end
+ first,last,n=nil,nil,0
+ if id==math_code then
+ current=end_of_math(current)
+ end
+ elseif id==disc_code then
+ setprop(current,a_state,s_medi)
+ last=current
+ else
+ if first and first==last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ first,last,n=nil,nil,0
+ if id==math_code then
+ current=end_of_math(current)
+ end
+ end
+ current=getnext(current)
+ end
+ if first and first==last then
+ setprop(last,a_state,s_isol)
+ elseif last then
+ setprop(last,a_state,s_fina)
+ end
+ return head,done
end
local function analyzeinitializer(tfmdata,value)
- local script,language=otf.scriptandlanguage(tfmdata)
- local action=initializers[script]
- if not action then
- elseif type(action)=="function" then
- return action(tfmdata,value)
- else
- local action=action[language]
- if action then
- return action(tfmdata,value)
- end
+ local script,language=otf.scriptandlanguage(tfmdata)
+ local action=initializers[script]
+ if not action then
+ elseif type(action)=="function" then
+ return action(tfmdata,value)
+ else
+ local action=action[language]
+ if action then
+ return action(tfmdata,value)
end
+ end
end
local function analyzeprocessor(head,font,attr)
- local tfmdata=fontdata[font]
- local script,language=otf.scriptandlanguage(tfmdata,attr)
- local action=methods[script]
- if not action then
- elseif type(action)=="function" then
- return action(head,font,attr)
- else
- action=action[language]
- if action then
- return action(head,font,attr)
- end
+ local tfmdata=fontdata[font]
+ local script,language=otf.scriptandlanguage(tfmdata,attr)
+ local action=methods[script]
+ if not action then
+ elseif type(action)=="function" then
+ return action(head,font,attr)
+ else
+ action=action[language]
+ if action then
+ return action(head,font,attr)
end
- return head,false
+ end
+ return head,false
end
registerotffeature {
- name="analyze",
- description="analysis of character classes",
- default=true,
- initializers={
- node=analyzeinitializer,
- },
- processors={
- position=1,
- node=analyzeprocessor,
- }
+ name="analyze",
+ description="analysis of character classes",
+ default=true,
+ initializers={
+ node=analyzeinitializer,
+ },
+ processors={
+ position=1,
+ node=analyzeprocessor,
+ }
}
methods.latn=analyzers.setstate
local arab_warned={}
local function warning(current,what)
- local char=getchar(current)
- if not arab_warned[char] then
- log.report("analyze","arab: character %C has no %a class",char,what)
- arab_warned[char]=true
- end
+ local char=getchar(current)
+ if not arab_warned[char] then
+ log.report("analyze","arab: character %C has no %a class",char,what)
+ arab_warned[char]=true
+ end
end
local mappers=allocate {
- l=s_init,
- d=s_medi,
- c=s_medi,
- r=s_fina,
- u=s_isol,
+ l=s_init,
+ d=s_medi,
+ c=s_medi,
+ r=s_fina,
+ u=s_isol,
}
local classifiers=characters.classifiers
if not classifiers then
- local f_arabic,l_arabic=characters.blockrange("arabic")
- local f_syriac,l_syriac=characters.blockrange("syriac")
- local f_mandiac,l_mandiac=characters.blockrange("mandiac")
- local f_nko,l_nko=characters.blockrange("nko")
- local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda")
- classifiers=table.setmetatableindex(function(t,k)
- if type(k)=="number" then
- local c=chardata[k]
- local v=false
- if c then
- local arabic=c.arabic
- if arabic then
- v=mappers[arabic]
- if not v then
- log.report("analyze","error in mapping arabic %C",k)
- v=false
- end
- elseif (k>=f_arabic and k<=l_arabic) or
- (k>=f_syriac and k<=l_syriac) or
- (k>=f_mandiac and k<=l_mandiac) or
- (k>=f_nko and k<=l_nko) or
- (k>=f_ext_a and k<=l_ext_a) then
- if categories[k]=="mn" then
- v=s_mark
- else
- v=s_rest
- end
- end
- end
- t[k]=v
- return v
+ local f_arabic,l_arabic=characters.blockrange("arabic")
+ local f_syriac,l_syriac=characters.blockrange("syriac")
+ local f_mandiac,l_mandiac=characters.blockrange("mandiac")
+ local f_nko,l_nko=characters.blockrange("nko")
+ local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda")
+ classifiers=table.setmetatableindex(function(t,k)
+ if type(k)=="number" then
+ local c=chardata[k]
+ local v=false
+ if c then
+ local arabic=c.arabic
+ if arabic then
+ v=mappers[arabic]
+ if not v then
+ log.report("analyze","error in mapping arabic %C",k)
+ v=false
+ end
+ elseif (k>=f_arabic and k<=l_arabic) or
+ (k>=f_syriac and k<=l_syriac) or
+ (k>=f_mandiac and k<=l_mandiac) or
+ (k>=f_nko and k<=l_nko) or
+ (k>=f_ext_a and k<=l_ext_a) then
+ if categories[k]=="mn" then
+ v=s_mark
+ else
+ v=s_rest
+ end
end
- end)
- characters.classifiers=classifiers
+ end
+ t[k]=v
+ return v
+ end
+ end)
+ characters.classifiers=classifiers
end
function methods.arab(head,font,attr)
- local first,last=nil,nil
- local c_first,c_last=nil,nil
- local current,done=head,false
- current=tonut(current)
- while current do
- local char,id=ischar(current,font)
- if char and not getprop(current,a_state) then
- done=true
- local classifier=classifiers[char]
- if not classifier then
- if last then
- if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
- else
- warning(last,"fina")
- setprop(last,a_state,s_error)
- end
- first,last=nil,nil
- elseif first then
- if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
- else
- warning(first,"isol")
- setprop(first,a_state,s_error)
- end
- first=nil
- end
- elseif classifier==s_mark then
- setprop(current,a_state,s_mark)
- elseif classifier==s_isol then
- if last then
- if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
- else
- warning(last,"fina")
- setprop(last,a_state,s_error)
- end
- first,last=nil,nil
- elseif first then
- if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
- else
- warning(first,"isol")
- setprop(first,a_state,s_error)
- end
- first=nil
- end
- setprop(current,a_state,s_isol)
- elseif classifier==s_medi then
- if first then
- last=current
- c_last=classifier
- setprop(current,a_state,s_medi)
- else
- setprop(current,a_state,s_init)
- first=current
- c_first=classifier
- end
- elseif classifier==s_fina then
- if last then
- if getprop(last,a_state)~=s_init then
- setprop(last,a_state,s_medi)
- end
- setprop(current,a_state,s_fina)
- first,last=nil,nil
- elseif first then
- setprop(current,a_state,s_fina)
- first=nil
- else
- setprop(current,a_state,s_isol)
- end
- else
- setprop(current,a_state,s_rest)
- if last then
- if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
- else
- warning(last,"fina")
- setprop(last,a_state,s_error)
- end
- first,last=nil,nil
- elseif first then
- if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
- else
- warning(first,"isol")
- setprop(first,a_state,s_error)
- end
- first=nil
- end
- end
- else
- if last then
- if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
- else
- warning(last,"fina")
- setprop(last,a_state,s_error)
- end
- first,last=nil,nil
- elseif first then
- if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
- else
- warning(first,"isol")
- setprop(first,a_state,s_error)
- end
- first=nil
- end
- if id==math_code then
- current=end_of_math(current)
- end
- end
- current=getnext(current)
- end
- if last then
- if c_last==s_medi or c_last==s_fina then
+ local first,last=nil,nil
+ local c_first,c_last=nil,nil
+ local current,done=head,false
+ current=tonut(current)
+ while current do
+ local char,id=ischar(current,font)
+ if char and not getprop(current,a_state) then
+ done=true
+ local classifier=classifiers[char]
+ if not classifier then
+ if last then
+ if c_last==s_medi or c_last==s_fina then
setprop(last,a_state,s_fina)
- else
+ else
warning(last,"fina")
setprop(last,a_state,s_error)
+ end
+ first,last=nil,nil
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first=nil
end
- elseif first then
- if c_first==s_medi or c_first==s_fina then
+ elseif classifier==s_mark then
+ setprop(current,a_state,s_mark)
+ elseif classifier==s_isol then
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first,last=nil,nil
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first=nil
+ end
+ setprop(current,a_state,s_isol)
+ elseif classifier==s_medi then
+ if first then
+ last=current
+ c_last=classifier
+ setprop(current,a_state,s_medi)
+ else
+ setprop(current,a_state,s_init)
+ first=current
+ c_first=classifier
+ end
+ elseif classifier==s_fina then
+ if last then
+ if getprop(last,a_state)~=s_init then
+ setprop(last,a_state,s_medi)
+ end
+ setprop(current,a_state,s_fina)
+ first,last=nil,nil
+ elseif first then
+ setprop(current,a_state,s_fina)
+ first=nil
else
+ setprop(current,a_state,s_isol)
+ end
+ else
+ setprop(current,a_state,s_rest)
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first,last=nil,nil
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
warning(first,"isol")
setprop(first,a_state,s_error)
+ end
+ first=nil
end
+ end
+ else
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ first,last=nil,nil
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
+ end
+ first=nil
+ end
+ if id==math_code then
+ current=end_of_math(current)
+ end
+ end
+ current=getnext(current)
+ end
+ if last then
+ if c_last==s_medi or c_last==s_fina then
+ setprop(last,a_state,s_fina)
+ else
+ warning(last,"fina")
+ setprop(last,a_state,s_error)
+ end
+ elseif first then
+ if c_first==s_medi or c_first==s_fina then
+ setprop(first,a_state,s_isol)
+ else
+ warning(first,"isol")
+ setprop(first,a_state,s_error)
end
- return head,done
+ end
+ return head,done
end
methods.syrc=methods.arab
methods.mand=methods.arab
methods.nko=methods.arab
directives.register("otf.analyze.useunicodemarks",function(v)
- analyzers.useunicodemarks=v
+ analyzers.useunicodemarks=v
end)
end -- closure
@@ -25455,11 +25455,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-ots']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
}
local type,next,tonumber=type,next,tonumber
local random=math.random
@@ -25473,31 +25473,31 @@ local attributes=attributes
local fonts=fonts
local otf=fonts.handlers.otf
local tracers=nodes.tracers
-local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end)
-local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end)
-local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end)
-local trace_ligatures=false registertracker("otf.ligatures",function(v) trace_ligatures=v end)
-local trace_contexts=false registertracker("otf.contexts",function(v) trace_contexts=v end)
-local trace_marks=false registertracker("otf.marks",function(v) trace_marks=v end)
-local trace_kerns=false registertracker("otf.kerns",function(v) trace_kerns=v end)
-local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursive=v end)
-local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end)
-local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end)
-local trace_details=false registertracker("otf.details",function(v) trace_details=v end)
-local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end)
-local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end)
-local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end)
-local trace_chains=false registertracker("otf.chains",function(v) trace_chains=v end)
-local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end)
-local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end)
-local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end)
+local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end)
+local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end)
+local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end)
+local trace_ligatures=false registertracker("otf.ligatures",function(v) trace_ligatures=v end)
+local trace_contexts=false registertracker("otf.contexts",function(v) trace_contexts=v end)
+local trace_marks=false registertracker("otf.marks",function(v) trace_marks=v end)
+local trace_kerns=false registertracker("otf.kerns",function(v) trace_kerns=v end)
+local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursive=v end)
+local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end)
+local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end)
+local trace_details=false registertracker("otf.details",function(v) trace_details=v end)
+local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end)
+local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end)
+local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end)
+local trace_chains=false registertracker("otf.chains",function(v) trace_chains=v end)
+local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end)
+local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end)
+local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end)
local forcediscretionaries=false
local forcepairadvance=false
directives.register("otf.forcediscretionaries",function(v)
- forcediscretionaries=v
+ forcediscretionaries=v
end)
directives.register("otf.forcepairadvance",function(v)
- forcepairadvance=v
+ forcepairadvance=v
end)
local report_direct=logs.reporter("fonts","otf direct")
local report_subchain=logs.reporter("fonts","otf subchain")
@@ -25596,2180 +25596,2180 @@ local notmatchreplace={}
local handlers={}
local isspace=injections.isspace
local getthreshold=injections.getthreshold
-local checkstep=(tracers and tracers.steppers.check) or function() end
+local checkstep=(tracers and tracers.steppers.check) or function() end
local registerstep=(tracers and tracers.steppers.register) or function() end
-local registermessage=(tracers and tracers.steppers.message) or function() end
+local registermessage=(tracers and tracers.steppers.message) or function() end
local function logprocess(...)
- if trace_steps then
- registermessage(...)
- if trace_steps=="silent" then
- return
- end
+ if trace_steps then
+ registermessage(...)
+ if trace_steps=="silent" then
+ return
end
- report_direct(...)
+ end
+ report_direct(...)
end
local function logwarning(...)
- report_direct(...)
-end
-local gref do
- local f_unicode=formatters["U+%X"]
- local f_uniname=formatters["U+%X (%s)"]
- local f_unilist=formatters["% t"]
- gref=function(n)
- if type(n)=="number" then
- local description=descriptions[n]
- local name=description and description.name
- if name then
- return f_uniname(n,name)
- else
- return f_unicode(n)
- end
- elseif n then
- local t={}
- for i=1,#n do
- local ni=n[i]
- if tonumber(ni) then
- local di=descriptions[ni]
- local nn=di and di.name
- if nn then
- t[#t+1]=f_uniname(ni,nn)
- else
- t[#t+1]=f_unicode(ni)
- end
- end
- end
- return f_unilist(t)
- else
- return "<error in node mode tracing>"
+ report_direct(...)
+end
+local gref do
+ local f_unicode=formatters["U+%X"]
+ local f_uniname=formatters["U+%X (%s)"]
+ local f_unilist=formatters["% t"]
+ gref=function(n)
+ if type(n)=="number" then
+ local description=descriptions[n]
+ local name=description and description.name
+ if name then
+ return f_uniname(n,name)
+ else
+ return f_unicode(n)
+ end
+ elseif n then
+ local t={}
+ for i=1,#n do
+ local ni=n[i]
+ if tonumber(ni) then
+ local di=descriptions[ni]
+ local nn=di and di.name
+ if nn then
+ t[#t+1]=f_uniname(ni,nn)
+ else
+ t[#t+1]=f_unicode(ni)
+ end
end
+ end
+ return f_unilist(t)
+ else
+ return "<error in node mode tracing>"
end
+ end
end
local function cref(dataset,sequence,index)
- if not dataset then
- return "no valid dataset"
- end
- local merged=sequence.merged and "merged " or ""
- if index then
- return formatters["feature %a, type %a, %schain lookup %a, index %a"](
- dataset[4],sequence.type,merged,sequence.name,index)
- else
- return formatters["feature %a, type %a, %schain lookup %a"](
- dataset[4],sequence.type,merged,sequence.name)
- end
+ if not dataset then
+ return "no valid dataset"
+ end
+ local merged=sequence.merged and "merged " or ""
+ if index then
+ return formatters["feature %a, type %a, %schain lookup %a, index %a"](
+ dataset[4],sequence.type,merged,sequence.name,index)
+ else
+ return formatters["feature %a, type %a, %schain lookup %a"](
+ dataset[4],sequence.type,merged,sequence.name)
+ end
end
local function pref(dataset,sequence)
- return formatters["feature %a, type %a, %slookup %a"](
- dataset[4],sequence.type,sequence.merged and "merged " or "",sequence.name)
+ return formatters["feature %a, type %a, %slookup %a"](
+ dataset[4],sequence.type,sequence.merged and "merged " or "",sequence.name)
end
local function mref(rlmode)
- if not rlmode or rlmode>=0 then
- return "l2r"
- else
- return "r2l"
- end
+ if not rlmode or rlmode>=0 then
+ return "l2r"
+ else
+ return "r2l"
+ end
end
local function flattendisk(head,disc)
- local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
- local prev,next=getboth(disc)
- local ishead=head==disc
- setdisc(disc)
- flush_node(disc)
- if pre then
- flush_node_list(pre)
- end
- if post then
- flush_node_list(post)
- end
- if ishead then
- if replace then
- if next then
- setlink(replacetail,next)
- end
- return replace,replace
- elseif next then
- return next,next
- else
- end
- else
- if replace then
- if next then
- setlink(replacetail,next)
- end
- setlink(prev,replace)
- return head,replace
- else
- setlink(prev,next)
- return head,next
- end
- end
-end
-local function appenddisc(disc,list)
- local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
- local posthead=list
- local replacehead=copy_node_list(list)
- if post then
- setlink(posttail,posthead)
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
+ local prev,next=getboth(disc)
+ local ishead=head==disc
+ setdisc(disc)
+ flush_node(disc)
+ if pre then
+ flush_node_list(pre)
+ end
+ if post then
+ flush_node_list(post)
+ end
+ if ishead then
+ if replace then
+ if next then
+ setlink(replacetail,next)
+ end
+ return replace,replace
+ elseif next then
+ return next,next
else
- post=posthead
end
+ else
if replace then
- setlink(replacetail,replacehead)
+ if next then
+ setlink(replacetail,next)
+ end
+ setlink(prev,replace)
+ return head,replace
else
- replace=replacehead
+ setlink(prev,next)
+ return head,next
end
- setdisc(disc,pre,post,replace)
+ end
+end
+local function appenddisc(disc,list)
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
+ local posthead=list
+ local replacehead=copy_node_list(list)
+ if post then
+ setlink(posttail,posthead)
+ else
+ post=posthead
+ end
+ if replace then
+ setlink(replacetail,replacehead)
+ else
+ replace=replacehead
+ end
+ setdisc(disc,pre,post,replace)
end
local copy_no_components=nuts.copy_no_components
local copy_only_glyphs=nuts.copy_only_glyphs
local set_components=setcomponents
local take_components=getcomponents
local function count_components(start,marks)
- local char=isglyph(start)
- if char then
- if getsubtype(start)==ligatureglyph_code then
- local i=0
- local components=getcomponents(start)
- while components do
- i=i+count_components(components,marks)
- components=getnext(components)
- end
- return i
- elseif not marks[char] then
- return 1
- end
- end
- return 0
+ local char=isglyph(start)
+ if char then
+ if getsubtype(start)==ligatureglyph_code then
+ local i=0
+ local components=getcomponents(start)
+ while components do
+ i=i+count_components(components,marks)
+ components=getnext(components)
+ end
+ return i
+ elseif not marks[char] then
+ return 1
+ end
+ end
+ return 0
end
local function markstoligature(head,start,stop,char)
- if start==stop and getchar(start)==char then
- return head,start
- else
- local prev=getprev(start)
- local next=getnext(stop)
- setprev(start)
- setnext(stop)
- local base=copy_no_components(start,copyinjection)
- if head==start then
- head=base
- end
- resetinjection(base)
- setchar(base,char)
- setsubtype(base,ligatureglyph_code)
- set_components(base,start)
- setlink(prev,base,next)
- return head,base
- end
-end
-local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks)
- if getattr(start,a_noligature)==1 then
- return head,start
- end
- if start==stop and getchar(start)==char then
- resetinjection(start)
- setchar(start,char)
- return head,start
- end
+ if start==stop and getchar(start)==char then
+ return head,start
+ else
local prev=getprev(start)
local next=getnext(stop)
- local comp=start
setprev(start)
setnext(stop)
local base=copy_no_components(start,copyinjection)
- if start==head then
- head=base
+ if head==start then
+ head=base
end
resetinjection(base)
setchar(base,char)
setsubtype(base,ligatureglyph_code)
- set_components(base,comp)
+ set_components(base,start)
setlink(prev,base,next)
- if not discfound then
- local deletemarks=not skiphash or hasmarks
- local components=start
- local baseindex=0
- local componentindex=0
- local head=base
- local current=base
- while start do
- local char=getchar(start)
- if not marks[char] then
- baseindex=baseindex+componentindex
- componentindex=count_components(start,marks)
- elseif not deletemarks then
- setligaindex(start,baseindex+getligaindex(start,componentindex))
- if trace_marks then
- logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
- end
- local n=copy_node(start)
- copyinjection(n,start)
- head,current=insert_node_after(head,current,n)
- elseif trace_marks then
- logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char))
- end
- start=getnext(start)
+ return head,base
+ end
+end
+local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks)
+ if getattr(start,a_noligature)==1 then
+ return head,start
+ end
+ if start==stop and getchar(start)==char then
+ resetinjection(start)
+ setchar(start,char)
+ return head,start
+ end
+ local prev=getprev(start)
+ local next=getnext(stop)
+ local comp=start
+ setprev(start)
+ setnext(stop)
+ local base=copy_no_components(start,copyinjection)
+ if start==head then
+ head=base
+ end
+ resetinjection(base)
+ setchar(base,char)
+ setsubtype(base,ligatureglyph_code)
+ set_components(base,comp)
+ setlink(prev,base,next)
+ if not discfound then
+ local deletemarks=not skiphash or hasmarks
+ local components=start
+ local baseindex=0
+ local componentindex=0
+ local head=base
+ local current=base
+ while start do
+ local char=getchar(start)
+ if not marks[char] then
+ baseindex=baseindex+componentindex
+ componentindex=count_components(start,marks)
+ elseif not deletemarks then
+ setligaindex(start,baseindex+getligaindex(start,componentindex))
+ if trace_marks then
+ logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
end
- local start=getnext(current)
- while start do
- local char=ischar(start)
- if char then
- if marks[char] then
- setligaindex(start,baseindex+getligaindex(start,componentindex))
- if trace_marks then
- logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
- end
- start=getnext(start)
- else
- break
- end
- else
- break
- end
+ local n=copy_node(start)
+ copyinjection(n,start)
+ head,current=insert_node_after(head,current,n)
+ elseif trace_marks then
+ logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char))
+ end
+ start=getnext(start)
+ end
+ local start=getnext(current)
+ while start do
+ local char=ischar(start)
+ if char then
+ if marks[char] then
+ setligaindex(start,baseindex+getligaindex(start,componentindex))
+ if trace_marks then
+ logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ end
+ start=getnext(start)
+ else
+ break
end
- else
- local discprev,discnext=getboth(discfound)
- if discprev and discnext then
- local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true)
- if not replace then
- local prev=getprev(base)
- local comp=take_components(base)
- local copied=copy_only_glyphs(comp)
- if pre then
- setlink(discprev,pre)
- else
- setnext(discprev)
- end
- pre=comp
- if post then
- setlink(posttail,discnext)
- setprev(post)
- else
- post=discnext
- setprev(discnext)
- end
- setlink(prev,discfound,next)
- setboth(base)
- set_components(base,copied)
- replace=base
- if forcediscretionaries then
- setdisc(discfound,pre,post,replace,discretionarydisc_code)
- else
- setdisc(discfound,pre,post,replace)
- end
- base=prev
- end
+ else
+ break
+ end
+ end
+ else
+ local discprev,discnext=getboth(discfound)
+ if discprev and discnext then
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true)
+ if not replace then
+ local prev=getprev(base)
+ local comp=take_components(base)
+ local copied=copy_only_glyphs(comp)
+ if pre then
+ setlink(discprev,pre)
+ else
+ setnext(discprev)
end
+ pre=comp
+ if post then
+ setlink(posttail,discnext)
+ setprev(post)
+ else
+ post=discnext
+ setprev(discnext)
+ end
+ setlink(prev,discfound,next)
+ setboth(base)
+ set_components(base,copied)
+ replace=base
+ if forcediscretionaries then
+ setdisc(discfound,pre,post,replace,discretionarydisc_code)
+ else
+ setdisc(discfound,pre,post,replace)
+ end
+ base=prev
+ end
end
- return head,base
+ end
+ return head,base
end
local function multiple_glyphs(head,start,multiple,skiphash,what,stop)
- local nofmultiples=#multiple
- if nofmultiples>0 then
- resetinjection(start)
- setchar(start,multiple[1])
- if nofmultiples>1 then
- local sn=getnext(start)
- for k=2,nofmultiples do
- local n=copy_node(start)
- resetinjection(n)
- setchar(n,multiple[k])
- insert_node_after(head,start,n)
- start=n
- end
- if what==true then
- elseif what>1 then
- local m=multiple[nofmultiples]
- for i=2,what do
- local n=copy_node(start)
- resetinjection(n)
- setchar(n,m)
- insert_node_after(head,start,n)
- start=n
- end
- end
- end
- return head,start,true
- else
- if trace_multiples then
- logprocess("no multiple for %s",gref(getchar(start)))
- end
- return head,start,false
+ local nofmultiples=#multiple
+ if nofmultiples>0 then
+ resetinjection(start)
+ setchar(start,multiple[1])
+ if nofmultiples>1 then
+ local sn=getnext(start)
+ for k=2,nofmultiples do
+ local n=copy_node(start)
+ resetinjection(n)
+ setchar(n,multiple[k])
+ insert_node_after(head,start,n)
+ start=n
+ end
+ if what==true then
+ elseif what>1 then
+ local m=multiple[nofmultiples]
+ for i=2,what do
+ local n=copy_node(start)
+ resetinjection(n)
+ setchar(n,m)
+ insert_node_after(head,start,n)
+ start=n
+ end
+ end
end
+ return head,start,true
+ else
+ if trace_multiples then
+ logprocess("no multiple for %s",gref(getchar(start)))
+ end
+ return head,start,false
+ end
end
local function get_alternative_glyph(start,alternatives,value)
- local n=#alternatives
- if n==1 then
- return alternatives[1],trace_alternatives and "1 (only one present)"
- elseif value=="random" then
- local r=getrandom and getrandom("glyph",1,n) or random(1,n)
- return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r)
- elseif value=="first" then
- return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1)
- elseif value=="last" then
- return alternatives[n],trace_alternatives and formatters["value %a, taking %a"](value,n)
- end
- value=value==true and 1 or tonumber(value)
- if type(value)~="number" then
- return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,1)
- end
- if value>n then
- local defaultalt=otf.defaultnodealternate
- if defaultalt=="first" then
- return alternatives[n],trace_alternatives and formatters["invalid value %s, taking %a"](value,1)
- elseif defaultalt=="last" then
- return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,n)
- else
- return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range")
- end
- elseif value==0 then
- return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change")
- elseif value<1 then
- return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1)
+ local n=#alternatives
+ if n==1 then
+ return alternatives[1],trace_alternatives and "1 (only one present)"
+ elseif value=="random" then
+ local r=getrandom and getrandom("glyph",1,n) or random(1,n)
+ return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r)
+ elseif value=="first" then
+ return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1)
+ elseif value=="last" then
+ return alternatives[n],trace_alternatives and formatters["value %a, taking %a"](value,n)
+ end
+ value=value==true and 1 or tonumber(value)
+ if type(value)~="number" then
+ return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,1)
+ end
+ if value>n then
+ local defaultalt=otf.defaultnodealternate
+ if defaultalt=="first" then
+ return alternatives[n],trace_alternatives and formatters["invalid value %s, taking %a"](value,1)
+ elseif defaultalt=="last" then
+ return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,n)
else
- return alternatives[value],trace_alternatives and formatters["value %a, taking %a"](value,value)
+ return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range")
end
+ elseif value==0 then
+ return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change")
+ elseif value<1 then
+ return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1)
+ else
+ return alternatives[value],trace_alternatives and formatters["value %a, taking %a"](value,value)
+ end
end
function handlers.gsub_single(head,start,dataset,sequence,replacement)
- if trace_singles then
- logprocess("%s: replacing %s by single %s",pref(dataset,sequence),gref(getchar(start)),gref(replacement))
- end
- resetinjection(start)
- setchar(start,replacement)
- return head,start,true
+ if trace_singles then
+ logprocess("%s: replacing %s by single %s",pref(dataset,sequence),gref(getchar(start)),gref(replacement))
+ end
+ resetinjection(start)
+ setchar(start,replacement)
+ return head,start,true
end
function handlers.gsub_alternate(head,start,dataset,sequence,alternative)
- local kind=dataset[4]
- local what=dataset[1]
- local value=what==true and tfmdata.shared.features[kind] or what
- local choice,comment=get_alternative_glyph(start,alternative,value)
- if choice then
- if trace_alternatives then
- logprocess("%s: replacing %s by alternative %a to %s, %s",pref(dataset,sequence),gref(getchar(start)),gref(choice),comment)
- end
- resetinjection(start)
- setchar(start,choice)
- else
- if trace_alternatives then
- logwarning("%s: no variant %a for %s, %s",pref(dataset,sequence),value,gref(getchar(start)),comment)
- end
+ local kind=dataset[4]
+ local what=dataset[1]
+ local value=what==true and tfmdata.shared.features[kind] or what
+ local choice,comment=get_alternative_glyph(start,alternative,value)
+ if choice then
+ if trace_alternatives then
+ logprocess("%s: replacing %s by alternative %a to %s, %s",pref(dataset,sequence),gref(getchar(start)),gref(choice),comment)
end
- return head,start,true
+ resetinjection(start)
+ setchar(start,choice)
+ else
+ if trace_alternatives then
+ logwarning("%s: no variant %a for %s, %s",pref(dataset,sequence),value,gref(getchar(start)),comment)
+ end
+ end
+ return head,start,true
end
function handlers.gsub_multiple(head,start,dataset,sequence,multiple,rlmode,skiphash)
- if trace_multiples then
- logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple))
- end
- return multiple_glyphs(head,start,multiple,skiphash,dataset[1])
+ if trace_multiples then
+ logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple))
+ end
+ return multiple_glyphs(head,start,multiple,skiphash,dataset[1])
end
function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skiphash)
- local current=getnext(start)
- if not current then
- return head,start,false,nil
- end
- local stop=nil
- local startchar=getchar(start)
- if skiphash and skiphash[startchar] then
- while current do
- local char=ischar(current,currentfont)
- if char then
- local lg=ligature[char]
- if lg then
- stop=current
- ligature=lg
- current=getnext(current)
- else
- break
- end
- else
- break
- end
+ local current=getnext(start)
+ if not current then
+ return head,start,false,nil
+ end
+ local stop=nil
+ local startchar=getchar(start)
+ if skiphash and skiphash[startchar] then
+ while current do
+ local char=ischar(current,currentfont)
+ if char then
+ local lg=ligature[char]
+ if lg then
+ stop=current
+ ligature=lg
+ current=getnext(current)
+ else
+ break
end
- if stop then
- local lig=ligature.ligature
- if lig then
- if trace_ligatures then
- local stopchar=getchar(stop)
- head,start=markstoligature(head,start,stop,lig)
- logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start)))
- else
- head,start=markstoligature(head,start,stop,lig)
- end
- return head,start,true,false
- else
- end
+ else
+ break
+ end
+ end
+ if stop then
+ local lig=ligature.ligature
+ if lig then
+ if trace_ligatures then
+ local stopchar=getchar(stop)
+ head,start=markstoligature(head,start,stop,lig)
+ logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start)))
+ else
+ head,start=markstoligature(head,start,stop,lig)
end
- else
- local discfound=false
- local hasmarks=marks[startchar]
- while current do
- local char,id=ischar(current,currentfont)
- if char then
- if skiphash and skiphash[char] then
- current=getnext(current)
- else
- local lg=ligature[char]
- if lg then
- if marks[char] then
- hasmarks=true
- end
- stop=current
- ligature=lg
- current=getnext(current)
- else
- break
- end
- end
- elseif char==false then
- break
- elseif id==disc_code then
- discfound=current
- break
- else
- break
+ return head,start,true,false
+ else
+ end
+ end
+ else
+ local discfound=false
+ local hasmarks=marks[startchar]
+ while current do
+ local char,id=ischar(current,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ current=getnext(current)
+ else
+ local lg=ligature[char]
+ if lg then
+ if marks[char] then
+ hasmarks=true
end
+ stop=current
+ ligature=lg
+ current=getnext(current)
+ else
+ break
+ end
end
- if discfound then
- local pre,post,replace=getdisc(discfound)
- local match
- if replace then
- local char=ischar(replace,currentfont)
- if char and ligature[char] then
- match=true
- end
- end
- if not match and pre then
- local char=ischar(pre,currentfont)
- if char and ligature[char] then
- match=true
- end
- end
- if not match and not pre or not replace then
- local n=getnext(discfound)
- local char=ischar(n,currentfont)
- if char and ligature[char] then
- match=true
- end
- end
- if match then
- local ishead=head==start
- local prev=getprev(start)
- if stop then
- setnext(stop)
- local tail=getprev(stop)
- local copy=copy_node_list(start)
- local liat=find_node_tail(copy)
- if pre and replace then
- setlink(liat,pre)
- end
- if replace then
- setlink(tail,replace)
- end
- pre=copy
- replace=start
- else
- setnext(start)
- local copy=copy_node(start)
- if pre then
- setlink(copy,pre)
- end
- if replace then
- setlink(start,replace)
- end
- pre=copy
- replace=start
- end
- setdisc(discfound,pre,post,replace)
- if prev then
- setlink(prev,discfound)
- else
- setprev(discfound)
- head=discfound
- end
- start=discfound
- return head,start,true,true
- end
+ elseif char==false then
+ break
+ elseif id==disc_code then
+ discfound=current
+ break
+ else
+ break
+ end
+ end
+ if discfound then
+ local pre,post,replace=getdisc(discfound)
+ local match
+ if replace then
+ local char=ischar(replace,currentfont)
+ if char and ligature[char] then
+ match=true
+ end
+ end
+ if not match and pre then
+ local char=ischar(pre,currentfont)
+ if char and ligature[char] then
+ match=true
+ end
+ end
+ if not match and not pre or not replace then
+ local n=getnext(discfound)
+ local char=ischar(n,currentfont)
+ if char and ligature[char] then
+ match=true
+ end
+ end
+ if match then
+ local ishead=head==start
+ local prev=getprev(start)
+ if stop then
+ setnext(stop)
+ local tail=getprev(stop)
+ local copy=copy_node_list(start)
+ local liat=find_node_tail(copy)
+ if pre and replace then
+ setlink(liat,pre)
+ end
+ if replace then
+ setlink(tail,replace)
+ end
+ pre=copy
+ replace=start
+ else
+ setnext(start)
+ local copy=copy_node(start)
+ if pre then
+ setlink(copy,pre)
+ end
+ if replace then
+ setlink(start,replace)
+ end
+ pre=copy
+ replace=start
end
- local lig=ligature.ligature
- if lig then
- if stop then
- if trace_ligatures then
- local stopchar=getchar(stop)
- head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
- logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig))
- else
- head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
- end
- else
- resetinjection(start)
- setchar(start,lig)
- if trace_ligatures then
- logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig))
- end
- end
- return head,start,true,false
+ setdisc(discfound,pre,post,replace)
+ if prev then
+ setlink(prev,discfound)
else
+ setprev(discfound)
+ head=discfound
+ end
+ start=discfound
+ return head,start,true,true
+ end
+ end
+ local lig=ligature.ligature
+ if lig then
+ if stop then
+ if trace_ligatures then
+ local stopchar=getchar(stop)
+ head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
+ logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig))
+ else
+ head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
+ end
+ else
+ resetinjection(start)
+ setchar(start,lig)
+ if trace_ligatures then
+ logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig))
end
+ end
+ return head,start,true,false
+ else
end
- return head,start,false,false
+ end
+ return head,start,false,false
end
function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
- local startchar=getchar(start)
- local format=step.format
- if format=="single" or type(kerns)=="table" then
- local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
- end
- else
- local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
- end
+ local startchar=getchar(start)
+ local format=step.format
+ if format=="single" or type(kerns)=="table" then
+ local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
end
- return head,start,true
+ else
+ local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
+ end
+ end
+ return head,start,true
end
function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
- local snext=getnext(start)
- if not snext then
- return head,start,false
- else
- local prev=start
- while snext do
- local nextchar=ischar(snext,currentfont)
- if nextchar then
- if skiphash and skiphash[nextchar] then
- prev=snext
- snext=getnext(snext)
- else
- local krn=kerns[nextchar]
- if not krn then
- break
- end
- local format=step.format
- if format=="pair" then
- local a,b=krn[1],krn[2]
- if a==true then
- elseif a then
- local x,y,w,h=setposition(1,start,factor,rlmode,a,injection)
- if trace_kerns then
- local startchar=getchar(start)
- logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
- end
- end
- if b==true then
- start=snext
- elseif b then
- local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection)
- if trace_kerns then
- local startchar=getchar(start)
- logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
- end
- start=snext
- elseif forcepairadvance then
- start=snext
- end
- return head,start,true
- elseif krn~=0 then
- local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
- if trace_kerns then
- logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
- end
- return head,start,true
- else
- break
- end
- end
- else
- break
+ local snext=getnext(start)
+ if not snext then
+ return head,start,false
+ else
+ local prev=start
+ while snext do
+ local nextchar=ischar(snext,currentfont)
+ if nextchar then
+ if skiphash and skiphash[nextchar] then
+ prev=snext
+ snext=getnext(snext)
+ else
+ local krn=kerns[nextchar]
+ if not krn then
+ break
+ end
+ local format=step.format
+ if format=="pair" then
+ local a,b=krn[1],krn[2]
+ if a==true then
+ elseif a then
+ local x,y,w,h=setposition(1,start,factor,rlmode,a,injection)
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
end
+ if b==true then
+ start=snext
+ elseif b then
+ local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection)
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ start=snext
+ elseif forcepairadvance then
+ start=snext
+ end
+ return head,start,true
+ elseif krn~=0 then
+ local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
+ if trace_kerns then
+ logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
+ end
+ return head,start,true
+ else
+ break
+ end
end
- return head,start,false
+ else
+ break
+ end
end
+ return head,start,false
+ end
end
function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash)
- local markchar=getchar(start)
- if marks[markchar] then
- local base=getprev(start)
- if base then
- local basechar=ischar(base,currentfont)
- if basechar then
- if marks[basechar] then
- while base do
- base=getprev(base)
- if base then
- basechar=ischar(base,currentfont)
- if basechar then
- if not marks[basechar] then
- break
- end
- else
- if trace_bugs then
- logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
- end
- return head,start,false
- end
- else
- if trace_bugs then
- logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
- end
- return head,start,false
- end
- end
- end
- local ba=markanchors[1][basechar]
- if ba then
- local ma=markanchors[2]
- local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
- if trace_marks then
- logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)",
- pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
- end
- return head,start,true
- elseif trace_bugs then
- logwarning("%s: mark %s is not anchored to %s",pref(dataset,sequence),gref(markchar),gref(basechar))
- end
- elseif trace_bugs then
- logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),1)
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local base=getprev(start)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base=getprev(base)
+ if base then
+ basechar=ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
+ end
+ return head,start,false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
+ end
+ return head,start,false
end
+ end
+ end
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)",
+ pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head,start,true
elseif trace_bugs then
- logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),2)
+ logwarning("%s: mark %s is not anchored to %s",pref(dataset,sequence),gref(markchar),gref(basechar))
end
+ elseif trace_bugs then
+ logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),1)
+ end
elseif trace_bugs then
- logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),2)
end
- return head,start,false
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
+ return head,start,false
end
function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlmode,skiphash)
- local markchar=getchar(start)
- if marks[markchar] then
- local base=getprev(start)
- if base then
- local basechar=ischar(base,currentfont)
- if basechar then
- if marks[basechar] then
- while base do
- base=getprev(base)
- if base then
- basechar=ischar(base,currentfont)
- if basechar then
- if not marks[basechar] then
- break
- end
- else
- if trace_bugs then
- logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
- end
- return head,start,false
- end
- else
- if trace_bugs then
- logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
- end
- return head,start,false
- end
- end
- end
- local ba=markanchors[1][basechar]
- if ba then
- local ma=markanchors[2]
- if ma then
- local index=getligaindex(start)
- ba=ba[index]
- if ba then
- local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
- if trace_marks then
- logprocess("%s, index %s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)",
- pref(dataset,sequence),index,bound,gref(markchar),gref(basechar),index,dx,dy)
- end
- return head,start,true
- else
- if trace_bugs then
- logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(dataset,sequence),gref(markchar),gref(basechar),index)
- end
- end
- end
- elseif trace_bugs then
- onetimemessage(currentfont,basechar,"no base anchors",report_fonts)
- end
- elseif trace_bugs then
- logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1)
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local base=getprev(start)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base=getprev(base)
+ if base then
+ basechar=ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
+ end
+ return head,start,false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
+ end
+ return head,start,false
end
+ end
+ end
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ if ma then
+ local index=getligaindex(start)
+ ba=ba[index]
+ if ba then
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, index %s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)",
+ pref(dataset,sequence),index,bound,gref(markchar),gref(basechar),index,dx,dy)
+ end
+ return head,start,true
+ else
+ if trace_bugs then
+ logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(dataset,sequence),gref(markchar),gref(basechar),index)
+ end
+ end
+ end
elseif trace_bugs then
- logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),2)
+ onetimemessage(currentfont,basechar,"no base anchors",report_fonts)
end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1)
+ end
elseif trace_bugs then
- logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),2)
end
- return head,start,false
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
+ return head,start,false
end
function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode,skiphash)
- local markchar=getchar(start)
- if marks[markchar] then
- local base=getprev(start)
- local slc=getligaindex(start)
- if slc then
- while base do
- local blc=getligaindex(base)
- if blc and blc~=slc then
- base=getprev(base)
- else
- break
- end
- end
- end
- if base then
- local basechar=ischar(base,currentfont)
- if basechar then
- local ba=markanchors[1][basechar]
- if ba then
- local ma=markanchors[2]
- local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks)
- if trace_marks then
- logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)",
- pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
- end
- return head,start,true
- end
- end
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local base=getprev(start)
+ local slc=getligaindex(start)
+ if slc then
+ while base do
+ local blc=getligaindex(base)
+ if blc and blc~=slc then
+ base=getprev(base)
+ else
+ break
+ end
+ end
+ end
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)",
+ pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
+ end
+ return head,start,true
end
- elseif trace_bugs then
- logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
end
- return head,start,false
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar))
+ end
+ return head,start,false
end
function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,skiphash,step)
- local startchar=getchar(start)
- if marks[startchar] then
- if trace_cursive then
- logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar))
- end
- else
- local nxt=getnext(start)
- while nxt do
- local nextchar=ischar(nxt,currentfont)
- if not nextchar then
- break
- elseif marks[nextchar] then
- nxt=getnext(nxt)
- else
- local exit=exitanchors[3]
- if exit then
- local entry=exitanchors[1][nextchar]
- if entry then
- entry=entry[2]
- if entry then
- local r2lflag=sequence.flags[4]
- local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag)
- if trace_cursive then
- logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode))
- end
- return head,start,true
- end
- end
- end
- break
+ local startchar=getchar(start)
+ if marks[startchar] then
+ if trace_cursive then
+ logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar))
+ end
+ else
+ local nxt=getnext(start)
+ while nxt do
+ local nextchar=ischar(nxt,currentfont)
+ if not nextchar then
+ break
+ elseif marks[nextchar] then
+ nxt=getnext(nxt)
+ else
+ local exit=exitanchors[3]
+ if exit then
+ local entry=exitanchors[1][nextchar]
+ if entry then
+ entry=entry[2]
+ if entry then
+ local r2lflag=sequence.flags[4]
+ local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag)
+ if trace_cursive then
+ logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode))
+ end
+ return head,start,true
end
+ end
end
+ break
+ end
end
- return head,start,false
+ end
+ return head,start,false
end
local chainprocs={}
local function logprocess(...)
- if trace_steps then
- registermessage(...)
- if trace_steps=="silent" then
- return
- end
+ if trace_steps then
+ registermessage(...)
+ if trace_steps=="silent" then
+ return
end
- report_subchain(...)
+ end
+ report_subchain(...)
end
local logwarning=report_subchain
local function logprocess(...)
- if trace_steps then
- registermessage(...)
- if trace_steps=="silent" then
- return
- end
+ if trace_steps then
+ registermessage(...)
+ if trace_steps=="silent" then
+ return
end
- report_chain(...)
+ end
+ report_chain(...)
end
local logwarning=report_chain
local function reversesub(head,start,stop,dataset,sequence,replacements,rlmode,skiphash)
- local char=getchar(start)
- local replacement=replacements[char]
- if replacement then
- if trace_singles then
- logprocess("%s: single reverse replacement of %s by %s",cref(dataset,sequence),gref(char),gref(replacement))
- end
- resetinjection(start)
- setchar(start,replacement)
- return head,start,true
- else
- return head,start,false
+ local char=getchar(start)
+ local replacement=replacements[char]
+ if replacement then
+ if trace_singles then
+ logprocess("%s: single reverse replacement of %s by %s",cref(dataset,sequence),gref(char),gref(replacement))
end
+ resetinjection(start)
+ setchar(start,replacement)
+ return head,start,true
+ else
+ return head,start,false
+ end
end
chainprocs.reversesub=reversesub
local function reportzerosteps(dataset,sequence)
- logwarning("%s: no steps",cref(dataset,sequence))
+ logwarning("%s: no steps",cref(dataset,sequence))
end
local function reportmoresteps(dataset,sequence)
- logwarning("%s: more than 1 step",cref(dataset,sequence))
+ logwarning("%s: more than 1 step",cref(dataset,sequence))
end
local function getmapping(dataset,sequence,currentlookup)
- local steps=currentlookup.steps
- local nofsteps=currentlookup.nofsteps
- if nofsteps==0 then
- reportzerosteps(dataset,sequence)
- currentlookup.mapping=false
- return false
- else
- if nofsteps>1 then
- reportmoresteps(dataset,sequence)
- end
- local mapping=steps[1].coverage
- currentlookup.mapping=mapping
- currentlookup.format=steps[1].format
- return mapping
+ local steps=currentlookup.steps
+ local nofsteps=currentlookup.nofsteps
+ if nofsteps==0 then
+ reportzerosteps(dataset,sequence)
+ currentlookup.mapping=false
+ return false
+ else
+ if nofsteps>1 then
+ reportmoresteps(dataset,sequence)
end
+ local mapping=steps[1].coverage
+ currentlookup.mapping=mapping
+ currentlookup.format=steps[1].format
+ return mapping
+ end
end
function chainprocs.gsub_remove(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- if trace_chains then
- logprocess("%s: removing character %s",cref(dataset,sequence,chainindex),gref(getchar(start)))
- end
- head,start=remove_node(head,start,true)
- return head,getprev(start),true
+ if trace_chains then
+ logprocess("%s: removing character %s",cref(dataset,sequence,chainindex),gref(getchar(start)))
+ end
+ head,start=remove_node(head,start,true)
+ return head,getprev(start),true
end
function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local current=start
- while current do
- local currentchar=ischar(current)
- if currentchar then
- local replacement=mapping[currentchar]
- if not replacement or replacement=="" then
- if trace_bugs then
- logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar))
- end
- else
- if trace_singles then
- logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement))
- end
- resetinjection(current)
- setchar(current,replacement)
- end
- return head,start,true
- elseif currentchar==false then
- break
- elseif current==stop then
- break
- else
- current=getnext(current)
- end
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local current=start
+ while current do
+ local currentchar=ischar(current)
+ if currentchar then
+ local replacement=mapping[currentchar]
+ if not replacement or replacement=="" then
+ if trace_bugs then
+ logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar))
+ end
+ else
+ if trace_singles then
+ logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement))
+ end
+ resetinjection(current)
+ setchar(current,replacement)
end
+ return head,start,true
+ elseif currentchar==false then
+ break
+ elseif current==stop then
+ break
+ else
+ current=getnext(current)
+ end
end
- return head,start,false
+ end
+ return head,start,false
end
function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local kind=dataset[4]
- local what=dataset[1]
- local value=what==true and tfmdata.shared.features[kind] or what
- local current=start
- while current do
- local currentchar=ischar(current)
- if currentchar then
- local alternatives=mapping[currentchar]
- if alternatives then
- local choice,comment=get_alternative_glyph(current,alternatives,value)
- if choice then
- if trace_alternatives then
- logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(currentchar),choice,gref(choice),comment)
- end
- resetinjection(start)
- setchar(start,choice)
- else
- if trace_alternatives then
- logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(currentchar),comment)
- end
- end
- end
- return head,start,true
- elseif currentchar==false then
- break
- elseif current==stop then
- break
- else
- current=getnext(current)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local kind=dataset[4]
+ local what=dataset[1]
+ local value=what==true and tfmdata.shared.features[kind] or what
+ local current=start
+ while current do
+ local currentchar=ischar(current)
+ if currentchar then
+ local alternatives=mapping[currentchar]
+ if alternatives then
+ local choice,comment=get_alternative_glyph(current,alternatives,value)
+ if choice then
+ if trace_alternatives then
+ logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(currentchar),choice,gref(choice),comment)
+ end
+ resetinjection(start)
+ setchar(start,choice)
+ else
+ if trace_alternatives then
+ logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(currentchar),comment)
end
+ end
end
+ return head,start,true
+ elseif currentchar==false then
+ break
+ elseif current==stop then
+ break
+ else
+ current=getnext(current)
+ end
end
- return head,start,false
+ end
+ return head,start,false
end
function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local startchar=getchar(start)
- local replacement=mapping[startchar]
- if not replacement or replacement=="" then
- if trace_bugs then
- logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar))
- end
- else
- if trace_multiples then
- logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement))
- end
- return multiple_glyphs(head,start,replacement,skiphash,dataset[1],stop)
- end
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local replacement=mapping[startchar]
+ if not replacement or replacement=="" then
+ if trace_bugs then
+ logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar))
+ end
+ else
+ if trace_multiples then
+ logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement))
+ end
+ return multiple_glyphs(head,start,replacement,skiphash,dataset[1],stop)
end
- return head,start,false
+ end
+ return head,start,false
end
function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local startchar=getchar(start)
- local ligatures=mapping[startchar]
- if not ligatures then
- if trace_bugs then
- logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar))
- end
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local ligatures=mapping[startchar]
+ if not ligatures then
+ if trace_bugs then
+ logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar))
+ end
+ else
+ local hasmarks=marks[startchar]
+ local current=getnext(start)
+ local discfound=false
+ local last=stop
+ local nofreplacements=1
+ while current do
+ local id=getid(current)
+ if id==disc_code then
+ if not discfound then
+ discfound=current
+ end
+ if current==stop then
+ break
+ else
+ current=getnext(current)
+ end
else
- local hasmarks=marks[startchar]
- local current=getnext(start)
- local discfound=false
- local last=stop
- local nofreplacements=1
- while current do
- local id=getid(current)
- if id==disc_code then
- if not discfound then
- discfound=current
- end
- if current==stop then
- break
- else
- current=getnext(current)
- end
- else
- local schar=getchar(current)
- if skiphash and skiphash[schar] then
- current=getnext(current)
- else
- local lg=ligatures[schar]
- if lg then
- ligatures=lg
- last=current
- nofreplacements=nofreplacements+1
- if marks[char] then
- hasmarks=true
- end
- if current==stop then
- break
- else
- current=getnext(current)
- end
- else
- break
- end
- end
- end
- end
- local ligature=ligatures.ligature
- if ligature then
- if chainindex then
- stop=last
- end
- if trace_ligatures then
- if start==stop then
- logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature))
- else
- logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature))
- end
- end
- head,start=toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks)
- return head,start,true,nofreplacements,discfound
- elseif trace_bugs then
- if start==stop then
- logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar))
- else
- logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)))
- end
+ local schar=getchar(current)
+ if skiphash and skiphash[schar] then
+ current=getnext(current)
+ else
+ local lg=ligatures[schar]
+ if lg then
+ ligatures=lg
+ last=current
+ nofreplacements=nofreplacements+1
+ if marks[char] then
+ hasmarks=true
+ end
+ if current==stop then
+ break
+ else
+ current=getnext(current)
+ end
+ else
+ break
end
+ end
+ end
+ end
+ local ligature=ligatures.ligature
+ if ligature then
+ if chainindex then
+ stop=last
+ end
+ if trace_ligatures then
+ if start==stop then
+ logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature))
+ else
+ logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature))
+ end
+ end
+ head,start=toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks)
+ return head,start,true,nofreplacements,discfound
+ elseif trace_bugs then
+ if start==stop then
+ logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar))
+ else
+ logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)))
end
+ end
end
- return head,start,false,0,false
+ end
+ return head,start,false,0,false
end
function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local kerns=mapping[startchar]
+ if kerns then
+ local format=currentlookup.format
+ if format=="single" then
+ local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else
+ local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ end
+ end
+ return head,start,true
end
- if mapping then
- local startchar=getchar(start)
- local kerns=mapping[startchar]
- if kerns then
+ end
+ return head,start,false
+end
+function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local snext=getnext(start)
+ if snext then
+ local startchar=getchar(start)
+ local kerns=mapping[startchar]
+ if kerns then
+ local prev=start
+ while snext do
+ local nextchar=ischar(snext,currentfont)
+ if not nextchar then
+ break
+ end
+ if skiphash and skiphash[nextchar] then
+ prev=snext
+ snext=getnext(snext)
+ else
+ local krn=kerns[nextchar]
+ if not krn then
+ break
+ end
local format=currentlookup.format
- if format=="single" then
- local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns)
+ if format=="pair" then
+ local a,b=krn[1],krn[2]
+ if a==true then
+ elseif a then
+ local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections")
if trace_kerns then
- logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ local startchar=getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
end
- else
- local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ end
+ if b==true then
+ start=snext
+ elseif b then
+ local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections")
if trace_kerns then
- logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ local startchar=getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
end
+ start=snext
+ elseif forcepairadvance then
+ start=snext
+ end
+ return head,start,true
+ elseif krn~=0 then
+ local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn)
+ if trace_kerns then
+ logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
+ end
+ return head,start,true
+ else
+ break
end
- return head,start,true
+ end
end
+ end
end
- return head,start,false
+ end
+ return head,start,false
end
-function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local snext=getnext(start)
- if snext then
- local startchar=getchar(start)
- local kerns=mapping[startchar]
- if kerns then
- local prev=start
- while snext do
- local nextchar=ischar(snext,currentfont)
- if not nextchar then
- break
+function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local markanchors=mapping[markchar]
+ if markanchors then
+ local base=getprev(start)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base=getprev(base)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
end
- if skiphash and skiphash[nextchar] then
- prev=snext
- snext=getnext(snext)
- else
- local krn=kerns[nextchar]
- if not krn then
- break
- end
- local format=currentlookup.format
- if format=="pair" then
- local a,b=krn[1],krn[2]
- if a==true then
- elseif a then
- local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections")
- if trace_kerns then
- local startchar=getchar(start)
- logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
- end
- end
- if b==true then
- start=snext
- elseif b then
- local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections")
- if trace_kerns then
- local startchar=getchar(start)
- logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
- end
- start=snext
- elseif forcepairadvance then
- start=snext
- end
- return head,start,true
- elseif krn~=0 then
- local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn)
- if trace_kerns then
- logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
- end
- return head,start,true
- else
- break
- end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
end
+ return head,start,false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
+ end
+ return head,start,false
end
+ end
end
- end
- end
- return head,start,false
-end
-function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local markchar=getchar(start)
- if marks[markchar] then
- local markanchors=mapping[markchar]
- if markanchors then
- local base=getprev(start)
- if base then
- local basechar=ischar(base,currentfont)
- if basechar then
- if marks[basechar] then
- while base do
- base=getprev(base)
- if base then
- local basechar=ischar(base,currentfont)
- if basechar then
- if not marks[basechar] then
- break
- end
- else
- if trace_bugs then
- logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1)
- end
- return head,start,false
- end
- else
- if trace_bugs then
- logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2)
- end
- return head,start,false
- end
- end
- end
- local ba=markanchors[1][basechar]
- if ba then
- local ma=markanchors[2]
- if ma then
- local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
- if trace_marks then
- logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)",
- cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
- end
- return head,start,true
- end
- end
- elseif trace_bugs then
- logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1)
- end
- elseif trace_bugs then
- logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2)
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ if ma then
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)",
+ cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
end
- elseif trace_bugs then
- logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ return head,start,true
+ end
end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1)
+ end
elseif trace_bugs then
- logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar))
+ logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2)
end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar))
end
- return head,start,false
+ end
+ return head,start,false
end
function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local markchar=getchar(start)
- if marks[markchar] then
- local markanchors=mapping[markchar]
- if markanchors then
- local base=getprev(start)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local markanchors=mapping[markchar]
+ if markanchors then
+ local base=getprev(start)
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if marks[basechar] then
+ while base do
+ base=getprev(base)
if base then
- local basechar=ischar(base,currentfont)
- if basechar then
- if marks[basechar] then
- while base do
- base=getprev(base)
- if base then
- local basechar=ischar(base,currentfont)
- if basechar then
- if not marks[basechar] then
- break
- end
- else
- if trace_bugs then
- logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1)
- end
- return head,start,false
- end
- else
- if trace_bugs then
- logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2)
- end
- return head,start,false
- end
- end
- end
- local ba=markanchors[1][basechar]
- if ba then
- local ma=markanchors[2]
- if ma then
- local index=getligaindex(start)
- ba=ba[index]
- if ba then
- local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
- if trace_marks then
- logprocess("%s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)",
- cref(dataset,sequence),a or bound,gref(markchar),gref(basechar),index,dx,dy)
- end
- return head,start,true
- end
- end
- end
- elseif trace_bugs then
- logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1)
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ if not marks[basechar] then
+ break
end
- elseif trace_bugs then
- logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2)
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1)
+ end
+ return head,start,false
+ end
+ else
+ if trace_bugs then
+ logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2)
+ end
+ return head,start,false
end
- elseif trace_bugs then
- logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ end
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ if ma then
+ local index=getligaindex(start)
+ ba=ba[index]
+ if ba then
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)",
+ cref(dataset,sequence),a or bound,gref(markchar),gref(basechar),index,dx,dy)
+ end
+ return head,start,true
+ end
+ end
end
+ elseif trace_bugs then
+ logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1)
+ end
elseif trace_bugs then
- logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar))
+ logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2)
end
+ elseif trace_bugs then
+ logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar))
end
- return head,start,false
+ end
+ return head,start,false
end
function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local markchar=getchar(start)
- if marks[markchar] then
- local markanchors=mapping[markchar]
- if markanchors then
- local base=getprev(start)
- local slc=getligaindex(start)
- if slc then
- while base do
- local blc=getligaindex(base)
- if blc and blc~=slc then
- base=getprev(base)
- else
- break
- end
- end
- end
- if base then
- local basechar=ischar(base,currentfont)
- if basechar then
- local ba=markanchors[1][basechar]
- if ba then
- local ma=markanchors[2]
- if ma then
- local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks)
- if trace_marks then
- logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)",
- cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
- end
- return head,start,true
- end
- end
- elseif trace_bugs then
- logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1)
- end
- elseif trace_bugs then
- logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2)
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local markchar=getchar(start)
+ if marks[markchar] then
+ local markanchors=mapping[markchar]
+ if markanchors then
+ local base=getprev(start)
+ local slc=getligaindex(start)
+ if slc then
+ while base do
+ local blc=getligaindex(base)
+ if blc and blc~=slc then
+ base=getprev(base)
+ else
+ break
+ end
+ end
+ end
+ if base then
+ local basechar=ischar(base,currentfont)
+ if basechar then
+ local ba=markanchors[1][basechar]
+ if ba then
+ local ma=markanchors[2]
+ if ma then
+ local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks)
+ if trace_marks then
+ logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)",
+ cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy)
end
- elseif trace_bugs then
- logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ return head,start,true
+ end
end
+ elseif trace_bugs then
+ logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1)
+ end
elseif trace_bugs then
- logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar))
+ logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2)
end
+ elseif trace_bugs then
+ logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar))
+ end
+ elseif trace_bugs then
+ logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar))
end
- return head,start,false
+ end
+ return head,start,false
end
function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local startchar=getchar(start)
- local exitanchors=mapping[startchar]
- if exitanchors then
- if marks[startchar] then
- if trace_cursive then
- logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar))
- end
- else
- local nxt=getnext(start)
- while nxt do
- local nextchar=ischar(nxt,currentfont)
- if not nextchar then
- break
- elseif marks[nextchar] then
- nxt=getnext(nxt)
- else
- local exit=exitanchors[3]
- if exit then
- local entry=exitanchors[1][nextchar]
- if entry then
- entry=entry[2]
- if entry then
- local r2lflag=sequence.flags[4]
- local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag)
- if trace_cursive then
- logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode))
- end
- return head,start,true
- end
- end
- elseif trace_bugs then
- onetimemessage(currentfont,startchar,"no entry anchors",report_fonts)
- end
- break
- end
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local exitanchors=mapping[startchar]
+ if exitanchors then
+ if marks[startchar] then
+ if trace_cursive then
+ logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar))
+ end
+ else
+ local nxt=getnext(start)
+ while nxt do
+ local nextchar=ischar(nxt,currentfont)
+ if not nextchar then
+ break
+ elseif marks[nextchar] then
+ nxt=getnext(nxt)
+ else
+ local exit=exitanchors[3]
+ if exit then
+ local entry=exitanchors[1][nextchar]
+ if entry then
+ entry=entry[2]
+ if entry then
+ local r2lflag=sequence.flags[4]
+ local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag)
+ if trace_cursive then
+ logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode))
+ end
+ return head,start,true
end
+ end
+ elseif trace_bugs then
+ onetimemessage(currentfont,startchar,"no entry anchors",report_fonts)
end
- elseif trace_cursive and trace_details then
- logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone)
+ break
+ end
end
+ end
+ elseif trace_cursive and trace_details then
+ logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone)
end
- return head,start,false
+ end
+ return head,start,false
end
local function show_skip(dataset,sequence,char,ck,class)
- logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2])
+ logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2])
end
local userkern=nuts.pool and nuts.pool.newkern
do if not userkern then
- local thekern=nuts.new("kern",1)
- local setkern=nuts.setkern
- userkern=function(k)
- local n=copy_node(thekern)
- setkern(n,k)
- return n
- end
+ local thekern=nuts.new("kern",1)
+ local setkern=nuts.setkern
+ userkern=function(k)
+ local n=copy_node(thekern)
+ setkern(n,k)
+ return n
+ end
end end
local function checked(head)
- local current=head
- while current do
- if getid(current)==glue_code then
- local kern=userkern(getwidth(current))
- if head==current then
- local next=getnext(current)
- if next then
- setlink(kern,next)
- end
- flush_node(current)
- head=kern
- current=next
- else
- local prev,next=getboth(current)
- setlink(prev,kern,next)
- flush_node(current)
- current=next
- end
- else
- current=getnext(current)
+ local current=head
+ while current do
+ if getid(current)==glue_code then
+ local kern=userkern(getwidth(current))
+ if head==current then
+ local next=getnext(current)
+ if next then
+ setlink(kern,next)
end
+ flush_node(current)
+ head=kern
+ current=next
+ else
+ local prev,next=getboth(current)
+ setlink(prev,kern,next)
+ flush_node(current)
+ current=next
+ end
+ else
+ current=getnext(current)
end
- return head
+ end
+ return head
end
local function setdiscchecked(d,pre,post,replace)
- if pre then pre=checked(pre) end
- if post then post=checked(post) end
- if replace then replace=checked(replace) end
- setdisc(d,pre,post,replace)
+ if pre then pre=checked(pre) end
+ if post then post=checked(post) end
+ if replace then replace=checked(replace) end
+ setdisc(d,pre,post,replace)
end
local noflags={ false,false,false,false }
local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
- local size=ck[5]-ck[4]+1
- local chainlookups=ck[6]
- local done=false
- if chainlookups then
- if size==1 then
- local chainlookup=chainlookups[1]
- for j=1,#chainlookup do
- local chainstep=chainlookup[j]
- local chainkind=chainstep.type
- local chainproc=chainprocs[chainkind]
- if chainproc then
- local ok
- head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash)
- if ok then
- done=true
- end
- else
- logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind)
- end
+ local size=ck[5]-ck[4]+1
+ local chainlookups=ck[6]
+ local done=false
+ if chainlookups then
+ if size==1 then
+ local chainlookup=chainlookups[1]
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ local chainkind=chainstep.type
+ local chainproc=chainprocs[chainkind]
+ if chainproc then
+ local ok
+ head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash)
+ if ok then
+ done=true
+ end
+ else
+ logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind)
+ end
+ end
+ else
+ local i=1
+ local laststart=start
+ local nofchainlookups=#chainlookups
+ while start do
+ if skiphash then
+ while start do
+ local char=ischar(start,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
+ break
+ end
+ else
+ break
end
- else
- local i=1
- local laststart=start
- local nofchainlookups=#chainlookups
- while start do
- if skiphash then
- while start do
- local char=ischar(start,currentfont)
- if char then
- if skiphash and skiphash[char] then
- start=getnext(start)
- else
- break
- end
- else
- break
- end
- end
- end
- local chainlookup=chainlookups[i]
- if chainlookup then
- for j=1,#chainlookup do
- local chainstep=chainlookup[j]
- local chainkind=chainstep.type
- local chainproc=chainprocs[chainkind]
- if chainproc then
- local ok,n
- head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,i)
- if ok then
- done=true
- if n and n>1 and i+n>nofchainlookups then
- i=size
- break
- end
- end
- else
- logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
- end
- end
- else
- end
- i=i+1
- if i>size or not start then
- break
- elseif start then
- laststart=start
- start=getnext(start)
+ end
+ end
+ local chainlookup=chainlookups[i]
+ if chainlookup then
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ local chainkind=chainstep.type
+ local chainproc=chainprocs[chainkind]
+ if chainproc then
+ local ok,n
+ head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,i)
+ if ok then
+ done=true
+ if n and n>1 and i+n>nofchainlookups then
+ i=size
+ break
end
+ end
+ else
+ logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
end
- if not start then
- start=laststart
- end
- end
- else
- local replacements=ck[7]
- if replacements then
- head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode,skiphash)
+ end
else
- done=true
- if trace_contexts then
- logprocess("%s: skipping match",cref(dataset,sequence))
- end
end
+ i=i+1
+ if i>size or not start then
+ break
+ elseif start then
+ laststart=start
+ start=getnext(start)
+ end
+ end
+ if not start then
+ start=laststart
+ end
+ end
+ else
+ local replacements=ck[7]
+ if replacements then
+ head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode,skiphash)
+ else
+ done=true
+ if trace_contexts then
+ logprocess("%s: skipping match",cref(dataset,sequence))
+ end
end
- return head,start,done
+ end
+ return head,start,done
end
local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
- if not start then
- return head,start,false
- end
- local startishead=start==head
- local seq=ck[3]
- local f=ck[4]
- local l=ck[5]
- local s=#seq
- local done=false
- local sweepnode=sweepnode
- local sweeptype=sweeptype
- local sweepoverflow=false
- local keepdisc=not sweepnode
- local lookaheaddisc=nil
- local backtrackdisc=nil
- local current=start
- local last=start
- local prev=getprev(start)
- local hasglue=false
- local i=f
- while i<=l do
- local id=getid(current)
- if id==glyph_code then
- i=i+1
- last=current
- current=getnext(current)
- elseif id==glue_code then
- i=i+1
- last=current
- current=getnext(current)
- hasglue=true
- elseif id==disc_code then
- if keepdisc then
- keepdisc=false
- lookaheaddisc=current
- local replace=getfield(current,"replace")
- if not replace then
- sweepoverflow=true
- sweepnode=current
- current=getnext(current)
- else
- while replace and i<=l do
- if getid(replace)==glyph_code then
- i=i+1
- end
- replace=getnext(replace)
- end
- current=getnext(replace)
- end
- last=current
- else
- head,current=flattendisk(head,current)
- end
+ if not start then
+ return head,start,false
+ end
+ local startishead=start==head
+ local seq=ck[3]
+ local f=ck[4]
+ local l=ck[5]
+ local s=#seq
+ local done=false
+ local sweepnode=sweepnode
+ local sweeptype=sweeptype
+ local sweepoverflow=false
+ local keepdisc=not sweepnode
+ local lookaheaddisc=nil
+ local backtrackdisc=nil
+ local current=start
+ local last=start
+ local prev=getprev(start)
+ local hasglue=false
+ local i=f
+ while i<=l do
+ local id=getid(current)
+ if id==glyph_code then
+ i=i+1
+ last=current
+ current=getnext(current)
+ elseif id==glue_code then
+ i=i+1
+ last=current
+ current=getnext(current)
+ hasglue=true
+ elseif id==disc_code then
+ if keepdisc then
+ keepdisc=false
+ lookaheaddisc=current
+ local replace=getfield(current,"replace")
+ if not replace then
+ sweepoverflow=true
+ sweepnode=current
+ current=getnext(current)
else
- last=current
- current=getnext(current)
+ while replace and i<=l do
+ if getid(replace)==glyph_code then
+ i=i+1
+ end
+ replace=getnext(replace)
+ end
+ current=getnext(replace)
end
- if current then
- elseif sweepoverflow then
- break
- elseif sweeptype=="post" or sweeptype=="replace" then
- current=getnext(sweepnode)
- if current then
- sweeptype=nil
- sweepoverflow=true
- else
- break
+ last=current
+ else
+ head,current=flattendisk(head,current)
+ end
+ else
+ last=current
+ current=getnext(current)
+ end
+ if current then
+ elseif sweepoverflow then
+ break
+ elseif sweeptype=="post" or sweeptype=="replace" then
+ current=getnext(sweepnode)
+ if current then
+ sweeptype=nil
+ sweepoverflow=true
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ if sweepoverflow then
+ local prev=current and getprev(current)
+ if not current or prev~=sweepnode then
+ local head=getnext(sweepnode)
+ local tail=nil
+ if prev then
+ tail=prev
+ setprev(current,sweepnode)
+ else
+ tail=find_node_tail(head)
+ end
+ setnext(sweepnode,current)
+ setprev(head)
+ setnext(tail)
+ appenddisc(sweepnode,head)
+ end
+ end
+ if l<s then
+ local i=l
+ local t=sweeptype=="post" or sweeptype=="replace"
+ while current and i<s do
+ local id=getid(current)
+ if id==glyph_code then
+ i=i+1
+ current=getnext(current)
+ elseif id==glue_code then
+ i=i+1
+ current=getnext(current)
+ hasglue=true
+ elseif id==disc_code then
+ if keepdisc then
+ keepdisc=false
+ if notmatchpre[current]~=notmatchreplace[current] then
+ lookaheaddisc=current
+ end
+ local replace=getfield(current,"replace")
+ while replace and i<s do
+ if getid(replace)==glyph_code then
+ i=i+1
end
+ replace=getnext(replace)
+ end
+ current=getnext(current)
+ elseif notmatchpre[current]~=notmatchreplace[current] then
+ head,current=flattendisk(head,current)
else
- break
+ current=getnext(current)
end
- end
- if sweepoverflow then
- local prev=current and getprev(current)
- if not current or prev~=sweepnode then
- local head=getnext(sweepnode)
- local tail=nil
- if prev then
- tail=prev
- setprev(current,sweepnode)
- else
- tail=find_node_tail(head)
- end
- setnext(sweepnode,current)
- setprev(head)
- setnext(tail)
- appenddisc(sweepnode,head)
+ else
+ current=getnext(current)
+ end
+ if not current and t then
+ current=getnext(sweepnode)
+ if current then
+ sweeptype=nil
end
+ end
end
- if l<s then
- local i=l
- local t=sweeptype=="post" or sweeptype=="replace"
- while current and i<s do
- local id=getid(current)
- if id==glyph_code then
- i=i+1
- current=getnext(current)
- elseif id==glue_code then
- i=i+1
- current=getnext(current)
- hasglue=true
- elseif id==disc_code then
- if keepdisc then
- keepdisc=false
- if notmatchpre[current]~=notmatchreplace[current] then
- lookaheaddisc=current
- end
- local replace=getfield(current,"replace")
- while replace and i<s do
- if getid(replace)==glyph_code then
- i=i+1
- end
- replace=getnext(replace)
- end
- current=getnext(current)
- elseif notmatchpre[current]~=notmatchreplace[current] then
- head,current=flattendisk(head,current)
- else
- current=getnext(current)
- end
- else
- current=getnext(current)
- end
- if not current and t then
- current=getnext(sweepnode)
- if current then
- sweeptype=nil
- end
- end
- end
+ end
+ if f>1 then
+ local current=prev
+ local i=f
+ local t=sweeptype=="pre" or sweeptype=="replace"
+ if not current and t and current==checkdisk then
+ current=getprev(sweepnode)
end
- if f>1 then
- local current=prev
- local i=f
- local t=sweeptype=="pre" or sweeptype=="replace"
- if not current and t and current==checkdisk then
- current=getprev(sweepnode)
- end
- while current and i>1 do
- local id=getid(current)
- if id==glyph_code then
- i=i-1
- elseif id==glue_code then
- i=i-1
- hasglue=true
- elseif id==disc_code then
- if keepdisc then
- keepdisc=false
- if notmatchpost[current]~=notmatchreplace[current] then
- backtrackdisc=current
- end
- local replace=getfield(current,"replace")
- while replace and i>1 do
- if getid(replace)==glyph_code then
- i=i-1
- end
- replace=getnext(replace)
- end
- elseif notmatchpost[current]~=notmatchreplace[current] then
- head,current=flattendisk(head,current)
- end
- end
- current=getprev(current)
- if t and current==checkdisk then
- current=getprev(sweepnode)
+ while current and i>1 do
+ local id=getid(current)
+ if id==glyph_code then
+ i=i-1
+ elseif id==glue_code then
+ i=i-1
+ hasglue=true
+ elseif id==disc_code then
+ if keepdisc then
+ keepdisc=false
+ if notmatchpost[current]~=notmatchreplace[current] then
+ backtrackdisc=current
+ end
+ local replace=getfield(current,"replace")
+ while replace and i>1 do
+ if getid(replace)==glyph_code then
+ i=i-1
end
- end
+ replace=getnext(replace)
+ end
+ elseif notmatchpost[current]~=notmatchreplace[current] then
+ head,current=flattendisk(head,current)
+ end
+ end
+ current=getprev(current)
+ if t and current==checkdisk then
+ current=getprev(sweepnode)
+ end
+ end
+ end
+ local done=false
+ if lookaheaddisc then
+ local cf=start
+ local cl=getprev(lookaheaddisc)
+ local cprev=getprev(start)
+ local insertedmarks=0
+ while cprev do
+ local char=ischar(cf,currentfont)
+ if char and marks[char] then
+ insertedmarks=insertedmarks+1
+ cf=cprev
+ startishead=cf==head
+ cprev=getprev(cprev)
+ else
+ break
+ end
end
- local done=false
- if lookaheaddisc then
- local cf=start
- local cl=getprev(lookaheaddisc)
- local cprev=getprev(start)
- local insertedmarks=0
- while cprev do
- local char=ischar(cf,currentfont)
- if char and marks[char] then
- insertedmarks=insertedmarks+1
- cf=cprev
- startishead=cf==head
- cprev=getprev(cprev)
- else
- break
- end
- end
- setlink(cprev,lookaheaddisc)
- setprev(cf)
- setnext(cl)
- if startishead then
- head=lookaheaddisc
- end
- local pre,post,replace=getdisc(lookaheaddisc)
- local new=copy_node_list(cf)
- local cnew=new
- if pre then
- setlink(find_node_tail(cf),pre)
- end
- if replace then
- local tail=find_node_tail(new)
- setlink(tail,replace)
- end
- for i=1,insertedmarks do
- cnew=getnext(cnew)
- end
- cl=start
- local clast=cnew
- for i=f,l do
- cl=getnext(cl)
- clast=getnext(clast)
- end
- if not notmatchpre[lookaheaddisc] then
- local ok=false
- cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck)
- if ok then
- done=true
- end
- end
- if not notmatchreplace[lookaheaddisc] then
- local ok=false
- new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck)
- if ok then
- done=true
- end
+ setlink(cprev,lookaheaddisc)
+ setprev(cf)
+ setnext(cl)
+ if startishead then
+ head=lookaheaddisc
+ end
+ local pre,post,replace=getdisc(lookaheaddisc)
+ local new=copy_node_list(cf)
+ local cnew=new
+ if pre then
+ setlink(find_node_tail(cf),pre)
+ end
+ if replace then
+ local tail=find_node_tail(new)
+ setlink(tail,replace)
+ end
+ for i=1,insertedmarks do
+ cnew=getnext(cnew)
+ end
+ cl=start
+ local clast=cnew
+ for i=f,l do
+ cl=getnext(cl)
+ clast=getnext(clast)
+ end
+ if not notmatchpre[lookaheaddisc] then
+ local ok=false
+ cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ if not notmatchreplace[lookaheaddisc] then
+ local ok=false
+ new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ if hasglue then
+ setdiscchecked(lookaheaddisc,cf,post,new)
+ else
+ setdisc(lookaheaddisc,cf,post,new)
+ end
+ start=getprev(lookaheaddisc)
+ sweephead[cf]=getnext(clast) or false
+ sweephead[new]=getnext(cl) or false
+ elseif backtrackdisc then
+ local cf=getnext(backtrackdisc)
+ local cl=start
+ local cnext=getnext(start)
+ local insertedmarks=0
+ while cnext do
+ local char=ischar(cnext,currentfont)
+ if char and marks[char] then
+ insertedmarks=insertedmarks+1
+ cl=cnext
+ cnext=getnext(cnext)
+ else
+ break
+ end
+ end
+ setlink(backtrackdisc,cnext)
+ setprev(cf)
+ setnext(cl)
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true)
+ local new=copy_node_list(cf)
+ local cnew=find_node_tail(new)
+ for i=1,insertedmarks do
+ cnew=getprev(cnew)
+ end
+ local clast=cnew
+ for i=f,l do
+ clast=getnext(clast)
+ end
+ if not notmatchpost[backtrackdisc] then
+ local ok=false
+ cf,start,ok=chainrun(cf,start,last,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ if not notmatchreplace[backtrackdisc] then
+ local ok=false
+ new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ if post then
+ setlink(posttail,cf)
+ else
+ post=cf
+ end
+ if replace then
+ setlink(replacetail,new)
+ else
+ replace=new
+ end
+ if hasglue then
+ setdiscchecked(backtrackdisc,pre,post,replace)
+ else
+ setdisc(backtrackdisc,pre,post,replace)
+ end
+ start=getprev(backtrackdisc)
+ sweephead[post]=getnext(clast) or false
+ sweephead[replace]=getnext(last) or false
+ else
+ local ok=false
+ head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
+ if ok then
+ done=true
+ end
+ end
+ return head,start,done
+end
+local function chaintrac(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode)
+ local rule=ck[1]
+ local lookuptype=ck[8] or ck[2]
+ local nofseq=#ck[3]
+ local first=ck[4]
+ local last=ck[5]
+ local char=getchar(start)
+ logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping",
+ cref(dataset,sequence),rule,match and "matches" or "nomatch",
+ gref(char),first-1,last-first+1,nofseq-last,lookuptype,
+ discseen and "" or "no ",sweepnode and "" or "not ")
+end
+local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash)
+ local sweepnode=sweepnode
+ local sweeptype=sweeptype
+ local postreplace
+ local prereplace
+ local checkdisc
+ local discseen
+ if sweeptype then
+ if sweeptype=="replace" then
+ postreplace=true
+ prereplace=true
+ else
+ postreplace=sweeptype=="post"
+ prereplace=sweeptype=="pre"
+ end
+ checkdisc=getprev(head)
+ end
+ local currentfont=currentfont
+ local skipped
+ local startprev,
+ startnext=getboth(start)
+ local done
+ local nofcontexts=contexts.n
+ local startchar=nofcontext==1 or ischar(start,currentfont)
+ for k=1,nofcontexts do
+ local ck=contexts[k]
+ local seq=ck[3]
+ local f=ck[4]
+ if not startchar or not seq[f][startchar] then
+ goto next
+ end
+ local s=seq.n
+ local l=ck[5]
+ local current=start
+ local last=start
+ if l>f then
+ local discfound
+ local n=f+1
+ last=startnext
+ while n<=l do
+ if postreplace and not last then
+ last=getnext(sweepnode)
+ sweeptype=nil
end
- if hasglue then
- setdiscchecked(lookaheaddisc,cf,post,new)
- else
- setdisc(lookaheaddisc,cf,post,new)
- end
- start=getprev(lookaheaddisc)
- sweephead[cf]=getnext(clast) or false
- sweephead[new]=getnext(cl) or false
- elseif backtrackdisc then
- local cf=getnext(backtrackdisc)
- local cl=start
- local cnext=getnext(start)
- local insertedmarks=0
- while cnext do
- local char=ischar(cnext,currentfont)
- if char and marks[char] then
- insertedmarks=insertedmarks+1
- cl=cnext
- cnext=getnext(cnext)
- else
+ if last then
+ local char,id=ischar(last,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped=true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ last=getnext(last)
+ elseif seq[n][char] then
+ if n<l then
+ last=getnext(last)
+ end
+ n=n+1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
break
+ end
+ else
+ goto next
end
- end
- setlink(backtrackdisc,cnext)
- setprev(cf)
- setnext(cl)
- local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true)
- local new=copy_node_list(cf)
- local cnew=find_node_tail(new)
- for i=1,insertedmarks do
- cnew=getprev(cnew)
- end
- local clast=cnew
- for i=f,l do
- clast=getnext(clast)
- end
- if not notmatchpost[backtrackdisc] then
- local ok=false
- cf,start,ok=chainrun(cf,start,last,dataset,sequence,rlmode,skiphash,ck)
- if ok then
- done=true
+ elseif char==false then
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif id==disc_code then
+ discseen=true
+ discfound=last
+ notmatchpre[last]=nil
+ notmatchpost[last]=true
+ notmatchreplace[last]=nil
+ local pre,post,replace=getdisc(last)
+ if pre then
+ local n=n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n=n+1
+ if n>l then
+ break
+ end
+ pre=getnext(pre)
+ else
+ notmatchpre[last]=true
+ break
+ end
+ end
+ else
+ notmatchpre[last]=true
end
- end
- if not notmatchreplace[backtrackdisc] then
- local ok=false
- new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck)
- if ok then
- done=true
+ if replace then
+ while replace do
+ if seq[n][getchar(replace)] then
+ n=n+1
+ if n>l then
+ break
+ end
+ replace=getnext(replace)
+ else
+ notmatchreplace[last]=true
+ if notmatchpre[last] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ if notmatchpre[last] then
+ goto next
+ end
end
- end
- if post then
- setlink(posttail,cf)
- else
- post=cf
- end
- if replace then
- setlink(replacetail,new)
- else
- replace=new
- end
- if hasglue then
- setdiscchecked(backtrackdisc,pre,post,replace)
+ last=getnext(last)
+ else
+ goto next
+ end
else
- setdisc(backtrackdisc,pre,post,replace)
- end
- start=getprev(backtrackdisc)
- sweephead[post]=getnext(clast) or false
- sweephead[replace]=getnext(last) or false
- else
- local ok=false
- head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
- if ok then
- done=true
+ goto next
end
+ end
end
- return head,start,done
-end
-local function chaintrac(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode)
- local rule=ck[1]
- local lookuptype=ck[8] or ck[2]
- local nofseq=#ck[3]
- local first=ck[4]
- local last=ck[5]
- local char=getchar(start)
- logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping",
- cref(dataset,sequence),rule,match and "matches" or "nomatch",
- gref(char),first-1,last-first+1,nofseq-last,lookuptype,
- discseen and "" or "no ",sweepnode and "" or "not ")
-end
-local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash)
- local sweepnode=sweepnode
- local sweeptype=sweeptype
- local postreplace
- local prereplace
- local checkdisc
- local discseen
- if sweeptype then
- if sweeptype=="replace" then
- postreplace=true
- prereplace=true
- else
- postreplace=sweeptype=="post"
- prereplace=sweeptype=="pre"
- end
- checkdisc=getprev(head)
- end
- local currentfont=currentfont
- local skipped
- local startprev,
- startnext=getboth(start)
- local done
- local nofcontexts=contexts.n
- local startchar=nofcontext==1 or ischar(start,currentfont)
- for k=1,nofcontexts do
- local ck=contexts[k]
- local seq=ck[3]
- local f=ck[4]
- if not startchar or not seq[f][startchar] then
- goto next
+ if f>1 then
+ if startprev then
+ local prev=startprev
+ if prereplace and prev==checkdisc then
+ prev=getprev(sweepnode)
end
- local s=seq.n
- local l=ck[5]
- local current=start
- local last=start
- if l>f then
- local discfound
- local n=f+1
- last=startnext
- while n<=l do
- if postreplace and not last then
- last=getnext(sweepnode)
- sweeptype=nil
+ if prev then
+ local discfound
+ local n=f-1
+ while n>=1 do
+ if prev then
+ local char,id=ischar(prev,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped=true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
+ end
+ prev=getprev(prev)
+ elseif seq[n][char] then
+ if n>1 then
+ prev=getprev(prev)
+ end
+ n=n-1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpost[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
end
- if last then
- local char,id=ischar(last,currentfont)
- if char then
- if skiphash and skiphash[char] then
- skipped=true
- if trace_skips then
- show_skip(dataset,sequence,char,ck,classes[char])
- end
- last=getnext(last)
- elseif seq[n][char] then
- if n<l then
- last=getnext(last)
- end
- n=n+1
- elseif discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
- goto next
- else
- break
- end
+ elseif char==false then
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpost[discfound] then
+ goto next
+ end
+ else
+ goto next
+ end
+ break
+ elseif id==disc_code then
+ discseen=true
+ discfound=prev
+ notmatchpre[prev]=true
+ notmatchpost[prev]=nil
+ notmatchreplace[prev]=nil
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true)
+ if pre~=start and post~=start and replace~=start then
+ if post then
+ local n=n
+ while posttail do
+ if seq[n][getchar(posttail)] then
+ n=n-1
+ if posttail==post or n<1 then
+ break
else
- goto next
+ posttail=getprev(posttail)
end
- elseif char==false then
- if discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
- goto next
- else
- break
- end
+ else
+ notmatchpost[prev]=true
+ break
+ end
+ end
+ if n>=1 then
+ notmatchpost[prev]=true
+ end
+ else
+ notmatchpost[prev]=true
+ end
+ if replace then
+ while replacetail do
+ if seq[n][getchar(replacetail)] then
+ n=n-1
+ if replacetail==replace or n<1 then
+ break
else
- goto next
+ replacetail=getprev(replacetail)
end
- elseif id==disc_code then
- discseen=true
- discfound=last
- notmatchpre[last]=nil
- notmatchpost[last]=true
- notmatchreplace[last]=nil
- local pre,post,replace=getdisc(last)
- if pre then
- local n=n
- while pre do
- if seq[n][getchar(pre)] then
- n=n+1
- if n>l then
- break
- end
- pre=getnext(pre)
- else
- notmatchpre[last]=true
- break
- end
- end
+ else
+ notmatchreplace[prev]=true
+ if notmatchpost[prev] then
+ goto next
else
- notmatchpre[last]=true
- end
- if replace then
- while replace do
- if seq[n][getchar(replace)] then
- n=n+1
- if n>l then
- break
- end
- replace=getnext(replace)
- else
- notmatchreplace[last]=true
- if notmatchpre[last] then
- goto next
- else
- break
- end
- end
- end
- if notmatchpre[last] then
- goto next
- end
+ break
end
- last=getnext(last)
- else
- goto next
+ end
end
+ else
+ notmatchreplace[prev]=true
+ end
+ end
+ prev=getprev(prev)
+ elseif id==glue_code then
+ local sn=seq[n]
+ if (sn[32] and spaces[prev]) or sn[0xFFFC] then
+ n=n-1
+ prev=getprev(prev)
else
- goto next
+ goto next
end
+ elseif seq[n][0xFFFC] then
+ n=n-1
+ prev=getprev(prev)
+ else
+ goto next
+ end
+ else
+ goto next
end
- end
- if f>1 then
- if startprev then
- local prev=startprev
- if prereplace and prev==checkdisc then
- prev=getprev(sweepnode)
+ end
+ else
+ goto next
+ end
+ else
+ goto next
+ end
+ end
+ if s>l then
+ local current=last and getnext(last)
+ if not current and postreplace then
+ current=getnext(sweepnode)
+ end
+ if current then
+ local discfound
+ local n=l+1
+ while n<=s do
+ if current then
+ local char,id=ischar(current,currentfont)
+ if char then
+ if skiphash and skiphash[char] then
+ skipped=true
+ if trace_skips then
+ show_skip(dataset,sequence,char,ck,classes[char])
end
- if prev then
- local discfound
- local n=f-1
- while n>=1 do
- if prev then
- local char,id=ischar(prev,currentfont)
- if char then
- if skiphash and skiphash[char] then
- skipped=true
- if trace_skips then
- show_skip(dataset,sequence,char,ck,classes[char])
- end
- prev=getprev(prev)
- elseif seq[n][char] then
- if n>1 then
- prev=getprev(prev)
- end
- n=n-1
- elseif discfound then
- notmatchreplace[discfound]=true
- if notmatchpost[discfound] then
- goto next
- else
- break
- end
- else
- goto next
- end
- elseif char==false then
- if discfound then
- notmatchreplace[discfound]=true
- if notmatchpost[discfound] then
- goto next
- end
- else
- goto next
- end
- break
- elseif id==disc_code then
- discseen=true
- discfound=prev
- notmatchpre[prev]=true
- notmatchpost[prev]=nil
- notmatchreplace[prev]=nil
- local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true)
- if pre~=start and post~=start and replace~=start then
- if post then
- local n=n
- while posttail do
- if seq[n][getchar(posttail)] then
- n=n-1
- if posttail==post or n<1 then
- break
- else
- posttail=getprev(posttail)
- end
- else
- notmatchpost[prev]=true
- break
- end
- end
- if n>=1 then
- notmatchpost[prev]=true
- end
- else
- notmatchpost[prev]=true
- end
- if replace then
- while replacetail do
- if seq[n][getchar(replacetail)] then
- n=n-1
- if replacetail==replace or n<1 then
- break
- else
- replacetail=getprev(replacetail)
- end
- else
- notmatchreplace[prev]=true
- if notmatchpost[prev] then
- goto next
- else
- break
- end
- end
- end
- else
- notmatchreplace[prev]=true
- end
- end
- prev=getprev(prev)
- elseif id==glue_code then
- local sn=seq[n]
- if (sn[32] and spaces[prev]) or sn[0xFFFC] then
- n=n-1
- prev=getprev(prev)
- else
- goto next
- end
- elseif seq[n][0xFFFC] then
- n=n-1
- prev=getprev(prev)
- else
- goto next
- end
- else
- goto next
- end
- end
+ current=getnext(current)
+ elseif seq[n][char] then
+ if n<s then
+ current=getnext(current)
+ end
+ n=n+1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
else
- goto next
+ break
end
- else
+ else
goto next
- end
- end
- if s>l then
- local current=last and getnext(last)
- if not current and postreplace then
- current=getnext(sweepnode)
- end
- if current then
- local discfound
- local n=l+1
- while n<=s do
- if current then
- local char,id=ischar(current,currentfont)
- if char then
- if skiphash and skiphash[char] then
- skipped=true
- if trace_skips then
- show_skip(dataset,sequence,char,ck,classes[char])
- end
- current=getnext(current)
- elseif seq[n][char] then
- if n<s then
- current=getnext(current)
- end
- n=n+1
- elseif discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
- goto next
- else
- break
- end
- else
- goto next
- end
- elseif char==false then
- if discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
- goto next
- else
- break
- end
- else
- goto next
- end
- elseif id==disc_code then
- discseen=true
- discfound=current
- notmatchpre[current]=nil
- notmatchpost[current]=true
- notmatchreplace[current]=nil
- local pre,post,replace=getdisc(current)
- if pre then
- local n=n
- while pre do
- if seq[n][getchar(pre)] then
- n=n+1
- if n>s then
- break
- else
- pre=getnext(pre)
- end
- else
- notmatchpre[current]=true
- break
- end
- end
- if n<=s then
- notmatchpre[current]=true
- end
- else
- notmatchpre[current]=true
- end
- if replace then
- while replace do
- if seq[n][getchar(replace)] then
- n=n+1
- if n>s then
- break
- else
- replace=getnext(replace)
- end
- else
- notmatchreplace[current]=true
- if notmatchpre[current] then
- goto next
- else
- break
- end
- end
- end
- else
- notmatchreplace[current]=true
- end
- current=getnext(current)
- elseif id==glue_code then
- local sn=seq[n]
- if (sn[32] and spaces[current]) or sn[0xFFFC] then
- n=n+1
- current=getnext(current)
- else
- goto next
- end
- elseif seq[n][0xFFFC] then
- n=n+1
- current=getnext(current)
- else
- goto next
- end
+ end
+ elseif char==false then
+ if discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
+ break
+ end
+ else
+ goto next
+ end
+ elseif id==disc_code then
+ discseen=true
+ discfound=current
+ notmatchpre[current]=nil
+ notmatchpost[current]=true
+ notmatchreplace[current]=nil
+ local pre,post,replace=getdisc(current)
+ if pre then
+ local n=n
+ while pre do
+ if seq[n][getchar(pre)] then
+ n=n+1
+ if n>s then
+ break
else
- goto next
+ pre=getnext(pre)
end
+ else
+ notmatchpre[current]=true
+ break
+ end
end
- else
+ if n<=s then
+ notmatchpre[current]=true
+ end
+ else
+ notmatchpre[current]=true
+ end
+ if replace then
+ while replace do
+ if seq[n][getchar(replace)] then
+ n=n+1
+ if n>s then
+ break
+ else
+ replace=getnext(replace)
+ end
+ else
+ notmatchreplace[current]=true
+ if notmatchpre[current] then
+ goto next
+ else
+ break
+ end
+ end
+ end
+ else
+ notmatchreplace[current]=true
+ end
+ current=getnext(current)
+ elseif id==glue_code then
+ local sn=seq[n]
+ if (sn[32] and spaces[current]) or sn[0xFFFC] then
+ n=n+1
+ current=getnext(current)
+ else
goto next
+ end
+ elseif seq[n][0xFFFC] then
+ n=n+1
+ current=getnext(current)
+ else
+ goto next
end
+ else
+ goto next
+ end
end
- if trace_contexts then
- chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode)
- end
- if discseen or sweepnode then
- head,start,done=chaindisk(head,start,dataset,sequence,rlmode,skipped and skiphash,ck)
- else
- head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck)
- end
- if done then
- break
- end
- ::next::
+ else
+ goto next
+ end
end
- if discseen then
- notmatchpre={}
- notmatchpost={}
- notmatchreplace={}
+ if trace_contexts then
+ chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode)
end
- return head,start,done
+ if discseen or sweepnode then
+ head,start,done=chaindisk(head,start,dataset,sequence,rlmode,skipped and skiphash,ck)
+ else
+ head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck)
+ end
+ if done then
+ break
+ end
+ ::next::
+ end
+ if discseen then
+ notmatchpre={}
+ notmatchpost={}
+ notmatchreplace={}
+ end
+ return head,start,done
end
handlers.gsub_context=handle_contextchain
handlers.gsub_contextchain=handle_contextchain
@@ -27777,17 +27777,17 @@ handlers.gsub_reversecontextchain=handle_contextchain
handlers.gpos_contextchain=handle_contextchain
handlers.gpos_context=handle_contextchain
local function chained_contextchain(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash)
- local steps=currentlookup.steps
- local nofsteps=currentlookup.nofsteps
- if nofsteps>1 then
- reportmoresteps(dataset,sequence)
- end
- local l=steps[1].coverage[getchar(start)]
- if l then
- return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash)
- else
- return head,start,false
- end
+ local steps=currentlookup.steps
+ local nofsteps=currentlookup.nofsteps
+ if nofsteps>1 then
+ reportmoresteps(dataset,sequence)
+ end
+ local l=steps[1].coverage[getchar(start)]
+ if l then
+ return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash)
+ else
+ return head,start,false
+ end
end
chainprocs.gsub_context=chained_contextchain
chainprocs.gsub_contextchain=chained_contextchain
@@ -27798,1270 +27798,1270 @@ local missing=setmetatableindex("table")
local logwarning=report_process
local resolved={}
local function logprocess(...)
- if trace_steps then
- registermessage(...)
- if trace_steps=="silent" then
- return
- end
+ if trace_steps then
+ registermessage(...)
+ if trace_steps=="silent" then
+ return
end
- report_process(...)
+ end
+ report_process(...)
end
local sequencelists=setmetatableindex(function(t,font)
- local sequences=fontdata[font].resources.sequences
- if not sequences or not next(sequences) then
- sequences=false
- end
- t[font]=sequences
- return sequences
+ local sequences=fontdata[font].resources.sequences
+ if not sequences or not next(sequences) then
+ sequences=false
+ end
+ t[font]=sequences
+ return sequences
end)
do
- local autofeatures=fonts.analyzers.features
- local featuretypes=otf.tables.featuretypes
- local defaultscript=otf.features.checkeddefaultscript
- local defaultlanguage=otf.features.checkeddefaultlanguage
- local wildcard="*"
- local default="dflt"
- local function initialize(sequence,script,language,enabled,autoscript,autolanguage)
- local features=sequence.features
- if features then
- local order=sequence.order
- if order then
- local featuretype=featuretypes[sequence.type or "unknown"]
- for i=1,#order do
- local kind=order[i]
- local valid=enabled[kind]
- if valid then
- local scripts=features[kind]
- local languages=scripts and (
- scripts[script] or
- scripts[wildcard] or
- (autoscript and defaultscript(featuretype,autoscript,scripts))
- )
- local enabled=languages and (
- languages[language] or
- languages[wildcard] or
- (autolanguage and defaultlanguage(featuretype,autolanguage,languages))
- )
- if enabled then
- return { valid,autofeatures[kind] or false,sequence,kind }
- end
- end
- end
- else
+ local autofeatures=fonts.analyzers.features
+ local featuretypes=otf.tables.featuretypes
+ local defaultscript=otf.features.checkeddefaultscript
+ local defaultlanguage=otf.features.checkeddefaultlanguage
+ local wildcard="*"
+ local default="dflt"
+ local function initialize(sequence,script,language,enabled,autoscript,autolanguage)
+ local features=sequence.features
+ if features then
+ local order=sequence.order
+ if order then
+ local featuretype=featuretypes[sequence.type or "unknown"]
+ for i=1,#order do
+ local kind=order[i]
+ local valid=enabled[kind]
+ if valid then
+ local scripts=features[kind]
+ local languages=scripts and (
+ scripts[script] or
+ scripts[wildcard] or
+ (autoscript and defaultscript(featuretype,autoscript,scripts))
+ )
+ local enabled=languages and (
+ languages[language] or
+ languages[wildcard] or
+ (autolanguage and defaultlanguage(featuretype,autolanguage,languages))
+ )
+ if enabled then
+ return { valid,autofeatures[kind] or false,sequence,kind }
end
+ end
end
- return false
+ else
+ end
end
- function otf.dataset(tfmdata,font)
- local shared=tfmdata.shared
- local properties=tfmdata.properties
- local language=properties.language or "dflt"
- local script=properties.script or "dflt"
- local enabled=shared.features
- local autoscript=enabled and enabled.autoscript
- local autolanguage=enabled and enabled.autolanguage
- local res=resolved[font]
- if not res then
- res={}
- resolved[font]=res
- end
- local rs=res[script]
- if not rs then
- rs={}
- res[script]=rs
- end
- local rl=rs[language]
- if not rl then
- rl={
- }
- rs[language]=rl
- local sequences=tfmdata.resources.sequences
- if sequences then
- for s=1,#sequences do
- local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage)
- if v then
- rl[#rl+1]=v
- end
- end
- end
+ return false
+ end
+ function otf.dataset(tfmdata,font)
+ local shared=tfmdata.shared
+ local properties=tfmdata.properties
+ local language=properties.language or "dflt"
+ local script=properties.script or "dflt"
+ local enabled=shared.features
+ local autoscript=enabled and enabled.autoscript
+ local autolanguage=enabled and enabled.autolanguage
+ local res=resolved[font]
+ if not res then
+ res={}
+ resolved[font]=res
+ end
+ local rs=res[script]
+ if not rs then
+ rs={}
+ res[script]=rs
+ end
+ local rl=rs[language]
+ if not rl then
+ rl={
+ }
+ rs[language]=rl
+ local sequences=tfmdata.resources.sequences
+ if sequences then
+ for s=1,#sequences do
+ local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage)
+ if v then
+ rl[#rl+1]=v
+ end
end
- return rl
+ end
end
+ return rl
+ end
end
local function report_disc(what,n)
- report_run("%s: %s > %s",what,n,languages.serializediscretionary(n))
+ report_run("%s: %s > %s",what,n,languages.serializediscretionary(n))
end
local function kernrun(disc,k_run,font,attr,...)
- if trace_kernruns then
- report_disc("kern",disc)
- end
- local prev,next=getboth(disc)
- local nextstart=next
- local done=false
- local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
- local prevmarks=prev
- while prevmarks do
- local char=ischar(prevmarks,font)
- if char and marks[char] then
- prevmarks=getprev(prevmarks)
- else
- break
- end
- end
- if prev and not ischar(prev,font) then
- prev=false
- end
- if next and not ischar(next,font) then
- next=false
- end
- if pre then
- if k_run(pre,"injections",nil,font,attr,...) then
- done=true
- end
- if prev then
- setlink(prev,pre)
- if k_run(prevmarks,"preinjections",pre,font,attr,...) then
- done=true
- end
- setprev(pre)
- setlink(prev,disc)
- end
- end
- if post then
- if k_run(post,"injections",nil,font,attr,...) then
- done=true
- end
- if next then
- setlink(posttail,next)
- if k_run(posttail,"postinjections",next,font,attr,...) then
- done=true
- end
- setnext(posttail)
- setlink(disc,next)
- end
- end
- if replace then
- if k_run(replace,"injections",nil,font,attr,...) then
- done=true
- end
- if prev then
- setlink(prev,replace)
- if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then
- done=true
- end
- setprev(replace)
- setlink(prev,disc)
- end
- if next then
- setlink(replacetail,next)
- if k_run(replacetail,"replaceinjections",next,font,attr,...) then
- done=true
- end
- setnext(replacetail)
- setlink(disc,next)
- end
- elseif prev and next then
- setlink(prev,next)
- if k_run(prevmarks,"emptyinjections",next,font,attr,...) then
- done=true
- end
- setlink(prev,disc,next)
- end
- if done and trace_testruns then
- report_disc("done",disc)
- end
- return nextstart,done
+ if trace_kernruns then
+ report_disc("kern",disc)
+ end
+ local prev,next=getboth(disc)
+ local nextstart=next
+ local done=false
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
+ local prevmarks=prev
+ while prevmarks do
+ local char=ischar(prevmarks,font)
+ if char and marks[char] then
+ prevmarks=getprev(prevmarks)
+ else
+ break
+ end
+ end
+ if prev and not ischar(prev,font) then
+ prev=false
+ end
+ if next and not ischar(next,font) then
+ next=false
+ end
+ if pre then
+ if k_run(pre,"injections",nil,font,attr,...) then
+ done=true
+ end
+ if prev then
+ setlink(prev,pre)
+ if k_run(prevmarks,"preinjections",pre,font,attr,...) then
+ done=true
+ end
+ setprev(pre)
+ setlink(prev,disc)
+ end
+ end
+ if post then
+ if k_run(post,"injections",nil,font,attr,...) then
+ done=true
+ end
+ if next then
+ setlink(posttail,next)
+ if k_run(posttail,"postinjections",next,font,attr,...) then
+ done=true
+ end
+ setnext(posttail)
+ setlink(disc,next)
+ end
+ end
+ if replace then
+ if k_run(replace,"injections",nil,font,attr,...) then
+ done=true
+ end
+ if prev then
+ setlink(prev,replace)
+ if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then
+ done=true
+ end
+ setprev(replace)
+ setlink(prev,disc)
+ end
+ if next then
+ setlink(replacetail,next)
+ if k_run(replacetail,"replaceinjections",next,font,attr,...) then
+ done=true
+ end
+ setnext(replacetail)
+ setlink(disc,next)
+ end
+ elseif prev and next then
+ setlink(prev,next)
+ if k_run(prevmarks,"emptyinjections",next,font,attr,...) then
+ done=true
+ end
+ setlink(prev,disc,next)
+ end
+ if done and trace_testruns then
+ report_disc("done",disc)
+ end
+ return nextstart,done
end
local function comprun(disc,c_run,...)
- if trace_compruns then
- report_disc("comp",disc)
- end
- local pre,post,replace=getdisc(disc)
- local renewed=false
- if pre then
- sweepnode=disc
- sweeptype="pre"
- local new,done=c_run(pre,...)
- if done then
- pre=new
- renewed=true
- end
- end
- if post then
- sweepnode=disc
- sweeptype="post"
- local new,done=c_run(post,...)
- if done then
- post=new
- renewed=true
- end
- end
- if replace then
- sweepnode=disc
- sweeptype="replace"
- local new,done=c_run(replace,...)
- if done then
- replace=new
- renewed=true
- end
- end
- sweepnode=nil
- sweeptype=nil
- if renewed then
- if trace_testruns then
- report_disc("done",disc)
- end
- setdisc(disc,pre,post,replace)
+ if trace_compruns then
+ report_disc("comp",disc)
+ end
+ local pre,post,replace=getdisc(disc)
+ local renewed=false
+ if pre then
+ sweepnode=disc
+ sweeptype="pre"
+ local new,done=c_run(pre,...)
+ if done then
+ pre=new
+ renewed=true
+ end
+ end
+ if post then
+ sweepnode=disc
+ sweeptype="post"
+ local new,done=c_run(post,...)
+ if done then
+ post=new
+ renewed=true
+ end
+ end
+ if replace then
+ sweepnode=disc
+ sweeptype="replace"
+ local new,done=c_run(replace,...)
+ if done then
+ replace=new
+ renewed=true
+ end
+ end
+ sweepnode=nil
+ sweeptype=nil
+ if renewed then
+ if trace_testruns then
+ report_disc("done",disc)
end
- return getnext(disc),renewed
+ setdisc(disc,pre,post,replace)
+ end
+ return getnext(disc),renewed
end
local function testrun(disc,t_run,c_run,...)
- if trace_testruns then
- report_disc("test",disc)
- end
- local prev,next=getboth(disc)
- if not next then
- return
- end
- local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
- local renewed=false
- if (post or replace) and prev then
- if post then
- setlink(posttail,next)
- else
- post=next
- end
- if replace then
- setlink(replacetail,next)
- else
- replace=next
- end
- local d_post=t_run(post,next,...)
- local d_replace=t_run(replace,next,...)
- if d_post>0 or d_replace>0 then
- local d=d_replace>d_post and d_replace or d_post
- local head=getnext(disc)
- local tail=head
- for i=1,d do
- local nx=getnext(tail)
- local id=getid(nx)
- if id==disc_code then
- head,tail=flattendisk(head,nx)
- elseif id==glyph_code then
- tail=nx
- else
- break
- end
- end
- next=getnext(tail)
- setnext(tail)
- setprev(head)
- local new=copy_node_list(head)
- if posttail then
- setlink(posttail,head)
- else
- post=head
- end
- if replacetail then
- setlink(replacetail,new)
- else
- replace=new
- end
- else
- if posttail then
- setnext(posttail)
- else
- post=nil
- end
- if replacetail then
- setnext(replacetail)
- else
- replace=nil
- end
- end
- setlink(disc,next)
- end
- if trace_testruns then
- report_disc("more",disc)
- end
- if pre then
- sweepnode=disc
- sweeptype="pre"
- local new,ok=c_run(pre,...)
- if ok then
- pre=new
- renewed=true
- end
- end
+ if trace_testruns then
+ report_disc("test",disc)
+ end
+ local prev,next=getboth(disc)
+ if not next then
+ return
+ end
+ local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
+ local renewed=false
+ if (post or replace) and prev then
if post then
- sweepnode=disc
- sweeptype="post"
- local new,ok=c_run(post,...)
- if ok then
- post=new
- renewed=true
- end
+ setlink(posttail,next)
+ else
+ post=next
end
if replace then
- sweepnode=disc
- sweeptype="replace"
- local new,ok=c_run(replace,...)
- if ok then
- replace=new
- renewed=true
- end
+ setlink(replacetail,next)
+ else
+ replace=next
+ end
+ local d_post=t_run(post,next,...)
+ local d_replace=t_run(replace,next,...)
+ if d_post>0 or d_replace>0 then
+ local d=d_replace>d_post and d_replace or d_post
+ local head=getnext(disc)
+ local tail=head
+ for i=1,d do
+ local nx=getnext(tail)
+ local id=getid(nx)
+ if id==disc_code then
+ head,tail=flattendisk(head,nx)
+ elseif id==glyph_code then
+ tail=nx
+ else
+ break
+ end
+ end
+ next=getnext(tail)
+ setnext(tail)
+ setprev(head)
+ local new=copy_node_list(head)
+ if posttail then
+ setlink(posttail,head)
+ else
+ post=head
+ end
+ if replacetail then
+ setlink(replacetail,new)
+ else
+ replace=new
+ end
+ else
+ if posttail then
+ setnext(posttail)
+ else
+ post=nil
+ end
+ if replacetail then
+ setnext(replacetail)
+ else
+ replace=nil
+ end
+ end
+ setlink(disc,next)
+ end
+ if trace_testruns then
+ report_disc("more",disc)
+ end
+ if pre then
+ sweepnode=disc
+ sweeptype="pre"
+ local new,ok=c_run(pre,...)
+ if ok then
+ pre=new
+ renewed=true
+ end
+ end
+ if post then
+ sweepnode=disc
+ sweeptype="post"
+ local new,ok=c_run(post,...)
+ if ok then
+ post=new
+ renewed=true
+ end
+ end
+ if replace then
+ sweepnode=disc
+ sweeptype="replace"
+ local new,ok=c_run(replace,...)
+ if ok then
+ replace=new
+ renewed=true
end
- sweepnode=nil
- sweeptype=nil
- if renewed then
- setdisc(disc,pre,post,replace)
- if trace_testruns then
- report_disc("done",disc)
- end
+ end
+ sweepnode=nil
+ sweeptype=nil
+ if renewed then
+ setdisc(disc,pre,post,replace)
+ if trace_testruns then
+ report_disc("done",disc)
end
- return getnext(disc),renewed
+ end
+ return getnext(disc),renewed
end
local nesting=0
local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
- local done=false
- local sweep=sweephead[head]
- if sweep then
- start=sweep
- sweephead[head]=false
- else
- start=head
- end
- while start do
- local char,id=ischar(start,font)
- if char then
- local a
- if attr then
- a=getattr(start,0)
- end
- if not a or (a==attr) then
- local lookupmatch=lookupcache[char]
- if lookupmatch then
- local ok
- head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
- if ok then
- done=true
- end
- end
- if start then
- start=getnext(start)
- end
- else
- start=getnext(start)
- end
- elseif char==false then
- return head,done
- elseif sweep then
- return head,done
- else
- start=getnext(start)
+ local done=false
+ local sweep=sweephead[head]
+ if sweep then
+ start=sweep
+ sweephead[head]=false
+ else
+ start=head
+ end
+ while start do
+ local char,id=ischar(start,font)
+ if char then
+ local a
+ if attr then
+ a=getattr(start,0)
+ end
+ if not a or (a==attr) then
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ done=true
+ end
+ end
+ if start then
+ start=getnext(start)
end
+ else
+ start=getnext(start)
+ end
+ elseif char==false then
+ return head,done
+ elseif sweep then
+ return head,done
+ else
+ start=getnext(start)
end
- return head,done
+ end
+ return head,done
end
local function t_run_single(start,stop,font,attr,lookupcache)
- local lastd=nil
- while start~=stop do
- local char=ischar(start,font)
- if char then
- local a
- if attr then
- a=getattr(start,0)
+ local lastd=nil
+ while start~=stop do
+ local char=ischar(start,font)
+ if char then
+ local a
+ if attr then
+ a=getattr(start,0)
+ end
+ local startnext=getnext(start)
+ if not a or (a==attr) then
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local s=startnext
+ local ss=nil
+ local sstop=s==stop
+ if not s then
+ s=ss
+ ss=nil
+ end
+ while getid(s)==disc_code do
+ ss=getnext(s)
+ s=getfield(s,"replace")
+ if not s then
+ s=ss
+ ss=nil
end
- local startnext=getnext(start)
- if not a or (a==attr) then
- local lookupmatch=lookupcache[char]
- if lookupmatch then
- local s=startnext
- local ss=nil
- local sstop=s==stop
- if not s then
- s=ss
- ss=nil
- end
- while getid(s)==disc_code do
- ss=getnext(s)
- s=getfield(s,"replace")
- if not s then
- s=ss
- ss=nil
- end
- end
- local l=nil
- local d=0
- while s do
- local char=ischar(s,font)
- if char then
- local lg=lookupmatch[char]
- if lg then
- if sstop then
- d=1
- elseif d>0 then
- d=d+1
- end
- l=lg
- s=getnext(s)
- sstop=s==stop
- if not s then
- s=ss
- ss=nil
- end
- while getid(s)==disc_code do
- ss=getnext(s)
- s=getfield(s,"replace")
- if not s then
- s=ss
- ss=nil
- end
- end
- else
- break
- end
- else
- break
- end
- end
- if l and l.ligature then
- lastd=d
- end
- else
- end
+ end
+ local l=nil
+ local d=0
+ while s do
+ local char=ischar(s,font)
+ if char then
+ local lg=lookupmatch[char]
+ if lg then
+ if sstop then
+ d=1
+ elseif d>0 then
+ d=d+1
+ end
+ l=lg
+ s=getnext(s)
+ sstop=s==stop
+ if not s then
+ s=ss
+ ss=nil
+ end
+ while getid(s)==disc_code do
+ ss=getnext(s)
+ s=getfield(s,"replace")
+ if not s then
+ s=ss
+ ss=nil
+ end
+ end
+ else
+ break
+ end
else
+ break
end
- if lastd then
- return lastd
- end
- start=startnext
+ end
+ if l and l.ligature then
+ lastd=d
+ end
else
- break
end
+ else
+ end
+ if lastd then
+ return lastd
+ end
+ start=startnext
+ else
+ break
end
- return 0
+ end
+ return 0
end
local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
- local a
- if attr then
- a=getattr(sub,0)
- end
- if not a or (a==attr) then
- for n in nextnode,sub do
- if n==last then
- break
- end
- local char=ischar(n)
- if char then
- local lookupmatch=lookupcache[char]
- if lookupmatch then
- local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection)
- if ok then
- return true
- end
- end
- end
+ local a
+ if attr then
+ a=getattr(sub,0)
+ end
+ if not a or (a==attr) then
+ for n in nextnode,sub do
+ if n==last then
+ break
+ end
+ local char=ischar(n)
+ if char then
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection)
+ if ok then
+ return true
+ end
end
+ end
end
+ end
end
local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
- local done=false
- local sweep=sweephead[head]
- if sweep then
- start=sweep
- sweephead[head]=false
- else
- start=head
- end
- while start do
- local char=ischar(start,font)
- if char then
- local a
- if attr then
- a=getattr(start,0)
- end
- if not a or (a==attr) then
- for i=1,nofsteps do
- local step=steps[i]
- local lookupcache=step.coverage
- local lookupmatch=lookupcache[char]
- if lookupmatch then
- local ok
- head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
- if ok then
- done=true
- break
- elseif not start then
- break
- end
- end
- end
- if start then
- start=getnext(start)
- end
- else
- start=getnext(start)
+ local done=false
+ local sweep=sweephead[head]
+ if sweep then
+ start=sweep
+ sweephead[head]=false
+ else
+ start=head
+ end
+ while start do
+ local char=ischar(start,font)
+ if char then
+ local a
+ if attr then
+ a=getattr(start,0)
+ end
+ if not a or (a==attr) then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ done=true
+ break
+ elseif not start then
+ break
end
- elseif char==false then
- return head,done
- elseif sweep then
- return head,done
- else
- start=getnext(start)
+ end
+ end
+ if start then
+ start=getnext(start)
end
+ else
+ start=getnext(start)
+ end
+ elseif char==false then
+ return head,done
+ elseif sweep then
+ return head,done
+ else
+ start=getnext(start)
end
- return head,done
+ end
+ return head,done
end
local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
- local lastd=nil
- while start~=stop do
- local char=ischar(start,font)
- if char then
- local a
- if attr then
- a=getattr(start,0)
+ local lastd=nil
+ while start~=stop do
+ local char=ischar(start,font)
+ if char then
+ local a
+ if attr then
+ a=getattr(start,0)
+ end
+ local startnext=getnext(start)
+ if not a or (a==attr) then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local s=startnext
+ local ss=nil
+ local sstop=s==stop
+ if not s then
+ s=ss
+ ss=nil
+ end
+ while getid(s)==disc_code do
+ ss=getnext(s)
+ s=getfield(s,"replace")
+ if not s then
+ s=ss
+ ss=nil
+ end
end
- local startnext=getnext(start)
- if not a or (a==attr) then
- for i=1,nofsteps do
- local step=steps[i]
- local lookupcache=step.coverage
- local lookupmatch=lookupcache[char]
- if lookupmatch then
- local s=startnext
- local ss=nil
- local sstop=s==stop
- if not s then
- s=ss
- ss=nil
- end
- while getid(s)==disc_code do
- ss=getnext(s)
- s=getfield(s,"replace")
- if not s then
- s=ss
- ss=nil
- end
- end
- local l=nil
- local d=0
- while s do
- local char=ischar(s)
- if char then
- local lg=lookupmatch[char]
- if lg then
- if sstop then
- d=1
- elseif d>0 then
- d=d+1
- end
- l=lg
- s=getnext(s)
- sstop=s==stop
- if not s then
- s=ss
- ss=nil
- end
- while getid(s)==disc_code do
- ss=getnext(s)
- s=getfield(s,"replace")
- if not s then
- s=ss
- ss=nil
- end
- end
- else
- break
- end
- else
- break
- end
- end
- if l and l.ligature then
- lastd=d
- end
+ local l=nil
+ local d=0
+ while s do
+ local char=ischar(s)
+ if char then
+ local lg=lookupmatch[char]
+ if lg then
+ if sstop then
+ d=1
+ elseif d>0 then
+ d=d+1
+ end
+ l=lg
+ s=getnext(s)
+ sstop=s==stop
+ if not s then
+ s=ss
+ ss=nil
+ end
+ while getid(s)==disc_code do
+ ss=getnext(s)
+ s=getfield(s,"replace")
+ if not s then
+ s=ss
+ ss=nil
end
+ end
+ else
+ break
end
- else
+ else
+ break
+ end
end
- if lastd then
- return lastd
+ if l and l.ligature then
+ lastd=d
end
- start=startnext
- else
- break
+ end
end
+ else
+ end
+ if lastd then
+ return lastd
+ end
+ start=startnext
+ else
+ break
end
- return 0
+ end
+ return 0
end
local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
- local a
- if attr then
- a=getattr(sub,0)
- end
- if not a or (a==attr) then
- for n in nextnode,sub do
- if n==last then
- break
- end
- local char=ischar(n)
- if char then
- for i=1,nofsteps do
- local step=steps[i]
- local lookupcache=step.coverage
- local lookupmatch=lookupcache[char]
- if lookupmatch then
- local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection)
- if ok then
- return true
- end
- end
- end
+ local a
+ if attr then
+ a=getattr(sub,0)
+ end
+ if not a or (a==attr) then
+ for n in nextnode,sub do
+ if n==last then
+ break
+ end
+ local char=ischar(n)
+ if char then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection)
+ if ok then
+ return true
end
+ end
end
+ end
end
+ end
end
-local txtdirstate,pardirstate do
- local getdirection=nuts.getdirection
- local lefttoright=0
- local righttoleft=1
- txtdirstate=function(start,stack,top,rlparmode)
- local dir,pop=getdirection(start)
- if pop then
- if top==1 then
- return 0,rlparmode
- else
- top=top-1
- if stack[top]==righttoleft then
- return top,-1
- else
- return top,1
- end
- end
- elseif dir==lefttoright then
- top=top+1
- stack[top]=lefttoright
- return top,1
- elseif dir==righttoleft then
- top=top+1
- stack[top]=righttoleft
- return top,-1
- else
- return top,rlparmode
- end
- end
- pardirstate=function(start)
- local dir=getdirection(start)
- if dir==lefttoright then
- return 1,1
- elseif dir==righttoleft then
- return -1,-1
- elseif dir=="TLT" then
- return 1,1
- elseif dir=="TRT" then
- return -1,-1
+local txtdirstate,pardirstate do
+ local getdirection=nuts.getdirection
+ local lefttoright=0
+ local righttoleft=1
+ txtdirstate=function(start,stack,top,rlparmode)
+ local dir,pop=getdirection(start)
+ if pop then
+ if top==1 then
+ return 0,rlparmode
+ else
+ top=top-1
+ if stack[top]==righttoleft then
+ return top,-1
else
- return 0,0
- end
+ return top,1
+ end
+ end
+ elseif dir==lefttoright then
+ top=top+1
+ stack[top]=lefttoright
+ return top,1
+ elseif dir==righttoleft then
+ top=top+1
+ stack[top]=righttoleft
+ return top,-1
+ else
+ return top,rlparmode
+ end
+ end
+ pardirstate=function(start)
+ local dir=getdirection(start)
+ if dir==lefttoright then
+ return 1,1
+ elseif dir==righttoleft then
+ return -1,-1
+ elseif dir=="TLT" then
+ return 1,1
+ elseif dir=="TRT" then
+ return -1,-1
+ else
+ return 0,0
end
+ end
end
otf.helpers=otf.helpers or {}
otf.helpers.txtdirstate=txtdirstate
otf.helpers.pardirstate=pardirstate
do
- local fastdisc=true
- local testdics=false
- directives.register("otf.fastdisc",function(v) fastdisc=v end)
- local otfdataset=nil
- local getfastdisc={ __index=function(t,k)
- local v=usesfont(k,currentfont)
- t[k]=v
- return v
- end }
- local getfastspace={ __index=function(t,k)
- local v=isspace(k,threshold) or false
- t[k]=v
- return v
- end }
- function otf.featuresprocessor(head,font,attr,direction,n)
- local sequences=sequencelists[font]
- nesting=nesting+1
- if nesting==1 then
- currentfont=font
- tfmdata=fontdata[font]
- descriptions=tfmdata.descriptions
- characters=tfmdata.characters
+ local fastdisc=true
+ local testdics=false
+ directives.register("otf.fastdisc",function(v) fastdisc=v end)
+ local otfdataset=nil
+ local getfastdisc={ __index=function(t,k)
+ local v=usesfont(k,currentfont)
+ t[k]=v
+ return v
+ end }
+ local getfastspace={ __index=function(t,k)
+ local v=isspace(k,threshold) or false
+ t[k]=v
+ return v
+ end }
+ function otf.featuresprocessor(head,font,attr,direction,n)
+ local sequences=sequencelists[font]
+ nesting=nesting+1
+ if nesting==1 then
+ currentfont=font
+ tfmdata=fontdata[font]
+ descriptions=tfmdata.descriptions
+ characters=tfmdata.characters
local resources=tfmdata.resources
- marks=resources.marks
- classes=resources.classes
- threshold,
- factor=getthreshold(font)
- checkmarks=tfmdata.properties.checkmarks
- if not otfdataset then
- otfdataset=otf.dataset
- end
- discs=fastdisc and n and n>1 and setmetatable({},getfastdisc)
- spaces=setmetatable({},getfastspace)
- elseif currentfont~=font then
- report_warning("nested call with a different font, level %s, quitting",nesting)
- nesting=nesting-1
- return head,false
- end
- if trace_steps then
- checkstep(head)
- end
- local initialrl=0
- if getid(head)==localpar_code and getsubtype(head)==0 then
- initialrl=pardirstate(start)
- elseif direction==1 or direction=="TRT" then
- initialrl=-1
- end
- local datasets=otfdataset(tfmdata,font,attr)
- local dirstack={ nil }
- sweephead={}
- for s=1,#datasets do
- local dataset=datasets[s]
- local attribute=dataset[2]
- local sequence=dataset[3]
- local rlparmode=initialrl
- local topstack=0
- local typ=sequence.type
- local gpossing=typ=="gpos_single" or typ=="gpos_pair"
- local forcetestrun=typ=="gsub_ligature"
- local handler=handlers[typ]
- local steps=sequence.steps
- local nofsteps=sequence.nofsteps
- local skiphash=sequence.skiphash
- if not steps then
- local h,ok=handler(head,dataset,sequence,initialrl,font,attr)
- if h and h~=head then
- head=h
- end
- elseif typ=="gsub_reversecontextchain" then
- local start=find_node_tail(head)
- local rlmode=0
- local merged=steps.merged
- while start do
- local char=ischar(start,font)
- if char then
- local m=merged[char]
- if m then
- local a
- if attr then
- a=getattr(start,0)
- end
- if not a or (a==attr) then
- for i=m[1],m[2] do
- local step=steps[i]
- local lookupcache=step.coverage
- local lookupmatch=lookupcache[char]
- if lookupmatch then
- local ok
- head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
- if ok then
- break
- end
- end
- end
- if start then
- start=getprev(start)
- end
- else
- start=getprev(start)
- end
- else
- start=getprev(start)
- end
- else
- start=getprev(start)
+ marks=resources.marks
+ classes=resources.classes
+ threshold,
+ factor=getthreshold(font)
+ checkmarks=tfmdata.properties.checkmarks
+ if not otfdataset then
+ otfdataset=otf.dataset
+ end
+ discs=fastdisc and n and n>1 and setmetatable({},getfastdisc)
+ spaces=setmetatable({},getfastspace)
+ elseif currentfont~=font then
+ report_warning("nested call with a different font, level %s, quitting",nesting)
+ nesting=nesting-1
+ return head,false
+ end
+ if trace_steps then
+ checkstep(head)
+ end
+ local initialrl=0
+ if getid(head)==localpar_code and getsubtype(head)==0 then
+ initialrl=pardirstate(head)
+ elseif direction==1 or direction=="TRT" then
+ initialrl=-1
+ end
+ local datasets=otfdataset(tfmdata,font,attr)
+ local dirstack={ nil }
+ sweephead={}
+ for s=1,#datasets do
+ local dataset=datasets[s]
+ local attribute=dataset[2]
+ local sequence=dataset[3]
+ local rlparmode=initialrl
+ local topstack=0
+ local typ=sequence.type
+ local gpossing=typ=="gpos_single" or typ=="gpos_pair"
+ local forcetestrun=typ=="gsub_ligature"
+ local handler=handlers[typ]
+ local steps=sequence.steps
+ local nofsteps=sequence.nofsteps
+ local skiphash=sequence.skiphash
+ if not steps then
+ local h,ok=handler(head,dataset,sequence,initialrl,font,attr)
+ if h and h~=head then
+ head=h
+ end
+ elseif typ=="gsub_reversecontextchain" then
+ local start=find_node_tail(head)
+ local rlmode=0
+ local merged=steps.merged
+ while start do
+ local char=ischar(start,font)
+ if char then
+ local m=merged[char]
+ if m then
+ local a
+ if attr then
+ a=getattr(start,0)
+ end
+ if not a or (a==attr) then
+ for i=m[1],m[2] do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ break
end
+ end
end
- else
- local start=head
- local rlmode=initialrl
- if nofsteps==1 then
- local step=steps[1]
- local lookupcache=step.coverage
- while start do
- local char,id=ischar(start,font)
- if char then
- if skiphash and skiphash[char] then
- start=getnext(start)
- else
- local lookupmatch=lookupcache[char]
- if lookupmatch then
- local a
- if attr then
- if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then
- a=true
- end
- elseif not attribute or getprop(start,a_state)==attribute then
- a=true
- end
- if a then
- local ok,df
- head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
- if df then
- elseif start then
- start=getnext(start)
- end
- else
- start=getnext(start)
- end
- else
- start=getnext(start)
- end
- end
- elseif char==false or id==glue_code then
- start=getnext(start)
- elseif id==disc_code then
- if not discs or discs[start]==true then
- local ok
- if gpossing then
- start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
- elseif forcetestrun then
- start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
- else
- start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
- end
- else
- start=getnext(start)
- end
- elseif id==math_code then
- start=getnext(end_of_math(start))
- elseif id==dir_code then
- topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
- start=getnext(start)
- else
- start=getnext(start)
- end
- end
- else
- local merged=steps.merged
- while start do
- local char,id=ischar(start,font)
- if char then
- if skiphash and skiphash[char] then
- start=getnext(start)
- else
- local m=merged[char]
- if m then
- local a
- if attr then
- if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then
- a=true
- end
- elseif not attribute or getprop(start,a_state)==attribute then
- a=true
- end
- if a then
- local ok,df
- for i=m[1],m[2] do
- local step=steps[i]
- local lookupcache=step.coverage
- local lookupmatch=lookupcache[char]
- if lookupmatch then
- head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
- if df then
- break
- elseif ok then
- break
- elseif not start then
- break
- end
- end
- end
- if df then
- elseif start then
- start=getnext(start)
- end
- else
- start=getnext(start)
- end
- else
- start=getnext(start)
- end
- end
- elseif char==false or id==glue_code then
- start=getnext(start)
- elseif id==disc_code then
- if not discs or discs[start]==true then
- local ok
- if gpossing then
- start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
- elseif forcetestrun then
- start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
- else
- start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
- end
- else
- start=getnext(start)
- end
- elseif id==math_code then
- start=getnext(end_of_math(start))
- elseif id==dir_code then
- topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
- start=getnext(start)
- else
- start=getnext(start)
- end
- end
+ if start then
+ start=getprev(start)
end
+ else
+ start=getprev(start)
+ end
+ else
+ start=getprev(start)
end
- if trace_steps then
- registerstep(head)
- end
+ else
+ start=getprev(start)
+ end
end
- nesting=nesting-1
- return head
- end
- function otf.datasetpositionprocessor(head,font,direction,dataset)
- currentfont=font
- tfmdata=fontdata[font]
- descriptions=tfmdata.descriptions
- characters=tfmdata.characters
- local resources=tfmdata.resources
- marks=resources.marks
- classes=resources.classes
- threshold,
- factor=getthreshold(font)
- checkmarks=tfmdata.properties.checkmarks
- if type(dataset)=="number" then
- dataset=otfdataset(tfmdata,font,0)[dataset]
- end
- local sequence=dataset[3]
- local typ=sequence.type
- local handler=handlers[typ]
- local steps=sequence.steps
- local nofsteps=sequence.nofsteps
- local done=false
- local dirstack={ nil }
+ else
local start=head
- local initialrl=(direction==1 or direction=="TRT") and -1 or 0
local rlmode=initialrl
- local rlparmode=initialrl
- local topstack=0
- local merged=steps.merged
- local position=0
- while start do
+ if nofsteps==1 then
+ local step=steps[1]
+ local lookupcache=step.coverage
+ while start do
+ local char,id=ischar(start,font)
+ if char then
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local a
+ if attr then
+ if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ a=true
+ end
+ elseif not attribute or getprop(start,a_state)==attribute then
+ a=true
+ end
+ if a then
+ local ok,df
+ head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if df then
+ elseif start then
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ else
+ start=getnext(start)
+ end
+ end
+ elseif char==false or id==glue_code then
+ start=getnext(start)
+ elseif id==disc_code then
+ if not discs or discs[start]==true then
+ local ok
+ if gpossing then
+ start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ elseif forcetestrun then
+ start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ else
+ start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ end
+ else
+ start=getnext(start)
+ end
+ elseif id==math_code then
+ start=getnext(end_of_math(start))
+ elseif id==dir_code then
+ topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
+ start=getnext(start)
+ else
+ start=getnext(start)
+ end
+ end
+ else
+ local merged=steps.merged
+ while start do
local char,id=ischar(start,font)
if char then
- position=position+1
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
local m=merged[char]
if m then
- if skiphash and skiphash[char] then
- start=getnext(start)
- else
- for i=m[1],m[2] do
- local step=steps[i]
- local lookupcache=step.coverage
- local lookupmatch=lookupcache[char]
- if lookupmatch then
- local ok
- head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
- if ok then
- break
- elseif not start then
- break
- end
- end
- end
- if start then
- start=getnext(start)
+ local a
+ if attr then
+ if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ a=true
+ end
+ elseif not attribute or getprop(start,a_state)==attribute then
+ a=true
+ end
+ if a then
+ local ok,df
+ for i=m[1],m[2] do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if df then
+ break
+ elseif ok then
+ break
+ elseif not start then
+ break
end
+ end
end
- else
+ if df then
+ elseif start then
+ start=getnext(start)
+ end
+ else
start=getnext(start)
+ end
+ else
+ start=getnext(start)
end
+ end
elseif char==false or id==glue_code then
+ start=getnext(start)
+ elseif id==disc_code then
+ if not discs or discs[start]==true then
+ local ok
+ if gpossing then
+ start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ elseif forcetestrun then
+ start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ else
+ start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ end
+ else
start=getnext(start)
+ end
elseif id==math_code then
- start=getnext(end_of_math(start))
+ start=getnext(end_of_math(start))
elseif id==dir_code then
- topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
- start=getnext(start)
+ topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
+ start=getnext(start)
else
- start=getnext(start)
+ start=getnext(start)
end
+ end
end
- return head
+ end
+ if trace_steps then
+ registerstep(head)
+ end
+ end
+ nesting=nesting-1
+ return head
+ end
+ function otf.datasetpositionprocessor(head,font,direction,dataset)
+ currentfont=font
+ tfmdata=fontdata[font]
+ descriptions=tfmdata.descriptions
+ characters=tfmdata.characters
+ local resources=tfmdata.resources
+ marks=resources.marks
+ classes=resources.classes
+ threshold,
+ factor=getthreshold(font)
+ checkmarks=tfmdata.properties.checkmarks
+ if type(dataset)=="number" then
+ dataset=otfdataset(tfmdata,font,0)[dataset]
+ end
+ local sequence=dataset[3]
+ local typ=sequence.type
+ local handler=handlers[typ]
+ local steps=sequence.steps
+ local nofsteps=sequence.nofsteps
+ local done=false
+ local dirstack={ nil }
+ local start=head
+ local initialrl=(direction==1 or direction=="TRT") and -1 or 0
+ local rlmode=initialrl
+ local rlparmode=initialrl
+ local topstack=0
+ local merged=steps.merged
+ local position=0
+ while start do
+ local char,id=ischar(start,font)
+ if char then
+ position=position+1
+ local m=merged[char]
+ if m then
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
+ for i=m[1],m[2] do
+ local step=steps[i]
+ local lookupcache=step.coverage
+ local lookupmatch=lookupcache[char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if ok then
+ break
+ elseif not start then
+ break
+ end
+ end
+ end
+ if start then
+ start=getnext(start)
+ end
+ end
+ else
+ start=getnext(start)
+ end
+ elseif char==false or id==glue_code then
+ start=getnext(start)
+ elseif id==math_code then
+ start=getnext(end_of_math(start))
+ elseif id==dir_code then
+ topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
+ start=getnext(start)
+ else
+ start=getnext(start)
+ end
end
+ return head
+ end
end
local plugins={}
otf.plugins=plugins
local report=logs.reporter("fonts")
function otf.registerplugin(name,f)
- if type(name)=="string" and type(f)=="function" then
- plugins[name]={ name,f }
- report()
- report("plugin %a has been loaded, please be aware of possible side effects",name)
- report()
- if logs.pushtarget then
- logs.pushtarget("log")
- end
- report("Plugins are not officially supported unless stated otherwise. This is because")
- report("they bypass the regular font handling and therefore some features in ConTeXt")
- report("(especially those related to fonts) might not work as expected or might not work")
- report("at all. Some plugins are for testing and development only and might change")
- report("whenever we feel the need for it.")
- report()
- if logs.poptarget then
- logs.poptarget()
- end
- end
+ if type(name)=="string" and type(f)=="function" then
+ plugins[name]={ name,f }
+ report()
+ report("plugin %a has been loaded, please be aware of possible side effects",name)
+ report()
+ if logs.pushtarget then
+ logs.pushtarget("log")
+ end
+ report("Plugins are not officially supported unless stated otherwise. This is because")
+ report("they bypass the regular font handling and therefore some features in ConTeXt")
+ report("(especially those related to fonts) might not work as expected or might not work")
+ report("at all. Some plugins are for testing and development only and might change")
+ report("whenever we feel the need for it.")
+ report()
+ if logs.poptarget then
+ logs.poptarget()
+ end
+ end
end
function otf.plugininitializer(tfmdata,value)
- if type(value)=="string" then
- tfmdata.shared.plugin=plugins[value]
- end
+ if type(value)=="string" then
+ tfmdata.shared.plugin=plugins[value]
+ end
end
function otf.pluginprocessor(head,font,attr,direction)
- local s=fontdata[font].shared
- local p=s and s.plugin
- if p then
- if trace_plugins then
- report_process("applying plugin %a",p[1])
- end
- return p[2](head,font,attr,direction)
- else
- return head,false
- end
+ local s=fontdata[font].shared
+ local p=s and s.plugin
+ if p then
+ if trace_plugins then
+ report_process("applying plugin %a",p[1])
+ end
+ return p[2](head,font,attr,direction)
+ else
+ return head,false
+ end
end
function otf.featuresinitializer(tfmdata,value)
end
registerotffeature {
- name="features",
- description="features",
- default=true,
- initializers={
- position=1,
- node=otf.featuresinitializer,
- plug=otf.plugininitializer,
- },
- processors={
- node=otf.featuresprocessor,
- plug=otf.pluginprocessor,
- }
+ name="features",
+ description="features",
+ default=true,
+ initializers={
+ position=1,
+ node=otf.featuresinitializer,
+ plug=otf.plugininitializer,
+ },
+ processors={
+ node=otf.featuresprocessor,
+ plug=otf.pluginprocessor,
+ }
}
otf.handlers=handlers
local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end
local tag="kern"
if fontfeatures then
- function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr)
- local features=fontfeatures[font]
- local enabled=features and features.spacekern and features[tag]
- if enabled then
- setspacekerns(font,sequence)
- end
- return head,enabled
- end
+ function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr)
+ local features=fontfeatures[font]
+ local enabled=features and features.spacekern and features[tag]
+ if enabled then
+ setspacekerns(font,sequence)
+ end
+ return head,enabled
+ end
else
- function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr)
- local shared=fontdata[font].shared
- local features=shared and shared.features
- local enabled=features and features.spacekern and features[tag]
- if enabled then
- setspacekerns(font,sequence)
- end
- return head,enabled
+ function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr)
+ local shared=fontdata[font].shared
+ local features=shared and shared.features
+ local enabled=features and features.spacekern and features[tag]
+ if enabled then
+ setspacekerns(font,sequence)
end
+ return head,enabled
+ end
end
local function hasspacekerns(data)
- local resources=data.resources
- local sequences=resources.sequences
- local validgpos=resources.features.gpos
- if validgpos and sequences then
- for i=1,#sequences do
- local sequence=sequences[i]
- local steps=sequence.steps
- if steps and sequence.features[tag] then
- local kind=sequence.type
- if kind=="gpos_pair" or kind=="gpos_single" then
- for i=1,#steps do
- local step=steps[i]
- local coverage=step.coverage
- local rules=step.rules
- if rules then
- elseif not coverage then
- elseif kind=="gpos_single" then
- elseif kind=="gpos_pair" then
- local format=step.format
- if format=="move" or format=="kern" then
- local kerns=coverage[32]
- if kerns then
- return true
- end
- for k,v in next,coverage do
- if v[32] then
- return true
- end
- end
- elseif format=="pair" then
- local kerns=coverage[32]
- if kerns then
- for k,v in next,kerns do
- local one=v[1]
- if one and one~=true then
- return true
- end
- end
- end
- for k,v in next,coverage do
- local kern=v[32]
- if kern then
- local one=kern[1]
- if one and one~=true then
- return true
- end
- end
- end
- end
- end
+ local resources=data.resources
+ local sequences=resources.sequences
+ local validgpos=resources.features.gpos
+ if validgpos and sequences then
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ if steps and sequence.features[tag] then
+ local kind=sequence.type
+ if kind=="gpos_pair" or kind=="gpos_single" then
+ for i=1,#steps do
+ local step=steps[i]
+ local coverage=step.coverage
+ local rules=step.rules
+ if rules then
+ elseif not coverage then
+ elseif kind=="gpos_single" then
+ elseif kind=="gpos_pair" then
+ local format=step.format
+ if format=="move" or format=="kern" then
+ local kerns=coverage[32]
+ if kerns then
+ return true
+ end
+ for k,v in next,coverage do
+ if v[32] then
+ return true
+ end
+ end
+ elseif format=="pair" then
+ local kerns=coverage[32]
+ if kerns then
+ for k,v in next,kerns do
+ local one=v[1]
+ if one and one~=true then
+ return true
+ end
+ end
+ end
+ for k,v in next,coverage do
+ local kern=v[32]
+ if kern then
+ local one=kern[1]
+ if one and one~=true then
+ return true
end
+ end
end
+ end
end
+ end
end
+ end
end
- return false
+ end
+ return false
end
otf.readers.registerextender {
- name="spacekerns",
- action=function(data)
- data.properties.hasspacekerns=hasspacekerns(data)
- end
+ name="spacekerns",
+ action=function(data)
+ data.properties.hasspacekerns=hasspacekerns(data)
+ end
}
local function spaceinitializer(tfmdata,value)
- local resources=tfmdata.resources
- local spacekerns=resources and resources.spacekerns
- if value and spacekerns==nil then
- local rawdata=tfmdata.shared and tfmdata.shared.rawdata
- local properties=rawdata.properties
- if properties and properties.hasspacekerns then
- local sequences=resources.sequences
- local validgpos=resources.features.gpos
- if validgpos and sequences then
- local left={}
- local right={}
- local last=0
- local feat=nil
- for i=1,#sequences do
- local sequence=sequences[i]
- local steps=sequence.steps
- if steps then
- local kern=sequence.features[tag]
- if kern then
- local kind=sequence.type
- if kind=="gpos_pair" or kind=="gpos_single" then
- if feat then
- for script,languages in next,kern do
- local f=feat[script]
- if f then
- for l in next,languages do
- f[l]=true
- end
- else
- feat[script]=languages
- end
- end
- else
- feat=kern
- end
- for i=1,#steps do
- local step=steps[i]
- local coverage=step.coverage
- local rules=step.rules
- if rules then
- elseif not coverage then
- elseif kind=="gpos_single" then
- elseif kind=="gpos_pair" then
- local format=step.format
- if format=="move" or format=="kern" then
- local kerns=coverage[32]
- if kerns then
- for k,v in next,kerns do
- right[k]=v
- end
- end
- for k,v in next,coverage do
- local kern=v[32]
- if kern then
- left[k]=kern
- end
- end
- elseif format=="pair" then
- local kerns=coverage[32]
- if kerns then
- for k,v in next,kerns do
- local one=v[1]
- if one and one~=true then
- right[k]=one[3]
- end
- end
- end
- for k,v in next,coverage do
- local kern=v[32]
- if kern then
- local one=kern[1]
- if one and one~=true then
- left[k]=one[3]
- end
- end
- end
- end
- end
- end
- last=i
- end
- else
- end
+ local resources=tfmdata.resources
+ local spacekerns=resources and resources.spacekerns
+ if value and spacekerns==nil then
+ local rawdata=tfmdata.shared and tfmdata.shared.rawdata
+ local properties=rawdata.properties
+ if properties and properties.hasspacekerns then
+ local sequences=resources.sequences
+ local validgpos=resources.features.gpos
+ if validgpos and sequences then
+ local left={}
+ local right={}
+ local last=0
+ local feat=nil
+ for i=1,#sequences do
+ local sequence=sequences[i]
+ local steps=sequence.steps
+ if steps then
+ local kern=sequence.features[tag]
+ if kern then
+ local kind=sequence.type
+ if kind=="gpos_pair" or kind=="gpos_single" then
+ if feat then
+ for script,languages in next,kern do
+ local f=feat[script]
+ if f then
+ for l in next,languages do
+ f[l]=true
+ end
+ else
+ feat[script]=languages
end
+ end
+ else
+ feat=kern
end
- left=next(left) and left or false
- right=next(right) and right or false
- if left or right then
- spacekerns={
- left=left,
- right=right,
- }
- if last>0 then
- local triggersequence={
- features={ [tag]=feat or { dflt={ dflt=true,} } },
- flags=noflags,
- name="trigger_space_kerns",
- order={ tag },
- type="trigger_space_kerns",
- left=left,
- right=right,
- }
- insert(sequences,last,triggersequence)
+ for i=1,#steps do
+ local step=steps[i]
+ local coverage=step.coverage
+ local rules=step.rules
+ if rules then
+ elseif not coverage then
+ elseif kind=="gpos_single" then
+ elseif kind=="gpos_pair" then
+ local format=step.format
+ if format=="move" or format=="kern" then
+ local kerns=coverage[32]
+ if kerns then
+ for k,v in next,kerns do
+ right[k]=v
+ end
+ end
+ for k,v in next,coverage do
+ local kern=v[32]
+ if kern then
+ left[k]=kern
+ end
+ end
+ elseif format=="pair" then
+ local kerns=coverage[32]
+ if kerns then
+ for k,v in next,kerns do
+ local one=v[1]
+ if one and one~=true then
+ right[k]=one[3]
+ end
+ end
+ end
+ for k,v in next,coverage do
+ local kern=v[32]
+ if kern then
+ local one=kern[1]
+ if one and one~=true then
+ left[k]=one[3]
+ end
+ end
+ end
end
+ end
end
+ last=i
+ end
+ else
end
+ end
+ end
+ left=next(left) and left or false
+ right=next(right) and right or false
+ if left or right then
+ spacekerns={
+ left=left,
+ right=right,
+ }
+ if last>0 then
+ local triggersequence={
+ features={ [tag]=feat or { dflt={ dflt=true,} } },
+ flags=noflags,
+ name="trigger_space_kerns",
+ order={ tag },
+ type="trigger_space_kerns",
+ left=left,
+ right=right,
+ }
+ insert(sequences,last,triggersequence)
+ end
end
- resources.spacekerns=spacekerns
+ end
end
- return spacekerns
+ resources.spacekerns=spacekerns
+ end
+ return spacekerns
end
registerotffeature {
- name="spacekern",
- description="space kern injection",
- default=true,
- initializers={
- node=spaceinitializer,
- },
+ name="spacekern",
+ description="space kern injection",
+ default=true,
+ initializers={
+ node=spaceinitializer,
+ },
}
local function markinitializer(tfmdata,value)
- local properties=tfmdata.properties
- properties.checkmarks=value
+ local properties=tfmdata.properties
+ properties.checkmarks=value
end
registerotffeature {
- name="checkmarks",
- description="check mark widths",
- default=true,
- initializers={
- node=markinitializer,
- },
+ name="checkmarks",
+ description="check mark widths",
+ default=true,
+ initializers={
+ node=markinitializer,
+ },
}
end -- closure
@@ -29069,17 +29069,17 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-osd']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Kai Eigner, TAT Zetwerk / Hans Hagen, PRAGMA ADE",
- copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Kai Eigner, TAT Zetwerk / Hans Hagen, PRAGMA ADE",
+ copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local insert,imerge,copy=table.insert,table.imerge,table.copy
local next,type=next,type
local report=logs.reporter("otf","devanagari")
-fonts=fonts or {}
-fonts.analyzers=fonts.analyzers or {}
+fonts=fonts or {}
+fonts.analyzers=fonts.analyzers or {}
fonts.analyzers.methods=fonts.analyzers.methods or { node={ otf={} } }
local otf=fonts.handlers.otf
local handlers=otf.handlers
@@ -29123,10 +29123,10 @@ local s_blwf=states.blwf
local s_pstf=states.pstf
local replace_all_nbsp=nil
replace_all_nbsp=function(head)
- replace_all_nbsp=typesetters and typesetters.characters and typesetters.characters.replacenbspaces or function(head)
- return head
- end
- return replace_all_nbsp(head)
+ replace_all_nbsp=typesetters and typesetters.characters and typesetters.characters.replacenbspaces or function(head)
+ return head
+ end
+ return replace_all_nbsp(head)
end
local processcharacters=nil
if context then
@@ -29134,99 +29134,99 @@ if context then
--removed
else
- function processcharacters(head,font)
- local processors=fontdata[font].shared.processes
- for i=1,#processors do
- head=processors[i](head,font,0)
- end
- return head
+ function processcharacters(head,font)
+ local processors=fontdata[font].shared.processes
+ for i=1,#processors do
+ head=processors[i](head,font,0)
end
+ return head
+ end
end
local indicgroups=characters and characters.indicgroups
if not indicgroups and characters then
- local indic={
- c={},
- i={},
- d={},
- m={},
- s={},
- o={},
- }
- local indicmarks={
- l={},
- t={},
- b={},
- r={},
- s={},
- }
- local indicclasses={
- nukta={},
- halant={},
- ra={},
- anudatta={},
- }
- local indicorders={
- bp={},
- ap={},
- bs={},
- as={},
- bh={},
- ah={},
- bm={},
- am={},
- }
- for k,v in next,characters.data do
- local i=v.indic
- if i then
- indic[i][k]=true
- i=v.indicmark
- if i then
- if i=="s" then
- local s=v.specials
- indicmarks[i][k]={ s[2],s[3] }
- else
- indicmarks[i][k]=true
- end
- end
- i=v.indicclass
- if i then
- indicclasses[i][k]=true
- end
- i=v.indicorder
- if i then
- indicorders[i][k]=true
- end
- end
- end
- indicgroups={
- consonant=indic.c,
- independent_vowel=indic.i,
- dependent_vowel=indic.d,
- vowel_modifier=indic.m,
- stress_tone_mark=indic.s,
- pre_mark=indicmarks.l,
- above_mark=indicmarks.t,
- below_mark=indicmarks.b,
- post_mark=indicmarks.r,
- twopart_mark=indicmarks.s,
- nukta=indicclasses.nukta,
- halant=indicclasses.halant,
- ra=indicclasses.ra,
- anudatta=indicclasses.anudatta,
- before_postscript=indicorders.bp,
- after_postscript=indicorders.ap,
- before_half=indicorders.bh,
- after_half=indicorders.ah,
- before_subscript=indicorders.bs,
- after_subscript=indicorders.as,
- before_main=indicorders.bm,
- after_main=indicorders.am,
- }
- indic=nil
- indicmarks=nil
- indicclasses=nil
- indicorders=nil
- characters.indicgroups=indicgroups
+ local indic={
+ c={},
+ i={},
+ d={},
+ m={},
+ s={},
+ o={},
+ }
+ local indicmarks={
+ l={},
+ t={},
+ b={},
+ r={},
+ s={},
+ }
+ local indicclasses={
+ nukta={},
+ halant={},
+ ra={},
+ anudatta={},
+ }
+ local indicorders={
+ bp={},
+ ap={},
+ bs={},
+ as={},
+ bh={},
+ ah={},
+ bm={},
+ am={},
+ }
+ for k,v in next,characters.data do
+ local i=v.indic
+ if i then
+ indic[i][k]=true
+ i=v.indicmark
+ if i then
+ if i=="s" then
+ local s=v.specials
+ indicmarks[i][k]={ s[2],s[3] }
+ else
+ indicmarks[i][k]=true
+ end
+ end
+ i=v.indicclass
+ if i then
+ indicclasses[i][k]=true
+ end
+ i=v.indicorder
+ if i then
+ indicorders[i][k]=true
+ end
+ end
+ end
+ indicgroups={
+ consonant=indic.c,
+ independent_vowel=indic.i,
+ dependent_vowel=indic.d,
+ vowel_modifier=indic.m,
+ stress_tone_mark=indic.s,
+ pre_mark=indicmarks.l,
+ above_mark=indicmarks.t,
+ below_mark=indicmarks.b,
+ post_mark=indicmarks.r,
+ twopart_mark=indicmarks.s,
+ nukta=indicclasses.nukta,
+ halant=indicclasses.halant,
+ ra=indicclasses.ra,
+ anudatta=indicclasses.anudatta,
+ before_postscript=indicorders.bp,
+ after_postscript=indicorders.ap,
+ before_half=indicorders.bh,
+ after_half=indicorders.ah,
+ before_subscript=indicorders.bs,
+ after_subscript=indicorders.as,
+ before_main=indicorders.bm,
+ after_main=indicorders.am,
+ }
+ indic=nil
+ indicmarks=nil
+ indicclasses=nil
+ indicorders=nil
+ characters.indicgroups=indicgroups
end
local consonant=indicgroups.consonant
local independent_vowel=indicgroups.independent_vowel
@@ -29251,1176 +29251,1176 @@ local after_subscript=indicgroups.after_subscript
local before_main=indicgroups.before_main
local after_main=indicgroups.after_main
local mark_four=table.merged (
- pre_mark,
- above_mark,
- below_mark,
- post_mark
+ pre_mark,
+ above_mark,
+ below_mark,
+ post_mark
)
local mark_above_below_post=table.merged (
- above_mark,
- below_mark,
- post_mark
+ above_mark,
+ below_mark,
+ post_mark
)
local zw_char={
- [c_zwnj]=true,
- [c_zwj ]=true,
+ [c_zwnj]=true,
+ [c_zwj ]=true,
}
local dflt_true={
- dflt=true
+ dflt=true
}
local two_defaults={
- dev2=dflt_true,
+ dev2=dflt_true,
}
local one_defaults={
- dev2=dflt_true,
- deva=dflt_true,
+ dev2=dflt_true,
+ deva=dflt_true,
}
local false_flags={ false,false,false,false }
local sequence_reorder_matras={
- features={ dv01=two_defaults },
- flags=false_flags,
- name="dv01_reorder_matras",
- order={ "dv01" },
- type="devanagari_reorder_matras",
- nofsteps=1,
- steps={
- {
- coverage=pre_mark,
- }
+ features={ dv01=two_defaults },
+ flags=false_flags,
+ name="dv01_reorder_matras",
+ order={ "dv01" },
+ type="devanagari_reorder_matras",
+ nofsteps=1,
+ steps={
+ {
+ coverage=pre_mark,
}
+ }
}
local sequence_reorder_reph={
- features={ dv02=two_defaults },
- flags=false_flags,
- name="dv02_reorder_reph",
- order={ "dv02" },
- type="devanagari_reorder_reph",
- nofsteps=1,
- steps={
- {
- coverage={},
- }
+ features={ dv02=two_defaults },
+ flags=false_flags,
+ name="dv02_reorder_reph",
+ order={ "dv02" },
+ type="devanagari_reorder_reph",
+ nofsteps=1,
+ steps={
+ {
+ coverage={},
}
+ }
}
local sequence_reorder_pre_base_reordering_consonants={
- features={ dv03=two_defaults },
- flags=false_flags,
- name="dv03_reorder_pre_base_reordering_consonants",
- order={ "dv03" },
- type="devanagari_reorder_pre_base_reordering_consonants",
- nofsteps=1,
- steps={
- {
- coverage={},
- }
+ features={ dv03=two_defaults },
+ flags=false_flags,
+ name="dv03_reorder_pre_base_reordering_consonants",
+ order={ "dv03" },
+ type="devanagari_reorder_pre_base_reordering_consonants",
+ nofsteps=1,
+ steps={
+ {
+ coverage={},
}
+ }
}
local sequence_remove_joiners={
- features={ dv04=one_defaults },
- flags=false_flags,
- name="dv04_remove_joiners",
- order={ "dv04" },
- type="devanagari_remove_joiners",
- nofsteps=1,
- steps={
- {
- coverage=zw_char,
- },
- }
+ features={ dv04=one_defaults },
+ flags=false_flags,
+ name="dv04_remove_joiners",
+ order={ "dv04" },
+ type="devanagari_remove_joiners",
+ nofsteps=1,
+ steps={
+ {
+ coverage=zw_char,
+ },
+ }
}
local basic_shaping_forms={
- akhn=true,
- blwf=true,
- cjct=true,
- half=true,
- nukt=true,
- pref=true,
- pstf=true,
- rkrf=true,
- rphf=true,
- vatu=true,
+ akhn=true,
+ blwf=true,
+ cjct=true,
+ half=true,
+ nukt=true,
+ pref=true,
+ pstf=true,
+ rkrf=true,
+ rphf=true,
+ vatu=true,
}
local valid={
- abvs=true,
- akhn=true,
- blwf=true,
- calt=true,
- cjct=true,
- half=true,
- haln=true,
- nukt=true,
- pref=true,
- pres=true,
- pstf=true,
- psts=true,
- rkrf=true,
- rphf=true,
- vatu=true,
- pres=true,
- abvs=true,
- blws=true,
- psts=true,
- haln=true,
- calt=true,
+ abvs=true,
+ akhn=true,
+ blwf=true,
+ calt=true,
+ cjct=true,
+ half=true,
+ haln=true,
+ nukt=true,
+ pref=true,
+ pres=true,
+ pstf=true,
+ psts=true,
+ rkrf=true,
+ rphf=true,
+ vatu=true,
+ pres=true,
+ abvs=true,
+ blws=true,
+ psts=true,
+ haln=true,
+ calt=true,
}
local scripts={}
local scripts_one={ "deva","mlym","beng","gujr","guru","knda","orya","taml","telu" }
local scripts_two={ "dev2","mlm2","bng2","gjr2","gur2","knd2","ory2","tml2","tel2" }
local nofscripts=#scripts_one
for i=1,nofscripts do
- local one=scripts_one[i]
- local two=scripts_two[i]
- scripts[one]=true
- scripts[two]=true
- two_defaults[one]=dflt_true
- one_defaults[one]=dflt_true
- one_defaults[two]=dflt_true
+ local one=scripts_one[i]
+ local two=scripts_two[i]
+ scripts[one]=true
+ scripts[two]=true
+ two_defaults[one]=dflt_true
+ one_defaults[one]=dflt_true
+ one_defaults[two]=dflt_true
end
local function valid_one(s) for i=1,nofscripts do if s[scripts_one[i]] then return true end end end
local function valid_two(s) for i=1,nofscripts do if s[scripts_two[i]] then return true end end end
local function initializedevanagi(tfmdata)
- local script,language=otf.scriptandlanguage(tfmdata,attr)
- if scripts[script] then
- local resources=tfmdata.resources
- local devanagari=resources.devanagari
- if not devanagari then
- report("adding devanagari features to font")
- local gsubfeatures=resources.features.gsub
- local sequences=resources.sequences
- local sharedfeatures=tfmdata.shared.features
- local lastmatch=0
- for s=1,#sequences do
- local features=sequences[s].features
- if features then
- for k,v in next,features do
- if basic_shaping_forms[k] then
- lastmatch=s
- end
- end
+ local script,language=otf.scriptandlanguage(tfmdata,attr)
+ if scripts[script] then
+ local resources=tfmdata.resources
+ local devanagari=resources.devanagari
+ if not devanagari then
+ report("adding devanagari features to font")
+ local gsubfeatures=resources.features.gsub
+ local sequences=resources.sequences
+ local sharedfeatures=tfmdata.shared.features
+ local lastmatch=0
+ for s=1,#sequences do
+ local features=sequences[s].features
+ if features then
+ for k,v in next,features do
+ if basic_shaping_forms[k] then
+ lastmatch=s
+ end
+ end
+ end
+ end
+ local insertindex=lastmatch+1
+ gsubfeatures["dv01"]=two_defaults
+ gsubfeatures["dv02"]=two_defaults
+ gsubfeatures["dv03"]=two_defaults
+ gsubfeatures["dv04"]=one_defaults
+ local reorder_pre_base_reordering_consonants=copy(sequence_reorder_pre_base_reordering_consonants)
+ local reorder_reph=copy(sequence_reorder_reph)
+ local reorder_matras=copy(sequence_reorder_matras)
+ local remove_joiners=copy(sequence_remove_joiners)
+ insert(sequences,insertindex,reorder_pre_base_reordering_consonants)
+ insert(sequences,insertindex,reorder_reph)
+ insert(sequences,insertindex,reorder_matras)
+ insert(sequences,insertindex,remove_joiners)
+ local blwfcache={}
+ local seqsubset={}
+ local rephstep={
+ coverage={}
+ }
+ local devanagari={
+ reph=false,
+ vattu=false,
+ blwfcache=blwfcache,
+ seqsubset=seqsubset,
+ reorderreph=rephstep,
+ }
+ reorder_reph.steps={ rephstep }
+ local pre_base_reordering_consonants={}
+ reorder_pre_base_reordering_consonants.steps[1].coverage=pre_base_reordering_consonants
+ resources.devanagari=devanagari
+ for s=1,#sequences do
+ local sequence=sequences[s]
+ local steps=sequence.steps
+ local nofsteps=sequence.nofsteps
+ local features=sequence.features
+ local has_rphf=features.rphf
+ local has_blwf=features.blwf
+ if has_rphf and has_rphf.deva then
+ devanagari.reph=true
+ elseif has_blwf and has_blwf.deva then
+ devanagari.vattu=true
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ for k,v in next,coverage do
+ if not blwfcache[k] then
+ blwfcache[k]=v
end
+ end
end
- local insertindex=lastmatch+1
- gsubfeatures["dv01"]=two_defaults
- gsubfeatures["dv02"]=two_defaults
- gsubfeatures["dv03"]=two_defaults
- gsubfeatures["dv04"]=one_defaults
- local reorder_pre_base_reordering_consonants=copy(sequence_reorder_pre_base_reordering_consonants)
- local reorder_reph=copy(sequence_reorder_reph)
- local reorder_matras=copy(sequence_reorder_matras)
- local remove_joiners=copy(sequence_remove_joiners)
- insert(sequences,insertindex,reorder_pre_base_reordering_consonants)
- insert(sequences,insertindex,reorder_reph)
- insert(sequences,insertindex,reorder_matras)
- insert(sequences,insertindex,remove_joiners)
- local blwfcache={}
- local seqsubset={}
- local rephstep={
- coverage={}
- }
- local devanagari={
- reph=false,
- vattu=false,
- blwfcache=blwfcache,
- seqsubset=seqsubset,
- reorderreph=rephstep,
- }
- reorder_reph.steps={ rephstep }
- local pre_base_reordering_consonants={}
- reorder_pre_base_reordering_consonants.steps[1].coverage=pre_base_reordering_consonants
- resources.devanagari=devanagari
- for s=1,#sequences do
- local sequence=sequences[s]
- local steps=sequence.steps
- local nofsteps=sequence.nofsteps
- local features=sequence.features
- local has_rphf=features.rphf
- local has_blwf=features.blwf
- if has_rphf and has_rphf.deva then
- devanagari.reph=true
- elseif has_blwf and has_blwf.deva then
- devanagari.vattu=true
- for i=1,nofsteps do
- local step=steps[i]
- local coverage=step.coverage
- if coverage then
- for k,v in next,coverage do
- if not blwfcache[k] then
- blwfcache[k]=v
- end
- end
- end
+ end
+ end
+ for kind,spec in next,features do
+ if valid[kind] and valid_two(spec)then
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ local reph=false
+ if kind=="rphf" then
+ for k,v in next,ra do
+ local r=coverage[k]
+ if r then
+ local h=false
+ for k,v in next,halant do
+ local h=r[k]
+ if h then
+ reph=h.ligature or false
+ break
+ end
+ end
+ if reph then
+ break
+ end
end
+ end
end
- for kind,spec in next,features do
- if valid[kind] and valid_two(spec)then
- for i=1,nofsteps do
- local step=steps[i]
- local coverage=step.coverage
- if coverage then
- local reph=false
- if kind=="rphf" then
- for k,v in next,ra do
- local r=coverage[k]
- if r then
- local h=false
- for k,v in next,halant do
- local h=r[k]
- if h then
- reph=h.ligature or false
- break
- end
- end
- if reph then
- break
- end
- end
- end
- end
- seqsubset[#seqsubset+1]={ kind,coverage,reph }
- end
- end
+ seqsubset[#seqsubset+1]={ kind,coverage,reph }
+ end
+ end
+ end
+ if kind=="pref" then
+ local steps=sequence.steps
+ local nofsteps=sequence.nofsteps
+ for i=1,nofsteps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ for k,v in next,halant do
+ local h=coverage[k]
+ if h then
+ local found=false
+ for k,v in next,h do
+ found=v and v.ligature
+ if found then
+ pre_base_reordering_consonants[k]=found
+ break
+ end
end
- if kind=="pref" then
- local steps=sequence.steps
- local nofsteps=sequence.nofsteps
- for i=1,nofsteps do
- local step=steps[i]
- local coverage=step.coverage
- if coverage then
- for k,v in next,halant do
- local h=coverage[k]
- if h then
- local found=false
- for k,v in next,h do
- found=v and v.ligature
- if found then
- pre_base_reordering_consonants[k]=found
- break
- end
- end
- if found then
- break
- end
- end
- end
- end
- end
+ if found then
+ break
end
+ end
end
+ end
end
- if script=="deva" then
- sharedfeatures["dv04"]=true
- elseif script=="dev2" then
- sharedfeatures["dv01"]=true
- sharedfeatures["dv02"]=true
- sharedfeatures["dv03"]=true
- sharedfeatures["dv04"]=true
- elseif script=="mlym" then
- sharedfeatures["pstf"]=true
- elseif script=="mlm2" then
- sharedfeatures["pstf"]=true
- sharedfeatures["pref"]=true
- sharedfeatures["dv03"]=true
- gsubfeatures ["dv03"]=two_defaults
- insert(sequences,insertindex,sequence_reorder_pre_base_reordering_consonants)
- elseif script=="taml" then
- sharedfeatures["dv04"]=true
-sharedfeatures["pstf"]=true
- elseif script=="tml2" then
- else
- report("todo: enable the right features for script %a",script)
- end
+ end
end
+ end
+ if script=="deva" then
+ sharedfeatures["dv04"]=true
+ elseif script=="dev2" then
+ sharedfeatures["dv01"]=true
+ sharedfeatures["dv02"]=true
+ sharedfeatures["dv03"]=true
+ sharedfeatures["dv04"]=true
+ elseif script=="mlym" then
+ sharedfeatures["pstf"]=true
+ elseif script=="mlm2" then
+ sharedfeatures["pstf"]=true
+ sharedfeatures["pref"]=true
+ sharedfeatures["dv03"]=true
+ gsubfeatures ["dv03"]=two_defaults
+ insert(sequences,insertindex,sequence_reorder_pre_base_reordering_consonants)
+ elseif script=="taml" then
+ sharedfeatures["dv04"]=true
+sharedfeatures["pstf"]=true
+ elseif script=="tml2" then
+ else
+ report("todo: enable the right features for script %a",script)
+ end
end
+ end
end
registerotffeature {
- name="devanagari",
- description="inject additional features",
- default=true,
- initializers={
- node=initializedevanagi,
- },
+ name="devanagari",
+ description="inject additional features",
+ default=true,
+ initializers={
+ node=initializedevanagi,
+ },
}
local show_syntax_errors=false
local function inject_syntax_error(head,current,char)
- local signal=copy_node(current)
- copyinjection(signal,current)
- if pre_mark[char] then
- setchar(signal,dotted_circle)
- else
- setchar(current,dotted_circle)
- end
- return insert_node_after(head,current,signal)
+ local signal=copy_node(current)
+ copyinjection(signal,current)
+ if pre_mark[char] then
+ setchar(signal,dotted_circle)
+ else
+ setchar(current,dotted_circle)
+ end
+ return insert_node_after(head,current,signal)
end
local function initialize_one(font,attr)
- local tfmdata=fontdata[font]
- local datasets=otf.dataset(tfmdata,font,attr)
- local devanagaridata=datasets.devanagari
- if not devanagaridata then
- devanagaridata={
- reph=false,
- vattu=false,
- blwfcache={},
- }
- datasets.devanagari=devanagaridata
- local resources=tfmdata.resources
- local devanagari=resources.devanagari
- for s=1,#datasets do
- local dataset=datasets[s]
- if dataset and dataset[1] then
- local kind=dataset[4]
- if kind=="rphf" then
- devanagaridata.reph=true
- elseif kind=="blwf" then
- devanagaridata.vattu=true
- devanagaridata.blwfcache=devanagari.blwfcache
- end
- end
+ local tfmdata=fontdata[font]
+ local datasets=otf.dataset(tfmdata,font,attr)
+ local devanagaridata=datasets.devanagari
+ if not devanagaridata then
+ devanagaridata={
+ reph=false,
+ vattu=false,
+ blwfcache={},
+ }
+ datasets.devanagari=devanagaridata
+ local resources=tfmdata.resources
+ local devanagari=resources.devanagari
+ for s=1,#datasets do
+ local dataset=datasets[s]
+ if dataset and dataset[1] then
+ local kind=dataset[4]
+ if kind=="rphf" then
+ devanagaridata.reph=true
+ elseif kind=="blwf" then
+ devanagaridata.vattu=true
+ devanagaridata.blwfcache=devanagari.blwfcache
end
+ end
end
- return devanagaridata.reph,devanagaridata.vattu,devanagaridata.blwfcache
+ end
+ return devanagaridata.reph,devanagaridata.vattu,devanagaridata.blwfcache
end
local function reorder_one(head,start,stop,font,attr,nbspaces)
- local reph,vattu,blwfcache=initialize_one(font,attr)
- local current=start
- local n=getnext(start)
- local base=nil
- local firstcons=nil
- local lastcons=nil
- local basefound=false
- if reph and ra[getchar(start)] and halant[getchar(n)] then
- if n==stop then
- return head,stop,nbspaces
- end
- if getchar(getnext(n))==c_zwj then
- current=start
- else
- current=getnext(n)
- setprop(start,a_state,s_rphf)
- end
- end
- if getchar(current)==c_nbsp then
- if current==stop then
- stop=getprev(stop)
- head=remove_node(head,current)
- flush_node(current)
- return head,stop,nbspaces
- else
- nbspaces=nbspaces+1
- base=current
- firstcons=current
- lastcons=current
- current=getnext(current)
- if current~=stop then
- local char=getchar(current)
- if nukta[char] then
- current=getnext(current)
- char=getchar(current)
- end
- if char==c_zwj and current~=stop then
- local next=getnext(current)
- if next~=stop and halant[getchar(next)] then
- current=next
- next=getnext(current)
- local tmp=next and getnext(next) or nil
- local changestop=next==stop
- local tempcurrent=copy_node(next)
- copyinjection(tempcurrent,next)
- local nextcurrent=copy_node(current)
- copyinjection(nextcurrent,current)
- setlink(tempcurrent,nextcurrent)
- setprop(tempcurrent,a_state,s_blwf)
- tempcurrent=processcharacters(tempcurrent,font)
- setprop(tempcurrent,a_state,unsetvalue)
- if getchar(next)==getchar(tempcurrent) then
- flush_list(tempcurrent)
- if show_syntax_errors then
- head,current=inject_syntax_error(head,current,char)
- end
- else
- setchar(current,getchar(tempcurrent))
- local freenode=getnext(current)
- setlink(current,tmp)
- flush_node(freenode)
- flush_list(tempcurrent)
- if changestop then
- stop=current
- end
- end
- end
- end
- end
- end
- end
- while not basefound do
+ local reph,vattu,blwfcache=initialize_one(font,attr)
+ local current=start
+ local n=getnext(start)
+ local base=nil
+ local firstcons=nil
+ local lastcons=nil
+ local basefound=false
+ if reph and ra[getchar(start)] and halant[getchar(n)] then
+ if n==stop then
+ return head,stop,nbspaces
+ end
+ if getchar(getnext(n))==c_zwj then
+ current=start
+ else
+ current=getnext(n)
+ setprop(start,a_state,s_rphf)
+ end
+ end
+ if getchar(current)==c_nbsp then
+ if current==stop then
+ stop=getprev(stop)
+ head=remove_node(head,current)
+ flush_node(current)
+ return head,stop,nbspaces
+ else
+ nbspaces=nbspaces+1
+ base=current
+ firstcons=current
+ lastcons=current
+ current=getnext(current)
+ if current~=stop then
local char=getchar(current)
- if consonant[char] then
- setprop(current,a_state,s_half)
- if not firstcons then
- firstcons=current
- end
- lastcons=current
- if not base then
- base=current
- elseif blwfcache[char] then
- setprop(current,a_state,s_blwf)
+ if nukta[char] then
+ current=getnext(current)
+ char=getchar(current)
+ end
+ if char==c_zwj and current~=stop then
+ local next=getnext(current)
+ if next~=stop and halant[getchar(next)] then
+ current=next
+ next=getnext(current)
+ local tmp=next and getnext(next) or nil
+ local changestop=next==stop
+ local tempcurrent=copy_node(next)
+ copyinjection(tempcurrent,next)
+ local nextcurrent=copy_node(current)
+ copyinjection(nextcurrent,current)
+ setlink(tempcurrent,nextcurrent)
+ setprop(tempcurrent,a_state,s_blwf)
+ tempcurrent=processcharacters(tempcurrent,font)
+ setprop(tempcurrent,a_state,unsetvalue)
+ if getchar(next)==getchar(tempcurrent) then
+ flush_list(tempcurrent)
+ if show_syntax_errors then
+ head,current=inject_syntax_error(head,current,char)
+ end
else
- base=current
+ setchar(current,getchar(tempcurrent))
+ local freenode=getnext(current)
+ setlink(current,tmp)
+ flush_node(freenode)
+ flush_list(tempcurrent)
+ if changestop then
+ stop=current
+ end
end
+ end
end
- basefound=current==stop
- current=getnext(current)
+ end
end
- if base~=lastcons then
- local np=base
- local n=getnext(base)
- local ch=getchar(n)
- if nukta[ch] then
- np=n
+ end
+ while not basefound do
+ local char=getchar(current)
+ if consonant[char] then
+ setprop(current,a_state,s_half)
+ if not firstcons then
+ firstcons=current
+ end
+ lastcons=current
+ if not base then
+ base=current
+ elseif blwfcache[char] then
+ setprop(current,a_state,s_blwf)
+ else
+ base=current
+ end
+ end
+ basefound=current==stop
+ current=getnext(current)
+ end
+ if base~=lastcons then
+ local np=base
+ local n=getnext(base)
+ local ch=getchar(n)
+ if nukta[ch] then
+ np=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ if halant[ch] then
+ if lastcons~=stop then
+ local ln=getnext(lastcons)
+ if nukta[getchar(ln)] then
+ lastcons=ln
+ end
+ end
+ local nn=getnext(n)
+ local ln=getnext(lastcons)
+ setlink(np,nn)
+ setnext(lastcons,n)
+ if ln then
+ setprev(ln,n)
+ end
+ setnext(n,ln)
+ setprev(n,lastcons)
+ if lastcons==stop then
+ stop=n
+ end
+ end
+ end
+ n=getnext(start)
+ if n~=stop and ra[getchar(start)] and halant[getchar(n)] and not zw_char[getchar(getnext(n))] then
+ local matra=base
+ if base~=stop then
+ local next=getnext(base)
+ if dependent_vowel[getchar(next)] then
+ matra=next
+ end
+ end
+ local sp=getprev(start)
+ local nn=getnext(n)
+ local mn=getnext(matra)
+ setlink(sp,nn)
+ setlink(matra,start)
+ setlink(n,mn)
+ if head==start then
+ head=nn
+ end
+ start=nn
+ if matra==stop then
+ stop=n
+ end
+ end
+ local current=start
+ while current~=stop do
+ local next=getnext(current)
+ if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then
+ setprop(current,a_state,unsetvalue)
+ end
+ current=next
+ end
+ if base~=stop and getprop(base,a_state) then
+ local next=getnext(base)
+ if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then
+ setprop(base,a_state,unsetvalue)
+ end
+ end
+ local current,allreordered,moved=start,false,{ [base]=true }
+ local a,b,p,bn=base,base,base,getnext(base)
+ if base~=stop and nukta[getchar(bn)] then
+ a,b,p=bn,bn,bn
+ end
+ while not allreordered do
+ local c=current
+ local n=getnext(current)
+ local l=nil
+ if c~=stop then
+ local ch=getchar(n)
+ if nukta[ch] then
+ c=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ if c~=stop then
+ if halant[ch] then
+ c=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ while c~=stop and dependent_vowel[ch] do
+ c=n
+ n=getnext(n)
+ ch=getchar(n)
+ end
+ if c~=stop then
+ if vowel_modifier[ch] then
+ c=n
n=getnext(n)
ch=getchar(n)
+ end
+ if c~=stop and stress_tone_mark[ch] then
+ c=n
+ n=getnext(n)
+ end
end
- if halant[ch] then
- if lastcons~=stop then
- local ln=getnext(lastcons)
- if nukta[getchar(ln)] then
- lastcons=ln
- end
- end
- local nn=getnext(n)
- local ln=getnext(lastcons)
- setlink(np,nn)
- setnext(lastcons,n)
- if ln then
- setprev(ln,n)
- end
- setnext(n,ln)
- setprev(n,lastcons)
- if lastcons==stop then
- stop=n
- end
- end
+ end
end
- n=getnext(start)
- if n~=stop and ra[getchar(start)] and halant[getchar(n)] and not zw_char[getchar(getnext(n))] then
- local matra=base
- if base~=stop then
- local next=getnext(base)
- if dependent_vowel[getchar(next)] then
- matra=next
- end
+ local bp=getprev(firstcons)
+ local cn=getnext(current)
+ local last=getnext(c)
+ while cn~=last do
+ if pre_mark[getchar(cn)] then
+ if bp then
+ setnext(bp,cn)
end
- local sp=getprev(start)
- local nn=getnext(n)
- local mn=getnext(matra)
- setlink(sp,nn)
- setlink(matra,start)
- setlink(n,mn)
- if head==start then
- head=nn
+ local prev,next=getboth(cn)
+ if next then
+ setprev(next,prev)
end
- start=nn
- if matra==stop then
- stop=n
+ setnext(prev,next)
+ if cn==stop then
+ stop=prev
end
- end
- local current=start
- while current~=stop do
- local next=getnext(current)
- if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then
- setprop(current,a_state,unsetvalue)
+ setprev(cn,bp)
+ setlink(cn,firstcons)
+ if firstcons==start then
+ if head==start then
+ head=cn
+ end
+ start=cn
end
- current=next
- end
- if base~=stop and getprop(base,a_state) then
- local next=getnext(base)
- if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then
- setprop(base,a_state,unsetvalue)
+ break
+ end
+ cn=getnext(cn)
+ end
+ allreordered=c==stop
+ current=getnext(c)
+ end
+ if reph or vattu then
+ local current,cns=start,nil
+ while current~=stop do
+ local c=current
+ local n=getnext(current)
+ if ra[getchar(current)] and halant[getchar(n)] then
+ c=n
+ n=getnext(n)
+ local b,bn=base,base
+ while bn~=stop do
+ local next=getnext(bn)
+ if dependent_vowel[getchar(next)] then
+ b=next
+ end
+ bn=next
end
- end
- local current,allreordered,moved=start,false,{ [base]=true }
- local a,b,p,bn=base,base,base,getnext(base)
- if base~=stop and nukta[getchar(bn)] then
- a,b,p=bn,bn,bn
- end
- while not allreordered do
- local c=current
- local n=getnext(current)
- local l=nil
- if c~=stop then
- local ch=getchar(n)
- if nukta[ch] then
- c=n
- n=getnext(n)
- ch=getchar(n)
+ if getprop(current,a_state)==s_rphf then
+ if b~=current then
+ if current==start then
+ if head==start then
+ head=n
+ end
+ start=n
end
- if c~=stop then
- if halant[ch] then
- c=n
- n=getnext(n)
- ch=getchar(n)
- end
- while c~=stop and dependent_vowel[ch] do
- c=n
- n=getnext(n)
- ch=getchar(n)
- end
- if c~=stop then
- if vowel_modifier[ch] then
- c=n
- n=getnext(n)
- ch=getchar(n)
- end
- if c~=stop and stress_tone_mark[ch] then
- c=n
- n=getnext(n)
- end
- end
+ if b==stop then
+ stop=c
end
+ local prev=getprev(current)
+ setlink(prev,n)
+ local next=getnext(b)
+ setlink(c,next)
+ setlink(b,current)
+ end
+ elseif cns and getnext(cns)~=current then
+ local cp=getprev(current)
+ local cnsn=getnext(cns)
+ setlink(cp,n)
+ setlink(cns,current)
+ setlink(c,cnsn)
+ if c==stop then
+ stop=cp
+ break
+ end
+ current=getprev(n)
end
- local bp=getprev(firstcons)
- local cn=getnext(current)
- local last=getnext(c)
- while cn~=last do
- if pre_mark[getchar(cn)] then
- if bp then
- setnext(bp,cn)
- end
- local prev,next=getboth(cn)
- if next then
- setprev(next,prev)
- end
- setnext(prev,next)
- if cn==stop then
- stop=prev
- end
- setprev(cn,bp)
- setlink(cn,firstcons)
- if firstcons==start then
- if head==start then
- head=cn
- end
- start=cn
- end
- break
- end
- cn=getnext(cn)
- end
- allreordered=c==stop
- current=getnext(c)
- end
- if reph or vattu then
- local current,cns=start,nil
- while current~=stop do
- local c=current
- local n=getnext(current)
- if ra[getchar(current)] and halant[getchar(n)] then
- c=n
- n=getnext(n)
- local b,bn=base,base
- while bn~=stop do
- local next=getnext(bn)
- if dependent_vowel[getchar(next)] then
- b=next
- end
- bn=next
- end
- if getprop(current,a_state)==s_rphf then
- if b~=current then
- if current==start then
- if head==start then
- head=n
- end
- start=n
- end
- if b==stop then
- stop=c
- end
- local prev=getprev(current)
- setlink(prev,n)
- local next=getnext(b)
- setlink(c,next)
- setlink(b,current)
- end
- elseif cns and getnext(cns)~=current then
- local cp=getprev(current)
- local cnsn=getnext(cns)
- setlink(cp,n)
- setlink(cns,current)
- setlink(c,cnsn)
- if c==stop then
- stop=cp
- break
- end
- current=getprev(n)
- end
- else
- local char=getchar(current)
- if consonant[char] then
- cns=current
- local next=getnext(cns)
- if halant[getchar(next)] then
- cns=next
- end
- elseif char==c_nbsp then
- nbspaces=nbspaces+1
- cns=current
- local next=getnext(cns)
- if halant[getchar(next)] then
- cns=next
- end
- end
- end
- current=getnext(current)
+ else
+ local char=getchar(current)
+ if consonant[char] then
+ cns=current
+ local next=getnext(cns)
+ if halant[getchar(next)] then
+ cns=next
+ end
+ elseif char==c_nbsp then
+ nbspaces=nbspaces+1
+ cns=current
+ local next=getnext(cns)
+ if halant[getchar(next)] then
+ cns=next
+ end
end
+ end
+ current=getnext(current)
end
- if getchar(base)==c_nbsp then
- nbspaces=nbspaces-1
- head=remove_node(head,base)
- flush_node(base)
- end
- return head,stop,nbspaces
+ end
+ if getchar(base)==c_nbsp then
+ nbspaces=nbspaces-1
+ head=remove_node(head,base)
+ flush_node(base)
+ end
+ return head,stop,nbspaces
end
function handlers.devanagari_reorder_matras(head,start)
- local current=start
- local startfont=getfont(start)
- local startattr=getprop(start,a_syllabe)
- while current do
- local char=ischar(current,startfont)
- local next=getnext(current)
- if char and getprop(current,a_syllabe)==startattr then
- if halant[char] and not getprop(current,a_state) then
- if next then
- local char=ischar(next,startfont)
- if char and zw_char[char] and getprop(next,a_syllabe)==startattr then
- current=next
- next=getnext(current)
- end
- end
- local startnext=getnext(start)
- head=remove_node(head,start)
- setlink(start,next)
- setlink(current,start)
- start=startnext
- break
- end
- else
- break
+ local current=start
+ local startfont=getfont(start)
+ local startattr=getprop(start,a_syllabe)
+ while current do
+ local char=ischar(current,startfont)
+ local next=getnext(current)
+ if char and getprop(current,a_syllabe)==startattr then
+ if halant[char] and not getprop(current,a_state) then
+ if next then
+ local char=ischar(next,startfont)
+ if char and zw_char[char] and getprop(next,a_syllabe)==startattr then
+ current=next
+ next=getnext(current)
+ end
end
- current=next
+ local startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(start,next)
+ setlink(current,start)
+ start=startnext
+ break
+ end
+ else
+ break
end
- return head,start,true
+ current=next
+ end
+ return head,start,true
end
function handlers.devanagari_reorder_reph(head,start)
- local current=getnext(start)
- local startnext=nil
- local startprev=nil
- local startfont=getfont(start)
- local startattr=getprop(start,a_syllabe)
- ::step_1::
- ::step_2::
- while current do
- local char=ischar(current,startfont)
- if char and getprop(current,a_syllabe)==startattr then
- if halant[char] and not getprop(current,a_state) then
- local next=getnext(current)
- if next then
- local nextchar=ischar(next,startfont)
- if nextchar and zw_char[nextchar] and getprop(next,a_syllabe)==startattr then
- current=next
- next=getnext(current)
- end
- end
- startnext=getnext(start)
- head=remove_node(head,start)
- setlink(start,next)
- setlink(current,start)
- start=startnext
- startattr=getprop(start,a_syllabe)
- break
- end
- current=getnext(current)
- else
- break
+ local current=getnext(start)
+ local startnext=nil
+ local startprev=nil
+ local startfont=getfont(start)
+ local startattr=getprop(start,a_syllabe)
+ ::step_1::
+ ::step_2::
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ if halant[char] and not getprop(current,a_state) then
+ local next=getnext(current)
+ if next then
+ local nextchar=ischar(next,startfont)
+ if nextchar and zw_char[nextchar] and getprop(next,a_syllabe)==startattr then
+ current=next
+ next=getnext(current)
+ end
end
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(start,next)
+ setlink(current,start)
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ break
+ end
+ current=getnext(current)
+ else
+ break
end
- ::step_3::
- ::step_4::
- if not startnext then
- current=getnext(start)
- while current do
- local char=ischar(current,startfont)
- if char and getprop(current,a_syllabe)==startattr then
- if getprop(current,a_state)==s_pstf then
- startnext=getnext(start)
- head=remove_node(head,start)
- setlink(getprev(current),start)
- setlink(start,current)
- start=startnext
- startattr=getprop(start,a_syllabe)
- break
- end
- current=getnext(current)
- else
- break
- end
+ end
+ ::step_3::
+ ::step_4::
+ if not startnext then
+ current=getnext(start)
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ if getprop(current,a_state)==s_pstf then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(getprev(current),start)
+ setlink(start,current)
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ break
end
+ current=getnext(current)
+ else
+ break
+ end
end
- ::step_5::
- if not startnext then
- current=getnext(start)
- local c=nil
- while current do
- local char=ischar(current,startfont)
- if char and getprop(current,a_syllabe)==startattr then
- if not c and mark_above_below_post[char] and not after_subscript[char] then
- c=current
- end
- current=getnext(current)
- else
- break
- end
- end
- if c then
- startnext=getnext(start)
- head=remove_node(head,start)
- setlink(getprev(c),start)
- setlink(start,c)
- start=startnext
- startattr=getprop(start,a_syllabe)
+ end
+ ::step_5::
+ if not startnext then
+ current=getnext(start)
+ local c=nil
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ if not c and mark_above_below_post[char] and not after_subscript[char] then
+ c=current
end
+ current=getnext(current)
+ else
+ break
+ end
+ end
+ if c then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(getprev(c),start)
+ setlink(start,c)
+ start=startnext
+ startattr=getprop(start,a_syllabe)
+ end
+ end
+ ::step_6::
+ if not startnext then
+ current=start
+ local next=getnext(current)
+ while next do
+ local nextchar=ischar(next,startfont)
+ if nextchar and getprop(next,a_syllabe)==startattr then
+ current=next
+ next=getnext(current)
+ else
+ break
+ end
end
- ::step_6::
- if not startnext then
- current=start
- local next=getnext(current)
- while next do
- local nextchar=ischar(next,startfont)
- if nextchar and getprop(next,a_syllabe)==startattr then
- current=next
- next=getnext(current)
- else
- break
- end
- end
- if start~=current then
- startnext=getnext(start)
- head=remove_node(head,start)
- setlink(start,getnext(current))
- setlink(current,start)
- start=startnext
- end
+ if start~=current then
+ startnext=getnext(start)
+ head=remove_node(head,start)
+ setlink(start,getnext(current))
+ setlink(current,start)
+ start=startnext
end
- return head,start,true
+ end
+ return head,start,true
end
function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start)
- local current=start
- local startnext=nil
- local startprev=nil
- local startfont=getfont(start)
- local startattr=getprop(start,a_syllabe)
- while current do
- local char=ischar(current,startfont)
- if char and getprop(current,a_syllabe)==startattr then
- local next=getnext(current)
- if halant[char] and not getprop(current,a_state) then
- if next then
- local nextchar=ischar(next,startfont)
- if nextchar and getprop(next,a_syllabe)==startattr then
- if nextchar==c_zwnj or nextchar==c_zwj then
- current=next
- next=getnext(current)
- end
- end
- end
- startnext=getnext(start)
- removenode(start,start)
- setlink(start,next)
- setlink(current,start)
- start=startnext
- break
+ local current=start
+ local startnext=nil
+ local startprev=nil
+ local startfont=getfont(start)
+ local startattr=getprop(start,a_syllabe)
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ local next=getnext(current)
+ if halant[char] and not getprop(current,a_state) then
+ if next then
+ local nextchar=ischar(next,startfont)
+ if nextchar and getprop(next,a_syllabe)==startattr then
+ if nextchar==c_zwnj or nextchar==c_zwj then
+ current=next
+ next=getnext(current)
end
- current=next
- else
- break
+ end
end
+ startnext=getnext(start)
+ removenode(start,start)
+ setlink(start,next)
+ setlink(current,start)
+ start=startnext
+ break
+ end
+ current=next
+ else
+ break
end
- if not startnext then
- current=getnext(start)
- startattr=getprop(start,a_syllabe)
- while current do
- local char=ischar(current,startfont)
- if char and getprop(current,a_syllabe)==startattr then
- if not consonant[char] and getprop(current,a_state) then
- startnext=getnext(start)
- removenode(start,start)
- setlink(getprev(current),start)
- setlink(start,current)
- start=startnext
- break
- end
- current=getnext(current)
- else
- break
- end
+ end
+ if not startnext then
+ current=getnext(start)
+ startattr=getprop(start,a_syllabe)
+ while current do
+ local char=ischar(current,startfont)
+ if char and getprop(current,a_syllabe)==startattr then
+ if not consonant[char] and getprop(current,a_state) then
+ startnext=getnext(start)
+ removenode(start,start)
+ setlink(getprev(current),start)
+ setlink(start,current)
+ start=startnext
+ break
end
+ current=getnext(current)
+ else
+ break
+ end
end
- return head,start,true
+ end
+ return head,start,true
end
function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replacement)
- local stop=getnext(start)
- local font=getfont(start)
- local last=start
- while stop do
- local char=ischar(stop,font)
- if char and (char==c_zwnj or char==c_zwj) then
- last=stop
- stop=getnext(stop)
- else
- break
- end
- end
- local prev=getprev(start)
- if stop then
- setnext(last)
- setlink(prev,stop)
- elseif prev then
- setnext(prev)
- end
- if head==start then
- head=stop
- end
- flush_list(start)
- return head,stop,true
+ local stop=getnext(start)
+ local font=getfont(start)
+ local last=start
+ while stop do
+ local char=ischar(stop,font)
+ if char and (char==c_zwnj or char==c_zwj) then
+ last=stop
+ stop=getnext(stop)
+ else
+ break
+ end
+ end
+ local prev=getprev(start)
+ if stop then
+ setnext(last)
+ setlink(prev,stop)
+ elseif prev then
+ setnext(prev)
+ end
+ if head==start then
+ head=stop
+ end
+ flush_list(start)
+ return head,stop,true
end
local function initialize_two(font,attr)
- local devanagari=fontdata[font].resources.devanagari
- if devanagari then
- return devanagari.seqsubset or {},devanagari.reorderreph or {}
- else
- return {},{}
- end
+ local devanagari=fontdata[font].resources.devanagari
+ if devanagari then
+ return devanagari.seqsubset or {},devanagari.reorderreph or {}
+ else
+ return {},{}
+ end
end
local function reorder_two(head,start,stop,font,attr,nbspaces)
- local seqsubset,reorderreph=initialize_two(font,attr)
- local reph=false
- local halfpos=nil
- local basepos=nil
- local subpos=nil
- local postpos=nil
- local locl={}
- for i=1,#seqsubset do
- local subset=seqsubset[i]
- local kind=subset[1]
- local lookupcache=subset[2]
- if kind=="rphf" then
- reph=subset[3]
- local current=start
- local last=getnext(stop)
- while current~=last do
- if current~=stop then
- local c=locl[current] or getchar(current)
- local found=lookupcache[c]
- if found then
- local next=getnext(current)
- local n=locl[next] or getchar(next)
- if found[n] then
- local afternext=next~=stop and getnext(next)
- if afternext and zw_char[getchar(afternext)] then
- current=afternext
- elseif current==start then
- setprop(current,a_state,s_rphf)
- current=next
- else
- current=next
- end
- end
- end
- end
- current=getnext(current)
- end
- elseif kind=="pref" then
- local current=start
- local last=getnext(stop)
- while current~=last do
- if current~=stop then
- local c=locl[current] or getchar(current)
- local found=lookupcache[c]
- if found then
- local next=getnext(current)
- local n=locl[next] or getchar(next)
- if found[n] then
- setprop(current,a_state,s_pref)
- setprop(next,a_state,s_pref)
- current=next
- end
- end
- end
- current=getnext(current)
- end
- elseif kind=="half" then
- local current=start
- local last=getnext(stop)
- while current~=last do
- if current~=stop then
- local c=locl[current] or getchar(current)
- local found=lookupcache[c]
- if found then
- local next=getnext(current)
- local n=locl[next] or getchar(next)
- if found[n] then
- if next~=stop and getchar(getnext(next))==c_zwnj then
- current=next
- else
- setprop(current,a_state,s_half)
- if not halfpos then
- halfpos=current
- end
- end
- current=getnext(current)
- end
- end
- end
- current=getnext(current)
- end
- elseif kind=="blwf" then
- local current=start
- local last=getnext(stop)
- while current~=last do
- if current~=stop then
- local c=locl[current] or getchar(current)
- local found=lookupcache[c]
- if found then
- local next=getnext(current)
- local n=locl[next] or getchar(next)
- if found[n] then
- setprop(current,a_state,s_blwf)
- setprop(next,a_state,s_blwf)
- current=next
- subpos=current
- end
- end
- end
- current=getnext(current)
- end
- elseif kind=="pstf" then
- local current=start
- local last=getnext(stop)
- while current~=last do
- if current~=stop then
- local c=locl[current] or getchar(current)
- local found=lookupcache[c]
- if found then
- local next=getnext(current)
- local n=locl[next] or getchar(next)
- if found[n] then
- setprop(current,a_state,s_pstf)
- setprop(next,a_state,s_pstf)
- current=next
- postpos=current
- end
- end
- end
- current=getnext(current)
+ local seqsubset,reorderreph=initialize_two(font,attr)
+ local reph=false
+ local halfpos=nil
+ local basepos=nil
+ local subpos=nil
+ local postpos=nil
+ local locl={}
+ for i=1,#seqsubset do
+ local subset=seqsubset[i]
+ local kind=subset[1]
+ local lookupcache=subset[2]
+ if kind=="rphf" then
+ reph=subset[3]
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=locl[current] or getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ local n=locl[next] or getchar(next)
+ if found[n] then
+ local afternext=next~=stop and getnext(next)
+ if afternext and zw_char[getchar(afternext)] then
+ current=afternext
+ elseif current==start then
+ setprop(current,a_state,s_rphf)
+ current=next
+ else
+ current=next
+ end
end
+ end
end
- end
- reorderreph.coverage={ [reph]=true }
- local current,base,firstcons=start,nil,nil
- if getprop(start,a_state)==s_rphf then
- current=getnext(getnext(start))
- end
- if current~=getnext(stop) and getchar(current)==c_nbsp then
- if current==stop then
- stop=getprev(stop)
- head=remove_node(head,current)
- flush_node(current)
- return head,stop,nbspaces
- else
- nbspaces=nbspaces+1
- base=current
- current=getnext(current)
- if current~=stop then
- local char=getchar(current)
- if nukta[char] then
- current=getnext(current)
- char=getchar(current)
- end
- if char==c_zwj then
- local next=getnext(current)
- if current~=stop and next~=stop and halant[getchar(next)] then
- current=next
- next=getnext(current)
- local tmp=getnext(next)
- local changestop=next==stop
- setnext(next)
- setprop(current,a_state,s_pref)
- current=processcharacters(current,font)
- setprop(current,a_state,s_blwf)
- current=processcharacters(current,font)
- setprop(current,a_state,s_pstf)
- current=processcharacters(current,font)
- setprop(current,a_state,unsetvalue)
- if halant[getchar(current)] then
- setnext(getnext(current),tmp)
- if show_syntax_errors then
- head,current=inject_syntax_error(head,current,char)
- end
- else
- setnext(current,tmp)
- if changestop then
- stop=current
- end
- end
- end
- end
+ current=getnext(current)
+ end
+ elseif kind=="pref" then
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=locl[current] or getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ local n=locl[next] or getchar(next)
+ if found[n] then
+ setprop(current,a_state,s_pref)
+ setprop(next,a_state,s_pref)
+ current=next
end
+ end
end
- else
- local last=getnext(stop)
- while current~=last do
+ current=getnext(current)
+ end
+ elseif kind=="half" then
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=locl[current] or getchar(current)
+ local found=lookupcache[c]
+ if found then
local next=getnext(current)
- if consonant[getchar(current)] then
- if not (current~=stop and next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwj) then
- if not firstcons then
- firstcons=current
- end
- local a=getprop(current,a_state)
- if not (a==s_pref or a==s_blwf or a==s_pstf) then
- base=current
- end
+ local n=locl[next] or getchar(next)
+ if found[n] then
+ if next~=stop and getchar(getnext(next))==c_zwnj then
+ current=next
+ else
+ setprop(current,a_state,s_half)
+ if not halfpos then
+ halfpos=current
end
+ end
+ current=getnext(current)
end
- current=next
- end
- if not base then
- base=firstcons
- end
- end
- if not base then
- if getprop(start,a_state)==s_rphf then
- setprop(start,a_state,unsetvalue)
+ end
end
- return head,stop,nbspaces
- else
- if getprop(base,a_state) then
- setprop(base,a_state,unsetvalue)
+ current=getnext(current)
+ end
+ elseif kind=="blwf" then
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=locl[current] or getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ local n=locl[next] or getchar(next)
+ if found[n] then
+ setprop(current,a_state,s_blwf)
+ setprop(next,a_state,s_blwf)
+ current=next
+ subpos=current
+ end
+ end
end
- basepos=base
- end
- if not halfpos then
- halfpos=base
- end
- if not subpos then
- subpos=base
- end
- if not postpos then
- postpos=subpos or base
- end
- local moved={}
- local current=start
- local last=getnext(stop)
- while current~=last do
- local char,target,cn=locl[current] or getchar(current),nil,getnext(current)
- local tpm=twopart_mark[char]
- if tpm then
- local extra=copy_node(current)
- copyinjection(extra,current)
- char=tpm[1]
- setchar(current,char)
- setchar(extra,tpm[2])
- head=insert_node_after(head,current,extra)
- end
- if not moved[current] and dependent_vowel[char] then
- if pre_mark[char] then
- moved[current]=true
- local prev,next=getboth(current)
- setlink(prev,next)
- if current==stop then
- stop=getprev(current)
- end
- if halfpos==start then
- if head==start then
- head=current
- end
- start=current
- end
- setlink(getprev(halfpos),current)
- setlink(current,halfpos)
- halfpos=current
- elseif above_mark[char] then
- target=basepos
- if subpos==basepos then
- subpos=current
- end
- if postpos==basepos then
- postpos=current
- end
- basepos=current
- elseif below_mark[char] then
- target=subpos
- if postpos==subpos then
- postpos=current
- end
- subpos=current
- elseif post_mark[char] then
- target=postpos
- postpos=current
- end
- if mark_above_below_post[char] then
- local prev=getprev(current)
- if prev~=target then
- local next=getnext(current)
- setlink(prev,next)
- if current==stop then
- stop=prev
- end
- setlink(current,getnext(target))
- setlink(target,current)
- end
+ current=getnext(current)
+ end
+ elseif kind=="pstf" then
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ if current~=stop then
+ local c=locl[current] or getchar(current)
+ local found=lookupcache[c]
+ if found then
+ local next=getnext(current)
+ local n=locl[next] or getchar(next)
+ if found[n] then
+ setprop(current,a_state,s_pstf)
+ setprop(next,a_state,s_pstf)
+ current=next
+ postpos=current
end
+ end
end
- current=cn
- end
- local current,c=start,nil
- while current~=stop do
+ current=getnext(current)
+ end
+ end
+ end
+ reorderreph.coverage={ [reph]=true }
+ local current,base,firstcons=start,nil,nil
+ if getprop(start,a_state)==s_rphf then
+ current=getnext(getnext(start))
+ end
+ if current~=getnext(stop) and getchar(current)==c_nbsp then
+ if current==stop then
+ stop=getprev(stop)
+ head=remove_node(head,current)
+ flush_node(current)
+ return head,stop,nbspaces
+ else
+ nbspaces=nbspaces+1
+ base=current
+ current=getnext(current)
+ if current~=stop then
local char=getchar(current)
- if halant[char] or stress_tone_mark[char] then
- if not c then
- c=current
- end
- else
- c=nil
+ if nukta[char] then
+ current=getnext(current)
+ char=getchar(current)
end
- local next=getnext(current)
- if c and nukta[getchar(next)] then
- if head==c then
- head=next
- end
- if stop==next then
+ if char==c_zwj then
+ local next=getnext(current)
+ if current~=stop and next~=stop and halant[getchar(next)] then
+ current=next
+ next=getnext(current)
+ local tmp=getnext(next)
+ local changestop=next==stop
+ setnext(next)
+ setprop(current,a_state,s_pref)
+ current=processcharacters(current,font)
+ setprop(current,a_state,s_blwf)
+ current=processcharacters(current,font)
+ setprop(current,a_state,s_pstf)
+ current=processcharacters(current,font)
+ setprop(current,a_state,unsetvalue)
+ if halant[getchar(current)] then
+ setnext(getnext(current),tmp)
+ if show_syntax_errors then
+ head,current=inject_syntax_error(head,current,char)
+ end
+ else
+ setnext(current,tmp)
+ if changestop then
stop=current
+ end
end
- setlink(getprev(c),next)
- local nextnext=getnext(next)
- setnext(current,nextnext)
- local nextnextnext=getnext(nextnext)
- if nextnextnext then
- setprev(nextnextnext,current)
- end
- setlink(nextnext,c)
+ end
end
- if stop==current then break end
- current=getnext(current)
+ end
end
- if getchar(base)==c_nbsp then
- if base==stop then
- stop=getprev(stop)
+ else
+ local last=getnext(stop)
+ while current~=last do
+ local next=getnext(current)
+ if consonant[getchar(current)] then
+ if not (current~=stop and next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwj) then
+ if not firstcons then
+ firstcons=current
+ end
+ local a=getprop(current,a_state)
+ if not (a==s_pref or a==s_blwf or a==s_pstf) then
+ base=current
+ end
end
- nbspaces=nbspaces-1
- head=remove_node(head,base)
- flush_node(base)
+ end
+ current=next
+ end
+ if not base then
+ base=firstcons
+ end
+ end
+ if not base then
+ if getprop(start,a_state)==s_rphf then
+ setprop(start,a_state,unsetvalue)
end
return head,stop,nbspaces
+ else
+ if getprop(base,a_state) then
+ setprop(base,a_state,unsetvalue)
+ end
+ basepos=base
+ end
+ if not halfpos then
+ halfpos=base
+ end
+ if not subpos then
+ subpos=base
+ end
+ if not postpos then
+ postpos=subpos or base
+ end
+ local moved={}
+ local current=start
+ local last=getnext(stop)
+ while current~=last do
+ local char,target,cn=locl[current] or getchar(current),nil,getnext(current)
+ local tpm=twopart_mark[char]
+ if tpm then
+ local extra=copy_node(current)
+ copyinjection(extra,current)
+ char=tpm[1]
+ setchar(current,char)
+ setchar(extra,tpm[2])
+ head=insert_node_after(head,current,extra)
+ end
+ if not moved[current] and dependent_vowel[char] then
+ if pre_mark[char] then
+ moved[current]=true
+ local prev,next=getboth(current)
+ setlink(prev,next)
+ if current==stop then
+ stop=getprev(current)
+ end
+ if halfpos==start then
+ if head==start then
+ head=current
+ end
+ start=current
+ end
+ setlink(getprev(halfpos),current)
+ setlink(current,halfpos)
+ halfpos=current
+ elseif above_mark[char] then
+ target=basepos
+ if subpos==basepos then
+ subpos=current
+ end
+ if postpos==basepos then
+ postpos=current
+ end
+ basepos=current
+ elseif below_mark[char] then
+ target=subpos
+ if postpos==subpos then
+ postpos=current
+ end
+ subpos=current
+ elseif post_mark[char] then
+ target=postpos
+ postpos=current
+ end
+ if mark_above_below_post[char] then
+ local prev=getprev(current)
+ if prev~=target then
+ local next=getnext(current)
+ setlink(prev,next)
+ if current==stop then
+ stop=prev
+ end
+ setlink(current,getnext(target))
+ setlink(target,current)
+ end
+ end
+ end
+ current=cn
+ end
+ local current,c=start,nil
+ while current~=stop do
+ local char=getchar(current)
+ if halant[char] or stress_tone_mark[char] then
+ if not c then
+ c=current
+ end
+ else
+ c=nil
+ end
+ local next=getnext(current)
+ if c and nukta[getchar(next)] then
+ if head==c then
+ head=next
+ end
+ if stop==next then
+ stop=current
+ end
+ setlink(getprev(c),next)
+ local nextnext=getnext(next)
+ setnext(current,nextnext)
+ local nextnextnext=getnext(nextnext)
+ if nextnextnext then
+ setprev(nextnextnext,current)
+ end
+ setlink(nextnext,c)
+ end
+ if stop==current then break end
+ current=getnext(current)
+ end
+ if getchar(base)==c_nbsp then
+ if base==stop then
+ stop=getprev(stop)
+ end
+ nbspaces=nbspaces-1
+ head=remove_node(head,base)
+ flush_node(base)
+ end
+ return head,stop,nbspaces
end
local separator={}
imerge(separator,consonant)
@@ -30428,572 +30428,572 @@ imerge(separator,independent_vowel)
imerge(separator,dependent_vowel)
imerge(separator,vowel_modifier)
imerge(separator,stress_tone_mark)
-for k,v in next,nukta do separator[k]=true end
+for k,v in next,nukta do separator[k]=true end
for k,v in next,halant do separator[k]=true end
local function analyze_next_chars_one(c,font,variant)
- local n=getnext(c)
- if not n then
- return c
- end
- if variant==1 then
- local v=ischar(n,font)
- if v and nukta[v] then
- n=getnext(n)
- if n then
- v=ischar(n,font)
- end
- end
- if n and v then
- local nn=getnext(n)
- if nn then
- local vv=ischar(nn,font)
- if vv then
- local nnn=getnext(nn)
- if nnn then
- local vvv=ischar(nnn,font)
- if vvv then
- if vv==c_zwj and consonant[vvv] then
- c=nnn
- elseif (vv==c_zwnj or vv==c_zwj) and halant[vvv] then
- local nnnn=getnext(nnn)
- if nnnn then
- local vvvv=ischar(nnnn,font)
- if vvvv and consonant[vvvv] then
- c=nnnn
- end
- end
- end
- end
- end
- end
- end
- end
- elseif variant==2 then
- local v=ischar(n,font)
- if v and nukta[v] then
- c=n
- end
- n=getnext(c)
- if n then
- v=ischar(n,font)
- if v then
- local nn=getnext(n)
- if nn then
- local vv=ischar(nn,font)
- if vv and zw_char[v] then
- n=nn
- v=vv
- nn=getnext(nn)
- vv=nn and ischar(nn,font)
- end
- if vv and halant[v] and consonant[vv] then
- c=nn
- end
+ local n=getnext(c)
+ if not n then
+ return c
+ end
+ if variant==1 then
+ local v=ischar(n,font)
+ if v and nukta[v] then
+ n=getnext(n)
+ if n then
+ v=ischar(n,font)
+ end
+ end
+ if n and v then
+ local nn=getnext(n)
+ if nn then
+ local vv=ischar(nn,font)
+ if vv then
+ local nnn=getnext(nn)
+ if nnn then
+ local vvv=ischar(nnn,font)
+ if vvv then
+ if vv==c_zwj and consonant[vvv] then
+ c=nnn
+ elseif (vv==c_zwnj or vv==c_zwj) and halant[vvv] then
+ local nnnn=getnext(nnn)
+ if nnnn then
+ local vvvv=ischar(nnnn,font)
+ if vvvv and consonant[vvvv] then
+ c=nnnn
+ end
end
+ end
end
+ end
end
+ end
+ end
+ elseif variant==2 then
+ local v=ischar(n,font)
+ if v and nukta[v] then
+ c=n
end
- local n=getnext(c)
+ n=getnext(c)
+ if n then
+ v=ischar(n,font)
+ if v then
+ local nn=getnext(n)
+ if nn then
+ local vv=ischar(nn,font)
+ if vv and zw_char[v] then
+ n=nn
+ v=vv
+ nn=getnext(nn)
+ vv=nn and ischar(nn,font)
+ end
+ if vv and halant[v] and consonant[vv] then
+ c=nn
+ end
+ end
+ end
+ end
+ end
+ local n=getnext(c)
+ if not n then
+ return c
+ end
+ local v=ischar(n,font)
+ if not v then
+ return c
+ end
+ if dependent_vowel[v] then
+ c=getnext(c)
+ n=getnext(c)
if not n then
- return c
+ return c
end
- local v=ischar(n,font)
+ v=ischar(n,font)
if not v then
- return c
+ return c
end
- if dependent_vowel[v] then
- c=getnext(c)
- n=getnext(c)
- if not n then
- return c
- end
- v=ischar(n,font)
- if not v then
- return c
- end
+ end
+ if nukta[v] then
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
end
- if nukta[v] then
- c=getnext(c)
- n=getnext(c)
- if not n then
- return c
- end
- v=ischar(n,font)
- if not v then
- return c
- end
+ v=ischar(n,font)
+ if not v then
+ return c
end
- if halant[v] then
- c=getnext(c)
- n=getnext(c)
- if not n then
- return c
- end
- v=ischar(n,font)
- if not v then
- return c
- end
+ end
+ if halant[v] then
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
end
- if vowel_modifier[v] then
- c=getnext(c)
- n=getnext(c)
- if not n then
- return c
- end
- v=ischar(n,font)
- if not v then
- return c
- end
+ v=ischar(n,font)
+ if not v then
+ return c
end
- if stress_tone_mark[v] then
- c=getnext(c)
- n=getnext(c)
- if not n then
- return c
- end
- v=ischar(n,font)
- if not v then
- return c
- end
+ end
+ if vowel_modifier[v] then
+ c=getnext(c)
+ n=getnext(c)
+ if not n then
+ return c
end
- if stress_tone_mark[v] then
- return n
- else
- return c
+ v=ischar(n,font)
+ if not v then
+ return c
end
-end
-local function analyze_next_chars_two(c,font)
- local n=getnext(c)
+ end
+ if stress_tone_mark[v] then
+ c=getnext(c)
+ n=getnext(c)
if not n then
- return c
+ return c
end
- local v=ischar(n,font)
- if v and nukta[v] then
- c=n
+ v=ischar(n,font)
+ if not v then
+ return c
end
- n=c
- while true do
+ end
+ if stress_tone_mark[v] then
+ return n
+ else
+ return c
+ end
+end
+local function analyze_next_chars_two(c,font)
+ local n=getnext(c)
+ if not n then
+ return c
+ end
+ local v=ischar(n,font)
+ if v and nukta[v] then
+ c=n
+ end
+ n=c
+ while true do
+ local nn=getnext(n)
+ if nn then
+ local vv=ischar(nn,font)
+ if vv then
+ if halant[vv] then
+ n=nn
+ local nnn=getnext(nn)
+ if nnn then
+ local vvv=ischar(nnn,font)
+ if vvv and zw_char[vvv] then
+ n=nnn
+ end
+ end
+ elseif vv==c_zwnj or vv==c_zwj then
+ local nnn=getnext(nn)
+ if nnn then
+ local vvv=ischar(nnn,font)
+ if vvv and halant[vvv] then
+ n=nnn
+ end
+ end
+ else
+ break
+ end
local nn=getnext(n)
if nn then
- local vv=ischar(nn,font)
- if vv then
- if halant[vv] then
- n=nn
- local nnn=getnext(nn)
- if nnn then
- local vvv=ischar(nnn,font)
- if vvv and zw_char[vvv] then
- n=nnn
- end
- end
- elseif vv==c_zwnj or vv==c_zwj then
- local nnn=getnext(nn)
- if nnn then
- local vvv=ischar(nnn,font)
- if vvv and halant[vvv] then
- n=nnn
- end
- end
- else
- break
- end
- local nn=getnext(n)
- if nn then
- local vv=ischar(nn,font)
- if vv and consonant[vv] then
- n=nn
- local nnn=getnext(nn)
- if nnn then
- local vvv=ischar(nnn,font)
- if vvv and nukta[vvv] then
- n=nnn
- end
- end
- c=n
- else
- break
- end
- else
- break
- end
- else
- break
+ local vv=ischar(nn,font)
+ if vv and consonant[vv] then
+ n=nn
+ local nnn=getnext(nn)
+ if nnn then
+ local vvv=ischar(nnn,font)
+ if vvv and nukta[vvv] then
+ n=nnn
+ end
end
- else
+ c=n
+ else
break
+ end
+ else
+ break
end
+ else
+ break
+ end
+ else
+ break
end
- if not c then
- return
+ end
+ if not c then
+ return
+ end
+ local n=getnext(c)
+ if not n then
+ return c
+ end
+ local v=ischar(n,font)
+ if not v then
+ return c
+ end
+ if anudatta[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
end
- local n=getnext(c)
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if halant[v] then
+ c=n
+ n=getnext(c)
if not n then
- return c
+ return c
end
- local v=ischar(n,font)
+ v=ischar(n,font)
if not v then
+ return c
+ end
+ if v==c_zwnj or v==c_zwj then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
return c
+ end
end
- if anudatta[v] then
- c=n
- n=getnext(c)
- if not n then
- return c
- end
- v=ischar(n,font)
- if not v then
- return c
- end
+ else
+ if dependent_vowel[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if nukta[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
end
if halant[v] then
- c=n
- n=getnext(c)
- if not n then
- return c
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ end
+ if vowel_modifier[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ c=n
+ n=getnext(c)
+ if not n then
+ return c
+ end
+ v=ischar(n,font)
+ if not v then
+ return c
+ end
+ end
+ if stress_tone_mark[v] then
+ return n
+ else
+ return c
+ end
+end
+local function method_one(head,font,attr)
+ local current=head
+ local start=true
+ local done=false
+ local nbspaces=0
+ while current do
+ local char=ischar(current,font)
+ if char then
+ done=true
+ local syllablestart=current
+ local syllableend=nil
+ local c=current
+ local n=getnext(c)
+ local first=char
+ if n and ra[first] then
+ local second=ischar(n,font)
+ if second and halant[second] then
+ local n=getnext(n)
+ if n then
+ local third=ischar(n,font)
+ if third then
+ c=n
+ first=third
+ end
+ end
end
- v=ischar(n,font)
- if not v then
- return c
+ end
+ local standalone=first==c_nbsp
+ if standalone then
+ local prev=getprev(current)
+ if prev then
+ local prevchar=ischar(prev,font)
+ if not prevchar then
+ elseif not separator[prevchar] then
+ else
+ standalone=false
+ end
+ else
end
- if v==c_zwnj or v==c_zwj then
- c=n
- n=getnext(c)
- if not n then
- return c
- end
- v=ischar(n,font)
- if not v then
- return c
- end
+ end
+ if standalone then
+ local syllableend=analyze_next_chars_one(c,font,2)
+ current=getnext(syllableend)
+ if syllablestart~=syllableend then
+ head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces)
+ current=getnext(current)
end
- else
- if dependent_vowel[v] then
- c=n
- n=getnext(c)
+ else
+ if consonant[char] then
+ local prevc=true
+ while prevc do
+ prevc=false
+ local n=getnext(current)
if not n then
- return c
+ break
end
- v=ischar(n,font)
+ local v=ischar(n,font)
if not v then
- return c
+ break
end
- end
- if nukta[v] then
- c=n
- n=getnext(c)
- if not n then
- return c
+ if nukta[v] then
+ n=getnext(n)
+ if not n then
+ break
+ end
+ v=ischar(n,font)
+ if not v then
+ break
+ end
end
- v=ischar(n,font)
- if not v then
- return c
+ if halant[v] then
+ n=getnext(n)
+ if not n then
+ break
+ end
+ v=ischar(n,font)
+ if not v then
+ break
+ end
+ if v==c_zwnj or v==c_zwj then
+ n=getnext(n)
+ if not n then
+ break
+ end
+ v=ischar(n,font)
+ if not v then
+ break
+ end
+ end
+ if consonant[v] then
+ prevc=true
+ current=n
+ end
end
- end
- if halant[v] then
- c=n
- n=getnext(c)
- if not n then
- return c
+ end
+ local n=getnext(current)
+ if n then
+ local v=ischar(n,font)
+ if v and nukta[v] then
+ current=n
+ n=getnext(current)
end
- v=ischar(n,font)
+ end
+ syllableend=current
+ current=n
+ if current then
+ local v=ischar(current,font)
if not v then
- return c
- end
- end
- end
- if vowel_modifier[v] then
- c=n
- n=getnext(c)
- if not n then
- return c
- end
- v=ischar(n,font)
- if not v then
- return c
- end
- end
- if stress_tone_mark[v] then
- c=n
- n=getnext(c)
- if not n then
- return c
- end
- v=ischar(n,font)
- if not v then
- return c
- end
- end
- if stress_tone_mark[v] then
- return n
- else
- return c
- end
-end
-local function method_one(head,font,attr)
- local current=head
- local start=true
- local done=false
- local nbspaces=0
- while current do
- local char=ischar(current,font)
- if char then
- done=true
- local syllablestart=current
- local syllableend=nil
- local c=current
- local n=getnext(c)
- local first=char
- if n and ra[first] then
- local second=ischar(n,font)
- if second and halant[second] then
- local n=getnext(n)
- if n then
- local third=ischar(n,font)
- if third then
- c=n
- first=third
- end
- end
- end
- end
- local standalone=first==c_nbsp
- if standalone then
- local prev=getprev(current)
- if prev then
- local prevchar=ischar(prev,font)
- if not prevchar then
- elseif not separator[prevchar] then
- else
- standalone=false
- end
+ elseif halant[v] then
+ local n=getnext(current)
+ if n then
+ local v=ischar(n,font)
+ if v and zw_char[v] then
+ syllableend=n
+ current=getnext(n)
else
+ syllableend=current
+ current=n
end
- end
- if standalone then
- local syllableend=analyze_next_chars_one(c,font,2)
- current=getnext(syllableend)
- if syllablestart~=syllableend then
- head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces)
- current=getnext(current)
- end
+ else
+ syllableend=current
+ current=n
+ end
else
- if consonant[char] then
- local prevc=true
- while prevc do
- prevc=false
- local n=getnext(current)
- if not n then
- break
- end
- local v=ischar(n,font)
- if not v then
- break
- end
- if nukta[v] then
- n=getnext(n)
- if not n then
- break
- end
- v=ischar(n,font)
- if not v then
- break
- end
- end
- if halant[v] then
- n=getnext(n)
- if not n then
- break
- end
- v=ischar(n,font)
- if not v then
- break
- end
- if v==c_zwnj or v==c_zwj then
- n=getnext(n)
- if not n then
- break
- end
- v=ischar(n,font)
- if not v then
- break
- end
- end
- if consonant[v] then
- prevc=true
- current=n
- end
- end
- end
- local n=getnext(current)
- if n then
- local v=ischar(n,font)
- if v and nukta[v] then
- current=n
- n=getnext(current)
- end
- end
- syllableend=current
- current=n
- if current then
- local v=ischar(current,font)
- if not v then
- elseif halant[v] then
- local n=getnext(current)
- if n then
- local v=ischar(n,font)
- if v and zw_char[v] then
- syllableend=n
- current=getnext(n)
- else
- syllableend=current
- current=n
- end
- else
- syllableend=current
- current=n
- end
- else
- if dependent_vowel[v] then
- syllableend=current
- current=getnext(current)
- v=ischar(current,font)
- end
- if v and vowel_modifier[v] then
- syllableend=current
- current=getnext(current)
- v=ischar(current,font)
- end
- if v and stress_tone_mark[v] then
- syllableend=current
- current=getnext(current)
- end
- end
- end
- if syllablestart~=syllableend then
- head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces)
- current=getnext(current)
- end
- elseif independent_vowel[char] then
- syllableend=current
- current=getnext(current)
- if current then
- local v=ischar(current,font)
- if v then
- if vowel_modifier[v] then
- syllableend=current
- current=getnext(current)
- v=ischar(current,font)
- end
- if v and stress_tone_mark[v] then
- syllableend=current
- current=getnext(current)
- end
- end
- end
- else
- if show_syntax_errors then
- local mark=mark_four[char]
- if mark then
- head,current=inject_syntax_error(head,current,char)
- end
- end
- current=getnext(current)
- end
+ if dependent_vowel[v] then
+ syllableend=current
+ current=getnext(current)
+ v=ischar(current,font)
+ end
+ if v and vowel_modifier[v] then
+ syllableend=current
+ current=getnext(current)
+ v=ischar(current,font)
+ end
+ if v and stress_tone_mark[v] then
+ syllableend=current
+ current=getnext(current)
+ end
end
- else
+ end
+ if syllablestart~=syllableend then
+ head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces)
current=getnext(current)
+ end
+ elseif independent_vowel[char] then
+ syllableend=current
+ current=getnext(current)
+ if current then
+ local v=ischar(current,font)
+ if v then
+ if vowel_modifier[v] then
+ syllableend=current
+ current=getnext(current)
+ v=ischar(current,font)
+ end
+ if v and stress_tone_mark[v] then
+ syllableend=current
+ current=getnext(current)
+ end
+ end
+ end
+ else
+ if show_syntax_errors then
+ local mark=mark_four[char]
+ if mark then
+ head,current=inject_syntax_error(head,current,char)
+ end
+ end
+ current=getnext(current)
end
- start=false
- end
- if nbspaces>0 then
- head=replace_all_nbsp(head)
+ end
+ else
+ current=getnext(current)
end
- return head,done
+ start=false
+ end
+ if nbspaces>0 then
+ head=replace_all_nbsp(head)
+ end
+ return head,done
end
local function method_two(head,font,attr)
- local current=head
- local start=true
- local done=false
- local syllabe=0
- local nbspaces=0
- while current do
- local syllablestart=nil
- local syllableend=nil
- local char=ischar(current,font)
- if char then
- done=true
- syllablestart=current
- local c=current
- local n=getnext(current)
- if n and ra[char] then
- local nextchar=ischar(n,font)
- if nextchar and halant[nextchar] then
- local n=getnext(n)
- if n then
- local nextnextchar=ischar(n,font)
- if nextnextchar then
- c=n
- char=nextnextchar
- end
- end
- end
- end
- if independent_vowel[char] then
- current=analyze_next_chars_one(c,font,1)
- syllableend=current
- else
- local standalone=char==c_nbsp
- if standalone then
- nbspaces=nbspaces+1
- local p=getprev(current)
- if not p then
- elseif ischar(p,font) then
- elseif not separator[getchar(p)] then
- else
- standalone=false
- end
- end
- if standalone then
- current=analyze_next_chars_one(c,font,2)
- syllableend=current
- elseif consonant[getchar(current)] then
- current=analyze_next_chars_two(current,font)
- syllableend=current
- end
- end
- end
- if syllableend then
- syllabe=syllabe+1
- local c=syllablestart
- local n=getnext(syllableend)
- while c~=n do
- setprop(c,a_syllabe,syllabe)
- c=getnext(c)
+ local current=head
+ local start=true
+ local done=false
+ local syllabe=0
+ local nbspaces=0
+ while current do
+ local syllablestart=nil
+ local syllableend=nil
+ local char=ischar(current,font)
+ if char then
+ done=true
+ syllablestart=current
+ local c=current
+ local n=getnext(current)
+ if n and ra[char] then
+ local nextchar=ischar(n,font)
+ if nextchar and halant[nextchar] then
+ local n=getnext(n)
+ if n then
+ local nextnextchar=ischar(n,font)
+ if nextnextchar then
+ c=n
+ char=nextnextchar
end
+ end
end
- if syllableend and syllablestart~=syllableend then
- head,current,nbspaces=reorder_two(head,syllablestart,syllableend,font,attr,nbspaces)
- end
- if not syllableend and show_syntax_errors then
- local char=ischar(current,font)
- if char and not getprop(current,a_state) then
- local mark=mark_four[char]
- if mark then
- head,current=inject_syntax_error(head,current,char)
- end
- end
+ end
+ if independent_vowel[char] then
+ current=analyze_next_chars_one(c,font,1)
+ syllableend=current
+ else
+ local standalone=char==c_nbsp
+ if standalone then
+ nbspaces=nbspaces+1
+ local p=getprev(current)
+ if not p then
+ elseif ischar(p,font) then
+ elseif not separator[getchar(p)] then
+ else
+ standalone=false
+ end
end
- start=false
- current=getnext(current)
+ if standalone then
+ current=analyze_next_chars_one(c,font,2)
+ syllableend=current
+ elseif consonant[getchar(current)] then
+ current=analyze_next_chars_two(current,font)
+ syllableend=current
+ end
+ end
+ end
+ if syllableend then
+ syllabe=syllabe+1
+ local c=syllablestart
+ local n=getnext(syllableend)
+ while c~=n do
+ setprop(c,a_syllabe,syllabe)
+ c=getnext(c)
+ end
+ end
+ if syllableend and syllablestart~=syllableend then
+ head,current,nbspaces=reorder_two(head,syllablestart,syllableend,font,attr,nbspaces)
end
- if nbspaces>0 then
- head=replace_all_nbsp(head)
+ if not syllableend and show_syntax_errors then
+ local char=ischar(current,font)
+ if char and not getprop(current,a_state) then
+ local mark=mark_four[char]
+ if mark then
+ head,current=inject_syntax_error(head,current,char)
+ end
+ end
end
- return head,done
+ start=false
+ current=getnext(current)
+ end
+ if nbspaces>0 then
+ head=replace_all_nbsp(head)
+ end
+ return head,done
end
for i=1,nofscripts do
- methods[scripts_one[i]]=method_one
- methods[scripts_two[i]]=method_two
+ methods[scripts_one[i]]=method_one
+ methods[scripts_two[i]]=method_two
end
end -- closure
@@ -31001,11 +31001,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-ocl']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tostring,tonumber,next=tostring,tonumber,next
local round,max=math.round,math.round
@@ -31026,440 +31026,440 @@ if context then
--removed
else
- local tounicode=fonts.mappings.tounicode16
- function otf.getactualtext(s)
- return
- "/Span << /ActualText <feff"..s.."> >> BDC",
- "EMC"
- end
+ local tounicode=fonts.mappings.tounicode16
+ function otf.getactualtext(s)
+ return
+ "/Span << /ActualText <feff"..s.."> >> BDC",
+ "EMC"
+ end
end
local sharedpalettes={}
local hash=setmetatableindex(function(t,k)
- local v={ "pdf","direct",k }
- t[k]=v
- return v
+ local v={ "pdf","direct",k }
+ t[k]=v
+ return v
end)
if context then
--removed
else
- function otf.registerpalette(name,values)
- sharedpalettes[name]=values
- for i=1,#values do
- local v=values[i]
- if v then
- values[i]=hash[f_color(
- max(round((v.r or 0)*255),255)/255,
- max(round((v.g or 0)*255),255)/255,
- max(round((v.b or 0)*255),255)/255
- )]
- end
- end
- end
+ function otf.registerpalette(name,values)
+ sharedpalettes[name]=values
+ for i=1,#values do
+ local v=values[i]
+ if v then
+ values[i]=hash[f_color(
+ max(round((v.r or 0)*255),255)/255,
+ max(round((v.g or 0)*255),255)/255,
+ max(round((v.b or 0)*255),255)/255
+ )]
+ end
+ end
+ end
end
local function convert(t,k)
- local v={}
- for i=1,#k do
- local p=k[i]
- local r,g,b=p[1],p[2],p[3]
- if r==g and g==b then
- v[i]=hash[f_gray(r/255)]
- else
- v[i]=hash[f_color(r/255,g/255,b/255)]
- end
+ local v={}
+ for i=1,#k do
+ local p=k[i]
+ local r,g,b=p[1],p[2],p[3]
+ if r==g and g==b then
+ v[i]=hash[f_gray(r/255)]
+ else
+ v[i]=hash[f_color(r/255,g/255,b/255)]
end
- t[k]=v
- return v
+ end
+ t[k]=v
+ return v
end
local start={ "pdf","mode","font" }
local push={ "pdf","page","q" }
local pop={ "pdf","page","Q" }
if not LUATEXFUNCTIONALITY or LUATEXFUNCTIONALITY<6472 then
- start={ "nop" }
+ start={ "nop" }
end
local function initialize(tfmdata,kind,value)
- if value then
- local resources=tfmdata.resources
- local palettes=resources.colorpalettes
- if palettes then
- local converted=resources.converted
- if not converted then
- converted=setmetatableindex(convert)
- resources.converted=converted
- end
- local colorvalues=sharedpalettes[value]
- local default=false
- if colorvalues then
- default=colorvalues[#colorvalues]
- else
- colorvalues=converted[palettes[tonumber(value) or 1] or palettes[1]] or {}
- end
- local classes=#colorvalues
- if classes==0 then
- return
- end
- local characters=tfmdata.characters
- local descriptions=tfmdata.descriptions
- local properties=tfmdata.properties
- properties.virtualized=true
- tfmdata.fonts={
- { id=0 }
+ if value then
+ local resources=tfmdata.resources
+ local palettes=resources.colorpalettes
+ if palettes then
+ local converted=resources.converted
+ if not converted then
+ converted=setmetatableindex(convert)
+ resources.converted=converted
+ end
+ local colorvalues=sharedpalettes[value]
+ local default=false
+ if colorvalues then
+ default=colorvalues[#colorvalues]
+ else
+ colorvalues=converted[palettes[tonumber(value) or 1] or palettes[1]] or {}
+ end
+ local classes=#colorvalues
+ if classes==0 then
+ return
+ end
+ local characters=tfmdata.characters
+ local descriptions=tfmdata.descriptions
+ local properties=tfmdata.properties
+ properties.virtualized=true
+ tfmdata.fonts={
+ { id=0 }
+ }
+ local getactualtext=otf.getactualtext
+ local b,e=getactualtext(tounicode(0xFFFD))
+ local actualb={ "pdf","page",b }
+ local actuale={ "pdf","page",e }
+ for unicode,character in next,characters do
+ local description=descriptions[unicode]
+ if description then
+ local colorlist=description.colors
+ if colorlist then
+ local u=description.unicode or characters[unicode].unicode
+ local w=character.width or 0
+ local s=#colorlist
+ local goback=w~=0 and leftcommand[w] or nil
+ local t={
+ start,
+ not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }
}
- local getactualtext=otf.getactualtext
- local b,e=getactualtext(tounicode(0xFFFD))
- local actualb={ "pdf","page",b }
- local actuale={ "pdf","page",e }
- for unicode,character in next,characters do
- local description=descriptions[unicode]
- if description then
- local colorlist=description.colors
- if colorlist then
- local u=description.unicode or characters[unicode].unicode
- local w=character.width or 0
- local s=#colorlist
- local goback=w~=0 and leftcommand[w] or nil
- local t={
- start,
- not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }
- }
- local n=2
- local l=nil
- local f=false
- for i=1,s do
- local entry=colorlist[i]
- local v=colorvalues[entry.class] or default
- if v and l~=v then
- if f then
- n=n+1 t[n]=pop
- end
- n=n+1 t[n]=push
- f=true
- n=n+1 t[n]=v
- l=v
- else
- if f then
- n=n+1 t[n]=pop
- end
- f=false
- l=nil
- end
- n=n+1 t[n]=charcommand[entry.slot]
- if s>1 and i<s and goback then
- n=n+1 t[n]=goback
- end
- end
- if f then
- n=n+1 t[n]=pop
- end
- n=n+1 t[n]=actuale
- character.commands=t
- end
+ local n=2
+ local l=nil
+ local f=false
+ for i=1,s do
+ local entry=colorlist[i]
+ local v=colorvalues[entry.class] or default
+ if v and l~=v then
+ if f then
+ n=n+1 t[n]=pop
+ end
+ n=n+1 t[n]=push
+ f=true
+ n=n+1 t[n]=v
+ l=v
+ else
+ if f then
+ n=n+1 t[n]=pop
end
+ f=false
+ l=nil
+ end
+ n=n+1 t[n]=charcommand[entry.slot]
+ if s>1 and i<s and goback then
+ n=n+1 t[n]=goback
+ end
end
+ if f then
+ n=n+1 t[n]=pop
+ end
+ n=n+1 t[n]=actuale
+ character.commands=t
+ end
end
+ end
end
+ end
end
fonts.handlers.otf.features.register {
- name="colr",
- description="color glyphs",
- manipulators={
- base=initialize,
- node=initialize,
- }
+ name="colr",
+ description="color glyphs",
+ manipulators={
+ base=initialize,
+ node=initialize,
+ }
}
do
- local nofstreams=0
- local f_name=formatters[ [[pdf-glyph-%05i]] ]
- local f_used=context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ]
- local hashed={}
- local cache={}
- if epdf then
- local openpdf=epdf.openMemStream
- function otf.storepdfdata(pdf)
- local done=hashed[pdf]
- if not done then
- nofstreams=nofstreams+1
- local o,n=openpdf(pdf,#pdf,f_name(nofstreams))
- cache[n]=o
- done=f_used(n)
- hashed[pdf]=done
- end
- return done
- end
- else
- local openpdf=pdfe.new
- function otf.storepdfdata(pdf)
- local done=hashed[pdf]
- if not done then
- nofstreams=nofstreams+1
- local f=f_name(nofstreams)
- local n=openpdf(pdf,#pdf,f)
- done=f_used(n)
- hashed[pdf]=done
- end
- return done
- end
- end
+ local nofstreams=0
+ local f_name=formatters[ [[pdf-glyph-%05i]] ]
+ local f_used=context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ]
+ local hashed={}
+ local cache={}
+ if epdf then
+ local openpdf=epdf.openMemStream
+ function otf.storepdfdata(pdf)
+ local done=hashed[pdf]
+ if not done then
+ nofstreams=nofstreams+1
+ local o,n=openpdf(pdf,#pdf,f_name(nofstreams))
+ cache[n]=o
+ done=f_used(n)
+ hashed[pdf]=done
+ end
+ return done
+ end
+ else
+ local openpdf=pdfe.new
+ function otf.storepdfdata(pdf)
+ local done=hashed[pdf]
+ if not done then
+ nofstreams=nofstreams+1
+ local f=f_name(nofstreams)
+ local n=openpdf(pdf,#pdf,f)
+ done=f_used(n)
+ hashed[pdf]=done
+ end
+ return done
+ end
+ end
end
local function pdftovirtual(tfmdata,pdfshapes,kind)
- if not tfmdata or not pdfshapes or not kind then
- return
- end
- local characters=tfmdata.characters
- local properties=tfmdata.properties
- local parameters=tfmdata.parameters
- local hfactor=parameters.hfactor
- properties.virtualized=true
- tfmdata.fonts={
- { id=0 }
- }
- local getactualtext=otf.getactualtext
- local storepdfdata=otf.storepdfdata
- local b,e=getactualtext(tounicode(0xFFFD))
- local actualb={ "pdf","page",b }
- local actuale={ "pdf","page",e }
- local vfimage=lpdf and lpdf.vfimage or function(wd,ht,dp,data,name)
- local name=storepdfdata(data)
- return { "image",{ filename=name,width=wd,height=ht,depth=dp } }
- end
- for unicode,character in sortedhash(characters) do
- local index=character.index
- if index then
- local pdf=pdfshapes[index]
- local typ=type(pdf)
- local data=nil
- local dx=nil
- local dy=nil
- if typ=="table" then
- data=pdf.data
- dx=pdf.dx or 0
- dy=pdf.dy or 0
- elseif typ=="string" then
- data=pdf
- dx=0
- dy=0
- end
- if data then
- local bt=unicode and getactualtext(unicode)
- local wd=character.width or 0
- local ht=character.height or 0
- local dp=character.depth or 0
- character.commands={
- not unicode and actualb or { "pdf","page",(getactualtext(unicode)) },
- downcommand[dp+dy*hfactor],
- rightcommand[dx*hfactor],
- vfimage(wd,ht,dp,data,name),
- actuale,
- }
- character[kind]=true
- end
- end
+ if not tfmdata or not pdfshapes or not kind then
+ return
+ end
+ local characters=tfmdata.characters
+ local properties=tfmdata.properties
+ local parameters=tfmdata.parameters
+ local hfactor=parameters.hfactor
+ properties.virtualized=true
+ tfmdata.fonts={
+ { id=0 }
+ }
+ local getactualtext=otf.getactualtext
+ local storepdfdata=otf.storepdfdata
+ local b,e=getactualtext(tounicode(0xFFFD))
+ local actualb={ "pdf","page",b }
+ local actuale={ "pdf","page",e }
+ local vfimage=lpdf and lpdf.vfimage or function(wd,ht,dp,data,name)
+ local name=storepdfdata(data)
+ return { "image",{ filename=name,width=wd,height=ht,depth=dp } }
+ end
+ for unicode,character in sortedhash(characters) do
+ local index=character.index
+ if index then
+ local pdf=pdfshapes[index]
+ local typ=type(pdf)
+ local data=nil
+ local dx=nil
+ local dy=nil
+ if typ=="table" then
+ data=pdf.data
+ dx=pdf.dx or 0
+ dy=pdf.dy or 0
+ elseif typ=="string" then
+ data=pdf
+ dx=0
+ dy=0
+ end
+ if data then
+ local bt=unicode and getactualtext(unicode)
+ local wd=character.width or 0
+ local ht=character.height or 0
+ local dp=character.depth or 0
+ character.commands={
+ not unicode and actualb or { "pdf","page",(getactualtext(unicode)) },
+ downcommand[dp+dy*hfactor],
+ rightcommand[dx*hfactor],
+ vfimage(wd,ht,dp,data,name),
+ actuale,
+ }
+ character[kind]=true
+ end
end
+ end
end
local otfsvg=otf.svg or {}
otf.svg=otfsvg
otf.svgenabled=true
do
- local report_svg=logs.reporter("fonts","svg conversion")
- local loaddata=io.loaddata
- local savedata=io.savedata
- local remove=os.remove
- if context and xml.convert then
- local xmlconvert=xml.convert
- local xmlfirst=xml.first
- function otfsvg.filterglyph(entry,index)
- local svg=xmlconvert(entry.data)
- local root=svg and xmlfirst(svg,"/svg[@id='glyph"..index.."']")
- local data=root and tostring(root)
- return data
- end
- else
- function otfsvg.filterglyph(entry,index)
- return entry.data
- end
- end
- local runner=sandbox and sandbox.registerrunner {
- name="otfsvg",
- program="inkscape",
- method="pipeto",
- template="--shell > temp-otf-svg-shape.log",
- reporter=report_svg,
- }
- if not runner then
- runner=function()
- return io.open("inkscape --shell > temp-otf-svg-shape.log","w")
- end
- end
- function otfsvg.topdf(svgshapes)
- local pdfshapes={}
- local inkscape=runner()
- if inkscape then
- local nofshapes=#svgshapes
- local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"]
- local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"]
- local f_convert=formatters["%s --export-pdf=%s\n"]
- local filterglyph=otfsvg.filterglyph
- local nofdone=0
- report_svg("processing %i svg containers",nofshapes)
- statistics.starttiming()
- for i=1,nofshapes do
- local entry=svgshapes[i]
- for index=entry.first,entry.last do
- local data=filterglyph(entry,index)
- if data and data~="" then
- local svgfile=f_svgfile(index)
- local pdffile=f_pdffile(index)
- savedata(svgfile,data)
- inkscape:write(f_convert(svgfile,pdffile))
- pdfshapes[index]=true
- nofdone=nofdone+1
- if nofdone%100==0 then
- report_svg("%i shapes processed",nofdone)
- end
- end
- end
- end
- inkscape:write("quit\n")
- inkscape:close()
- report_svg("processing %i pdf results",nofshapes)
- for index in next,pdfshapes do
- local svgfile=f_svgfile(index)
- local pdffile=f_pdffile(index)
- pdfshapes[index]=loaddata(pdffile)
- remove(svgfile)
- remove(pdffile)
- end
- statistics.stoptiming()
- if statistics.elapsedseconds then
- report_svg("svg conversion time %s",statistics.elapsedseconds() or "-")
+ local report_svg=logs.reporter("fonts","svg conversion")
+ local loaddata=io.loaddata
+ local savedata=io.savedata
+ local remove=os.remove
+ if context and xml.convert then
+ local xmlconvert=xml.convert
+ local xmlfirst=xml.first
+ function otfsvg.filterglyph(entry,index)
+ local svg=xmlconvert(entry.data)
+ local root=svg and xmlfirst(svg,"/svg[@id='glyph"..index.."']")
+ local data=root and tostring(root)
+ return data
+ end
+ else
+ function otfsvg.filterglyph(entry,index)
+ return entry.data
+ end
+ end
+ local runner=sandbox and sandbox.registerrunner {
+ name="otfsvg",
+ program="inkscape",
+ method="pipeto",
+ template="--shell > temp-otf-svg-shape.log",
+ reporter=report_svg,
+ }
+ if not runner then
+ runner=function()
+ return io.open("inkscape --shell > temp-otf-svg-shape.log","w")
+ end
+ end
+ function otfsvg.topdf(svgshapes)
+ local pdfshapes={}
+ local inkscape=runner()
+ if inkscape then
+ local nofshapes=#svgshapes
+ local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"]
+ local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"]
+ local f_convert=formatters["%s --export-pdf=%s\n"]
+ local filterglyph=otfsvg.filterglyph
+ local nofdone=0
+ report_svg("processing %i svg containers",nofshapes)
+ statistics.starttiming()
+ for i=1,nofshapes do
+ local entry=svgshapes[i]
+ for index=entry.first,entry.last do
+ local data=filterglyph(entry,index)
+ if data and data~="" then
+ local svgfile=f_svgfile(index)
+ local pdffile=f_pdffile(index)
+ savedata(svgfile,data)
+ inkscape:write(f_convert(svgfile,pdffile))
+ pdfshapes[index]=true
+ nofdone=nofdone+1
+ if nofdone%100==0 then
+ report_svg("%i shapes processed",nofdone)
end
+ end
end
- return pdfshapes
+ end
+ inkscape:write("quit\n")
+ inkscape:close()
+ report_svg("processing %i pdf results",nofshapes)
+ for index in next,pdfshapes do
+ local svgfile=f_svgfile(index)
+ local pdffile=f_pdffile(index)
+ pdfshapes[index]=loaddata(pdffile)
+ remove(svgfile)
+ remove(pdffile)
+ end
+ statistics.stoptiming()
+ if statistics.elapsedseconds then
+ report_svg("svg conversion time %s",statistics.elapsedseconds() or "-")
+ end
end
+ return pdfshapes
+ end
end
local function initializesvg(tfmdata,kind,value)
- if value and otf.svgenabled then
- local svg=tfmdata.properties.svg
- local hash=svg and svg.hash
- local timestamp=svg and svg.timestamp
- if not hash then
- return
- end
- local pdffile=containers.read(otf.pdfcache,hash)
- local pdfshapes=pdffile and pdffile.pdfshapes
- if not pdfshapes or pdffile.timestamp~=timestamp then
- local svgfile=containers.read(otf.svgcache,hash)
- local svgshapes=svgfile and svgfile.svgshapes
- pdfshapes=svgshapes and otfsvg.topdf(svgshapes) or {}
- containers.write(otf.pdfcache,hash,{
- pdfshapes=pdfshapes,
- timestamp=timestamp,
- })
- end
- pdftovirtual(tfmdata,pdfshapes,"svg")
- end
+ if value and otf.svgenabled then
+ local svg=tfmdata.properties.svg
+ local hash=svg and svg.hash
+ local timestamp=svg and svg.timestamp
+ if not hash then
+ return
+ end
+ local pdffile=containers.read(otf.pdfcache,hash)
+ local pdfshapes=pdffile and pdffile.pdfshapes
+ if not pdfshapes or pdffile.timestamp~=timestamp then
+ local svgfile=containers.read(otf.svgcache,hash)
+ local svgshapes=svgfile and svgfile.svgshapes
+ pdfshapes=svgshapes and otfsvg.topdf(svgshapes) or {}
+ containers.write(otf.pdfcache,hash,{
+ pdfshapes=pdfshapes,
+ timestamp=timestamp,
+ })
+ end
+ pdftovirtual(tfmdata,pdfshapes,"svg")
+ end
end
fonts.handlers.otf.features.register {
- name="svg",
- description="svg glyphs",
- manipulators={
- base=initializesvg,
- node=initializesvg,
- }
+ name="svg",
+ description="svg glyphs",
+ manipulators={
+ base=initializesvg,
+ node=initializesvg,
+ }
}
local otfpng=otf.png or {}
otf.png=otfpng
otf.pngenabled=true
do
- local report_png=logs.reporter("fonts","png conversion")
- local loaddata=io.loaddata
- local savedata=io.savedata
- local remove=os.remove
- local runner=sandbox and sandbox.registerrunner {
- name="otfpng",
- program="gm",
- template="convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log",
- }
- if not runner then
- runner=function()
- return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log")
- end
- end
- function otfpng.topdf(pngshapes)
- local pdfshapes={}
- local pngfile="temp-otf-png-shape.png"
- local pdffile="temp-otf-png-shape.pdf"
- local nofdone=0
- local indices=sortedkeys(pngshapes)
- local nofindices=#indices
- report_png("processing %i png containers",nofindices)
- statistics.starttiming()
- for i=1,nofindices do
- local index=indices[i]
- local entry=pngshapes[index]
- local data=entry.data
- local x=entry.x
- local y=entry.y
- savedata(pngfile,data)
- runner()
- pdfshapes[index]={
- x=x~=0 and x or nil,
- y=y~=0 and y or nil,
- data=loaddata(pdffile),
- }
- nofdone=nofdone+1
- if nofdone%100==0 then
- report_png("%i shapes processed",nofdone)
- end
- end
- report_png("processing %i pdf results",nofindices)
- remove(pngfile)
- remove(pdffile)
- statistics.stoptiming()
- if statistics.elapsedseconds then
- report_png("png conversion time %s",statistics.elapsedseconds() or "-")
- end
- return pdfshapes
- end
+ local report_png=logs.reporter("fonts","png conversion")
+ local loaddata=io.loaddata
+ local savedata=io.savedata
+ local remove=os.remove
+ local runner=sandbox and sandbox.registerrunner {
+ name="otfpng",
+ program="gm",
+ template="convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log",
+ }
+ if not runner then
+ runner=function()
+ return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log")
+ end
+ end
+ function otfpng.topdf(pngshapes)
+ local pdfshapes={}
+ local pngfile="temp-otf-png-shape.png"
+ local pdffile="temp-otf-png-shape.pdf"
+ local nofdone=0
+ local indices=sortedkeys(pngshapes)
+ local nofindices=#indices
+ report_png("processing %i png containers",nofindices)
+ statistics.starttiming()
+ for i=1,nofindices do
+ local index=indices[i]
+ local entry=pngshapes[index]
+ local data=entry.data
+ local x=entry.x
+ local y=entry.y
+ savedata(pngfile,data)
+ runner()
+ pdfshapes[index]={
+ x=x~=0 and x or nil,
+ y=y~=0 and y or nil,
+ data=loaddata(pdffile),
+ }
+ nofdone=nofdone+1
+ if nofdone%100==0 then
+ report_png("%i shapes processed",nofdone)
+ end
+ end
+ report_png("processing %i pdf results",nofindices)
+ remove(pngfile)
+ remove(pdffile)
+ statistics.stoptiming()
+ if statistics.elapsedseconds then
+ report_png("png conversion time %s",statistics.elapsedseconds() or "-")
+ end
+ return pdfshapes
+ end
end
local function initializepng(tfmdata,kind,value)
- if value and otf.pngenabled then
- local png=tfmdata.properties.png
- local hash=png and png.hash
- local timestamp=png and png.timestamp
- if not hash then
- return
- end
- local pdffile=containers.read(otf.pdfcache,hash)
- local pdfshapes=pdffile and pdffile.pdfshapes
- if not pdfshapes or pdffile.timestamp~=timestamp then
- local pngfile=containers.read(otf.pngcache,hash)
- local pngshapes=pngfile and pngfile.pngshapes
- pdfshapes=pngshapes and otfpng.topdf(pngshapes) or {}
- containers.write(otf.pdfcache,hash,{
- pdfshapes=pdfshapes,
- timestamp=timestamp,
- })
- end
- pdftovirtual(tfmdata,pdfshapes,"png")
- end
+ if value and otf.pngenabled then
+ local png=tfmdata.properties.png
+ local hash=png and png.hash
+ local timestamp=png and png.timestamp
+ if not hash then
+ return
+ end
+ local pdffile=containers.read(otf.pdfcache,hash)
+ local pdfshapes=pdffile and pdffile.pdfshapes
+ if not pdfshapes or pdffile.timestamp~=timestamp then
+ local pngfile=containers.read(otf.pngcache,hash)
+ local pngshapes=pngfile and pngfile.pngshapes
+ pdfshapes=pngshapes and otfpng.topdf(pngshapes) or {}
+ containers.write(otf.pdfcache,hash,{
+ pdfshapes=pdfshapes,
+ timestamp=timestamp,
+ })
+ end
+ pdftovirtual(tfmdata,pdfshapes,"png")
+ end
end
fonts.handlers.otf.features.register {
- name="sbix",
- description="sbix glyphs",
- manipulators={
- base=initializepng,
- node=initializepng,
- }
+ name="sbix",
+ description="sbix glyphs",
+ manipulators={
+ base=initializepng,
+ node=initializepng,
+ }
}
fonts.handlers.otf.features.register {
- name="cblc",
- description="cblc glyphs",
- manipulators={
- base=initializepng,
- node=initializepng,
- }
+ name="cblc",
+ description="cblc glyphs",
+ manipulators={
+ base=initializepng,
+ node=initializepng,
+ }
}
end -- closure
@@ -31467,18 +31467,18 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-otc']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local insert,sortedkeys,sortedhash,tohash=table.insert,table.sortedkeys,table.sortedhash,table.tohash
local type,next,tonumber=type,next,tonumber
local lpegmatch=lpeg.match
local utfbyte,utflen=utf.byte,utf.len
local sortedhash=table.sortedhash
-local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
+local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end)
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
@@ -31488,727 +31488,727 @@ local checkmerge=fonts.helpers.checkmerge
local checkflags=fonts.helpers.checkflags
local checksteps=fonts.helpers.checksteps
local normalized={
- substitution="substitution",
- single="substitution",
- ligature="ligature",
- alternate="alternate",
- multiple="multiple",
- kern="kern",
- pair="pair",
- single="single",
- chainsubstitution="chainsubstitution",
- chainposition="chainposition",
+ substitution="substitution",
+ single="substitution",
+ ligature="ligature",
+ alternate="alternate",
+ multiple="multiple",
+ kern="kern",
+ pair="pair",
+ single="single",
+ chainsubstitution="chainsubstitution",
+ chainposition="chainposition",
}
local types={
- substitution="gsub_single",
- ligature="gsub_ligature",
- alternate="gsub_alternate",
- multiple="gsub_multiple",
- kern="gpos_pair",
- pair="gpos_pair",
- single="gpos_single",
- chainsubstitution="gsub_contextchain",
- chainposition="gpos_contextchain",
+ substitution="gsub_single",
+ ligature="gsub_ligature",
+ alternate="gsub_alternate",
+ multiple="gsub_multiple",
+ kern="gpos_pair",
+ pair="gpos_pair",
+ single="gpos_single",
+ chainsubstitution="gsub_contextchain",
+ chainposition="gpos_contextchain",
}
local names={
- gsub_single="gsub",
- gsub_multiple="gsub",
- gsub_alternate="gsub",
- gsub_ligature="gsub",
- gsub_context="gsub",
- gsub_contextchain="gsub",
- gsub_reversecontextchain="gsub",
- gpos_single="gpos",
- gpos_pair="gpos",
- gpos_cursive="gpos",
- gpos_mark2base="gpos",
- gpos_mark2ligature="gpos",
- gpos_mark2mark="gpos",
- gpos_context="gpos",
- gpos_contextchain="gpos",
+ gsub_single="gsub",
+ gsub_multiple="gsub",
+ gsub_alternate="gsub",
+ gsub_ligature="gsub",
+ gsub_context="gsub",
+ gsub_contextchain="gsub",
+ gsub_reversecontextchain="gsub",
+ gpos_single="gpos",
+ gpos_pair="gpos",
+ gpos_cursive="gpos",
+ gpos_mark2base="gpos",
+ gpos_mark2ligature="gpos",
+ gpos_mark2mark="gpos",
+ gpos_context="gpos",
+ gpos_contextchain="gpos",
}
setmetatableindex(types,function(t,k) t[k]=k return k end)
local everywhere={ ["*"]={ ["*"]=true } }
local noflags={ false,false,false,false }
local function getrange(sequences,category)
- local count=#sequences
- local first=nil
- local last=nil
- for i=1,count do
- local t=sequences[i].type
- if t and names[t]==category then
- if not first then
- first=i
- end
- last=i
- end
- end
- return first or 1,last or count
+ local count=#sequences
+ local first=nil
+ local last=nil
+ for i=1,count do
+ local t=sequences[i].type
+ if t and names[t]==category then
+ if not first then
+ first=i
+ end
+ last=i
+ end
+ end
+ return first or 1,last or count
end
local function validspecification(specification,name)
- local dataset=specification.dataset
- if dataset then
- elseif specification[1] then
- dataset=specification
- specification={ dataset=dataset }
- else
- dataset={ { data=specification.data } }
- specification.data=nil
- specification.dataset=dataset
- end
- local first=dataset[1]
- if first then
- first=first.data
- end
- if not first then
- report_otf("invalid feature specification, no dataset")
- return
- end
- if type(name)~="string" then
- name=specification.name or first.name
- end
- if type(name)~="string" then
- report_otf("invalid feature specification, no name")
- return
- end
- local n=#dataset
- if n>0 then
- for i=1,n do
- setmetatableindex(dataset[i],specification)
- end
- return specification,name
+ local dataset=specification.dataset
+ if dataset then
+ elseif specification[1] then
+ dataset=specification
+ specification={ dataset=dataset }
+ else
+ dataset={ { data=specification.data } }
+ specification.data=nil
+ specification.dataset=dataset
+ end
+ local first=dataset[1]
+ if first then
+ first=first.data
+ end
+ if not first then
+ report_otf("invalid feature specification, no dataset")
+ return
+ end
+ if type(name)~="string" then
+ name=specification.name or first.name
+ end
+ if type(name)~="string" then
+ report_otf("invalid feature specification, no name")
+ return
+ end
+ local n=#dataset
+ if n>0 then
+ for i=1,n do
+ setmetatableindex(dataset[i],specification)
end
+ return specification,name
+ end
end
local function addfeature(data,feature,specifications)
- if not specifications then
- report_otf("missing specification")
- return
- end
- local descriptions=data.descriptions
- local resources=data.resources
- local features=resources.features
- local sequences=resources.sequences
- if not features or not sequences then
- report_otf("missing specification")
- return
- end
- local alreadydone=resources.alreadydone
- if not alreadydone then
- alreadydone={}
- resources.alreadydone=alreadydone
- end
- if alreadydone[specifications] then
- return
- else
- alreadydone[specifications]=true
- end
- local fontfeatures=resources.features or everywhere
- local unicodes=resources.unicodes
- local splitter=lpeg.splitter(" ",unicodes)
- local done=0
- local skip=0
- local aglunicodes=false
- local specifications=validspecification(specifications,feature)
- if not specifications then
- return
- end
- local p=lpeg.P("P")*(lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)*lpeg.P(-1)
- local function tounicode(code)
- if not code then
- return
+ if not specifications then
+ report_otf("missing specification")
+ return
+ end
+ local descriptions=data.descriptions
+ local resources=data.resources
+ local features=resources.features
+ local sequences=resources.sequences
+ if not features or not sequences then
+ report_otf("missing specification")
+ return
+ end
+ local alreadydone=resources.alreadydone
+ if not alreadydone then
+ alreadydone={}
+ resources.alreadydone=alreadydone
+ end
+ if alreadydone[specifications] then
+ return
+ else
+ alreadydone[specifications]=true
+ end
+ local fontfeatures=resources.features or everywhere
+ local unicodes=resources.unicodes
+ local splitter=lpeg.splitter(" ",unicodes)
+ local done=0
+ local skip=0
+ local aglunicodes=false
+ local specifications=validspecification(specifications,feature)
+ if not specifications then
+ return
+ end
+ local p=lpeg.P("P")*(lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)*lpeg.P(-1)
+ local function tounicode(code)
+ if not code then
+ return
+ end
+ if type(code)=="number" then
+ return code
+ end
+ local u=unicodes[code]
+ if u then
+ return u
+ end
+ if utflen(code)==1 then
+ u=utfbyte(code)
+ if u then
+ return u
+ end
+ end
+ local u=lpegmatch(p,code)
+ if u then
+ return u
+ end
+ if not aglunicodes then
+ aglunicodes=fonts.encodings.agl.unicodes
+ end
+ local u=aglunicodes[code]
+ if u then
+ return u
+ end
+ end
+ local coverup=otf.coverup
+ local coveractions=coverup.actions
+ local stepkey=coverup.stepkey
+ local register=coverup.register
+ local function prepare_substitution(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ else
+ if type(replacement)=="table" then
+ replacement=replacement[1]
+ end
+ replacement=tounicode(replacement)
+ if replacement and descriptions[replacement] then
+ cover(coverage,unicode,replacement)
+ done=done+1
+ else
+ skip=skip+1
end
- if type(code)=="number" then
- return code
+ end
+ end
+ return coverage
+ end
+ local function prepare_alternate(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ elseif type(replacement)=="table" then
+ local r={}
+ for i=1,#replacement do
+ local u=tounicode(replacement[i])
+ r[i]=(nocheck or descriptions[u]) and u or unicode
end
- local u=unicodes[code]
+ cover(coverage,unicode,r)
+ done=done+1
+ else
+ local u=tounicode(replacement)
if u then
- return u
- end
- if utflen(code)==1 then
- u=utfbyte(code)
- if u then
- return u
- end
+ cover(coverage,unicode,{ u })
+ done=done+1
+ else
+ skip=skip+1
end
- local u=lpegmatch(p,code)
- if u then
- return u
+ end
+ end
+ return coverage
+ end
+ local function prepare_multiple(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ elseif type(replacement)=="table" then
+ local r,n={},0
+ for i=1,#replacement do
+ local u=tounicode(replacement[i])
+ if nocheck or descriptions[u] then
+ n=n+1
+ r[n]=u
+ end
end
- if not aglunicodes then
- aglunicodes=fonts.encodings.agl.unicodes
+ if n>0 then
+ cover(coverage,unicode,r)
+ done=done+1
+ else
+ skip=skip+1
end
- local u=aglunicodes[code]
+ else
+ local u=tounicode(replacement)
if u then
- return u
- end
- end
- local coverup=otf.coverup
- local coveractions=coverup.actions
- local stepkey=coverup.stepkey
- local register=coverup.register
- local function prepare_substitution(list,featuretype,nocheck)
- local coverage={}
- local cover=coveractions[featuretype]
- for code,replacement in next,list do
- local unicode=tounicode(code)
- local description=descriptions[unicode]
- if not nocheck and not description then
- skip=skip+1
- else
- if type(replacement)=="table" then
- replacement=replacement[1]
- end
- replacement=tounicode(replacement)
- if replacement and descriptions[replacement] then
- cover(coverage,unicode,replacement)
- done=done+1
- else
- skip=skip+1
- end
- end
+ cover(coverage,unicode,{ u })
+ done=done+1
+ else
+ skip=skip+1
end
- return coverage
- end
- local function prepare_alternate(list,featuretype,nocheck)
- local coverage={}
- local cover=coveractions[featuretype]
- for code,replacement in next,list do
- local unicode=tounicode(code)
- local description=descriptions[unicode]
- if not nocheck and not description then
- skip=skip+1
- elseif type(replacement)=="table" then
- local r={}
- for i=1,#replacement do
- local u=tounicode(replacement[i])
- r[i]=(nocheck or descriptions[u]) and u or unicode
- end
- cover(coverage,unicode,r)
- done=done+1
- else
- local u=tounicode(replacement)
- if u then
- cover(coverage,unicode,{ u })
- done=done+1
- else
- skip=skip+1
- end
- end
+ end
+ end
+ return coverage
+ end
+ local function prepare_ligature(list,featuretype,nocheck)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ for code,ligature in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if not nocheck and not description then
+ skip=skip+1
+ else
+ if type(ligature)=="string" then
+ ligature={ lpegmatch(splitter,ligature) }
+ end
+ local present=true
+ for i=1,#ligature do
+ local l=ligature[i]
+ local u=tounicode(l)
+ if nocheck or descriptions[u] then
+ ligature[i]=u
+ else
+ present=false
+ break
+ end
end
- return coverage
- end
- local function prepare_multiple(list,featuretype,nocheck)
- local coverage={}
- local cover=coveractions[featuretype]
- for code,replacement in next,list do
- local unicode=tounicode(code)
- local description=descriptions[unicode]
- if not nocheck and not description then
- skip=skip+1
- elseif type(replacement)=="table" then
- local r,n={},0
- for i=1,#replacement do
- local u=tounicode(replacement[i])
- if nocheck or descriptions[u] then
- n=n+1
- r[n]=u
- end
- end
- if n>0 then
- cover(coverage,unicode,r)
- done=done+1
- else
- skip=skip+1
- end
- else
- local u=tounicode(replacement)
- if u then
- cover(coverage,unicode,{ u })
- done=done+1
- else
- skip=skip+1
- end
- end
+ if present then
+ cover(coverage,unicode,ligature)
+ done=done+1
+ else
+ skip=skip+1
end
- return coverage
+ end
end
- local function prepare_ligature(list,featuretype,nocheck)
- local coverage={}
- local cover=coveractions[featuretype]
- for code,ligature in next,list do
- local unicode=tounicode(code)
- local description=descriptions[unicode]
- if not nocheck and not description then
- skip=skip+1
- else
- if type(ligature)=="string" then
- ligature={ lpegmatch(splitter,ligature) }
- end
- local present=true
- for i=1,#ligature do
- local l=ligature[i]
- local u=tounicode(l)
- if nocheck or descriptions[u] then
- ligature[i]=u
- else
- present=false
- break
- end
- end
- if present then
- cover(coverage,unicode,ligature)
- done=done+1
- else
- skip=skip+1
- end
+ return coverage
+ end
+ local function resetspacekerns()
+ data.properties.hasspacekerns=true
+ data.resources .spacekerns=nil
+ end
+ local function prepare_kern(list,featuretype)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ local isspace=false
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if description and type(replacement)=="table" then
+ local r={}
+ for k,v in next,replacement do
+ local u=tounicode(k)
+ if u then
+ r[u]=v
+ if u==32 then
+ isspace=true
end
+ end
end
- return coverage
- end
- local function resetspacekerns()
- data.properties.hasspacekerns=true
- data.resources .spacekerns=nil
- end
- local function prepare_kern(list,featuretype)
- local coverage={}
- local cover=coveractions[featuretype]
- local isspace=false
- for code,replacement in next,list do
- local unicode=tounicode(code)
- local description=descriptions[unicode]
- if description and type(replacement)=="table" then
- local r={}
- for k,v in next,replacement do
- local u=tounicode(k)
- if u then
- r[u]=v
- if u==32 then
- isspace=true
- end
- end
- end
- if next(r) then
- cover(coverage,unicode,r)
- done=done+1
- if unicode==32 then
- isspace=true
- end
- else
- skip=skip+1
- end
- else
- skip=skip+1
- end
- end
- if isspace then
- resetspacekerns()
- end
- return coverage
- end
- local function prepare_pair(list,featuretype)
- local coverage={}
- local cover=coveractions[featuretype]
- if cover then
- for code,replacement in next,list do
- local unicode=tounicode(code)
- local description=descriptions[unicode]
- if description and type(replacement)=="table" then
- local r={}
- for k,v in next,replacement do
- local u=tounicode(k)
- if u then
- r[u]=v
- if u==32 then
- isspace=true
- end
- end
- end
- if next(r) then
- cover(coverage,unicode,r)
- done=done+1
- if unicode==32 then
- isspace=true
- end
- else
- skip=skip+1
- end
- else
- skip=skip+1
- end
- end
- if isspace then
- resetspacekerns()
- end
+ if next(r) then
+ cover(coverage,unicode,r)
+ done=done+1
+ if unicode==32 then
+ isspace=true
+ end
else
- report_otf("unknown cover type %a",featuretype)
+ skip=skip+1
end
- return coverage
+ else
+ skip=skip+1
+ end
end
- local prepare_single=prepare_pair
- local function prepare_chain(list,featuretype,sublookups)
- local rules=list.rules
- local coverage={}
- if rules then
- local rulehash={}
- local rulesize=0
- local lookuptype=types[featuretype]
- for nofrules=1,#rules do
- local rule=rules[nofrules]
- local current=rule.current
- local before=rule.before
- local after=rule.after
- local replacements=rule.replacements or false
- local sequence={}
- local nofsequences=0
- if before then
- for n=1,#before do
- nofsequences=nofsequences+1
- sequence[nofsequences]=before[n]
- end
- end
- local start=nofsequences+1
- for n=1,#current do
- nofsequences=nofsequences+1
- sequence[nofsequences]=current[n]
- end
- local stop=nofsequences
- if after then
- for n=1,#after do
- nofsequences=nofsequences+1
- sequence[nofsequences]=after[n]
- end
- end
- local lookups=rule.lookups or false
- local subtype=nil
- if lookups and sublookups then
- for k,v in sortedhash(lookups) do
- local t=type(v)
- if t=="table" then
- for i=1,#v do
- local vi=v[i]
- if type(vi)~="table" then
- v[i]={ vi }
- end
- end
- elseif t=="number" then
- local lookup=sublookups[v]
- if lookup then
- lookups[k]={ lookup }
- if not subtype then
- subtype=lookup.type
- end
- elseif v==0 then
- lookups[k]={ { type="gsub_remove" } }
- else
- lookups[k]=false
- end
- else
- lookups[k]=false
- end
- end
- end
- if nofsequences>0 then
- local hashed={}
- for i=1,nofsequences do
- local t={}
- local s=sequence[i]
- for i=1,#s do
- local u=tounicode(s[i])
- if u then
- t[u]=true
- end
- end
- hashed[i]=t
- end
- sequence=hashed
- rulesize=rulesize+1
- rulehash[rulesize]={
- nofrules,
- lookuptype,
- sequence,
- start,
- stop,
- lookups,
- replacements,
- subtype,
- }
- for unic in sortedhash(sequence[start]) do
- local cu=coverage[unic]
- if not cu then
- coverage[unic]=rulehash
- end
- end
- sequence.n=nofsequences
- end
+ if isspace then
+ resetspacekerns()
+ end
+ return coverage
+ end
+ local function prepare_pair(list,featuretype)
+ local coverage={}
+ local cover=coveractions[featuretype]
+ if cover then
+ for code,replacement in next,list do
+ local unicode=tounicode(code)
+ local description=descriptions[unicode]
+ if description and type(replacement)=="table" then
+ local r={}
+ for k,v in next,replacement do
+ local u=tounicode(k)
+ if u then
+ r[u]=v
+ if u==32 then
+ isspace=true
+ end
+ end
+ end
+ if next(r) then
+ cover(coverage,unicode,r)
+ done=done+1
+ if unicode==32 then
+ isspace=true
end
- rulehash.n=rulesize
+ else
+ skip=skip+1
+ end
+ else
+ skip=skip+1
end
- return coverage
- end
- local dataset=specifications.dataset
- local function report(name,category,position,first,last,sequences)
- report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]",
- name,category,position,first,last,1,#sequences)
+ end
+ if isspace then
+ resetspacekerns()
+ end
+ else
+ report_otf("unknown cover type %a",featuretype)
end
- local function inject(specification,sequences,sequence,first,last,category,name)
- local position=specification.position or false
- if not position then
- position=specification.prepend
- if position==true then
- if trace_loading then
- report(name,category,first,first,last,sequences)
- end
- insert(sequences,first,sequence)
- return
- end
+ return coverage
+ end
+ local prepare_single=prepare_pair
+ local function prepare_chain(list,featuretype,sublookups)
+ local rules=list.rules
+ local coverage={}
+ if rules then
+ local rulehash={}
+ local rulesize=0
+ local lookuptype=types[featuretype]
+ for nofrules=1,#rules do
+ local rule=rules[nofrules]
+ local current=rule.current
+ local before=rule.before
+ local after=rule.after
+ local replacements=rule.replacements or false
+ local sequence={}
+ local nofsequences=0
+ if before then
+ for n=1,#before do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=before[n]
+ end
end
- if not position then
- position=specification.append
- if position==true then
- if trace_loading then
- report(name,category,last+1,first,last,sequences)
- end
- insert(sequences,last+1,sequence)
- return
- end
+ local start=nofsequences+1
+ for n=1,#current do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=current[n]
end
- local kind=type(position)
- if kind=="string" then
- local index=false
- for i=first,last do
- local s=sequences[i]
- local f=s.features
- if f then
- for k in sortedhash(f) do
- if k==position then
- index=i
- break
- end
- end
- if index then
- break
- end
+ local stop=nofsequences
+ if after then
+ for n=1,#after do
+ nofsequences=nofsequences+1
+ sequence[nofsequences]=after[n]
+ end
+ end
+ local lookups=rule.lookups or false
+ local subtype=nil
+ if lookups and sublookups then
+ for k,v in sortedhash(lookups) do
+ local t=type(v)
+ if t=="table" then
+ for i=1,#v do
+ local vi=v[i]
+ if type(vi)~="table" then
+ v[i]={ vi }
end
- end
- if index then
- position=index
+ end
+ elseif t=="number" then
+ local lookup=sublookups[v]
+ if lookup then
+ lookups[k]={ lookup }
+ if not subtype then
+ subtype=lookup.type
+ end
+ elseif v==0 then
+ lookups[k]={ { type="gsub_remove" } }
+ else
+ lookups[k]=false
+ end
else
- position=last+1
+ lookups[k]=false
end
- elseif kind=="number" then
- if position<0 then
- position=last-position+1
+ end
+ end
+ if nofsequences>0 then
+ local hashed={}
+ for i=1,nofsequences do
+ local t={}
+ local s=sequence[i]
+ for i=1,#s do
+ local u=tounicode(s[i])
+ if u then
+ t[u]=true
+ end
end
- if position>last then
- position=last+1
- elseif position<first then
- position=first
+ hashed[i]=t
+ end
+ sequence=hashed
+ rulesize=rulesize+1
+ rulehash[rulesize]={
+ nofrules,
+ lookuptype,
+ sequence,
+ start,
+ stop,
+ lookups,
+ replacements,
+ subtype,
+ }
+ for unic in sortedhash(sequence[start]) do
+ local cu=coverage[unic]
+ if not cu then
+ coverage[unic]=rulehash
end
- else
- position=last+1
+ end
+ sequence.n=nofsequences
+ end
+ end
+ rulehash.n=rulesize
+ end
+ return coverage
+ end
+ local dataset=specifications.dataset
+ local function report(name,category,position,first,last,sequences)
+ report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]",
+ name,category,position,first,last,1,#sequences)
+ end
+ local function inject(specification,sequences,sequence,first,last,category,name)
+ local position=specification.position or false
+ if not position then
+ position=specification.prepend
+ if position==true then
+ if trace_loading then
+ report(name,category,first,first,last,sequences)
end
+ insert(sequences,first,sequence)
+ return
+ end
+ end
+ if not position then
+ position=specification.append
+ if position==true then
if trace_loading then
- report(name,category,position,first,last,sequences)
- end
- insert(sequences,position,sequence)
- end
- for s=1,#dataset do
- local specification=dataset[s]
- local valid=specification.valid
- local feature=specification.name or feature
- if not feature or feature=="" then
- report_otf("no valid name given for extra feature")
- elseif not valid or valid(data,specification,feature) then
- local initialize=specification.initialize
- if initialize then
- specification.initialize=initialize(specification,data) and initialize or nil
- end
- local askedfeatures=specification.features or everywhere
- local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
- local featuretype=normalized[specification.type or "substitution"] or "substitution"
- local featureflags=specification.flags or noflags
- local nocheck=specification.nocheck
- local futuresteps=specification.futuresteps
- local featureorder=specification.order or { feature }
- local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0
- local nofsteps=0
- local steps={}
- local sublookups=specification.lookups
- local category=nil
- checkflags(specification,resources)
- if sublookups then
- local s={}
- for i=1,#sublookups do
- local specification=sublookups[i]
- local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
- local featuretype=normalized[specification.type or "substitution"] or "substitution"
- local featureflags=specification.flags or noflags
- local nofsteps=0
- local steps={}
- for i=1,#askedsteps do
- local list=askedsteps[i]
- local coverage=nil
- local format=nil
- if featuretype=="substitution" then
- coverage=prepare_substitution(list,featuretype,nocheck)
- elseif featuretype=="ligature" then
- coverage=prepare_ligature(list,featuretype,nocheck)
- elseif featuretype=="alternate" then
- coverage=prepare_alternate(list,featuretype,nocheck)
- elseif featuretype=="multiple" then
- coverage=prepare_multiple(list,featuretype,nocheck)
- elseif featuretype=="kern" or featuretype=="move" then
- format=featuretype
- coverage=prepare_kern(list,featuretype)
- elseif featuretype=="pair" then
- format="pair"
- coverage=prepare_pair(list,featuretype)
- elseif featuretype=="single" then
- format="single"
- coverage=prepare_single(list,featuretype)
- end
- if coverage and next(coverage) then
- nofsteps=nofsteps+1
- steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
- end
- end
- checkmerge(specification)
- checksteps(specification)
- s[i]={
- [stepkey]=steps,
- nofsteps=nofsteps,
- flags=featureflags,
- type=types[featuretype],
- }
- end
- sublookups=s
- end
- for i=1,#askedsteps do
- local list=askedsteps[i]
- local coverage=nil
- local format=nil
- if featuretype=="substitution" then
- category="gsub"
- coverage=prepare_substitution(list,featuretype,nocheck)
- elseif featuretype=="ligature" then
- category="gsub"
- coverage=prepare_ligature(list,featuretype,nocheck)
- elseif featuretype=="alternate" then
- category="gsub"
- coverage=prepare_alternate(list,featuretype,nocheck)
- elseif featuretype=="multiple" then
- category="gsub"
- coverage=prepare_multiple(list,featuretype,nocheck)
- elseif featuretype=="kern" or featuretype=="move" then
- category="gpos"
- format=featuretype
- coverage=prepare_kern(list,featuretype)
- elseif featuretype=="pair" then
- category="gpos"
- format="pair"
- coverage=prepare_pair(list,featuretype)
- elseif featuretype=="single" then
- category="gpos"
- format="single"
- coverage=prepare_single(list,featuretype)
- elseif featuretype=="chainsubstitution" then
- category="gsub"
- coverage=prepare_chain(list,featuretype,sublookups)
- elseif featuretype=="chainposition" then
- category="gpos"
- coverage=prepare_chain(list,featuretype,sublookups)
- else
- report_otf("not registering feature %a, unknown category",feature)
- return
- end
- if coverage and next(coverage) then
- nofsteps=nofsteps+1
- steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
- end
- end
- if nofsteps>0 then
- for k,v in next,askedfeatures do
- if v[1] then
- askedfeatures[k]=tohash(v)
- end
- end
- if featureflags[1] then featureflags[1]="mark" end
- if featureflags[2] then featureflags[2]="ligature" end
- if featureflags[3] then featureflags[3]="base" end
- local steptype=types[featuretype]
- local sequence={
- chain=featurechain,
- features={ [feature]=askedfeatures },
- flags=featureflags,
- name=feature,
- order=featureorder,
- [stepkey]=steps,
- nofsteps=nofsteps,
- type=steptype,
- }
- checkflags(sequence,resources)
- checkmerge(sequence)
- checksteps(sequence)
- local first,last=getrange(sequences,category)
- inject(specification,sequences,sequence,first,last,category,feature)
- local features=fontfeatures[category]
- if not features then
- features={}
- fontfeatures[category]=features
- end
- local k=features[feature]
- if not k then
- k={}
- features[feature]=k
- end
- for script,languages in next,askedfeatures do
- local kk=k[script]
- if not kk then
- kk={}
- k[script]=kk
- end
- for language,value in next,languages do
- kk[language]=value
- end
- end
+ report(name,category,last+1,first,last,sequences)
+ end
+ insert(sequences,last+1,sequence)
+ return
+ end
+ end
+ local kind=type(position)
+ if kind=="string" then
+ local index=false
+ for i=first,last do
+ local s=sequences[i]
+ local f=s.features
+ if f then
+ for k in sortedhash(f) do
+ if k==position then
+ index=i
+ break
end
+ end
+ if index then
+ break
+ end
end
+ end
+ if index then
+ position=index
+ else
+ position=last+1
+ end
+ elseif kind=="number" then
+ if position<0 then
+ position=last-position+1
+ end
+ if position>last then
+ position=last+1
+ elseif position<first then
+ position=first
+ end
+ else
+ position=last+1
end
if trace_loading then
- report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip)
+ report(name,category,position,first,last,sequences)
+ end
+ insert(sequences,position,sequence)
+ end
+ for s=1,#dataset do
+ local specification=dataset[s]
+ local valid=specification.valid
+ local feature=specification.name or feature
+ if not feature or feature=="" then
+ report_otf("no valid name given for extra feature")
+ elseif not valid or valid(data,specification,feature) then
+ local initialize=specification.initialize
+ if initialize then
+ specification.initialize=initialize(specification,data) and initialize or nil
+ end
+ local askedfeatures=specification.features or everywhere
+ local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
+ local featuretype=normalized[specification.type or "substitution"] or "substitution"
+ local featureflags=specification.flags or noflags
+ local nocheck=specification.nocheck
+ local futuresteps=specification.futuresteps
+ local featureorder=specification.order or { feature }
+ local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0
+ local nofsteps=0
+ local steps={}
+ local sublookups=specification.lookups
+ local category=nil
+ checkflags(specification,resources)
+ if sublookups then
+ local s={}
+ for i=1,#sublookups do
+ local specification=sublookups[i]
+ local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
+ local featuretype=normalized[specification.type or "substitution"] or "substitution"
+ local featureflags=specification.flags or noflags
+ local nofsteps=0
+ local steps={}
+ for i=1,#askedsteps do
+ local list=askedsteps[i]
+ local coverage=nil
+ local format=nil
+ if featuretype=="substitution" then
+ coverage=prepare_substitution(list,featuretype,nocheck)
+ elseif featuretype=="ligature" then
+ coverage=prepare_ligature(list,featuretype,nocheck)
+ elseif featuretype=="alternate" then
+ coverage=prepare_alternate(list,featuretype,nocheck)
+ elseif featuretype=="multiple" then
+ coverage=prepare_multiple(list,featuretype,nocheck)
+ elseif featuretype=="kern" or featuretype=="move" then
+ format=featuretype
+ coverage=prepare_kern(list,featuretype)
+ elseif featuretype=="pair" then
+ format="pair"
+ coverage=prepare_pair(list,featuretype)
+ elseif featuretype=="single" then
+ format="single"
+ coverage=prepare_single(list,featuretype)
+ end
+ if coverage and next(coverage) then
+ nofsteps=nofsteps+1
+ steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
+ end
+ end
+ checkmerge(specification)
+ checksteps(specification)
+ s[i]={
+ [stepkey]=steps,
+ nofsteps=nofsteps,
+ flags=featureflags,
+ type=types[featuretype],
+ }
+ end
+ sublookups=s
+ end
+ for i=1,#askedsteps do
+ local list=askedsteps[i]
+ local coverage=nil
+ local format=nil
+ if featuretype=="substitution" then
+ category="gsub"
+ coverage=prepare_substitution(list,featuretype,nocheck)
+ elseif featuretype=="ligature" then
+ category="gsub"
+ coverage=prepare_ligature(list,featuretype,nocheck)
+ elseif featuretype=="alternate" then
+ category="gsub"
+ coverage=prepare_alternate(list,featuretype,nocheck)
+ elseif featuretype=="multiple" then
+ category="gsub"
+ coverage=prepare_multiple(list,featuretype,nocheck)
+ elseif featuretype=="kern" or featuretype=="move" then
+ category="gpos"
+ format=featuretype
+ coverage=prepare_kern(list,featuretype)
+ elseif featuretype=="pair" then
+ category="gpos"
+ format="pair"
+ coverage=prepare_pair(list,featuretype)
+ elseif featuretype=="single" then
+ category="gpos"
+ format="single"
+ coverage=prepare_single(list,featuretype)
+ elseif featuretype=="chainsubstitution" then
+ category="gsub"
+ coverage=prepare_chain(list,featuretype,sublookups)
+ elseif featuretype=="chainposition" then
+ category="gpos"
+ coverage=prepare_chain(list,featuretype,sublookups)
+ else
+ report_otf("not registering feature %a, unknown category",feature)
+ return
+ end
+ if coverage and next(coverage) then
+ nofsteps=nofsteps+1
+ steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
+ end
+ end
+ if nofsteps>0 then
+ for k,v in next,askedfeatures do
+ if v[1] then
+ askedfeatures[k]=tohash(v)
+ end
+ end
+ if featureflags[1] then featureflags[1]="mark" end
+ if featureflags[2] then featureflags[2]="ligature" end
+ if featureflags[3] then featureflags[3]="base" end
+ local steptype=types[featuretype]
+ local sequence={
+ chain=featurechain,
+ features={ [feature]=askedfeatures },
+ flags=featureflags,
+ name=feature,
+ order=featureorder,
+ [stepkey]=steps,
+ nofsteps=nofsteps,
+ type=steptype,
+ }
+ checkflags(sequence,resources)
+ checkmerge(sequence)
+ checksteps(sequence)
+ local first,last=getrange(sequences,category)
+ inject(specification,sequences,sequence,first,last,category,feature)
+ local features=fontfeatures[category]
+ if not features then
+ features={}
+ fontfeatures[category]=features
+ end
+ local k=features[feature]
+ if not k then
+ k={}
+ features[feature]=k
+ end
+ for script,languages in next,askedfeatures do
+ local kk=k[script]
+ if not kk then
+ kk={}
+ k[script]=kk
+ end
+ for language,value in next,languages do
+ kk[language]=value
+ end
+ end
+ end
end
+ end
+ if trace_loading then
+ report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip)
+ end
end
otf.enhancers.addfeature=addfeature
local extrafeatures={}
local knownfeatures={}
function otf.addfeature(name,specification)
- if type(name)=="table" then
- specification=name
- end
- if type(specification)~="table" then
- report_otf("invalid feature specification, no valid table")
- return
- end
- specification,name=validspecification(specification,name)
- if name and specification then
- local slot=knownfeatures[name]
- if not slot then
- slot=#extrafeatures+1
- knownfeatures[name]=slot
- elseif specification.overload==false then
- slot=#extrafeatures+1
- knownfeatures[name]=slot
- else
- end
- specification.name=name
- extrafeatures[slot]=specification
+ if type(name)=="table" then
+ specification=name
+ end
+ if type(specification)~="table" then
+ report_otf("invalid feature specification, no valid table")
+ return
+ end
+ specification,name=validspecification(specification,name)
+ if name and specification then
+ local slot=knownfeatures[name]
+ if not slot then
+ slot=#extrafeatures+1
+ knownfeatures[name]=slot
+ elseif specification.overload==false then
+ slot=#extrafeatures+1
+ knownfeatures[name]=slot
+ else
end
+ specification.name=name
+ extrafeatures[slot]=specification
+ end
end
local function enhance(data,filename,raw)
- for slot=1,#extrafeatures do
- local specification=extrafeatures[slot]
- addfeature(data,specification.name,specification)
- end
+ for slot=1,#extrafeatures do
+ local specification=extrafeatures[slot]
+ addfeature(data,specification.name,specification)
+ end
end
otf.enhancers.enhance=enhance
otf.enhancers.register("check extra features",enhance)
@@ -32218,11 +32218,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-onr']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local fonts,logs,trackers,resolvers=fonts,logs,trackers,resolvers
local next,type,tonumber,rawget,rawset=next,type,tonumber,rawget,rawset
@@ -32232,8 +32232,8 @@ local abs=math.abs
local bxor,rshift=bit32.bxor,bit32.rshift
local P,S,R,V,Cmt,C,Ct,Cs,Carg,Cf,Cg,Cc=lpeg.P,lpeg.S,lpeg.R,lpeg.V,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg,lpeg.Cc
local lpegmatch,patterns=lpeg.match,lpeg.patterns
-local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
-local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
+local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
+local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
local report_afm=logs.reporter("fonts","afm loading")
local report_pfb=logs.reporter("fonts","pfb loading")
local handlers=fonts.handlers
@@ -32244,180 +32244,180 @@ afm.readers=readers
afm.version=1.513
local get_indexes,get_shapes
do
- local decrypt
- do
- local r,c1,c2,n=0,0,0,0
- local function step(c)
- local cipher=byte(c)
- local plain=bxor(cipher,rshift(r,8))
- r=((cipher+r)*c1+c2)%65536
- return char(plain)
- end
- decrypt=function(binary,initial,seed)
- r,c1,c2,n=initial,52845,22719,seed
- binary=gsub(binary,".",step)
- return sub(binary,n+1)
- end
- end
- local charstrings=P("/CharStrings")
- local subroutines=P("/Subrs")
- local encoding=P("/Encoding")
- local dup=P("dup")
- local put=P("put")
- local array=P("array")
- local name=P("/")*C((R("az","AZ","09")+S("-_."))^1)
- local digits=R("09")^1
- local cardinal=digits/tonumber
- local spaces=P(" ")^1
- local spacing=patterns.whitespace^0
- local routines,vector,chars,n,m
- local initialize=function(str,position,size)
- n=0
- m=size
- return position+1
- end
- local setroutine=function(str,position,index,size,filename)
- if routines[index] then
- return false
- end
- local forward=position+size
- local stream=decrypt(sub(str,position+1,forward),4330,4)
- routines[index]={ byte(stream,1,#stream) }
+ local decrypt
+ do
+ local r,c1,c2,n=0,0,0,0
+ local function step(c)
+ local cipher=byte(c)
+ local plain=bxor(cipher,rshift(r,8))
+ r=((cipher+r)*c1+c2)%65536
+ return char(plain)
+ end
+ decrypt=function(binary,initial,seed)
+ r,c1,c2,n=initial,52845,22719,seed
+ binary=gsub(binary,".",step)
+ return sub(binary,n+1)
+ end
+ end
+ local charstrings=P("/CharStrings")
+ local subroutines=P("/Subrs")
+ local encoding=P("/Encoding")
+ local dup=P("dup")
+ local put=P("put")
+ local array=P("array")
+ local name=P("/")*C((R("az","AZ","09")+S("-_."))^1)
+ local digits=R("09")^1
+ local cardinal=digits/tonumber
+ local spaces=P(" ")^1
+ local spacing=patterns.whitespace^0
+ local routines,vector,chars,n,m
+ local initialize=function(str,position,size)
+ n=0
+ m=size
+ return position+1
+ end
+ local setroutine=function(str,position,index,size,filename)
+ if routines[index] then
+ return false
+ end
+ local forward=position+size
+ local stream=decrypt(sub(str,position+1,forward),4330,4)
+ routines[index]={ byte(stream,1,#stream) }
+ n=n+1
+ if n>=m then
+ return #str
+ end
+ return forward+1
+ end
+ local setvector=function(str,position,name,size,filename)
+ local forward=position+tonumber(size)
+ if n>=m then
+ return #str
+ elseif forward<#str then
+ if n==0 and name~=".notdef" then
+ report_pfb("reserving .notdef at index 0 in %a",filename)
n=n+1
- if n>=m then
- return #str
- end
- return forward+1
- end
- local setvector=function(str,position,name,size,filename)
- local forward=position+tonumber(size)
- if n>=m then
- return #str
- elseif forward<#str then
- if n==0 and name~=".notdef" then
- report_pfb("reserving .notdef at index 0 in %a",filename)
- n=n+1
- end
- vector[n]=name
- n=n+1
- return forward
- else
- return #str
- end
- end
- local setshapes=function(str,position,name,size,filename)
- local forward=position+tonumber(size)
- local stream=sub(str,position+1,forward)
- if n>m then
- return #str
- elseif forward<#str then
- if n==0 and name~=".notdef" then
- report_pfb("reserving .notdef at index 0 in %a",filename)
- n=n+1
- end
- vector[n]=name
- n=n+1
- chars [n]=decrypt(stream,4330,4)
- return forward
- else
- return #str
- end
- end
- local p_rd=spacing*(P("RD")+P("-|"))
- local p_np=spacing*(P("NP")+P("|"))
- local p_nd=spacing*(P("ND")+P("|"))
- local p_filterroutines=
- (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd*Carg(1),setroutine)*p_np+(1-p_nd))^1
- local p_filtershapes=
- (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd*Carg(1),setshapes)*p_nd+P(1))^1
- local p_filternames=Ct (
- (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*Carg(1),setvector)+P(1))^1
- )
- local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf(
- Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1
+ end
+ vector[n]=name
+ n=n+1
+ return forward
+ else
+ return #str
+ end
+ end
+ local setshapes=function(str,position,name,size,filename)
+ local forward=position+tonumber(size)
+ local stream=sub(str,position+1,forward)
+ if n>m then
+ return #str
+ elseif forward<#str then
+ if n==0 and name~=".notdef" then
+ report_pfb("reserving .notdef at index 0 in %a",filename)
+ n=n+1
+ end
+ vector[n]=name
+ n=n+1
+ chars [n]=decrypt(stream,4330,4)
+ return forward
+ else
+ return #str
+ end
+ end
+ local p_rd=spacing*(P("RD")+P("-|"))
+ local p_np=spacing*(P("NP")+P("|"))
+ local p_nd=spacing*(P("ND")+P("|"))
+ local p_filterroutines=
+ (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd*Carg(1),setroutine)*p_np+(1-p_nd))^1
+ local p_filtershapes=
+ (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd*Carg(1),setshapes)*p_nd+P(1))^1
+ local p_filternames=Ct (
+ (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*Carg(1),setvector)+P(1))^1
+ )
+ local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf(
+ Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1
,rawset)
- local key=spacing*P("/")*R("az","AZ")
- local str=spacing*Cs { (P("(")/"")*((1-P("\\(")-P("\\)")-S("()"))+V(1))^0*(P(")")/"") }
- local num=spacing*(R("09")+S("+-."))^1/tonumber
- local arr=spacing*Ct (S("[{")*(num)^0*spacing*S("]}"))
- local boo=spacing*(P("true")*Cc(true)+P("false")*Cc(false))
- local nam=spacing*P("/")*Cs(R("az","AZ")^1)
- local p_filtermetadata=(
- P("/")*Carg(1)*((
- C("version")*str+C("Copyright")*str+C("Notice")*str+C("FullName")*str+C("FamilyName")*str+C("Weight")*str+C("ItalicAngle")*num+C("isFixedPitch")*boo+C("UnderlinePosition")*num+C("UnderlineThickness")*num+C("FontName")*nam+C("FontMatrix")*arr+C("FontBBox")*arr
- ) )/function(t,k,v) t[lower(k)]=v end+P(1)
- )^0*Carg(1)
- local function loadpfbvector(filename,shapestoo,streams)
- local data=io.loaddata(resolvers.findfile(filename))
- if not data then
- report_pfb("no data in %a",filename)
- return
- end
- if not (find(data,"!PS-AdobeFont-",1,true) or find(data,"%!FontType1",1,true)) then
- report_pfb("no font in %a",filename)
- return
- end
- local ascii,binary=match(data,"(.*)eexec%s+......(.*)")
- if not binary then
- report_pfb("no binary data in %a",filename)
- return
- end
- binary=decrypt(binary,55665,4)
- local names={}
- local encoding=lpegmatch(p_filterencoding,ascii)
- local metadata=lpegmatch(p_filtermetadata,ascii,1,{})
- local glyphs={}
- routines,vector,chars={},{},{}
- if shapestoo or streams then
- lpegmatch(p_filterroutines,binary,1,filename)
- lpegmatch(p_filtershapes,binary,1,filename)
- local data={
- dictionaries={
- {
- charstrings=chars,
- charset=vector,
- subroutines=routines,
- }
- },
- }
- fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,"cff",streams)
+ local key=spacing*P("/")*R("az","AZ")
+ local str=spacing*Cs { (P("(")/"")*((1-P("\\(")-P("\\)")-S("()"))+V(1))^0*(P(")")/"") }
+ local num=spacing*(R("09")+S("+-."))^1/tonumber
+ local arr=spacing*Ct (S("[{")*(num)^0*spacing*S("]}"))
+ local boo=spacing*(P("true")*Cc(true)+P("false")*Cc(false))
+ local nam=spacing*P("/")*Cs(R("az","AZ")^1)
+ local p_filtermetadata=(
+ P("/")*Carg(1)*((
+ C("version")*str+C("Copyright")*str+C("Notice")*str+C("FullName")*str+C("FamilyName")*str+C("Weight")*str+C("ItalicAngle")*num+C("isFixedPitch")*boo+C("UnderlinePosition")*num+C("UnderlineThickness")*num+C("FontName")*nam+C("FontMatrix")*arr+C("FontBBox")*arr
+ ) )/function(t,k,v) t[lower(k)]=v end+P(1)
+ )^0*Carg(1)
+ local function loadpfbvector(filename,shapestoo,streams)
+ local data=io.loaddata(resolvers.findfile(filename))
+ if not data then
+ report_pfb("no data in %a",filename)
+ return
+ end
+ if not (find(data,"!PS-AdobeFont-",1,true) or find(data,"%!FontType1",1,true)) then
+ report_pfb("no font in %a",filename)
+ return
+ end
+ local ascii,binary=match(data,"(.*)eexec%s+......(.*)")
+ if not binary then
+ report_pfb("no binary data in %a",filename)
+ return
+ end
+ binary=decrypt(binary,55665,4)
+ local names={}
+ local encoding=lpegmatch(p_filterencoding,ascii)
+ local metadata=lpegmatch(p_filtermetadata,ascii,1,{})
+ local glyphs={}
+ routines,vector,chars={},{},{}
+ if shapestoo or streams then
+ lpegmatch(p_filterroutines,binary,1,filename)
+ lpegmatch(p_filtershapes,binary,1,filename)
+ local data={
+ dictionaries={
+ {
+ charstrings=chars,
+ charset=vector,
+ subroutines=routines,
+ }
+ },
+ }
+ fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,"cff",streams)
+ else
+ lpegmatch(p_filternames,binary,1,filename)
+ end
+ names=vector
+ routines,vector,chars=nil,nil,nil
+ return names,encoding,glyphs,metadata
+ end
+ local pfb=handlers.pfb or {}
+ handlers.pfb=pfb
+ pfb.loadvector=loadpfbvector
+ get_indexes=function(data,pfbname)
+ local vector=loadpfbvector(pfbname)
+ if vector then
+ local characters=data.characters
+ if trace_loading then
+ report_afm("getting index data from %a",pfbname)
+ end
+ for index=0,#vector do
+ local name=vector[index]
+ local char=characters[name]
+ if char then
+ if trace_indexing then
+ report_afm("glyph %a has index %a",name,index)
+ end
+ char.index=index
else
- lpegmatch(p_filternames,binary,1,filename)
- end
- names=vector
- routines,vector,chars=nil,nil,nil
- return names,encoding,glyphs,metadata
- end
- local pfb=handlers.pfb or {}
- handlers.pfb=pfb
- pfb.loadvector=loadpfbvector
- get_indexes=function(data,pfbname)
- local vector=loadpfbvector(pfbname)
- if vector then
- local characters=data.characters
- if trace_loading then
- report_afm("getting index data from %a",pfbname)
- end
- for index=0,#vector do
- local name=vector[index]
- local char=characters[name]
- if char then
- if trace_indexing then
- report_afm("glyph %a has index %a",name,index)
- end
- char.index=index
- else
- if trace_indexing then
- report_afm("glyph %a has index %a but no data",name,index)
- end
- end
- end
+ if trace_indexing then
+ report_afm("glyph %a has index %a but no data",name,index)
+ end
end
+ end
end
- get_shapes=function(pfbname)
- local vector,encoding,glyphs=loadpfbvector(pfbname,true)
- return glyphs
- end
+ end
+ get_shapes=function(pfbname)
+ local vector,encoding,glyphs=loadpfbvector(pfbname,true)
+ return glyphs
+ end
end
local spacer=patterns.spacer
local whitespace=patterns.whitespace
@@ -32432,74 +32432,74 @@ local semicolon=spacing*P(";")
local plus=spacing*P("plus")*number
local minus=spacing*P("minus")*number
local function addkernpair(data,one,two,value)
- local chr=data.characters[one]
- if chr then
- local kerns=chr.kerns
- if kerns then
- kerns[two]=tonumber(value)
- else
- chr.kerns={ [two]=tonumber(value) }
- end
+ local chr=data.characters[one]
+ if chr then
+ local kerns=chr.kerns
+ if kerns then
+ kerns[two]=tonumber(value)
+ else
+ chr.kerns={ [two]=tonumber(value) }
end
+ end
end
local p_kernpair=(fontdata*P("KPX")*name*name*number)/addkernpair
local chr=false
local ind=0
local function start(data,version)
- data.metadata.afmversion=version
- ind=0
- chr={}
+ data.metadata.afmversion=version
+ ind=0
+ chr={}
end
local function stop()
- ind=0
- chr=false
+ ind=0
+ chr=false
end
local function setindex(i)
- if i<0 then
- ind=ind+1
- else
- ind=i
- end
- chr={
- index=ind
- }
+ if i<0 then
+ ind=ind+1
+ else
+ ind=i
+ end
+ chr={
+ index=ind
+ }
end
local function setwidth(width)
- chr.width=width
+ chr.width=width
end
local function setname(data,name)
- data.characters[name]=chr
+ data.characters[name]=chr
end
local function setboundingbox(boundingbox)
- chr.boundingbox=boundingbox
+ chr.boundingbox=boundingbox
end
local function setligature(plus,becomes)
- local ligatures=chr.ligatures
- if ligatures then
- ligatures[plus]=becomes
- else
- chr.ligatures={ [plus]=becomes }
- end
+ local ligatures=chr.ligatures
+ if ligatures then
+ ligatures[plus]=becomes
+ else
+ chr.ligatures={ [plus]=becomes }
+ end
end
local p_charmetric=((
- P("C")*number/setindex+P("WX")*number/setwidth+P("N")*fontdata*name/setname+P("B")*Ct((number)^4)/setboundingbox+P("L")*(name)^2/setligature
- )*semicolon )^1
+ P("C")*number/setindex+P("WX")*number/setwidth+P("N")*fontdata*name/setname+P("B")*Ct((number)^4)/setboundingbox+P("L")*(name)^2/setligature
+ )*semicolon )^1
local p_charmetrics=P("StartCharMetrics")*number*(p_charmetric+(1-P("EndCharMetrics")))^0*P("EndCharMetrics")
-local p_kernpairs=P("StartKernPairs")*number*(p_kernpair+(1-P("EndKernPairs" )))^0*P("EndKernPairs" )
-local function set_1(data,key,a) data.metadata[lower(key)]=a end
-local function set_2(data,key,a,b) data.metadata[lower(key)]={ a,b } end
+local p_kernpairs=P("StartKernPairs")*number*(p_kernpair+(1-P("EndKernPairs" )))^0*P("EndKernPairs" )
+local function set_1(data,key,a) data.metadata[lower(key)]=a end
+local function set_2(data,key,a,b) data.metadata[lower(key)]={ a,b } end
local function set_3(data,key,a,b,c) data.metadata[lower(key)]={ a,b,c } end
local p_parameters=P(false)+fontdata*((P("FontName")+P("FullName")+P("FamilyName"))/lower)*words/function(data,key,value)
- data.metadata[key]=value
- end+fontdata*((P("Weight")+P("Version"))/lower)*name/function(data,key,value)
- data.metadata[key]=value
- end+fontdata*P("IsFixedPitch")*name/function(data,pitch)
- data.metadata.monospaced=toboolean(pitch,true)
- end+fontdata*P("FontBBox")*Ct(number^4)/function(data,boundingbox)
- data.metadata.boundingbox=boundingbox
- end+fontdata*((P("CharWidth")+P("CapHeight")+P("XHeight")+P("Descender")+P("Ascender")+P("ItalicAngle"))/lower)*number/function(data,key,value)
- data.metadata[key]=value
- end+P("Comment")*spacing*(P(false)+(fontdata*C("DESIGNSIZE")*number*rest)/set_1
+ data.metadata[key]=value
+ end+fontdata*((P("Weight")+P("Version"))/lower)*name/function(data,key,value)
+ data.metadata[key]=value
+ end+fontdata*P("IsFixedPitch")*name/function(data,pitch)
+ data.metadata.monospaced=toboolean(pitch,true)
+ end+fontdata*P("FontBBox")*Ct(number^4)/function(data,boundingbox)
+ data.metadata.boundingbox=boundingbox
+ end+fontdata*((P("CharWidth")+P("CapHeight")+P("XHeight")+P("Descender")+P("Ascender")+P("ItalicAngle"))/lower)*number/function(data,key,value)
+ data.metadata[key]=value
+ end+P("Comment")*spacing*(P(false)+(fontdata*C("DESIGNSIZE")*number*rest)/set_1
+(fontdata*C("TFM designsize")*number*rest)/set_1+(fontdata*C("DesignSize")*number*rest)/set_1+(fontdata*C("CODINGSCHEME")*words*rest)/set_1
+(fontdata*C("CHECKSUM")*number*words*rest)/set_1
+(fontdata*C("SPACE")*number*plus*minus*rest)/set_3
@@ -32513,78 +32513,78 @@ local p_parameters=P(false)+fontdata*((P("FontName")+P("FullName")+P("FamilyName
+(fontdata*C("SUBDROP")*number*rest)/set_1
+(fontdata*C("DELIM")*number*number*rest)/set_2
+(fontdata*C("AXISHEIGHT")*number*rest)/set_1
- )
+ )
local fullparser=(P("StartFontMetrics")*fontdata*name/start )*(p_charmetrics+p_kernpairs+p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop )
local infoparser=(P("StartFontMetrics")*fontdata*name/start )*(p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop )
local function read(filename,parser)
- local afmblob=io.loaddata(filename)
- if afmblob then
- local data={
- resources={
- filename=resolvers.unresolve(filename),
- version=afm.version,
- creator="context mkiv",
- },
- properties={
- hasitalics=false,
- },
- goodies={},
- metadata={
- filename=file.removesuffix(file.basename(filename))
- },
- characters={
- },
- descriptions={
- },
- }
- if trace_loading then
- report_afm("parsing afm file %a",filename)
- end
- lpegmatch(parser,afmblob,1,data)
- return data
- else
- if trace_loading then
- report_afm("no valid afm file %a",filename)
- end
- return nil
+ local afmblob=io.loaddata(filename)
+ if afmblob then
+ local data={
+ resources={
+ filename=resolvers.unresolve(filename),
+ version=afm.version,
+ creator="context mkiv",
+ },
+ properties={
+ hasitalics=false,
+ },
+ goodies={},
+ metadata={
+ filename=file.removesuffix(file.basename(filename))
+ },
+ characters={
+ },
+ descriptions={
+ },
+ }
+ if trace_loading then
+ report_afm("parsing afm file %a",filename)
end
+ lpegmatch(parser,afmblob,1,data)
+ return data
+ else
+ if trace_loading then
+ report_afm("no valid afm file %a",filename)
+ end
+ return nil
+ end
end
function readers.loadfont(afmname,pfbname)
- local data=read(resolvers.findfile(afmname),fullparser)
- if data then
- if not pfbname or pfbname=="" then
- pfbname=resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb"))
- end
- if pfbname and pfbname~="" then
- data.resources.filename=resolvers.unresolve(pfbname)
- get_indexes(data,pfbname)
- return data
- else
- report_afm("no pfb file for %a",afmname)
- end
+ local data=read(resolvers.findfile(afmname),fullparser)
+ if data then
+ if not pfbname or pfbname=="" then
+ pfbname=resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb"))
+ end
+ if pfbname and pfbname~="" then
+ data.resources.filename=resolvers.unresolve(pfbname)
+ get_indexes(data,pfbname)
+ return data
+ else
+ report_afm("no pfb file for %a",afmname)
end
+ end
end
function readers.loadshapes(filename)
- local fullname=resolvers.findfile(filename) or ""
- if fullname=="" then
- return {
- filename="not found: "..filename,
- glyphs={}
- }
- else
- return {
- filename=fullname,
- format="opentype",
- glyphs=get_shapes(fullname) or {},
- units=1000,
- }
- end
+ local fullname=resolvers.findfile(filename) or ""
+ if fullname=="" then
+ return {
+ filename="not found: "..filename,
+ glyphs={}
+ }
+ else
+ return {
+ filename=fullname,
+ format="opentype",
+ glyphs=get_shapes(fullname) or {},
+ units=1000,
+ }
+ end
end
function readers.getinfo(filename)
- local data=read(resolvers.findfile(filename),infoparser)
- if data then
- return data.metadata
- end
+ local data=read(resolvers.findfile(filename),infoparser)
+ if data then
+ return data.metadata
+ end
end
end -- closure
@@ -32592,11 +32592,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-one']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local fonts,logs,trackers,containers,resolvers=fonts,logs,trackers,containers,resolvers
local next,type,tonumber,rawget=next,type,tonumber,rawget
@@ -32605,10 +32605,10 @@ local abs=math.abs
local P,S,R,Cmt,C,Ct,Cs,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg
local lpegmatch,patterns=lpeg.match,lpeg.patterns
local sortedhash=table.sortedhash
-local trace_features=false trackers.register("afm.features",function(v) trace_features=v end)
-local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
-local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
-local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local trace_features=false trackers.register("afm.features",function(v) trace_features=v end)
+local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
+local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
local report_afm=logs.reporter("fonts","afm loading")
local setmetatableindex=table.setmetatableindex
local derivetable=table.derive
@@ -32629,658 +32629,658 @@ local registerafmenhancer=afmenhancers.register
afm.version=1.513
afm.cache=containers.define("fonts","one",afm.version,true)
afm.autoprefixed=true
-afm.helpdata={}
+afm.helpdata={}
afm.syncspace=true
local overloads=fonts.mappings.overloads
local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes
function afm.load(filename)
- filename=resolvers.findfile(filename,'afm') or ""
- if filename~="" and not fonts.names.ignoredfile(filename) then
- local name=file.removesuffix(file.basename(filename))
- local data=containers.read(afm.cache,name)
- local attr=lfs.attributes(filename)
- local size,time=attr and attr.size or 0,attr and attr.modification or 0
- local pfbfile=file.replacesuffix(name,"pfb")
- local pfbname=resolvers.findfile(pfbfile,"pfb") or ""
- if pfbname=="" then
- pfbname=resolvers.findfile(file.basename(pfbfile),"pfb") or ""
- end
- local pfbsize,pfbtime=0,0
- if pfbname~="" then
- local attr=lfs.attributes(pfbname)
- pfbsize=attr.size or 0
- pfbtime=attr.modification or 0
- end
- if not data or data.size~=size or data.time~=time or data.pfbsize~=pfbsize or data.pfbtime~=pfbtime then
- report_afm("reading %a",filename)
- data=afm.readers.loadfont(filename,pfbname)
- if data then
- afmenhancers.apply(data,filename)
- fonts.mappings.addtounicode(data,filename)
- otfreaders.stripredundant(data)
- otfreaders.pack(data)
- data.size=size
- data.time=time
- data.pfbsize=pfbsize
- data.pfbtime=pfbtime
- report_afm("saving %a in cache",name)
- data=containers.write(afm.cache,name,data)
- data=containers.read(afm.cache,name)
- end
- end
- if data then
- otfreaders.unpack(data)
- otfreaders.expand(data)
- otfreaders.addunicodetable(data)
- otfenhancers.apply(data,filename,data)
- if applyruntimefixes then
- applyruntimefixes(filename,data)
- end
- end
- return data
+ filename=resolvers.findfile(filename,'afm') or ""
+ if filename~="" and not fonts.names.ignoredfile(filename) then
+ local name=file.removesuffix(file.basename(filename))
+ local data=containers.read(afm.cache,name)
+ local attr=lfs.attributes(filename)
+ local size,time=attr and attr.size or 0,attr and attr.modification or 0
+ local pfbfile=file.replacesuffix(name,"pfb")
+ local pfbname=resolvers.findfile(pfbfile,"pfb") or ""
+ if pfbname=="" then
+ pfbname=resolvers.findfile(file.basename(pfbfile),"pfb") or ""
+ end
+ local pfbsize,pfbtime=0,0
+ if pfbname~="" then
+ local attr=lfs.attributes(pfbname)
+ pfbsize=attr.size or 0
+ pfbtime=attr.modification or 0
+ end
+ if not data or data.size~=size or data.time~=time or data.pfbsize~=pfbsize or data.pfbtime~=pfbtime then
+ report_afm("reading %a",filename)
+ data=afm.readers.loadfont(filename,pfbname)
+ if data then
+ afmenhancers.apply(data,filename)
+ fonts.mappings.addtounicode(data,filename)
+ otfreaders.stripredundant(data)
+ otfreaders.pack(data)
+ data.size=size
+ data.time=time
+ data.pfbsize=pfbsize
+ data.pfbtime=pfbtime
+ report_afm("saving %a in cache",name)
+ data=containers.write(afm.cache,name,data)
+ data=containers.read(afm.cache,name)
+ end
+ end
+ if data then
+ otfreaders.unpack(data)
+ otfreaders.expand(data)
+ otfreaders.addunicodetable(data)
+ otfenhancers.apply(data,filename,data)
+ if applyruntimefixes then
+ applyruntimefixes(filename,data)
+ end
end
+ return data
+ end
end
local uparser=fonts.mappings.makenameparser()
local function enhance_unify_names(data,filename)
- local unicodevector=fonts.encodings.agl.unicodes
- local unicodes={}
- local names={}
- local private=data.private or privateoffset
- local descriptions=data.descriptions
- for name,blob in sortedhash(data.characters) do
- local code=unicodevector[name]
- if not code then
- code=lpegmatch(uparser,name)
- if type(code)~="number" then
- code=private
- private=private+1
- report_afm("assigning private slot %U for unknown glyph name %a",code,name)
- end
- end
- local index=blob.index
- unicodes[name]=code
- names[name]=index
- blob.name=name
- descriptions[code]={
- boundingbox=blob.boundingbox,
- width=blob.width,
- kerns=blob.kerns,
- index=index,
- name=name,
- }
- end
- for unicode,description in next,descriptions do
- local kerns=description.kerns
- if kerns then
- local krn={}
- for name,kern in next,kerns do
- local unicode=unicodes[name]
- if unicode then
- krn[unicode]=kern
- else
- end
- end
- description.kerns=krn
+ local unicodevector=fonts.encodings.agl.unicodes
+ local unicodes={}
+ local names={}
+ local private=data.private or privateoffset
+ local descriptions=data.descriptions
+ for name,blob in sortedhash(data.characters) do
+ local code=unicodevector[name]
+ if not code then
+ code=lpegmatch(uparser,name)
+ if type(code)~="number" then
+ code=private
+ private=private+1
+ report_afm("assigning private slot %U for unknown glyph name %a",code,name)
+ end
+ end
+ local index=blob.index
+ unicodes[name]=code
+ names[name]=index
+ blob.name=name
+ descriptions[code]={
+ boundingbox=blob.boundingbox,
+ width=blob.width,
+ kerns=blob.kerns,
+ index=index,
+ name=name,
+ }
+ end
+ for unicode,description in next,descriptions do
+ local kerns=description.kerns
+ if kerns then
+ local krn={}
+ for name,kern in next,kerns do
+ local unicode=unicodes[name]
+ if unicode then
+ krn[unicode]=kern
+ else
end
+ end
+ description.kerns=krn
end
- data.characters=nil
- data.private=private
- local resources=data.resources
- local filename=resources.filename or file.removesuffix(file.basename(filename))
- resources.filename=resolvers.unresolve(filename)
- resources.unicodes=unicodes
- resources.marks={}
+ end
+ data.characters=nil
+ data.private=private
+ local resources=data.resources
+ local filename=resources.filename or file.removesuffix(file.basename(filename))
+ resources.filename=resolvers.unresolve(filename)
+ resources.unicodes=unicodes
+ resources.marks={}
end
local everywhere={ ["*"]={ ["*"]=true } }
local noflags={ false,false,false,false }
local function enhance_normalize_features(data)
- local ligatures=setmetatableindex("table")
- local kerns=setmetatableindex("table")
- local extrakerns=setmetatableindex("table")
- for u,c in next,data.descriptions do
- local l=c.ligatures
- local k=c.kerns
- local e=c.extrakerns
- if l then
- ligatures[u]=l
- for u,v in next,l do
- l[u]={ ligature=v }
- end
- c.ligatures=nil
- end
- if k then
- kerns[u]=k
- for u,v in next,k do
- k[u]=v
- end
- c.kerns=nil
- end
- if e then
- extrakerns[u]=e
- for u,v in next,e do
- e[u]=v
- end
- c.extrakerns=nil
- end
+ local ligatures=setmetatableindex("table")
+ local kerns=setmetatableindex("table")
+ local extrakerns=setmetatableindex("table")
+ for u,c in next,data.descriptions do
+ local l=c.ligatures
+ local k=c.kerns
+ local e=c.extrakerns
+ if l then
+ ligatures[u]=l
+ for u,v in next,l do
+ l[u]={ ligature=v }
+ end
+ c.ligatures=nil
end
- local features={
- gpos={},
- gsub={},
+ if k then
+ kerns[u]=k
+ for u,v in next,k do
+ k[u]=v
+ end
+ c.kerns=nil
+ end
+ if e then
+ extrakerns[u]=e
+ for u,v in next,e do
+ e[u]=v
+ end
+ c.extrakerns=nil
+ end
+ end
+ local features={
+ gpos={},
+ gsub={},
+ }
+ local sequences={
+ }
+ if next(ligatures) then
+ features.gsub.liga=everywhere
+ data.properties.hasligatures=true
+ sequences[#sequences+1]={
+ features={
+ liga=everywhere,
+ },
+ flags=noflags,
+ name="s_s_0",
+ nofsteps=1,
+ order={ "liga" },
+ type="gsub_ligature",
+ steps={
+ {
+ coverage=ligatures,
+ },
+ },
}
- local sequences={
+ end
+ if next(kerns) then
+ features.gpos.kern=everywhere
+ data.properties.haskerns=true
+ sequences[#sequences+1]={
+ features={
+ kern=everywhere,
+ },
+ flags=noflags,
+ name="p_s_0",
+ nofsteps=1,
+ order={ "kern" },
+ type="gpos_pair",
+ steps={
+ {
+ format="kern",
+ coverage=kerns,
+ },
+ },
}
- if next(ligatures) then
- features.gsub.liga=everywhere
- data.properties.hasligatures=true
- sequences[#sequences+1]={
- features={
- liga=everywhere,
- },
- flags=noflags,
- name="s_s_0",
- nofsteps=1,
- order={ "liga" },
- type="gsub_ligature",
- steps={
- {
- coverage=ligatures,
- },
- },
- }
- end
- if next(kerns) then
- features.gpos.kern=everywhere
- data.properties.haskerns=true
- sequences[#sequences+1]={
- features={
- kern=everywhere,
- },
- flags=noflags,
- name="p_s_0",
- nofsteps=1,
- order={ "kern" },
- type="gpos_pair",
- steps={
- {
- format="kern",
- coverage=kerns,
- },
- },
- }
- end
- if next(extrakerns) then
- features.gpos.extrakerns=everywhere
- data.properties.haskerns=true
- sequences[#sequences+1]={
- features={
- extrakerns=everywhere,
- },
- flags=noflags,
- name="p_s_1",
- nofsteps=1,
- order={ "extrakerns" },
- type="gpos_pair",
- steps={
- {
- format="kern",
- coverage=extrakerns,
- },
- },
- }
- end
- data.resources.features=features
- data.resources.sequences=sequences
+ end
+ if next(extrakerns) then
+ features.gpos.extrakerns=everywhere
+ data.properties.haskerns=true
+ sequences[#sequences+1]={
+ features={
+ extrakerns=everywhere,
+ },
+ flags=noflags,
+ name="p_s_1",
+ nofsteps=1,
+ order={ "extrakerns" },
+ type="gpos_pair",
+ steps={
+ {
+ format="kern",
+ coverage=extrakerns,
+ },
+ },
+ }
+ end
+ data.resources.features=features
+ data.resources.sequences=sequences
end
local function enhance_fix_names(data)
- for k,v in next,data.descriptions do
- local n=v.name
- local r=overloads[n]
- if r then
- local name=r.name
- if trace_indexing then
- report_afm("renaming characters %a to %a",n,name)
- end
- v.name=name
- v.unicode=r.unicode
- end
- end
+ for k,v in next,data.descriptions do
+ local n=v.name
+ local r=overloads[n]
+ if r then
+ local name=r.name
+ if trace_indexing then
+ report_afm("renaming characters %a to %a",n,name)
+ end
+ v.name=name
+ v.unicode=r.unicode
+ end
+ end
end
local addthem=function(rawdata,ligatures)
- if ligatures then
- local descriptions=rawdata.descriptions
- local resources=rawdata.resources
- local unicodes=resources.unicodes
- for ligname,ligdata in next,ligatures do
- local one=descriptions[unicodes[ligname]]
- if one then
- for _,pair in next,ligdata do
- local two,three=unicodes[pair[1]],unicodes[pair[2]]
- if two and three then
- local ol=one.ligatures
- if ol then
- if not ol[two] then
- ol[two]=three
- end
- else
- one.ligatures={ [two]=three }
- end
- end
- end
+ if ligatures then
+ local descriptions=rawdata.descriptions
+ local resources=rawdata.resources
+ local unicodes=resources.unicodes
+ for ligname,ligdata in next,ligatures do
+ local one=descriptions[unicodes[ligname]]
+ if one then
+ for _,pair in next,ligdata do
+ local two,three=unicodes[pair[1]],unicodes[pair[2]]
+ if two and three then
+ local ol=one.ligatures
+ if ol then
+ if not ol[two] then
+ ol[two]=three
+ end
+ else
+ one.ligatures={ [two]=three }
end
+ end
end
+ end
end
+ end
end
local function enhance_add_ligatures(rawdata)
- addthem(rawdata,afm.helpdata.ligatures)
+ addthem(rawdata,afm.helpdata.ligatures)
end
local function enhance_add_extra_kerns(rawdata)
- local descriptions=rawdata.descriptions
- local resources=rawdata.resources
- local unicodes=resources.unicodes
- local function do_it_left(what)
- if what then
- for unicode,description in next,descriptions do
- local kerns=description.kerns
- if kerns then
- local extrakerns
- for complex,simple in next,what do
- complex=unicodes[complex]
- simple=unicodes[simple]
- if complex and simple then
- local ks=kerns[simple]
- if ks and not kerns[complex] then
- if extrakerns then
- extrakerns[complex]=ks
- else
- extrakerns={ [complex]=ks }
- end
- end
- end
- end
- if extrakerns then
- description.extrakerns=extrakerns
- end
- end
- end
- end
- end
- local function do_it_copy(what)
- if what then
- for complex,simple in next,what do
- complex=unicodes[complex]
- simple=unicodes[simple]
- if complex and simple then
- local complexdescription=descriptions[complex]
- if complexdescription then
- local simpledescription=descriptions[complex]
- if simpledescription then
- local extrakerns
- local kerns=simpledescription.kerns
- if kerns then
- for unicode,kern in next,kerns do
- if extrakerns then
- extrakerns[unicode]=kern
- else
- extrakerns={ [unicode]=kern }
- end
- end
- end
- local extrakerns=simpledescription.extrakerns
- if extrakerns then
- for unicode,kern in next,extrakerns do
- if extrakerns then
- extrakerns[unicode]=kern
- else
- extrakerns={ [unicode]=kern }
- end
- end
- end
- if extrakerns then
- complexdescription.extrakerns=extrakerns
- end
- end
- end
+ local descriptions=rawdata.descriptions
+ local resources=rawdata.resources
+ local unicodes=resources.unicodes
+ local function do_it_left(what)
+ if what then
+ for unicode,description in next,descriptions do
+ local kerns=description.kerns
+ if kerns then
+ local extrakerns
+ for complex,simple in next,what do
+ complex=unicodes[complex]
+ simple=unicodes[simple]
+ if complex and simple then
+ local ks=kerns[simple]
+ if ks and not kerns[complex] then
+ if extrakerns then
+ extrakerns[complex]=ks
+ else
+ extrakerns={ [complex]=ks }
end
+ end
end
+ end
+ if extrakerns then
+ description.extrakerns=extrakerns
+ end
end
- end
- do_it_left(afm.helpdata.leftkerned)
- do_it_left(afm.helpdata.bothkerned)
- do_it_copy(afm.helpdata.bothkerned)
- do_it_copy(afm.helpdata.rightkerned)
-end
-local function adddimensions(data)
- if data then
- for unicode,description in next,data.descriptions do
- local bb=description.boundingbox
- if bb then
- local ht,dp=bb[4],-bb[2]
- if ht==0 or ht<0 then
- else
- description.height=ht
+ end
+ end
+ end
+ local function do_it_copy(what)
+ if what then
+ for complex,simple in next,what do
+ complex=unicodes[complex]
+ simple=unicodes[simple]
+ if complex and simple then
+ local complexdescription=descriptions[complex]
+ if complexdescription then
+ local simpledescription=descriptions[complex]
+ if simpledescription then
+ local extrakerns
+ local kerns=simpledescription.kerns
+ if kerns then
+ for unicode,kern in next,kerns do
+ if extrakerns then
+ extrakerns[unicode]=kern
+ else
+ extrakerns={ [unicode]=kern }
+ end
end
- if dp==0 or dp<0 then
- else
- description.depth=dp
+ end
+ local extrakerns=simpledescription.extrakerns
+ if extrakerns then
+ for unicode,kern in next,extrakerns do
+ if extrakerns then
+ extrakerns[unicode]=kern
+ else
+ extrakerns={ [unicode]=kern }
+ end
end
+ end
+ if extrakerns then
+ complexdescription.extrakerns=extrakerns
+ end
end
+ end
end
+ end
end
+ end
+ do_it_left(afm.helpdata.leftkerned)
+ do_it_left(afm.helpdata.bothkerned)
+ do_it_copy(afm.helpdata.bothkerned)
+ do_it_copy(afm.helpdata.rightkerned)
end
-local function copytotfm(data)
- if data and data.descriptions then
- local metadata=data.metadata
- local resources=data.resources
- local properties=derivetable(data.properties)
- local descriptions=derivetable(data.descriptions)
- local goodies=derivetable(data.goodies)
- local characters={}
- local parameters={}
- local unicodes=resources.unicodes
- for unicode,description in next,data.descriptions do
- characters[unicode]={}
- end
- local filename=constructors.checkedfilename(resources)
- local fontname=metadata.fontname or metadata.fullname
- local fullname=metadata.fullname or metadata.fontname
- local endash=0x0020
- local emdash=0x2014
- local spacer="space"
- local spaceunits=500
- local monospaced=metadata.monospaced
- local charwidth=metadata.charwidth
- local italicangle=metadata.italicangle
- local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight
- properties.monospaced=monospaced
- parameters.italicangle=italicangle
- parameters.charwidth=charwidth
- parameters.charxheight=charxheight
- if properties.monospaced then
- if descriptions[endash] then
- spaceunits,spacer=descriptions[endash].width,"space"
- end
- if not spaceunits and descriptions[emdash] then
- spaceunits,spacer=descriptions[emdash].width,"emdash"
- end
- if not spaceunits and charwidth then
- spaceunits,spacer=charwidth,"charwidth"
- end
- else
- if descriptions[endash] then
- spaceunits,spacer=descriptions[endash].width,"space"
- end
- if not spaceunits and charwidth then
- spaceunits,spacer=charwidth,"charwidth"
- end
- end
- spaceunits=tonumber(spaceunits)
- if spaceunits<200 then
- end
- parameters.slant=0
- parameters.space=spaceunits
- parameters.space_stretch=500
- parameters.space_shrink=333
- parameters.x_height=400
- parameters.quad=1000
- if italicangle and italicangle~=0 then
- parameters.italicangle=italicangle
- parameters.italicfactor=math.cos(math.rad(90+italicangle))
- parameters.slant=- math.tan(italicangle*math.pi/180)
- end
- if monospaced then
- parameters.space_stretch=0
- parameters.space_shrink=0
- elseif afm.syncspace then
- parameters.space_stretch=spaceunits/2
- parameters.space_shrink=spaceunits/3
- end
- parameters.extra_space=parameters.space_shrink
- if charxheight then
- parameters.x_height=charxheight
+local function adddimensions(data)
+ if data then
+ for unicode,description in next,data.descriptions do
+ local bb=description.boundingbox
+ if bb then
+ local ht,dp=bb[4],-bb[2]
+ if ht==0 or ht<0 then
else
- local x=0x0078
- if x then
- local x=descriptions[x]
- if x then
- parameters.x_height=x.height
- end
- end
+ description.height=ht
end
- if metadata.sup then
- local dummy={ 0,0,0 }
- parameters[ 1]=metadata.designsize or 0
- parameters[ 2]=metadata.checksum or 0
- parameters[ 3],
- parameters[ 4],
- parameters[ 5]=unpack(metadata.space or dummy)
- parameters[ 6]=metadata.quad or 0
- parameters[ 7]=metadata.extraspace or 0
- parameters[ 8],
- parameters[ 9],
- parameters[10]=unpack(metadata.num or dummy)
- parameters[11],
- parameters[12]=unpack(metadata.denom or dummy)
- parameters[13],
- parameters[14],
- parameters[15]=unpack(metadata.sup or dummy)
- parameters[16],
- parameters[17]=unpack(metadata.sub or dummy)
- parameters[18]=metadata.supdrop or 0
- parameters[19]=metadata.subdrop or 0
- parameters[20],
- parameters[21]=unpack(metadata.delim or dummy)
- parameters[22]=metadata.axisheight or 0
- end
- parameters.designsize=(metadata.designsize or 10)*65536
- parameters.ascender=abs(metadata.ascender or 0)
- parameters.descender=abs(metadata.descender or 0)
- parameters.units=1000
- properties.spacer=spacer
- properties.encodingbytes=2
- properties.format=fonts.formats[filename] or "type1"
- properties.filename=filename
- properties.fontname=fontname
- properties.fullname=fullname
- properties.psname=fullname
- properties.name=filename or fullname or fontname
- properties.private=properties.private or data.private or privateoffset
- if next(characters) then
- return {
- characters=characters,
- descriptions=descriptions,
- parameters=parameters,
- resources=resources,
- properties=properties,
- goodies=goodies,
- }
+ if dp==0 or dp<0 then
+ else
+ description.depth=dp
end
+ end
end
- return nil
+ end
end
-function afm.setfeatures(tfmdata,features)
- local okay=constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm)
- if okay then
- return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm)
+local function copytotfm(data)
+ if data and data.descriptions then
+ local metadata=data.metadata
+ local resources=data.resources
+ local properties=derivetable(data.properties)
+ local descriptions=derivetable(data.descriptions)
+ local goodies=derivetable(data.goodies)
+ local characters={}
+ local parameters={}
+ local unicodes=resources.unicodes
+ for unicode,description in next,data.descriptions do
+ characters[unicode]={}
+ end
+ local filename=constructors.checkedfilename(resources)
+ local fontname=metadata.fontname or metadata.fullname
+ local fullname=metadata.fullname or metadata.fontname
+ local endash=0x0020
+ local emdash=0x2014
+ local spacer="space"
+ local spaceunits=500
+ local monospaced=metadata.monospaced
+ local charwidth=metadata.charwidth
+ local italicangle=metadata.italicangle
+ local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight
+ properties.monospaced=monospaced
+ parameters.italicangle=italicangle
+ parameters.charwidth=charwidth
+ parameters.charxheight=charxheight
+ if properties.monospaced then
+ if descriptions[endash] then
+ spaceunits,spacer=descriptions[endash].width,"space"
+ end
+ if not spaceunits and descriptions[emdash] then
+ spaceunits,spacer=descriptions[emdash].width,"emdash"
+ end
+ if not spaceunits and charwidth then
+ spaceunits,spacer=charwidth,"charwidth"
+ end
else
- return {}
- end
+ if descriptions[endash] then
+ spaceunits,spacer=descriptions[endash].width,"space"
+ end
+ if not spaceunits and charwidth then
+ spaceunits,spacer=charwidth,"charwidth"
+ end
+ end
+ spaceunits=tonumber(spaceunits)
+ if spaceunits<200 then
+ end
+ parameters.slant=0
+ parameters.space=spaceunits
+ parameters.space_stretch=500
+ parameters.space_shrink=333
+ parameters.x_height=400
+ parameters.quad=1000
+ if italicangle and italicangle~=0 then
+ parameters.italicangle=italicangle
+ parameters.italicfactor=math.cos(math.rad(90+italicangle))
+ parameters.slant=- math.tan(italicangle*math.pi/180)
+ end
+ if monospaced then
+ parameters.space_stretch=0
+ parameters.space_shrink=0
+ elseif afm.syncspace then
+ parameters.space_stretch=spaceunits/2
+ parameters.space_shrink=spaceunits/3
+ end
+ parameters.extra_space=parameters.space_shrink
+ if charxheight then
+ parameters.x_height=charxheight
+ else
+ local x=0x0078
+ if x then
+ local x=descriptions[x]
+ if x then
+ parameters.x_height=x.height
+ end
+ end
+ end
+ if metadata.sup then
+ local dummy={ 0,0,0 }
+ parameters[ 1]=metadata.designsize or 0
+ parameters[ 2]=metadata.checksum or 0
+ parameters[ 3],
+ parameters[ 4],
+ parameters[ 5]=unpack(metadata.space or dummy)
+ parameters[ 6]=metadata.quad or 0
+ parameters[ 7]=metadata.extraspace or 0
+ parameters[ 8],
+ parameters[ 9],
+ parameters[10]=unpack(metadata.num or dummy)
+ parameters[11],
+ parameters[12]=unpack(metadata.denom or dummy)
+ parameters[13],
+ parameters[14],
+ parameters[15]=unpack(metadata.sup or dummy)
+ parameters[16],
+ parameters[17]=unpack(metadata.sub or dummy)
+ parameters[18]=metadata.supdrop or 0
+ parameters[19]=metadata.subdrop or 0
+ parameters[20],
+ parameters[21]=unpack(metadata.delim or dummy)
+ parameters[22]=metadata.axisheight or 0
+ end
+ parameters.designsize=(metadata.designsize or 10)*65536
+ parameters.ascender=abs(metadata.ascender or 0)
+ parameters.descender=abs(metadata.descender or 0)
+ parameters.units=1000
+ properties.spacer=spacer
+ properties.encodingbytes=2
+ properties.format=fonts.formats[filename] or "type1"
+ properties.filename=filename
+ properties.fontname=fontname
+ properties.fullname=fullname
+ properties.psname=fullname
+ properties.name=filename or fullname or fontname
+ properties.private=properties.private or data.private or privateoffset
+ if next(characters) then
+ return {
+ characters=characters,
+ descriptions=descriptions,
+ parameters=parameters,
+ resources=resources,
+ properties=properties,
+ goodies=goodies,
+ }
+ end
+ end
+ return nil
+end
+function afm.setfeatures(tfmdata,features)
+ local okay=constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm)
+ if okay then
+ return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm)
+ else
+ return {}
+ end
end
local function addtables(data)
- local resources=data.resources
- local lookuptags=resources.lookuptags
- local unicodes=resources.unicodes
- if not lookuptags then
- lookuptags={}
- resources.lookuptags=lookuptags
- end
- setmetatableindex(lookuptags,function(t,k)
- local v=type(k)=="number" and ("lookup "..k) or k
- t[k]=v
- return v
+ local resources=data.resources
+ local lookuptags=resources.lookuptags
+ local unicodes=resources.unicodes
+ if not lookuptags then
+ lookuptags={}
+ resources.lookuptags=lookuptags
+ end
+ setmetatableindex(lookuptags,function(t,k)
+ local v=type(k)=="number" and ("lookup "..k) or k
+ t[k]=v
+ return v
+ end)
+ if not unicodes then
+ unicodes={}
+ resources.unicodes=unicodes
+ setmetatableindex(unicodes,function(t,k)
+ setmetatableindex(unicodes,nil)
+ for u,d in next,data.descriptions do
+ local n=d.name
+ if n then
+ t[n]=u
+ end
+ end
+ return rawget(t,k)
end)
- if not unicodes then
- unicodes={}
- resources.unicodes=unicodes
- setmetatableindex(unicodes,function(t,k)
- setmetatableindex(unicodes,nil)
- for u,d in next,data.descriptions do
- local n=d.name
- if n then
- t[n]=u
- end
- end
- return rawget(t,k)
- end)
- end
- constructors.addcoreunicodes(unicodes)
+ end
+ constructors.addcoreunicodes(unicodes)
end
local function afmtotfm(specification)
- local afmname=specification.filename or specification.name
- if specification.forced=="afm" or specification.format=="afm" then
- if trace_loading then
- report_afm("forcing afm format for %a",afmname)
- end
- else
- local tfmname=findbinfile(afmname,"ofm") or ""
- if tfmname~="" then
- if trace_loading then
- report_afm("fallback from afm to tfm for %a",afmname)
- end
- return
- end
- end
- if afmname~="" then
- local features=constructors.checkedfeatures("afm",specification.features.normal)
- specification.features.normal=features
- constructors.hashinstance(specification,true)
- specification=definers.resolve(specification)
- local cache_id=specification.hash
- local tfmdata=containers.read(constructors.cache,cache_id)
- if not tfmdata then
- local rawdata=afm.load(afmname)
- if rawdata and next(rawdata) then
- addtables(rawdata)
- adddimensions(rawdata)
- tfmdata=copytotfm(rawdata)
- if tfmdata and next(tfmdata) then
- local shared=tfmdata.shared
- if not shared then
- shared={}
- tfmdata.shared=shared
- end
- shared.rawdata=rawdata
- shared.dynamics={}
- tfmdata.changed={}
- shared.features=features
- shared.processes=afm.setfeatures(tfmdata,features)
- end
- elseif trace_loading then
- report_afm("no (valid) afm file found with name %a",afmname)
- end
- tfmdata=containers.write(constructors.cache,cache_id,tfmdata)
+ local afmname=specification.filename or specification.name
+ if specification.forced=="afm" or specification.format=="afm" then
+ if trace_loading then
+ report_afm("forcing afm format for %a",afmname)
+ end
+ else
+ local tfmname=findbinfile(afmname,"ofm") or ""
+ if tfmname~="" then
+ if trace_loading then
+ report_afm("fallback from afm to tfm for %a",afmname)
+ end
+ return
+ end
+ end
+ if afmname~="" then
+ local features=constructors.checkedfeatures("afm",specification.features.normal)
+ specification.features.normal=features
+ constructors.hashinstance(specification,true)
+ specification=definers.resolve(specification)
+ local cache_id=specification.hash
+ local tfmdata=containers.read(constructors.cache,cache_id)
+ if not tfmdata then
+ local rawdata=afm.load(afmname)
+ if rawdata and next(rawdata) then
+ addtables(rawdata)
+ adddimensions(rawdata)
+ tfmdata=copytotfm(rawdata)
+ if tfmdata and next(tfmdata) then
+ local shared=tfmdata.shared
+ if not shared then
+ shared={}
+ tfmdata.shared=shared
+ end
+ shared.rawdata=rawdata
+ shared.dynamics={}
+ tfmdata.changed={}
+ shared.features=features
+ shared.processes=afm.setfeatures(tfmdata,features)
end
- return tfmdata
+ elseif trace_loading then
+ report_afm("no (valid) afm file found with name %a",afmname)
+ end
+ tfmdata=containers.write(constructors.cache,cache_id,tfmdata)
end
+ return tfmdata
+ end
end
local function read_from_afm(specification)
- local tfmdata=afmtotfm(specification)
- if tfmdata then
- tfmdata.properties.name=specification.name
- tfmdata=constructors.scale(tfmdata,specification)
- local allfeatures=tfmdata.shared.features or specification.features.normal
- constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm)
- fonts.loggers.register(tfmdata,'afm',specification)
- end
- return tfmdata
+ local tfmdata=afmtotfm(specification)
+ if tfmdata then
+ tfmdata.properties.name=specification.name
+ tfmdata=constructors.scale(tfmdata,specification)
+ local allfeatures=tfmdata.shared.features or specification.features.normal
+ constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm)
+ fonts.loggers.register(tfmdata,'afm',specification)
+ end
+ return tfmdata
end
registerafmfeature {
- name="mode",
- description="mode",
- initializers={
- base=otf.modeinitializer,
- node=otf.modeinitializer,
- }
+ name="mode",
+ description="mode",
+ initializers={
+ base=otf.modeinitializer,
+ node=otf.modeinitializer,
+ }
}
registerafmfeature {
- name="features",
- description="features",
- default=true,
- initializers={
- node=otf.nodemodeinitializer,
- base=otf.basemodeinitializer,
- },
- processors={
- node=otf.featuresprocessor,
- }
+ name="features",
+ description="features",
+ default=true,
+ initializers={
+ node=otf.nodemodeinitializer,
+ base=otf.basemodeinitializer,
+ },
+ processors={
+ node=otf.featuresprocessor,
+ }
}
fonts.formats.afm="type1"
fonts.formats.pfb="type1"
local function check_afm(specification,fullname)
- local foundname=findbinfile(fullname,'afm') or ""
- if foundname=="" then
- foundname=fonts.names.getfilename(fullname,"afm") or ""
- end
- if foundname=="" and afm.autoprefixed then
- local encoding,shortname=match(fullname,"^(.-)%-(.*)$")
- if encoding and shortname and fonts.encodings.known[encoding] then
- shortname=findbinfile(shortname,'afm') or ""
- if shortname~="" then
- foundname=shortname
- if trace_defining then
- report_afm("stripping encoding prefix from filename %a",afmname)
- end
- end
+ local foundname=findbinfile(fullname,'afm') or ""
+ if foundname=="" then
+ foundname=fonts.names.getfilename(fullname,"afm") or ""
+ end
+ if foundname=="" and afm.autoprefixed then
+ local encoding,shortname=match(fullname,"^(.-)%-(.*)$")
+ if encoding and shortname and fonts.encodings.known[encoding] then
+ shortname=findbinfile(shortname,'afm') or ""
+ if shortname~="" then
+ foundname=shortname
+ if trace_defining then
+ report_afm("stripping encoding prefix from filename %a",afmname)
end
+ end
end
- if foundname~="" then
- specification.filename=foundname
- specification.format="afm"
- return read_from_afm(specification)
- end
+ end
+ if foundname~="" then
+ specification.filename=foundname
+ specification.format="afm"
+ return read_from_afm(specification)
+ end
end
function readers.afm(specification,method)
- local fullname=specification.filename or ""
- local tfmdata=nil
- if fullname=="" then
- local forced=specification.forced or ""
- if forced~="" then
- tfmdata=check_afm(specification,specification.name.."."..forced)
- end
- if not tfmdata then
- local check_tfm=readers.check_tfm
- method=(check_tfm and (method or definers.method or "afm or tfm")) or "afm"
- if method=="tfm" then
- tfmdata=check_tfm(specification,specification.name)
- elseif method=="afm" then
- tfmdata=check_afm(specification,specification.name)
- elseif method=="tfm or afm" then
- tfmdata=check_tfm(specification,specification.name) or check_afm(specification,specification.name)
- else
- tfmdata=check_afm(specification,specification.name) or check_tfm(specification,specification.name)
- end
- end
- else
- tfmdata=check_afm(specification,fullname)
+ local fullname=specification.filename or ""
+ local tfmdata=nil
+ if fullname=="" then
+ local forced=specification.forced or ""
+ if forced~="" then
+ tfmdata=check_afm(specification,specification.name.."."..forced)
end
- return tfmdata
+ if not tfmdata then
+ local check_tfm=readers.check_tfm
+ method=(check_tfm and (method or definers.method or "afm or tfm")) or "afm"
+ if method=="tfm" then
+ tfmdata=check_tfm(specification,specification.name)
+ elseif method=="afm" then
+ tfmdata=check_afm(specification,specification.name)
+ elseif method=="tfm or afm" then
+ tfmdata=check_tfm(specification,specification.name) or check_afm(specification,specification.name)
+ else
+ tfmdata=check_afm(specification,specification.name) or check_tfm(specification,specification.name)
+ end
+ end
+ else
+ tfmdata=check_afm(specification,fullname)
+ end
+ return tfmdata
end
function readers.pfb(specification,method)
- local original=specification.specification
- if trace_defining then
- report_afm("using afm reader for %a",original)
- end
- specification.forced="afm"
- local function swap(name)
- local value=specification[swap]
- if value then
- specification[swap]=gsub("%.pfb",".afm",1)
- end
+ local original=specification.specification
+ if trace_defining then
+ report_afm("using afm reader for %a",original)
+ end
+ specification.forced="afm"
+ local function swap(name)
+ local value=specification[swap]
+ if value then
+ specification[swap]=gsub("%.pfb",".afm",1)
end
- swap("filename")
- swap("fullname")
- swap("forcedname")
- swap("specification")
- return readers.afm(specification,method)
+ end
+ swap("filename")
+ swap("fullname")
+ swap("forcedname")
+ swap("specification")
+ return readers.afm(specification,method)
end
registerafmenhancer("unify names",enhance_unify_names)
registerafmenhancer("add ligatures",enhance_add_ligatures)
@@ -33294,168 +33294,168 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-afk']={
- version=1.001,
- comment="companion to font-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
- dataonly=true,
+ version=1.001,
+ comment="companion to font-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files",
+ dataonly=true,
}
local allocate=utilities.storage.allocate
fonts.handlers.afm.helpdata={
- ligatures=allocate {
- ['f']={
- { 'f','ff' },
- { 'i','fi' },
- { 'l','fl' },
- },
- ['ff']={
- { 'i','ffi' }
- },
- ['fi']={
- { 'i','fii' }
- },
- ['fl']={
- { 'i','fli' }
- },
- ['s']={
- { 't','st' }
- },
- ['i']={
- { 'j','ij' }
- },
+ ligatures=allocate {
+ ['f']={
+ { 'f','ff' },
+ { 'i','fi' },
+ { 'l','fl' },
},
- texligatures=allocate {
- ['quoteleft']={
- { 'quoteleft','quotedblleft' }
- },
- ['quoteright']={
- { 'quoteright','quotedblright' }
- },
- ['hyphen']={
- { 'hyphen','endash' }
- },
- ['endash']={
- { 'hyphen','emdash' }
- }
+ ['ff']={
+ { 'i','ffi' }
},
- leftkerned=allocate {
- AEligature="A",aeligature="a",
- OEligature="O",oeligature="o",
- IJligature="I",ijligature="i",
- AE="A",ae="a",
- OE="O",oe="o",
- IJ="I",ij="i",
- Ssharp="S",ssharp="s",
+ ['fi']={
+ { 'i','fii' }
},
- rightkerned=allocate {
- AEligature="E",aeligature="e",
- OEligature="E",oeligature="e",
- IJligature="J",ijligature="j",
- AE="E",ae="e",
- OE="E",oe="e",
- IJ="J",ij="j",
- Ssharp="S",ssharp="s",
+ ['fl']={
+ { 'i','fli' }
},
- bothkerned=allocate {
- Acircumflex="A",acircumflex="a",
- Ccircumflex="C",ccircumflex="c",
- Ecircumflex="E",ecircumflex="e",
- Gcircumflex="G",gcircumflex="g",
- Hcircumflex="H",hcircumflex="h",
- Icircumflex="I",icircumflex="i",
- Jcircumflex="J",jcircumflex="j",
- Ocircumflex="O",ocircumflex="o",
- Scircumflex="S",scircumflex="s",
- Ucircumflex="U",ucircumflex="u",
- Wcircumflex="W",wcircumflex="w",
- Ycircumflex="Y",ycircumflex="y",
- Agrave="A",agrave="a",
- Egrave="E",egrave="e",
- Igrave="I",igrave="i",
- Ograve="O",ograve="o",
- Ugrave="U",ugrave="u",
- Ygrave="Y",ygrave="y",
- Atilde="A",atilde="a",
- Itilde="I",itilde="i",
- Otilde="O",otilde="o",
- Utilde="U",utilde="u",
- Ntilde="N",ntilde="n",
- Adiaeresis="A",adiaeresis="a",Adieresis="A",adieresis="a",
- Ediaeresis="E",ediaeresis="e",Edieresis="E",edieresis="e",
- Idiaeresis="I",idiaeresis="i",Idieresis="I",idieresis="i",
- Odiaeresis="O",odiaeresis="o",Odieresis="O",odieresis="o",
- Udiaeresis="U",udiaeresis="u",Udieresis="U",udieresis="u",
- Ydiaeresis="Y",ydiaeresis="y",Ydieresis="Y",ydieresis="y",
- Aacute="A",aacute="a",
- Cacute="C",cacute="c",
- Eacute="E",eacute="e",
- Iacute="I",iacute="i",
- Lacute="L",lacute="l",
- Nacute="N",nacute="n",
- Oacute="O",oacute="o",
- Racute="R",racute="r",
- Sacute="S",sacute="s",
- Uacute="U",uacute="u",
- Yacute="Y",yacute="y",
- Zacute="Z",zacute="z",
- Dstroke="D",dstroke="d",
- Hstroke="H",hstroke="h",
- Tstroke="T",tstroke="t",
- Cdotaccent="C",cdotaccent="c",
- Edotaccent="E",edotaccent="e",
- Gdotaccent="G",gdotaccent="g",
- Idotaccent="I",idotaccent="i",
- Zdotaccent="Z",zdotaccent="z",
- Amacron="A",amacron="a",
- Emacron="E",emacron="e",
- Imacron="I",imacron="i",
- Omacron="O",omacron="o",
- Umacron="U",umacron="u",
- Ccedilla="C",ccedilla="c",
- Kcedilla="K",kcedilla="k",
- Lcedilla="L",lcedilla="l",
- Ncedilla="N",ncedilla="n",
- Rcedilla="R",rcedilla="r",
- Scedilla="S",scedilla="s",
- Tcedilla="T",tcedilla="t",
- Ohungarumlaut="O",ohungarumlaut="o",
- Uhungarumlaut="U",uhungarumlaut="u",
- Aogonek="A",aogonek="a",
- Eogonek="E",eogonek="e",
- Iogonek="I",iogonek="i",
- Uogonek="U",uogonek="u",
- Aring="A",aring="a",
- Uring="U",uring="u",
- Abreve="A",abreve="a",
- Ebreve="E",ebreve="e",
- Gbreve="G",gbreve="g",
- Ibreve="I",ibreve="i",
- Obreve="O",obreve="o",
- Ubreve="U",ubreve="u",
- Ccaron="C",ccaron="c",
- Dcaron="D",dcaron="d",
- Ecaron="E",ecaron="e",
- Lcaron="L",lcaron="l",
- Ncaron="N",ncaron="n",
- Rcaron="R",rcaron="r",
- Scaron="S",scaron="s",
- Tcaron="T",tcaron="t",
- Zcaron="Z",zcaron="z",
- dotlessI="I",dotlessi="i",
- dotlessJ="J",dotlessj="j",
- AEligature="AE",aeligature="ae",AE="AE",ae="ae",
- OEligature="OE",oeligature="oe",OE="OE",oe="oe",
- IJligature="IJ",ijligature="ij",IJ="IJ",ij="ij",
- Lstroke="L",lstroke="l",Lslash="L",lslash="l",
- Ostroke="O",ostroke="o",Oslash="O",oslash="o",
- Ssharp="SS",ssharp="ss",
- Aumlaut="A",aumlaut="a",
- Eumlaut="E",eumlaut="e",
- Iumlaut="I",iumlaut="i",
- Oumlaut="O",oumlaut="o",
- Uumlaut="U",uumlaut="u",
+ ['s']={
+ { 't','st' }
+ },
+ ['i']={
+ { 'j','ij' }
+ },
+ },
+ texligatures=allocate {
+ ['quoteleft']={
+ { 'quoteleft','quotedblleft' }
+ },
+ ['quoteright']={
+ { 'quoteright','quotedblright' }
+ },
+ ['hyphen']={
+ { 'hyphen','endash' }
+ },
+ ['endash']={
+ { 'hyphen','emdash' }
}
+ },
+ leftkerned=allocate {
+ AEligature="A",aeligature="a",
+ OEligature="O",oeligature="o",
+ IJligature="I",ijligature="i",
+ AE="A",ae="a",
+ OE="O",oe="o",
+ IJ="I",ij="i",
+ Ssharp="S",ssharp="s",
+ },
+ rightkerned=allocate {
+ AEligature="E",aeligature="e",
+ OEligature="E",oeligature="e",
+ IJligature="J",ijligature="j",
+ AE="E",ae="e",
+ OE="E",oe="e",
+ IJ="J",ij="j",
+ Ssharp="S",ssharp="s",
+ },
+ bothkerned=allocate {
+ Acircumflex="A",acircumflex="a",
+ Ccircumflex="C",ccircumflex="c",
+ Ecircumflex="E",ecircumflex="e",
+ Gcircumflex="G",gcircumflex="g",
+ Hcircumflex="H",hcircumflex="h",
+ Icircumflex="I",icircumflex="i",
+ Jcircumflex="J",jcircumflex="j",
+ Ocircumflex="O",ocircumflex="o",
+ Scircumflex="S",scircumflex="s",
+ Ucircumflex="U",ucircumflex="u",
+ Wcircumflex="W",wcircumflex="w",
+ Ycircumflex="Y",ycircumflex="y",
+ Agrave="A",agrave="a",
+ Egrave="E",egrave="e",
+ Igrave="I",igrave="i",
+ Ograve="O",ograve="o",
+ Ugrave="U",ugrave="u",
+ Ygrave="Y",ygrave="y",
+ Atilde="A",atilde="a",
+ Itilde="I",itilde="i",
+ Otilde="O",otilde="o",
+ Utilde="U",utilde="u",
+ Ntilde="N",ntilde="n",
+ Adiaeresis="A",adiaeresis="a",Adieresis="A",adieresis="a",
+ Ediaeresis="E",ediaeresis="e",Edieresis="E",edieresis="e",
+ Idiaeresis="I",idiaeresis="i",Idieresis="I",idieresis="i",
+ Odiaeresis="O",odiaeresis="o",Odieresis="O",odieresis="o",
+ Udiaeresis="U",udiaeresis="u",Udieresis="U",udieresis="u",
+ Ydiaeresis="Y",ydiaeresis="y",Ydieresis="Y",ydieresis="y",
+ Aacute="A",aacute="a",
+ Cacute="C",cacute="c",
+ Eacute="E",eacute="e",
+ Iacute="I",iacute="i",
+ Lacute="L",lacute="l",
+ Nacute="N",nacute="n",
+ Oacute="O",oacute="o",
+ Racute="R",racute="r",
+ Sacute="S",sacute="s",
+ Uacute="U",uacute="u",
+ Yacute="Y",yacute="y",
+ Zacute="Z",zacute="z",
+ Dstroke="D",dstroke="d",
+ Hstroke="H",hstroke="h",
+ Tstroke="T",tstroke="t",
+ Cdotaccent="C",cdotaccent="c",
+ Edotaccent="E",edotaccent="e",
+ Gdotaccent="G",gdotaccent="g",
+ Idotaccent="I",idotaccent="i",
+ Zdotaccent="Z",zdotaccent="z",
+ Amacron="A",amacron="a",
+ Emacron="E",emacron="e",
+ Imacron="I",imacron="i",
+ Omacron="O",omacron="o",
+ Umacron="U",umacron="u",
+ Ccedilla="C",ccedilla="c",
+ Kcedilla="K",kcedilla="k",
+ Lcedilla="L",lcedilla="l",
+ Ncedilla="N",ncedilla="n",
+ Rcedilla="R",rcedilla="r",
+ Scedilla="S",scedilla="s",
+ Tcedilla="T",tcedilla="t",
+ Ohungarumlaut="O",ohungarumlaut="o",
+ Uhungarumlaut="U",uhungarumlaut="u",
+ Aogonek="A",aogonek="a",
+ Eogonek="E",eogonek="e",
+ Iogonek="I",iogonek="i",
+ Uogonek="U",uogonek="u",
+ Aring="A",aring="a",
+ Uring="U",uring="u",
+ Abreve="A",abreve="a",
+ Ebreve="E",ebreve="e",
+ Gbreve="G",gbreve="g",
+ Ibreve="I",ibreve="i",
+ Obreve="O",obreve="o",
+ Ubreve="U",ubreve="u",
+ Ccaron="C",ccaron="c",
+ Dcaron="D",dcaron="d",
+ Ecaron="E",ecaron="e",
+ Lcaron="L",lcaron="l",
+ Ncaron="N",ncaron="n",
+ Rcaron="R",rcaron="r",
+ Scaron="S",scaron="s",
+ Tcaron="T",tcaron="t",
+ Zcaron="Z",zcaron="z",
+ dotlessI="I",dotlessi="i",
+ dotlessJ="J",dotlessj="j",
+ AEligature="AE",aeligature="ae",AE="AE",ae="ae",
+ OEligature="OE",oeligature="oe",OE="OE",oe="oe",
+ IJligature="IJ",ijligature="ij",IJ="IJ",ij="ij",
+ Lstroke="L",lstroke="l",Lslash="L",lslash="l",
+ Ostroke="O",ostroke="o",Oslash="O",oslash="o",
+ Ssharp="SS",ssharp="ss",
+ Aumlaut="A",aumlaut="a",
+ Eumlaut="E",eumlaut="e",
+ Iumlaut="I",iumlaut="i",
+ Oumlaut="O",oumlaut="o",
+ Uumlaut="U",uumlaut="u",
+ }
}
end -- closure
@@ -33463,18 +33463,18 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-tfm']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type=next,type
local match,format=string.match,string.format
local concat,sortedhash=table.concat,table.sortedhash
local idiv=number.idiv
-local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
-local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end)
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end)
local report_defining=logs.reporter("fonts","defining")
local report_tfm=logs.reporter("fonts","tfm loading")
local findbinfile=resolvers.findbinfile
@@ -33500,358 +33500,358 @@ constructors.resolvevirtualtoo=false
fonts.formats.tfm="type1"
fonts.formats.ofm="type1"
function tfm.setfeatures(tfmdata,features)
- local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm)
- if okay then
- return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm)
- else
- return {}
- end
+ local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm)
+ if okay then
+ return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm)
+ else
+ return {}
+ end
end
local depth={}
-local read_from_tfm,check_tfm do
- local tfmreaders=context and tfm.readers
- local loadtfmvf=tfmreaders and tfmreaders.loadtfmvf
- local loadtfm=font.read_tfm
- local loadvf=font.read_vf
- directives.register("fonts.tfm.builtin",function(v)
- loadtfmvf=tfmreaders and tfmreaders.loadtfmvf
- if v and loadtfm then
- loadtfmvf=false
+local read_from_tfm,check_tfm do
+ local tfmreaders=context and tfm.readers
+ local loadtfmvf=tfmreaders and tfmreaders.loadtfmvf
+ local loadtfm=font.read_tfm
+ local loadvf=font.read_vf
+ directives.register("fonts.tfm.builtin",function(v)
+ loadtfmvf=tfmreaders and tfmreaders.loadtfmvf
+ if v and loadtfm then
+ loadtfmvf=false
+ end
+ end)
+ read_from_tfm=function(specification)
+ local filename=specification.filename
+ local size=specification.size
+ depth[filename]=(depth[filename] or 0)+1
+ if trace_defining then
+ report_defining("loading tfm file %a at size %s",filename,size)
+ end
+ local tfmdata
+ if loadtfmvf then
+ tfmdata=loadtfmvf(filename,size)
+ else
+ tfmdata=loadtfm(filename,size)
+ end
+ if tfmdata then
+ local features=specification.features and specification.features.normal or {}
+ local features=constructors.checkedfeatures("tfm",features)
+ specification.features.normal=features
+ local newtfmdata=(depth[filename]==1) and tfm.reencode(tfmdata,specification)
+ if newtfmdata then
+ tfmdata=newtfmdata
+ end
+ local resources=tfmdata.resources or {}
+ local properties=tfmdata.properties or {}
+ local parameters=tfmdata.parameters or {}
+ local shared=tfmdata.shared or {}
+ shared.features=features
+ shared.resources=resources
+ properties.name=tfmdata.name
+ properties.fontname=tfmdata.fontname
+ properties.psname=tfmdata.psname
+ properties.fullname=tfmdata.fullname
+ properties.filename=specification.filename
+ properties.format=tfmdata.format or fonts.formats.tfm
+ properties.usedbitmap=tfmdata.usedbitmap
+ tfmdata.properties=properties
+ tfmdata.resources=resources
+ tfmdata.parameters=parameters
+ tfmdata.shared=shared
+ shared.rawdata={ resources=resources }
+ shared.features=features
+ if newtfmdata then
+ if not resources.marks then
+ resources.marks={}
+ end
+ if not resources.sequences then
+ resources.sequences={}
+ end
+ if not resources.features then
+ resources.features={
+ gsub={},
+ gpos={},
+ }
end
- end)
- read_from_tfm=function(specification)
- local filename=specification.filename
- local size=specification.size
- depth[filename]=(depth[filename] or 0)+1
- if trace_defining then
- report_defining("loading tfm file %a at size %s",filename,size)
+ if not tfmdata.changed then
+ tfmdata.changed={}
end
- local tfmdata
- if loadtfmvf then
- tfmdata=loadtfmvf(filename,size)
- else
- tfmdata=loadtfm(filename,size)
- end
- if tfmdata then
- local features=specification.features and specification.features.normal or {}
- local features=constructors.checkedfeatures("tfm",features)
- specification.features.normal=features
- local newtfmdata=(depth[filename]==1) and tfm.reencode(tfmdata,specification)
- if newtfmdata then
- tfmdata=newtfmdata
- end
- local resources=tfmdata.resources or {}
- local properties=tfmdata.properties or {}
- local parameters=tfmdata.parameters or {}
- local shared=tfmdata.shared or {}
- shared.features=features
- shared.resources=resources
- properties.name=tfmdata.name
- properties.fontname=tfmdata.fontname
- properties.psname=tfmdata.psname
- properties.fullname=tfmdata.fullname
- properties.filename=specification.filename
- properties.format=tfmdata.format or fonts.formats.tfm
- properties.usedbitmap=tfmdata.usedbitmap
- tfmdata.properties=properties
- tfmdata.resources=resources
- tfmdata.parameters=parameters
- tfmdata.shared=shared
- shared.rawdata={ resources=resources }
- shared.features=features
- if newtfmdata then
- if not resources.marks then
- resources.marks={}
- end
- if not resources.sequences then
- resources.sequences={}
- end
- if not resources.features then
- resources.features={
- gsub={},
- gpos={},
- }
- end
- if not tfmdata.changed then
- tfmdata.changed={}
- end
- if not tfmdata.descriptions then
- tfmdata.descriptions=tfmdata.characters
- end
- otf.readers.addunicodetable(tfmdata)
- tfmenhancers.apply(tfmdata,filename)
- constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm)
- otf.readers.unifymissing(tfmdata)
- fonts.mappings.addtounicode(tfmdata,filename)
- tfmdata.tounicode=1
- local tounicode=fonts.mappings.tounicode
- for unicode,v in next,tfmdata.characters do
- local u=v.unicode
- if u then
- v.tounicode=tounicode(u)
- end
- end
- if tfmdata.usedbitmap then
- tfm.addtounicode(tfmdata)
+ if not tfmdata.descriptions then
+ tfmdata.descriptions=tfmdata.characters
+ end
+ otf.readers.addunicodetable(tfmdata)
+ tfmenhancers.apply(tfmdata,filename)
+ constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm)
+ otf.readers.unifymissing(tfmdata)
+ fonts.mappings.addtounicode(tfmdata,filename)
+ tfmdata.tounicode=1
+ local tounicode=fonts.mappings.tounicode
+ for unicode,v in next,tfmdata.characters do
+ local u=v.unicode
+ if u then
+ v.tounicode=tounicode(u)
+ end
+ end
+ if tfmdata.usedbitmap then
+ tfm.addtounicode(tfmdata)
+ end
+ end
+ shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil
+ if size<0 then
+ size=idiv(65536*-size,100)
+ end
+ parameters.factor=1
+ parameters.units=1000
+ parameters.size=size
+ parameters.slant=parameters.slant or parameters[1] or 0
+ parameters.space=parameters.space or parameters[2] or 0
+ parameters.space_stretch=parameters.space_stretch or parameters[3] or 0
+ parameters.space_shrink=parameters.space_shrink or parameters[4] or 0
+ parameters.x_height=parameters.x_height or parameters[5] or 0
+ parameters.quad=parameters.quad or parameters[6] or 0
+ parameters.extra_space=parameters.extra_space or parameters[7] or 0
+ constructors.enhanceparameters(parameters)
+ properties.private=properties.private or tfmdata.private or privateoffset
+ if newtfmdata then
+ elseif loadtfmvf then
+ local fonts=tfmdata.fonts
+ if fonts then
+ for i=1,#fonts do
+ local font=fonts[i]
+ local id=font.id
+ if not id then
+ local name=font.name
+ local size=font.size
+ if name and size then
+ local data,id=constructors.readanddefine(name,size)
+ if id then
+ font.id=id
+ font.name=nil
+ font.size=nil
end
+ end
end
- shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil
- if size<0 then
- size=idiv(65536*-size,100)
- end
- parameters.factor=1
- parameters.units=1000
- parameters.size=size
- parameters.slant=parameters.slant or parameters[1] or 0
- parameters.space=parameters.space or parameters[2] or 0
- parameters.space_stretch=parameters.space_stretch or parameters[3] or 0
- parameters.space_shrink=parameters.space_shrink or parameters[4] or 0
- parameters.x_height=parameters.x_height or parameters[5] or 0
- parameters.quad=parameters.quad or parameters[6] or 0
- parameters.extra_space=parameters.extra_space or parameters[7] or 0
- constructors.enhanceparameters(parameters)
- properties.private=properties.private or tfmdata.private or privateoffset
- if newtfmdata then
- elseif loadtfmvf then
- local fonts=tfmdata.fonts
- if fonts then
- for i=1,#fonts do
- local font=fonts[i]
- local id=font.id
- if not id then
- local name=font.name
- local size=font.size
- if name and size then
- local data,id=constructors.readanddefine(name,size)
- if id then
- font.id=id
- font.name=nil
- font.size=nil
- end
- end
- end
- end
- end
- elseif constructors.resolvevirtualtoo then
- fonts.loggers.register(tfmdata,file.suffix(filename),specification)
- local vfname=findbinfile(specification.name,'ovf')
- if vfname and vfname~="" then
- local vfdata=loadvf(vfname,size)
- if vfdata then
- local chars=tfmdata.characters
- for k,v in next,vfdata.characters do
- chars[k].commands=v.commands
- end
- properties.virtualized=true
- tfmdata.fonts=vfdata.fonts
- tfmdata.type="virtual"
- local fontlist=vfdata.fonts
- local name=file.nameonly(filename)
- for i=1,#fontlist do
- local n=fontlist[i].name
- local s=fontlist[i].size
- local d=depth[filename]
- s=constructors.scaled(s,vfdata.designsize)
- if d>tfm.maxnestingdepth then
- report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth)
- fontlist[i]={ id=0 }
- elseif (d>1) and (s>tfm.maxnestingsize) then
- report_defining("virtual font %a exceeds size %s",n,s)
- fontlist[i]={ id=0 }
- else
- local t,id=constructors.readanddefine(n,s)
- fontlist[i]={ id=id }
- end
- end
- end
- end
+ end
+ end
+ elseif constructors.resolvevirtualtoo then
+ fonts.loggers.register(tfmdata,file.suffix(filename),specification)
+ local vfname=findbinfile(specification.name,'ovf')
+ if vfname and vfname~="" then
+ local vfdata=loadvf(vfname,size)
+ if vfdata then
+ local chars=tfmdata.characters
+ for k,v in next,vfdata.characters do
+ chars[k].commands=v.commands
end
- properties.haskerns=true
- properties.hasligatures=true
- properties.hasitalics=true
- resources.unicodes={}
- resources.lookuptags={}
- depth[filename]=depth[filename]-1
- return tfmdata
- else
- depth[filename]=depth[filename]-1
+ properties.virtualized=true
+ tfmdata.fonts=vfdata.fonts
+ tfmdata.type="virtual"
+ local fontlist=vfdata.fonts
+ local name=file.nameonly(filename)
+ for i=1,#fontlist do
+ local n=fontlist[i].name
+ local s=fontlist[i].size
+ local d=depth[filename]
+ s=constructors.scaled(s,vfdata.designsize)
+ if d>tfm.maxnestingdepth then
+ report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth)
+ fontlist[i]={ id=0 }
+ elseif (d>1) and (s>tfm.maxnestingsize) then
+ report_defining("virtual font %a exceeds size %s",n,s)
+ fontlist[i]={ id=0 }
+ else
+ local t,id=constructors.readanddefine(n,s)
+ fontlist[i]={ id=id }
+ end
+ end
+ end
end
+ end
+ properties.haskerns=true
+ properties.hasligatures=true
+ properties.hasitalics=true
+ resources.unicodes={}
+ resources.lookuptags={}
+ depth[filename]=depth[filename]-1
+ return tfmdata
+ else
+ depth[filename]=depth[filename]-1
end
- check_tfm=function(specification,fullname)
- local foundname=findbinfile(fullname,'tfm') or ""
- if foundname=="" then
- foundname=findbinfile(fullname,'ofm') or ""
- end
- if foundname=="" then
- foundname=fonts.names.getfilename(fullname,"tfm") or ""
- end
- if foundname~="" then
- specification.filename=foundname
- specification.format="ofm"
- return read_from_tfm(specification)
- elseif trace_defining then
- report_defining("loading tfm with name %a fails",specification.name)
- end
+ end
+ check_tfm=function(specification,fullname)
+ local foundname=findbinfile(fullname,'tfm') or ""
+ if foundname=="" then
+ foundname=findbinfile(fullname,'ofm') or ""
+ end
+ if foundname=="" then
+ foundname=fonts.names.getfilename(fullname,"tfm") or ""
end
+ if foundname~="" then
+ specification.filename=foundname
+ specification.format="ofm"
+ return read_from_tfm(specification)
+ elseif trace_defining then
+ report_defining("loading tfm with name %a fails",specification.name)
+ end
+ end
end
readers.check_tfm=check_tfm
function readers.tfm(specification)
- local fullname=specification.filename or ""
- if fullname=="" then
- local forced=specification.forced or ""
- if forced~="" then
- fullname=specification.name.."."..forced
- else
- fullname=specification.name
- end
+ local fullname=specification.filename or ""
+ if fullname=="" then
+ local forced=specification.forced or ""
+ if forced~="" then
+ fullname=specification.name.."."..forced
+ else
+ fullname=specification.name
end
- return check_tfm(specification,fullname)
+ end
+ return check_tfm(specification,fullname)
end
readers.ofm=readers.tfm
do
- local outfiles={}
- local tfmcache=table.setmetatableindex(function(t,tfmdata)
- local id=font.define(tfmdata)
- t[tfmdata]=id
- return id
- end)
- local encdone=table.setmetatableindex("table")
- function tfm.reencode(tfmdata,specification)
- local features=specification.features
- if not features then
- return
+ local outfiles={}
+ local tfmcache=table.setmetatableindex(function(t,tfmdata)
+ local id=font.define(tfmdata)
+ t[tfmdata]=id
+ return id
+ end)
+ local encdone=table.setmetatableindex("table")
+ function tfm.reencode(tfmdata,specification)
+ local features=specification.features
+ if not features then
+ return
+ end
+ local features=features.normal
+ if not features then
+ return
+ end
+ local tfmfile=file.basename(tfmdata.name)
+ local encfile=features.reencode
+ local pfbfile=features.pfbfile
+ local bitmap=features.bitmap
+ if not encfile then
+ return
+ end
+ local pfbfile=outfiles[tfmfile]
+ if pfbfile==nil then
+ if bitmap then
+ pfbfile=false
+ elseif type(pfbfile)~="string" then
+ pfbfile=tfmfile
+ end
+ if type(pfbfile)=="string" then
+ pfbfile=file.addsuffix(pfbfile,"pfb")
+ report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile)
+ else
+ report_tfm("using bitmap shapes for %a",tfmfile)
+ pfbfile=false
+ end
+ outfiles[tfmfile]=pfbfile
+ end
+ local encoding=false
+ local vector=false
+ if type(pfbfile)=="string" then
+ local pfb=constructors.handlers.pfb
+ if pfb and pfb.loadvector then
+ local v,e=pfb.loadvector(pfbfile)
+ if v then
+ vector=v
end
- local features=features.normal
- if not features then
- return
- end
- local tfmfile=file.basename(tfmdata.name)
- local encfile=features.reencode
- local pfbfile=features.pfbfile
- local bitmap=features.bitmap
- if not encfile then
- return
- end
- local pfbfile=outfiles[tfmfile]
- if pfbfile==nil then
- if bitmap then
- pfbfile=false
- elseif type(pfbfile)~="string" then
- pfbfile=tfmfile
- end
- if type(pfbfile)=="string" then
- pfbfile=file.addsuffix(pfbfile,"pfb")
- report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile)
- else
- report_tfm("using bitmap shapes for %a",tfmfile)
- pfbfile=false
- end
- outfiles[tfmfile]=pfbfile
- end
- local encoding=false
- local vector=false
- if type(pfbfile)=="string" then
- local pfb=constructors.handlers.pfb
- if pfb and pfb.loadvector then
- local v,e=pfb.loadvector(pfbfile)
- if v then
- vector=v
- end
- if e then
- encoding=e
- end
- end
+ if e then
+ encoding=e
end
- if type(encfile)=="string" and encfile~="auto" then
- encoding=fonts.encodings.load(file.addsuffix(encfile,"enc"))
- if encoding then
- encoding=encoding.vector
- end
- end
- if not encoding then
- report_tfm("bad encoding for %a, quitting",tfmfile)
- return
- end
- local unicoding=fonts.encodings.agl and fonts.encodings.agl.unicodes
- local virtualid=tfmcache[tfmdata]
- local tfmdata=table.copy(tfmdata)
- local characters={}
- local originals=tfmdata.characters
- local indices={}
- local parentfont={ "font",1 }
- local private=tfmdata.privateoffset or constructors.privateoffset
- local reported=encdone[tfmfile][encfile]
- local backmap=vector and table.swapped(vector)
- local done={}
- for index,name in sortedhash(encoding) do
- local unicode=unicoding[name]
- local original=originals[index]
- if original then
- if unicode then
- original.unicode=unicode
- else
- unicode=private
- private=private+1
- if not reported then
- report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode)
- end
- end
- characters[unicode]=original
- indices[index]=unicode
- original.name=name
- if backmap then
- original.index=backmap[name]
- else
- original.commands={ parentfont,charcommand[index] }
- original.oindex=index
- end
- done[name]=true
- elseif not done[name] then
- report_tfm("bad index %a in font %a with name %a",index,tfmfile,name)
- end
+ end
+ end
+ if type(encfile)=="string" and encfile~="auto" then
+ encoding=fonts.encodings.load(file.addsuffix(encfile,"enc"))
+ if encoding then
+ encoding=encoding.vector
+ end
+ end
+ if not encoding then
+ report_tfm("bad encoding for %a, quitting",tfmfile)
+ return
+ end
+ local unicoding=fonts.encodings.agl and fonts.encodings.agl.unicodes
+ local virtualid=tfmcache[tfmdata]
+ local tfmdata=table.copy(tfmdata)
+ local characters={}
+ local originals=tfmdata.characters
+ local indices={}
+ local parentfont={ "font",1 }
+ local private=tfmdata.privateoffset or constructors.privateoffset
+ local reported=encdone[tfmfile][encfile]
+ local backmap=vector and table.swapped(vector)
+ local done={}
+ for index,name in sortedhash(encoding) do
+ local unicode=unicoding[name]
+ local original=originals[index]
+ if original then
+ if unicode then
+ original.unicode=unicode
+ else
+ unicode=private
+ private=private+1
+ if not reported then
+ report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode)
+ end
end
- encdone[tfmfile][encfile]=true
- for k,v in next,characters do
- local kerns=v.kerns
- if kerns then
- local t={}
- for k,v in next,kerns do
- local i=indices[k]
- if i then
- t[i]=v
- end
- end
- v.kerns=next(t) and t or nil
- end
- local ligatures=v.ligatures
- if ligatures then
- local t={}
- for k,v in next,ligatures do
- local i=indices[k]
- if i then
- t[i]=v
- v.char=indices[v.char]
- end
- end
- v.ligatures=next(t) and t or nil
- end
+ characters[unicode]=original
+ indices[index]=unicode
+ original.name=name
+ if backmap then
+ original.index=backmap[name]
+ else
+ original.commands={ parentfont,charcommand[index] }
+ original.oindex=index
+ end
+ done[name]=true
+ elseif not done[name] then
+ report_tfm("bad index %a in font %a with name %a",index,tfmfile,name)
+ end
+ end
+ encdone[tfmfile][encfile]=true
+ for k,v in next,characters do
+ local kerns=v.kerns
+ if kerns then
+ local t={}
+ for k,v in next,kerns do
+ local i=indices[k]
+ if i then
+ t[i]=v
+ end
end
- tfmdata.fonts={ { id=virtualid } }
- tfmdata.characters=characters
- tfmdata.fullname=tfmdata.fullname or tfmdata.name
- tfmdata.psname=file.nameonly(pfbfile or tfmdata.name)
- tfmdata.filename=pfbfile
- tfmdata.encodingbytes=2
- tfmdata.format="type1"
- tfmdata.tounicode=1
- tfmdata.embedding="subset"
- tfmdata.usedbitmap=bitmap and virtualid
- tfmdata.private=private
- return tfmdata
- end
+ v.kerns=next(t) and t or nil
+ end
+ local ligatures=v.ligatures
+ if ligatures then
+ local t={}
+ for k,v in next,ligatures do
+ local i=indices[k]
+ if i then
+ t[i]=v
+ v.char=indices[v.char]
+ end
+ end
+ v.ligatures=next(t) and t or nil
+ end
+ end
+ tfmdata.fonts={ { id=virtualid } }
+ tfmdata.characters=characters
+ tfmdata.fullname=tfmdata.fullname or tfmdata.name
+ tfmdata.psname=file.nameonly(pfbfile or tfmdata.name)
+ tfmdata.filename=pfbfile
+ tfmdata.encodingbytes=2
+ tfmdata.format="type1"
+ tfmdata.tounicode=1
+ tfmdata.embedding="subset"
+ tfmdata.usedbitmap=bitmap and virtualid
+ tfmdata.private=private
+ return tfmdata
+ end
end
do
- local template=[[
+ local template=[[
/CIDInit /ProcSet findresource begin
12 dict begin
begincmap
@@ -33869,145 +33869,145 @@ CMapName currentdict /CMap defineresource pop end
end
end
]]
- local flushstreamobject=lpdf and lpdf.flushstreamobject
- local setfontattributes=lpdf and lpdf.setfontattributes
- if not flushstreamobject then
- flushstreamobject=function(data)
- return pdf.obj { immediate=true,type="stream",string=data }
- end
- end
- if not setfontattributes then
- setfontattributes=function(id,data)
- return pdf.setfontattributes(id,data)
- end
- end
- function tfm.addtounicode(tfmdata)
- local id=tfmdata.usedbitmap
- local map={}
- local char={}
- for k,v in next,tfmdata.characters do
- local index=v.oindex
- local tounicode=v.tounicode
- if index and tounicode then
- map[index]=tounicode
- end
- end
- for k,v in sortedhash(map) do
- char[#char+1]=format("<%02X> <%s>",k,v)
- end
- char=concat(char,"\n")
- local stream=format(template,id,id,#char,char)
- local reference=flushstreamobject(stream,nil,true)
- setfontattributes(id,format("/ToUnicode %i 0 R",reference))
- end
+ local flushstreamobject=lpdf and lpdf.flushstreamobject
+ local setfontattributes=lpdf and lpdf.setfontattributes
+ if not flushstreamobject then
+ flushstreamobject=function(data)
+ return pdf.obj { immediate=true,type="stream",string=data }
+ end
+ end
+ if not setfontattributes then
+ setfontattributes=function(id,data)
+ return pdf.setfontattributes(id,data)
+ end
+ end
+ function tfm.addtounicode(tfmdata)
+ local id=tfmdata.usedbitmap
+ local map={}
+ local char={}
+ for k,v in next,tfmdata.characters do
+ local index=v.oindex
+ local tounicode=v.tounicode
+ if index and tounicode then
+ map[index]=tounicode
+ end
+ end
+ for k,v in sortedhash(map) do
+ char[#char+1]=format("<%02X> <%s>",k,v)
+ end
+ char=concat(char,"\n")
+ local stream=format(template,id,id,#char,char)
+ local reference=flushstreamobject(stream,nil,true)
+ setfontattributes(id,format("/ToUnicode %i 0 R",reference))
+ end
end
do
- local everywhere={ ["*"]={ ["*"]=true } }
- local noflags={ false,false,false,false }
- local function enhance_normalize_features(data)
- local ligatures=setmetatableindex("table")
- local kerns=setmetatableindex("table")
- local characters=data.characters
- for u,c in next,characters do
- local l=c.ligatures
- local k=c.kerns
- if l then
- ligatures[u]=l
- for u,v in next,l do
- l[u]={ ligature=v.char }
- end
- c.ligatures=nil
- end
- if k then
- kerns[u]=k
- for u,v in next,k do
- k[u]=v
- end
- c.kerns=nil
- end
- end
- for u,l in next,ligatures do
- for k,v in next,l do
- local vl=v.ligature
- local dl=ligatures[vl]
- if dl then
- for kk,vv in next,dl do
- v[kk]=vv
- end
- end
- end
- end
- local features={
- gpos={},
- gsub={},
- }
- local sequences={
- }
- if next(ligatures) then
- features.gsub.liga=everywhere
- data.properties.hasligatures=true
- sequences[#sequences+1]={
- features={
- liga=everywhere,
- },
- flags=noflags,
- name="s_s_0",
- nofsteps=1,
- order={ "liga" },
- type="gsub_ligature",
- steps={
- {
- coverage=ligatures,
- },
- },
- }
- end
- if next(kerns) then
- features.gpos.kern=everywhere
- data.properties.haskerns=true
- sequences[#sequences+1]={
- features={
- kern=everywhere,
- },
- flags=noflags,
- name="p_s_0",
- nofsteps=1,
- order={ "kern" },
- type="gpos_pair",
- steps={
- {
- format="kern",
- coverage=kerns,
- },
- },
- }
+ local everywhere={ ["*"]={ ["*"]=true } }
+ local noflags={ false,false,false,false }
+ local function enhance_normalize_features(data)
+ local ligatures=setmetatableindex("table")
+ local kerns=setmetatableindex("table")
+ local characters=data.characters
+ for u,c in next,characters do
+ local l=c.ligatures
+ local k=c.kerns
+ if l then
+ ligatures[u]=l
+ for u,v in next,l do
+ l[u]={ ligature=v.char }
+ end
+ c.ligatures=nil
+ end
+ if k then
+ kerns[u]=k
+ for u,v in next,k do
+ k[u]=v
+ end
+ c.kerns=nil
+ end
+ end
+ for u,l in next,ligatures do
+ for k,v in next,l do
+ local vl=v.ligature
+ local dl=ligatures[vl]
+ if dl then
+ for kk,vv in next,dl do
+ v[kk]=vv
+ end
end
- data.resources.features=features
- data.resources.sequences=sequences
- data.shared.resources=data.shared.resources or resources
+ end
+ end
+ local features={
+ gpos={},
+ gsub={},
+ }
+ local sequences={
+ }
+ if next(ligatures) then
+ features.gsub.liga=everywhere
+ data.properties.hasligatures=true
+ sequences[#sequences+1]={
+ features={
+ liga=everywhere,
+ },
+ flags=noflags,
+ name="s_s_0",
+ nofsteps=1,
+ order={ "liga" },
+ type="gsub_ligature",
+ steps={
+ {
+ coverage=ligatures,
+ },
+ },
+ }
+ end
+ if next(kerns) then
+ features.gpos.kern=everywhere
+ data.properties.haskerns=true
+ sequences[#sequences+1]={
+ features={
+ kern=everywhere,
+ },
+ flags=noflags,
+ name="p_s_0",
+ nofsteps=1,
+ order={ "kern" },
+ type="gpos_pair",
+ steps={
+ {
+ format="kern",
+ coverage=kerns,
+ },
+ },
+ }
end
- registertfmenhancer("normalize features",enhance_normalize_features)
- registertfmenhancer("check extra features",otfenhancers.enhance)
+ data.resources.features=features
+ data.resources.sequences=sequences
+ data.shared.resources=data.shared.resources or resources
+ end
+ registertfmenhancer("normalize features",enhance_normalize_features)
+ registertfmenhancer("check extra features",otfenhancers.enhance)
end
registertfmfeature {
- name="mode",
- description="mode",
- initializers={
- base=otf.modeinitializer,
- node=otf.modeinitializer,
- }
+ name="mode",
+ description="mode",
+ initializers={
+ base=otf.modeinitializer,
+ node=otf.modeinitializer,
+ }
}
registertfmfeature {
- name="features",
- description="features",
- default=true,
- initializers={
- base=otf.basemodeinitializer,
- node=otf.nodemodeinitializer,
- },
- processors={
- node=otf.featuresprocessor,
- }
+ name="features",
+ description="features",
+ default=true,
+ initializers={
+ base=otf.basemodeinitializer,
+ node=otf.nodemodeinitializer,
+ },
+ processors={
+ node=otf.featuresprocessor,
+ }
}
end -- closure
@@ -34015,41 +34015,41 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-lua']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
+local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
local report_lua=logs.reporter("fonts","lua loading")
local fonts=fonts
local readers=fonts.readers
fonts.formats.lua="lua"
local function check_lua(specification,fullname)
- local fullname=resolvers.findfile(fullname) or ""
- if fullname~="" then
- local loader=loadfile(fullname)
- loader=loader and loader()
- return loader and loader(specification)
- end
+ local fullname=resolvers.findfile(fullname) or ""
+ if fullname~="" then
+ local loader=loadfile(fullname)
+ loader=loader and loader()
+ return loader and loader(specification)
+ end
end
readers.check_lua=check_lua
function readers.lua(specification)
- local original=specification.specification
- if trace_defining then
- report_lua("using lua reader for %a",original)
- end
- local fullname=specification.filename or ""
- if fullname=="" then
- local forced=specification.forced or ""
- if forced~="" then
- fullname=specification.name.."."..forced
- else
- fullname=specification.name
- end
+ local original=specification.specification
+ if trace_defining then
+ report_lua("using lua reader for %a",original)
+ end
+ local fullname=specification.filename or ""
+ if fullname=="" then
+ local forced=specification.forced or ""
+ if forced~="" then
+ fullname=specification.name.."."..forced
+ else
+ fullname=specification.name
end
- return check_lua(specification,fullname)
+ end
+ return check_lua(specification,fullname)
end
end -- closure
@@ -34057,11 +34057,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-def']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local lower,gsub=string.lower,string.gsub
local tostring,next=tostring,next
@@ -34070,8 +34070,8 @@ local suffixonly,removesuffix,basename=file.suffix,file.removesuffix,file.basena
local formatters=string.formatters
local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
local allocate=utilities.storage.allocate
-local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end)
-local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end)
+local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end)
+local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end)
trackers.register("fonts.loading","fonts.defining","otf.loading","afm.loading","tfm.loading")
local report_defining=logs.reporter("fonts","defining")
local fonts=fonts
@@ -34091,27 +34091,27 @@ local loadedfonts=constructors.loadedfonts
local designsizes=constructors.designsizes
local resolvefile=fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end
local function makespecification(specification,lookup,name,sub,method,detail,size)
- size=size or 655360
- if not lookup or lookup=="" then
- lookup=definers.defaultlookup
- end
- if trace_defining then
- report_defining("specification %a, lookup %a, name %a, sub %a, method %a, detail %a",
- specification,lookup,name,sub,method,detail)
- end
- local t={
- lookup=lookup,
- specification=specification,
- size=size,
- name=name,
- sub=sub,
- method=method,
- detail=detail,
- resolved="",
- forced="",
- features={},
- }
- return t
+ size=size or 655360
+ if not lookup or lookup=="" then
+ lookup=definers.defaultlookup
+ end
+ if trace_defining then
+ report_defining("specification %a, lookup %a, name %a, sub %a, method %a, detail %a",
+ specification,lookup,name,sub,method,detail)
+ end
+ local t={
+ lookup=lookup,
+ specification=specification,
+ size=size,
+ name=name,
+ sub=sub,
+ method=method,
+ detail=detail,
+ resolved="",
+ forced="",
+ features={},
+ }
+ return t
end
definers.makespecification=makespecification
if context then
@@ -34122,299 +34122,299 @@ end
definers.resolvers=definers.resolvers or {}
local resolvers=definers.resolvers
function resolvers.file(specification)
- local name=resolvefile(specification.name)
- local suffix=lower(suffixonly(name))
- if fonts.formats[suffix] then
- specification.forced=suffix
- specification.forcedname=name
- specification.name=removesuffix(name)
- else
- specification.name=name
- end
+ local name=resolvefile(specification.name)
+ local suffix=lower(suffixonly(name))
+ if fonts.formats[suffix] then
+ specification.forced=suffix
+ specification.forcedname=name
+ specification.name=removesuffix(name)
+ else
+ specification.name=name
+ end
end
function resolvers.name(specification)
- local resolve=fonts.names.resolve
- if resolve then
- local resolved,sub,subindex,instance=resolve(specification.name,specification.sub,specification)
- if resolved then
- specification.resolved=resolved
- specification.sub=sub
- specification.subindex=subindex
- if instance then
- specification.instance=instance
- local features=specification.features
- if not features then
- features={}
- specification.features=features
- end
- local normal=features.normal
- if not normal then
- normal={}
- features.normal=normal
- end
- normal.instance=instance
- end
- local suffix=lower(suffixonly(resolved))
- if fonts.formats[suffix] then
- specification.forced=suffix
- specification.forcedname=resolved
- specification.name=removesuffix(resolved)
- else
- specification.name=resolved
- end
- end
- else
- resolvers.file(specification)
+ local resolve=fonts.names.resolve
+ if resolve then
+ local resolved,sub,subindex,instance=resolve(specification.name,specification.sub,specification)
+ if resolved then
+ specification.resolved=resolved
+ specification.sub=sub
+ specification.subindex=subindex
+ if instance then
+ specification.instance=instance
+ local features=specification.features
+ if not features then
+ features={}
+ specification.features=features
+ end
+ local normal=features.normal
+ if not normal then
+ normal={}
+ features.normal=normal
+ end
+ normal.instance=instance
+ end
+ local suffix=lower(suffixonly(resolved))
+ if fonts.formats[suffix] then
+ specification.forced=suffix
+ specification.forcedname=resolved
+ specification.name=removesuffix(resolved)
+ else
+ specification.name=resolved
+ end
end
+ else
+ resolvers.file(specification)
+ end
end
function resolvers.spec(specification)
- local resolvespec=fonts.names.resolvespec
- if resolvespec then
- local resolved,sub,subindex=resolvespec(specification.name,specification.sub,specification)
- if resolved then
- specification.resolved=resolved
- specification.sub=sub
- specification.subindex=subindex
- specification.forced=lower(suffixonly(resolved))
- specification.forcedname=resolved
- specification.name=removesuffix(resolved)
- end
- else
- resolvers.name(specification)
- end
+ local resolvespec=fonts.names.resolvespec
+ if resolvespec then
+ local resolved,sub,subindex=resolvespec(specification.name,specification.sub,specification)
+ if resolved then
+ specification.resolved=resolved
+ specification.sub=sub
+ specification.subindex=subindex
+ specification.forced=lower(suffixonly(resolved))
+ specification.forcedname=resolved
+ specification.name=removesuffix(resolved)
+ end
+ else
+ resolvers.name(specification)
+ end
end
function definers.resolve(specification)
- if not specification.resolved or specification.resolved=="" then
- local r=resolvers[specification.lookup]
- if r then
- r(specification)
- end
- end
- if specification.forced=="" then
- specification.forced=nil
- specification.forcedname=nil
- end
- specification.hash=lower(specification.name..' @ '..constructors.hashfeatures(specification))
- if specification.sub and specification.sub~="" then
- specification.hash=specification.sub..' @ '..specification.hash
- end
- return specification
+ if not specification.resolved or specification.resolved=="" then
+ local r=resolvers[specification.lookup]
+ if r then
+ r(specification)
+ end
+ end
+ if specification.forced=="" then
+ specification.forced=nil
+ specification.forcedname=nil
+ end
+ specification.hash=lower(specification.name..' @ '..constructors.hashfeatures(specification))
+ if specification.sub and specification.sub~="" then
+ specification.hash=specification.sub..' @ '..specification.hash
+ end
+ return specification
end
function definers.applypostprocessors(tfmdata)
- local postprocessors=tfmdata.postprocessors
- if postprocessors then
- local properties=tfmdata.properties
- for i=1,#postprocessors do
- local extrahash=postprocessors[i](tfmdata)
- if type(extrahash)=="string" and extrahash~="" then
- extrahash=gsub(lower(extrahash),"[^a-z]","-")
- properties.fullname=formatters["%s-%s"](properties.fullname,extrahash)
- end
- end
+ local postprocessors=tfmdata.postprocessors
+ if postprocessors then
+ local properties=tfmdata.properties
+ for i=1,#postprocessors do
+ local extrahash=postprocessors[i](tfmdata)
+ if type(extrahash)=="string" and extrahash~="" then
+ extrahash=gsub(lower(extrahash),"[^a-z]","-")
+ properties.fullname=formatters["%s-%s"](properties.fullname,extrahash)
+ end
end
- return tfmdata
+ end
+ return tfmdata
end
local function checkembedding(tfmdata)
- local properties=tfmdata.properties
- local embedding
- if directive_embedall then
- embedding="full"
- elseif properties and properties.filename and constructors.dontembed[properties.filename] then
- embedding="no"
- else
- embedding="subset"
- end
- if properties then
- properties.embedding=embedding
- else
- tfmdata.properties={ embedding=embedding }
- end
- tfmdata.embedding=embedding
+ local properties=tfmdata.properties
+ local embedding
+ if directive_embedall then
+ embedding="full"
+ elseif properties and properties.filename and constructors.dontembed[properties.filename] then
+ embedding="no"
+ else
+ embedding="subset"
+ end
+ if properties then
+ properties.embedding=embedding
+ else
+ tfmdata.properties={ embedding=embedding }
+ end
+ tfmdata.embedding=embedding
end
local function checkfeatures(tfmdata)
- local resources=tfmdata.resources
- local shared=tfmdata.shared
- if resources and shared then
- local features=resources.features
- local usedfeatures=shared.features
- if features and usedfeatures then
- local usedlanguage=usedfeatures.language or "dflt"
- local usedscript=usedfeatures.script or "dflt"
- local function check(what)
- if what then
- local foundlanguages={}
- for feature,scripts in next,what do
- if usedscript=="auto" or scripts["*"] then
- elseif not scripts[usedscript] then
- else
- for script,languages in next,scripts do
- if languages["*"] then
- elseif not languages[usedlanguage] then
- report_defining("font %!font:name!, feature %a, script %a, no language %a",
- tfmdata,feature,script,usedlanguage)
- end
- end
- end
- for script,languages in next,scripts do
- for language in next,languages do
- foundlanguages[language]=true
- end
- end
- end
- if false then
- foundlanguages["*"]=nil
- foundlanguages=sortedkeys(foundlanguages)
- for feature,scripts in sortedhash(what) do
- for script,languages in next,scripts do
- if not languages["*"] then
- for i=1,#foundlanguages do
- local language=foundlanguages[i]
- if not languages[language] then
- report_defining("font %!font:name!, feature %a, script %a, no language %a",
- tfmdata,feature,script,language)
- end
- end
- end
- end
- end
- end
+ local resources=tfmdata.resources
+ local shared=tfmdata.shared
+ if resources and shared then
+ local features=resources.features
+ local usedfeatures=shared.features
+ if features and usedfeatures then
+ local usedlanguage=usedfeatures.language or "dflt"
+ local usedscript=usedfeatures.script or "dflt"
+ local function check(what)
+ if what then
+ local foundlanguages={}
+ for feature,scripts in next,what do
+ if usedscript=="auto" or scripts["*"] then
+ elseif not scripts[usedscript] then
+ else
+ for script,languages in next,scripts do
+ if languages["*"] then
+ elseif not languages[usedlanguage] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,usedlanguage)
end
+ end
end
- check(features.gsub)
- check(features.gpos)
- end
- end
-end
-function definers.loadfont(specification)
- local hash=constructors.hashinstance(specification)
- local tfmdata=loadedfonts[hash]
- if not tfmdata then
- local forced=specification.forced or ""
- if forced~="" then
- local reader=readers[lower(forced)]
- tfmdata=reader and reader(specification)
- if not tfmdata then
- report_defining("forced type %a of %a not found",forced,specification.name)
+ for script,languages in next,scripts do
+ for language in next,languages do
+ foundlanguages[language]=true
+ end
end
- else
- local sequence=readers.sequence
- for s=1,#sequence do
- local reader=sequence[s]
- if readers[reader] then
- if trace_defining then
- report_defining("trying (reader sequence driven) type %a for %a with file %a",reader,specification.name,specification.filename)
- end
- tfmdata=readers[reader](specification)
- if tfmdata then
- break
- else
- specification.filename=nil
- end
+ end
+ if false then
+ foundlanguages["*"]=nil
+ foundlanguages=sortedkeys(foundlanguages)
+ for feature,scripts in sortedhash(what) do
+ for script,languages in next,scripts do
+ if not languages["*"] then
+ for i=1,#foundlanguages do
+ local language=foundlanguages[i]
+ if not languages[language] then
+ report_defining("font %!font:name!, feature %a, script %a, no language %a",
+ tfmdata,feature,script,language)
+ end
+ end
end
+ end
end
+ end
end
- if tfmdata then
- tfmdata=definers.applypostprocessors(tfmdata)
- checkembedding(tfmdata)
- loadedfonts[hash]=tfmdata
- designsizes[specification.hash]=tfmdata.parameters.designsize
- checkfeatures(tfmdata)
- end
+ end
+ check(features.gsub)
+ check(features.gpos)
end
- if not tfmdata then
- report_defining("font with asked name %a is not found using lookup %a",specification.name,specification.lookup)
+ end
+end
+function definers.loadfont(specification)
+ local hash=constructors.hashinstance(specification)
+ local tfmdata=loadedfonts[hash]
+ if not tfmdata then
+ local forced=specification.forced or ""
+ if forced~="" then
+ local reader=readers[lower(forced)]
+ tfmdata=reader and reader(specification)
+ if not tfmdata then
+ report_defining("forced type %a of %a not found",forced,specification.name)
+ end
+ else
+ local sequence=readers.sequence
+ for s=1,#sequence do
+ local reader=sequence[s]
+ if readers[reader] then
+ if trace_defining then
+ report_defining("trying (reader sequence driven) type %a for %a with file %a",reader,specification.name,specification.filename)
+ end
+ tfmdata=readers[reader](specification)
+ if tfmdata then
+ break
+ else
+ specification.filename=nil
+ end
+ end
+ end
end
- return tfmdata
+ if tfmdata then
+ tfmdata=definers.applypostprocessors(tfmdata)
+ checkembedding(tfmdata)
+ loadedfonts[hash]=tfmdata
+ designsizes[specification.hash]=tfmdata.parameters.designsize
+ checkfeatures(tfmdata)
+ end
+ end
+ if not tfmdata then
+ report_defining("font with asked name %a is not found using lookup %a",specification.name,specification.lookup)
+ end
+ return tfmdata
end
function constructors.readanddefine(name,size)
- local specification=definers.analyze(name,size)
- local method=specification.method
- if method and variants[method] then
- specification=variants[method](specification)
- end
- specification=definers.resolve(specification)
- local hash=constructors.hashinstance(specification)
- local id=definers.registered(hash)
- if not id then
- local tfmdata=definers.loadfont(specification)
- if tfmdata then
- tfmdata.properties.hash=hash
- id=font.define(tfmdata)
- definers.register(tfmdata,id)
- else
- id=0
- end
+ local specification=definers.analyze(name,size)
+ local method=specification.method
+ if method and variants[method] then
+ specification=variants[method](specification)
+ end
+ specification=definers.resolve(specification)
+ local hash=constructors.hashinstance(specification)
+ local id=definers.registered(hash)
+ if not id then
+ local tfmdata=definers.loadfont(specification)
+ if tfmdata then
+ tfmdata.properties.hash=hash
+ id=font.define(tfmdata)
+ definers.register(tfmdata,id)
+ else
+ id=0
end
- return fontdata[id],id
+ end
+ return fontdata[id],id
end
function definers.current()
- return lastdefined
+ return lastdefined
end
function definers.registered(hash)
- local id=internalized[hash]
- return id,id and fontdata[id]
+ local id=internalized[hash]
+ return id,id and fontdata[id]
end
function definers.register(tfmdata,id)
- if tfmdata and id then
- local hash=tfmdata.properties.hash
- if not hash then
- report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?")
- elseif not internalized[hash] then
- internalized[hash]=id
- if trace_defining then
- report_defining("registering font, id %s, hash %a",id,hash)
- end
- fontdata[id]=tfmdata
- end
- end
+ if tfmdata and id then
+ local hash=tfmdata.properties.hash
+ if not hash then
+ report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?")
+ elseif not internalized[hash] then
+ internalized[hash]=id
+ if trace_defining then
+ report_defining("registering font, id %s, hash %a",id,hash)
+ end
+ fontdata[id]=tfmdata
+ end
+ end
end
function definers.read(specification,size,id)
- statistics.starttiming(fonts)
- if type(specification)=="string" then
- specification=definers.analyze(specification,size)
- end
- local method=specification.method
- if method and variants[method] then
- specification=variants[method](specification)
+ statistics.starttiming(fonts)
+ if type(specification)=="string" then
+ specification=definers.analyze(specification,size)
+ end
+ local method=specification.method
+ if method and variants[method] then
+ specification=variants[method](specification)
+ end
+ specification=definers.resolve(specification)
+ local hash=constructors.hashinstance(specification)
+ local tfmdata=definers.registered(hash)
+ if tfmdata then
+ if trace_defining then
+ report_defining("already hashed: %s",hash)
end
- specification=definers.resolve(specification)
- local hash=constructors.hashinstance(specification)
- local tfmdata=definers.registered(hash)
+ else
+ tfmdata=definers.loadfont(specification)
if tfmdata then
- if trace_defining then
- report_defining("already hashed: %s",hash)
- end
+ if trace_defining then
+ report_defining("loaded and hashed: %s",hash)
+ end
+ tfmdata.properties.hash=hash
+ if id then
+ definers.register(tfmdata,id)
+ end
else
- tfmdata=definers.loadfont(specification)
- if tfmdata then
- if trace_defining then
- report_defining("loaded and hashed: %s",hash)
- end
- tfmdata.properties.hash=hash
- if id then
- definers.register(tfmdata,id)
- end
- else
- if trace_defining then
- report_defining("not loaded and hashed: %s",hash)
- end
- end
- end
- lastdefined=tfmdata or id
- if not tfmdata then
- report_defining("unknown font %a, loading aborted",specification.name)
- elseif trace_defining and type(tfmdata)=="table" then
- local properties=tfmdata.properties or {}
- local parameters=tfmdata.parameters or {}
- report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a",
- properties.format or "unknown",id or "-",properties.name,parameters.size,properties.encodingbytes,
- properties.encodingname,properties.fullname,basename(properties.filename))
- end
- statistics.stoptiming(fonts)
- return tfmdata
+ if trace_defining then
+ report_defining("not loaded and hashed: %s",hash)
+ end
+ end
+ end
+ lastdefined=tfmdata or id
+ if not tfmdata then
+ report_defining("unknown font %a, loading aborted",specification.name)
+ elseif trace_defining and type(tfmdata)=="table" then
+ local properties=tfmdata.properties or {}
+ local parameters=tfmdata.parameters or {}
+ report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a",
+ properties.format or "unknown",id or "-",properties.name,parameters.size,properties.encodingbytes,
+ properties.encodingname,properties.fullname,basename(properties.filename))
+ end
+ statistics.stoptiming(fonts)
+ return tfmdata
end
function font.getfont(id)
- return fontdata[id]
+ return fontdata[id]
end
callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)")
@@ -34423,11 +34423,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['luatex-fonts-def']={
- version=1.001,
- comment="companion to luatex-*.tex",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if context then
--removed
@@ -34436,18 +34436,18 @@ end
local fonts=fonts
fonts.constructors.namemode="specification"
function fonts.definers.getspecification(str)
- return "",str,"",":",str
+ return "",str,"",":",str
end
local list={}
-local function issome () list.lookup='name' end
-local function isfile () list.lookup='file' end
-local function isname () list.lookup='name' end
-local function thename(s) list.name=s end
-local function issub (v) list.sub=v end
-local function iscrap (s) list.crap=string.lower(s) end
-local function iskey (k,v) list[k]=v end
-local function istrue (s) list[s]=true end
-local function isfalse(s) list[s]=false end
+local function issome () list.lookup='name' end
+local function isfile () list.lookup='file' end
+local function isname () list.lookup='name' end
+local function thename(s) list.name=s end
+local function issub (v) list.sub=v end
+local function iscrap (s) list.crap=string.lower(s) end
+local function iskey (k,v) list[k]=v end
+local function istrue (s) list[s]=true end
+local function isfalse(s) list[s]=false end
local P,S,R,C,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs
local spaces=P(" ")^0
local namespec=Cs((P("{")/"")*(1-S("}"))^0*(P("}")/"")+(1-S("/:("))^0)
@@ -34468,38 +34468,38 @@ local option=spaces*(keyvalue+falsevalue+truevalue+somevalue)*spaces
local options=P(":")*spaces*(P(";")^0*option)^0
local pattern=(filename_1+filename_2+fontname_1+fontname_2)*subvalue^0*crapspec^0*options^0
function fonts.definers.analyze(str,size)
- local specification=fonts.definers.makespecification(str,nil,nil,nil,":",nil,size)
- list={}
- lpeg.match(pattern,str)
- list.crap=nil
- if list.name then
- specification.name=list.name
- list.name=nil
- end
- if list.lookup then
- specification.lookup=list.lookup
- list.lookup=nil
- end
- if list.sub then
- specification.sub=list.sub
- list.sub=nil
- end
- specification.features.normal=fonts.handlers.otf.features.normalize(list)
- list=nil
- return specification
+ local specification=fonts.definers.makespecification(str,nil,nil,nil,":",nil,size)
+ list={}
+ lpeg.match(pattern,str)
+ list.crap=nil
+ if list.name then
+ specification.name=list.name
+ list.name=nil
+ end
+ if list.lookup then
+ specification.lookup=list.lookup
+ list.lookup=nil
+ end
+ if list.sub then
+ specification.sub=list.sub
+ list.sub=nil
+ end
+ specification.features.normal=fonts.handlers.otf.features.normalize(list)
+ list=nil
+ return specification
end
function fonts.definers.applypostprocessors(tfmdata)
- local postprocessors=tfmdata.postprocessors
- if postprocessors then
- for i=1,#postprocessors do
- local extrahash=postprocessors[i](tfmdata)
- if type(extrahash)=="string" and extrahash~="" then
- extrahash=string.gsub(lower(extrahash),"[^a-z]","-")
- tfmdata.properties.fullname=format("%s-%s",tfmdata.properties.fullname,extrahash)
- end
- end
- end
- return tfmdata
+ local postprocessors=tfmdata.postprocessors
+ if postprocessors then
+ for i=1,#postprocessors do
+ local extrahash=postprocessors[i](tfmdata)
+ if type(extrahash)=="string" and extrahash~="" then
+ extrahash=string.gsub(lower(extrahash),"[^a-z]","-")
+ tfmdata.properties.fullname=format("%s-%s",tfmdata.properties.fullname,extrahash)
+ end
+ end
+ end
+ return tfmdata
end
end -- closure
@@ -34507,11 +34507,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['luatex-fonts-ext']={
- version=1.001,
- comment="companion to luatex-*.tex",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if context then
--removed
@@ -34525,170 +34525,170 @@ local afm=handlers.afm
local registerotffeature=otf.features.register
local registerafmfeature=afm.features.register
function fonts.loggers.onetimemessage() end
-fonts.protrusions=fonts.protrusions or {}
+fonts.protrusions=fonts.protrusions or {}
fonts.protrusions.setups=fonts.protrusions.setups or {}
local setups=fonts.protrusions.setups
setups['default']={
- factor=1,
- left=1,
- right=1,
- [0x002C]={ 0,1 },
- [0x002E]={ 0,1 },
- [0x003A]={ 0,1 },
- [0x003B]={ 0,1 },
- [0x002D]={ 0,1 },
- [0x2013]={ 0,0.50 },
- [0x2014]={ 0,0.33 },
- [0x3001]={ 0,1 },
- [0x3002]={ 0,1 },
- [0x060C]={ 0,1 },
- [0x061B]={ 0,1 },
- [0x06D4]={ 0,1 },
+ factor=1,
+ left=1,
+ right=1,
+ [0x002C]={ 0,1 },
+ [0x002E]={ 0,1 },
+ [0x003A]={ 0,1 },
+ [0x003B]={ 0,1 },
+ [0x002D]={ 0,1 },
+ [0x2013]={ 0,0.50 },
+ [0x2014]={ 0,0.33 },
+ [0x3001]={ 0,1 },
+ [0x3002]={ 0,1 },
+ [0x060C]={ 0,1 },
+ [0x061B]={ 0,1 },
+ [0x06D4]={ 0,1 },
}
local function initializeprotrusion(tfmdata,value)
- if value then
- local setup=setups[value]
- if setup then
- local factor,left,right=setup.factor or 1,setup.left or 1,setup.right or 1
- local emwidth=tfmdata.parameters.quad
- tfmdata.parameters.protrusion={
- auto=true,
- }
- for i,chr in next,tfmdata.characters do
- local v,pl,pr=setup[i],nil,nil
- if v then
- pl,pr=v[1],v[2]
- end
- if pl and pl~=0 then chr.left_protruding=left*pl*factor end
- if pr and pr~=0 then chr.right_protruding=right*pr*factor end
- end
+ if value then
+ local setup=setups[value]
+ if setup then
+ local factor,left,right=setup.factor or 1,setup.left or 1,setup.right or 1
+ local emwidth=tfmdata.parameters.quad
+ tfmdata.parameters.protrusion={
+ auto=true,
+ }
+ for i,chr in next,tfmdata.characters do
+ local v,pl,pr=setup[i],nil,nil
+ if v then
+ pl,pr=v[1],v[2]
end
+ if pl and pl~=0 then chr.left_protruding=left*pl*factor end
+ if pr and pr~=0 then chr.right_protruding=right*pr*factor end
+ end
end
+ end
end
local specification={
- name="protrusion",
- description="shift characters into the left and or right margin",
- initializers={
- base=initializeprotrusion,
- node=initializeprotrusion,
- }
+ name="protrusion",
+ description="shift characters into the left and or right margin",
+ initializers={
+ base=initializeprotrusion,
+ node=initializeprotrusion,
+ }
}
registerotffeature(specification)
registerafmfeature(specification)
-fonts.expansions=fonts.expansions or {}
+fonts.expansions=fonts.expansions or {}
fonts.expansions.setups=fonts.expansions.setups or {}
local setups=fonts.expansions.setups
setups['default']={
- stretch=2,
- shrink=2,
- step=.5,
- factor=1,
- [byte('A')]=0.5,[byte('B')]=0.7,[byte('C')]=0.7,[byte('D')]=0.5,[byte('E')]=0.7,
- [byte('F')]=0.7,[byte('G')]=0.5,[byte('H')]=0.7,[byte('K')]=0.7,[byte('M')]=0.7,
- [byte('N')]=0.7,[byte('O')]=0.5,[byte('P')]=0.7,[byte('Q')]=0.5,[byte('R')]=0.7,
- [byte('S')]=0.7,[byte('U')]=0.7,[byte('W')]=0.7,[byte('Z')]=0.7,
- [byte('a')]=0.7,[byte('b')]=0.7,[byte('c')]=0.7,[byte('d')]=0.7,[byte('e')]=0.7,
- [byte('g')]=0.7,[byte('h')]=0.7,[byte('k')]=0.7,[byte('m')]=0.7,[byte('n')]=0.7,
- [byte('o')]=0.7,[byte('p')]=0.7,[byte('q')]=0.7,[byte('s')]=0.7,[byte('u')]=0.7,
- [byte('w')]=0.7,[byte('z')]=0.7,
- [byte('2')]=0.7,[byte('3')]=0.7,[byte('6')]=0.7,[byte('8')]=0.7,[byte('9')]=0.7,
+ stretch=2,
+ shrink=2,
+ step=.5,
+ factor=1,
+ [byte('A')]=0.5,[byte('B')]=0.7,[byte('C')]=0.7,[byte('D')]=0.5,[byte('E')]=0.7,
+ [byte('F')]=0.7,[byte('G')]=0.5,[byte('H')]=0.7,[byte('K')]=0.7,[byte('M')]=0.7,
+ [byte('N')]=0.7,[byte('O')]=0.5,[byte('P')]=0.7,[byte('Q')]=0.5,[byte('R')]=0.7,
+ [byte('S')]=0.7,[byte('U')]=0.7,[byte('W')]=0.7,[byte('Z')]=0.7,
+ [byte('a')]=0.7,[byte('b')]=0.7,[byte('c')]=0.7,[byte('d')]=0.7,[byte('e')]=0.7,
+ [byte('g')]=0.7,[byte('h')]=0.7,[byte('k')]=0.7,[byte('m')]=0.7,[byte('n')]=0.7,
+ [byte('o')]=0.7,[byte('p')]=0.7,[byte('q')]=0.7,[byte('s')]=0.7,[byte('u')]=0.7,
+ [byte('w')]=0.7,[byte('z')]=0.7,
+ [byte('2')]=0.7,[byte('3')]=0.7,[byte('6')]=0.7,[byte('8')]=0.7,[byte('9')]=0.7,
}
local function initializeexpansion(tfmdata,value)
- if value then
- local setup=setups[value]
- if setup then
- local factor=setup.factor or 1
- tfmdata.parameters.expansion={
- stretch=10*(setup.stretch or 0),
- shrink=10*(setup.shrink or 0),
- step=10*(setup.step or 0),
- auto=true,
- }
- for i,chr in next,tfmdata.characters do
- local v=setup[i]
- if v and v~=0 then
- chr.expansion_factor=v*factor
- else
- chr.expansion_factor=factor
- end
- end
+ if value then
+ local setup=setups[value]
+ if setup then
+ local factor=setup.factor or 1
+ tfmdata.parameters.expansion={
+ stretch=10*(setup.stretch or 0),
+ shrink=10*(setup.shrink or 0),
+ step=10*(setup.step or 0),
+ auto=true,
+ }
+ for i,chr in next,tfmdata.characters do
+ local v=setup[i]
+ if v and v~=0 then
+ chr.expansion_factor=v*factor
+ else
+ chr.expansion_factor=factor
end
+ end
end
+ end
end
local specification={
- name="expansion",
- description="apply hz optimization",
- initializers={
- base=initializeexpansion,
- node=initializeexpansion,
- }
+ name="expansion",
+ description="apply hz optimization",
+ initializers={
+ base=initializeexpansion,
+ node=initializeexpansion,
+ }
}
registerotffeature(specification)
registerafmfeature(specification)
if not otf.features.normalize then
- otf.features.normalize=function(t)
- if t.rand then
- t.rand="random"
- end
- return t
+ otf.features.normalize=function(t)
+ if t.rand then
+ t.rand="random"
end
+ return t
+ end
end
function fonts.helpers.nametoslot(name)
- local t=type(name)
- if t=="string" then
- local tfmdata=fonts.hashes.identifiers[currentfont()]
- local shared=tfmdata and tfmdata.shared
- local fntdata=shared and shared.rawdata
- return fntdata and fntdata.resources.unicodes[name]
- elseif t=="number" then
- return n
- end
+ local t=type(name)
+ if t=="string" then
+ local tfmdata=fonts.hashes.identifiers[currentfont()]
+ local shared=tfmdata and tfmdata.shared
+ local fntdata=shared and shared.rawdata
+ return fntdata and fntdata.resources.unicodes[name]
+ elseif t=="number" then
+ return n
+ end
end
fonts.encodings=fonts.encodings or {}
local reencodings={}
fonts.encodings.reencodings=reencodings
local function specialreencode(tfmdata,value)
- local encoding=value and reencodings[value]
- if encoding then
- local temp={}
- local char=tfmdata.characters
- for k,v in next,encoding do
- temp[k]=char[v]
- end
- for k,v in next,temp do
- char[k]=temp[k]
- end
- return string.format("reencoded:%s",value)
+ local encoding=value and reencodings[value]
+ if encoding then
+ local temp={}
+ local char=tfmdata.characters
+ for k,v in next,encoding do
+ temp[k]=char[v]
+ end
+ for k,v in next,temp do
+ char[k]=temp[k]
end
+ return string.format("reencoded:%s",value)
+ end
end
local function initialize(tfmdata,value)
- tfmdata.postprocessors=tfmdata.postprocessors or {}
- table.insert(tfmdata.postprocessors,
- function(tfmdata)
- return specialreencode(tfmdata,value)
- end
- )
+ tfmdata.postprocessors=tfmdata.postprocessors or {}
+ table.insert(tfmdata.postprocessors,
+ function(tfmdata)
+ return specialreencode(tfmdata,value)
+ end
+ )
end
registerotffeature {
- name="reencode",
- description="reencode characters",
- manipulators={
- base=initialize,
- node=initialize,
- }
+ name="reencode",
+ description="reencode characters",
+ manipulators={
+ base=initialize,
+ node=initialize,
+ }
}
local function initialize(tfmdata,key,value)
- if value then
- tfmdata.mathparameters=nil
- end
+ if value then
+ tfmdata.mathparameters=nil
+ end
end
registerotffeature {
- name="ignoremathconstants",
- description="ignore math constants table",
- initializers={
- base=initialize,
- node=initialize,
- }
+ name="ignoremathconstants",
+ description="ignore math constants table",
+ initializers={
+ base=initialize,
+ node=initialize,
+ }
}
end -- closure
@@ -34696,11 +34696,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-imp-tex']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next=next
local fonts=fonts
@@ -34708,88 +34708,88 @@ local otf=fonts.handlers.otf
local registerotffeature=otf.features.register
local addotffeature=otf.addfeature
local specification={
- type="ligature",
- order={ "tlig" },
- prepend=true,
- data={
- [0x2013]={ 0x002D,0x002D },
- [0x2014]={ 0x002D,0x002D,0x002D },
- },
+ type="ligature",
+ order={ "tlig" },
+ prepend=true,
+ data={
+ [0x2013]={ 0x002D,0x002D },
+ [0x2014]={ 0x002D,0x002D,0x002D },
+ },
}
addotffeature("tlig",specification)
registerotffeature {
- name="tlig",
- description="tex ligatures",
+ name="tlig",
+ description="tex ligatures",
}
local specification={
- type="substitution",
- order={ "trep" },
- prepend=true,
- data={
- [0x0027]=0x2019,
- },
+ type="substitution",
+ order={ "trep" },
+ prepend=true,
+ data={
+ [0x0027]=0x2019,
+ },
}
addotffeature("trep",specification)
registerotffeature {
- name="trep",
- description="tex replacements",
+ name="trep",
+ description="tex replacements",
}
local anum_arabic={
- [0x0030]=0x0660,
- [0x0031]=0x0661,
- [0x0032]=0x0662,
- [0x0033]=0x0663,
- [0x0034]=0x0664,
- [0x0035]=0x0665,
- [0x0036]=0x0666,
- [0x0037]=0x0667,
- [0x0038]=0x0668,
- [0x0039]=0x0669,
+ [0x0030]=0x0660,
+ [0x0031]=0x0661,
+ [0x0032]=0x0662,
+ [0x0033]=0x0663,
+ [0x0034]=0x0664,
+ [0x0035]=0x0665,
+ [0x0036]=0x0666,
+ [0x0037]=0x0667,
+ [0x0038]=0x0668,
+ [0x0039]=0x0669,
}
local anum_persian={
- [0x0030]=0x06F0,
- [0x0031]=0x06F1,
- [0x0032]=0x06F2,
- [0x0033]=0x06F3,
- [0x0034]=0x06F4,
- [0x0035]=0x06F5,
- [0x0036]=0x06F6,
- [0x0037]=0x06F7,
- [0x0038]=0x06F8,
- [0x0039]=0x06F9,
+ [0x0030]=0x06F0,
+ [0x0031]=0x06F1,
+ [0x0032]=0x06F2,
+ [0x0033]=0x06F3,
+ [0x0034]=0x06F4,
+ [0x0035]=0x06F5,
+ [0x0036]=0x06F6,
+ [0x0037]=0x06F7,
+ [0x0038]=0x06F8,
+ [0x0039]=0x06F9,
}
local function valid(data)
- local features=data.resources.features
- if features then
- for k,v in next,features do
- for k,v in next,v do
- if v.arab then
- return true
- end
- end
+ local features=data.resources.features
+ if features then
+ for k,v in next,features do
+ for k,v in next,v do
+ if v.arab then
+ return true
end
+ end
end
+ end
end
local specification={
- {
- type="substitution",
- features={ arab={ urd=true,dflt=true } },
- order={ "anum" },
- data=anum_arabic,
- valid=valid,
- },
- {
- type="substitution",
- features={ arab={ urd=true } },
- order={ "anum" },
- data=anum_persian,
- valid=valid,
- },
+ {
+ type="substitution",
+ features={ arab={ urd=true,dflt=true } },
+ order={ "anum" },
+ data=anum_arabic,
+ valid=valid,
+ },
+ {
+ type="substitution",
+ features={ arab={ urd=true } },
+ order={ "anum" },
+ data=anum_persian,
+ valid=valid,
+ },
}
addotffeature("anum",specification)
registerotffeature {
- name="anum",
- description="arabic digits",
+ name="anum",
+ description="arabic digits",
}
end -- closure
@@ -34797,11 +34797,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-imp-ligatures']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local lpegmatch=lpeg.match
local utfsplit=utf.split
@@ -34816,88 +34816,88 @@ local revert={}
local zwjchar=0x200C
local zwj={ zwjchar }
addotffeature {
- name="blockligatures",
- type="chainsubstitution",
- nocheck=true,
- prepend=true,
- future=true,
- lookups={
- {
- type="multiple",
- data=lookups,
- },
+ name="blockligatures",
+ type="chainsubstitution",
+ nocheck=true,
+ prepend=true,
+ future=true,
+ lookups={
+ {
+ type="multiple",
+ data=lookups,
},
- data={
- rules=protect,
- }
+ },
+ data={
+ rules=protect,
+ }
}
addotffeature {
- name="blockligatures",
- type="chainsubstitution",
- nocheck=true,
- append=true,
- overload=false,
- lookups={
- {
- type="ligature",
- data=lookups,
- },
+ name="blockligatures",
+ type="chainsubstitution",
+ nocheck=true,
+ append=true,
+ overload=false,
+ lookups={
+ {
+ type="ligature",
+ data=lookups,
},
- data={
- rules=revert,
- }
+ },
+ data={
+ rules=revert,
+ }
}
registerotffeature {
- name='blockligatures',
- description='block certain ligatures',
+ name='blockligatures',
+ description='block certain ligatures',
}
local splitter=lpeg.splitat(":")
local function blockligatures(str)
- local t=settings_to_array(str)
- for i=1,#t do
- local ti=t[i]
- local before,current,after=lpegmatch(splitter,ti)
- if current and after then
- if before then
- before=utfsplit(before)
- for i=1,#before do
- before[i]={ before[i] }
- end
- end
- if current then
- current=utfsplit(current)
- end
- if after then
- after=utfsplit(after)
- for i=1,#after do
- after[i]={ after[i] }
- end
- end
- else
- before=nil
- current=utfsplit(ti)
- after=nil
- end
- if #current>1 then
- local one=current[1]
- local two=current[2]
- lookups[one]={ one,zwjchar }
- local one={ one }
- local two={ two }
- local new=#protect+1
- protect[new]={
- before=before,
- current={ one,two },
- after=after,
- lookups={ 1 },
- }
- revert[new]={
- current={ one,zwj },
- after={ two },
- lookups={ 1 },
- }
- end
- end
+ local t=settings_to_array(str)
+ for i=1,#t do
+ local ti=t[i]
+ local before,current,after=lpegmatch(splitter,ti)
+ if current and after then
+ if before then
+ before=utfsplit(before)
+ for i=1,#before do
+ before[i]={ before[i] }
+ end
+ end
+ if current then
+ current=utfsplit(current)
+ end
+ if after then
+ after=utfsplit(after)
+ for i=1,#after do
+ after[i]={ after[i] }
+ end
+ end
+ else
+ before=nil
+ current=utfsplit(ti)
+ after=nil
+ end
+ if #current>1 then
+ local one=current[1]
+ local two=current[2]
+ lookups[one]={ one,zwjchar }
+ local one={ one }
+ local two={ two }
+ local new=#protect+1
+ protect[new]={
+ before=before,
+ current={ one,two },
+ after=after,
+ lookups={ 1 },
+ }
+ revert[new]={
+ current={ one,zwj },
+ after={ two },
+ lookups={ 1 },
+ }
+ end
+ end
end
otf.helpers.blockligatures=blockligatures
if context then
@@ -34911,11 +34911,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-imp-italics']={
- version=1.001,
- comment="companion to font-ini.mkiv and hand-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv and hand-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next=next
local fonts=fonts
@@ -34923,43 +34923,43 @@ local handlers=fonts.handlers
local registerotffeature=handlers.otf.features.register
local registerafmfeature=handlers.afm.features.register
local function initialize(tfmdata,key,value)
- for unicode,character in next,tfmdata.characters do
- local olditalic=character.italic
- if olditalic and olditalic~=0 then
- character.width=character.width+olditalic
- character.italic=0
- end
+ for unicode,character in next,tfmdata.characters do
+ local olditalic=character.italic
+ if olditalic and olditalic~=0 then
+ character.width=character.width+olditalic
+ character.italic=0
end
+ end
end
local specification={
- name="italicwidths",
- description="add italic to width",
- manipulators={
- base=initialize,
- node=initialize,
- }
+ name="italicwidths",
+ description="add italic to width",
+ manipulators={
+ base=initialize,
+ node=initialize,
+ }
}
registerotffeature(specification)
registerafmfeature(specification)
local function initialize(tfmdata,value)
- if value then
- local parameters=tfmdata.parameters
- local italicangle=parameters.italicangle
- if italicangle and italicangle~=0 then
- local properties=tfmdata.properties
- local factor=tonumber(value) or 1
- properties.hasitalics=true
- properties.autoitalicamount=factor*(parameters.uwidth or 40)/2
- end
+ if value then
+ local parameters=tfmdata.parameters
+ local italicangle=parameters.italicangle
+ if italicangle and italicangle~=0 then
+ local properties=tfmdata.properties
+ local factor=tonumber(value) or 1
+ properties.hasitalics=true
+ properties.autoitalicamount=factor*(parameters.uwidth or 40)/2
end
+ end
end
local specification={
- name="itlc",
- description="italic correction",
- initializers={
- base=initialize,
- node=initialize,
- }
+ name="itlc",
+ description="italic correction",
+ initializers={
+ base=initialize,
+ node=initialize,
+ }
}
registerotffeature(specification)
registerafmfeature(specification)
@@ -34969,39 +34969,39 @@ if context then
end
if context then
- local letter=characters.is_letter
- local always=true
- local function collapseitalics(tfmdata,key,value)
- local threshold=value==true and 100 or tonumber(value)
- if threshold and threshold>0 then
- if threshold>100 then
- threshold=100
- end
- for unicode,data in next,tfmdata.characters do
- if always or letter[unicode] or letter[data.unicode] then
- local italic=data.italic
- if italic and italic~=0 then
- local width=data.width
- if width and width~=0 then
- local delta=threshold*italic/100
- data.width=width+delta
- data.italic=italic-delta
- end
- end
- end
+ local letter=characters.is_letter
+ local always=true
+ local function collapseitalics(tfmdata,key,value)
+ local threshold=value==true and 100 or tonumber(value)
+ if threshold and threshold>0 then
+ if threshold>100 then
+ threshold=100
+ end
+ for unicode,data in next,tfmdata.characters do
+ if always or letter[unicode] or letter[data.unicode] then
+ local italic=data.italic
+ if italic and italic~=0 then
+ local width=data.width
+ if width and width~=0 then
+ local delta=threshold*italic/100
+ data.width=width+delta
+ data.italic=italic-delta
end
+ end
end
+ end
end
- local dimensions_specification={
- name="collapseitalics",
- description="collapse italics",
- manipulators={
- base=collapseitalics,
- node=collapseitalics,
- }
+ end
+ local dimensions_specification={
+ name="collapseitalics",
+ description="collapse italics",
+ manipulators={
+ base=collapseitalics,
+ node=collapseitalics,
}
- registerotffeature(dimensions_specification)
- registerafmfeature(dimensions_specification)
+ }
+ registerotffeature(dimensions_specification)
+ registerafmfeature(dimensions_specification)
end
end -- closure
@@ -35009,11 +35009,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['font-imp-effects']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to font-ini.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,tonumber=next,type,tonumber
local is_boolean=string.is_boolean
@@ -35040,325 +35040,325 @@ trackers.register("fonts.slant",function(v) trace=v end)
trackers.register("fonts.extend",function(v) trace=v end)
trackers.register("fonts.squeeze",function(v) trace=v end)
local function initializeslant(tfmdata,value)
- value=tonumber(value)
- if not value then
- value=0
- elseif value>1 then
- value=1
- elseif value<-1 then
- value=-1
- end
- if trace then
- report_slant("applying %0.3f",value)
- end
- tfmdata.parameters.slantfactor=value
+ value=tonumber(value)
+ if not value then
+ value=0
+ elseif value>1 then
+ value=1
+ elseif value<-1 then
+ value=-1
+ end
+ if trace then
+ report_slant("applying %0.3f",value)
+ end
+ tfmdata.parameters.slantfactor=value
end
local specification={
- name="slant",
- description="slant glyphs",
- initializers={
- base=initializeslant,
- node=initializeslant,
- }
+ name="slant",
+ description="slant glyphs",
+ initializers={
+ base=initializeslant,
+ node=initializeslant,
+ }
}
registerotffeature(specification)
registerafmfeature(specification)
local function initializeextend(tfmdata,value)
- value=tonumber(value)
- if not value then
- value=0
- elseif value>10 then
- value=10
- elseif value<-10 then
- value=-10
- end
- if trace then
- report_extend("applying %0.3f",value)
- end
- tfmdata.parameters.extendfactor=value
+ value=tonumber(value)
+ if not value then
+ value=0
+ elseif value>10 then
+ value=10
+ elseif value<-10 then
+ value=-10
+ end
+ if trace then
+ report_extend("applying %0.3f",value)
+ end
+ tfmdata.parameters.extendfactor=value
end
local specification={
- name="extend",
- description="scale glyphs horizontally",
- initializers={
- base=initializeextend,
- node=initializeextend,
- }
+ name="extend",
+ description="scale glyphs horizontally",
+ initializers={
+ base=initializeextend,
+ node=initializeextend,
+ }
}
registerotffeature(specification)
registerafmfeature(specification)
local function initializesqueeze(tfmdata,value)
- value=tonumber(value)
- if not value then
- value=0
- elseif value>10 then
- value=10
- elseif value<-10 then
- value=-10
- end
- if trace then
- report_squeeze("applying %0.3f",value)
- end
- tfmdata.parameters.squeezefactor=value
+ value=tonumber(value)
+ if not value then
+ value=0
+ elseif value>10 then
+ value=10
+ elseif value<-10 then
+ value=-10
+ end
+ if trace then
+ report_squeeze("applying %0.3f",value)
+ end
+ tfmdata.parameters.squeezefactor=value
end
local specification={
- name="squeeze",
- description="scale glyphs vertically",
- initializers={
- base=initializesqueeze,
- node=initializesqueeze,
- }
+ name="squeeze",
+ description="scale glyphs vertically",
+ initializers={
+ base=initializesqueeze,
+ node=initializesqueeze,
+ }
}
registerotffeature(specification)
registerafmfeature(specification)
local effects={
- inner=0,
- normal=0,
- outer=1,
- outline=1,
- both=2,
- hidden=3,
+ inner=0,
+ normal=0,
+ outer=1,
+ outline=1,
+ both=2,
+ hidden=3,
}
local function initializeeffect(tfmdata,value)
- local spec
- if type(value)=="number" then
- spec={ width=value }
- else
- spec=settings_to_hash(value)
- end
- local effect=spec.effect or "both"
- local width=tonumber(spec.width) or 0
- local mode=effects[effect]
- if not mode then
- report_effect("invalid effect %a",effect)
- elseif width==0 and mode==0 then
- report_effect("invalid width %a for effect %a",width,effect)
- else
- local parameters=tfmdata.parameters
- local properties=tfmdata.properties
- parameters.mode=mode
- parameters.width=width*1000
- if is_boolean(spec.auto)==true then
- local squeeze=1-width/20
- local average=(1-squeeze)*width*100
- spec.squeeze=squeeze
- spec.extend=1+width/2
- spec.wdelta=average
- spec.hdelta=average/2
- spec.ddelta=average/2
- spec.vshift=average/2
- end
- local factor=tonumber(spec.factor) or 0
- local hfactor=tonumber(spec.hfactor) or factor
- local vfactor=tonumber(spec.vfactor) or factor
- local delta=tonumber(spec.delta) or 1
- local wdelta=tonumber(spec.wdelta) or delta
- local hdelta=tonumber(spec.hdelta) or delta
- local ddelta=tonumber(spec.ddelta) or hdelta
- local vshift=tonumber(spec.vshift) or 0
- local slant=spec.slant
- local extend=spec.extend
- local squeeze=spec.squeeze
- if slant then
- initializeslant(tfmdata,slant)
- end
- if extend then
- initializeextend(tfmdata,extend)
- end
- if squeeze then
- initializesqueeze(tfmdata,squeeze)
- end
- properties.effect={
- effect=effect,
- width=width,
- factor=factor,
- hfactor=hfactor,
- vfactor=vfactor,
- wdelta=wdelta,
- hdelta=hdelta,
- ddelta=ddelta,
- vshift=vshift,
- slant=tfmdata.parameters.slantfactor,
- extend=tfmdata.parameters.extendfactor,
- squeeze=tfmdata.parameters.squeezefactor,
- }
+ local spec
+ if type(value)=="number" then
+ spec={ width=value }
+ else
+ spec=settings_to_hash(value)
+ end
+ local effect=spec.effect or "both"
+ local width=tonumber(spec.width) or 0
+ local mode=effects[effect]
+ if not mode then
+ report_effect("invalid effect %a",effect)
+ elseif width==0 and mode==0 then
+ report_effect("invalid width %a for effect %a",width,effect)
+ else
+ local parameters=tfmdata.parameters
+ local properties=tfmdata.properties
+ parameters.mode=mode
+ parameters.width=width*1000
+ if is_boolean(spec.auto)==true then
+ local squeeze=1-width/20
+ local average=(1-squeeze)*width*100
+ spec.squeeze=squeeze
+ spec.extend=1+width/2
+ spec.wdelta=average
+ spec.hdelta=average/2
+ spec.ddelta=average/2
+ spec.vshift=average/2
+ end
+ local factor=tonumber(spec.factor) or 0
+ local hfactor=tonumber(spec.hfactor) or factor
+ local vfactor=tonumber(spec.vfactor) or factor
+ local delta=tonumber(spec.delta) or 1
+ local wdelta=tonumber(spec.wdelta) or delta
+ local hdelta=tonumber(spec.hdelta) or delta
+ local ddelta=tonumber(spec.ddelta) or hdelta
+ local vshift=tonumber(spec.vshift) or 0
+ local slant=spec.slant
+ local extend=spec.extend
+ local squeeze=spec.squeeze
+ if slant then
+ initializeslant(tfmdata,slant)
+ end
+ if extend then
+ initializeextend(tfmdata,extend)
+ end
+ if squeeze then
+ initializesqueeze(tfmdata,squeeze)
end
+ properties.effect={
+ effect=effect,
+ width=width,
+ factor=factor,
+ hfactor=hfactor,
+ vfactor=vfactor,
+ wdelta=wdelta,
+ hdelta=hdelta,
+ ddelta=ddelta,
+ vshift=vshift,
+ slant=tfmdata.parameters.slantfactor,
+ extend=tfmdata.parameters.extendfactor,
+ squeeze=tfmdata.parameters.squeezefactor,
+ }
+ end
end
local rules={
- "RadicalRuleThickness",
- "OverbarRuleThickness",
- "FractionRuleThickness",
- "UnderbarRuleThickness",
+ "RadicalRuleThickness",
+ "OverbarRuleThickness",
+ "FractionRuleThickness",
+ "UnderbarRuleThickness",
}
local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
- if delta~=0 then
- for i=1,#rules do
- local name=rules[i]
- local value=mathparameters[name]
- if value then
- mathparameters[name]=(squeeze or 1)*(value+dx)
- end
- end
+ if delta~=0 then
+ for i=1,#rules do
+ local name=rules[i]
+ local value=mathparameters[name]
+ if value then
+ mathparameters[name]=(squeeze or 1)*(value+dx)
+ end
end
+ end
end
local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
- local function wdpatch(char)
- if wsnap~=0 then
- char.width=char.width+wdelta/2
- end
- end
- local function htpatch(char)
- if hsnap~=0 then
- local height=char.height
- if height then
- char.height=char.height+2*dy
- end
- end
+ local function wdpatch(char)
+ if wsnap~=0 then
+ char.width=char.width+wdelta/2
+ end
+ end
+ local function htpatch(char)
+ if hsnap~=0 then
+ local height=char.height
+ if height then
+ char.height=char.height+2*dy
+ end
+ end
+ end
+ local character=characters[0x221A]
+ if character and character.next then
+ local char=character
+ local next=character.next
+ wdpatch(char)
+ htpatch(char)
+ while next do
+ char=characters[next]
+ wdpatch(char)
+ htpatch(char)
+ next=char.next
end
- local character=characters[0x221A]
- if character and character.next then
- local char=character
- local next=character.next
- wdpatch(char)
- htpatch(char)
- while next do
- char=characters[next]
- wdpatch(char)
- htpatch(char)
- next=char.next
- end
- if char then
- local v=char.vert_variants
- if v then
- local top=v[#v]
- if top then
- local char=characters[top.glyph]
- htpatch(char)
- end
- end
+ if char then
+ local v=char.vert_variants
+ if v then
+ local top=v[#v]
+ if top then
+ local char=characters[top.glyph]
+ htpatch(char)
end
+ end
end
+ end
end
local function manipulateeffect(tfmdata)
- local effect=tfmdata.properties.effect
- if effect then
- local characters=tfmdata.characters
- local parameters=tfmdata.parameters
- local mathparameters=tfmdata.mathparameters
- local multiplier=effect.width*100
- local factor=parameters.factor
- local hfactor=parameters.hfactor
- local vfactor=parameters.vfactor
- local wdelta=effect.wdelta*hfactor*multiplier
- local hdelta=effect.hdelta*vfactor*multiplier
- local ddelta=effect.ddelta*vfactor*multiplier
- local vshift=effect.vshift*vfactor*multiplier
- local squeeze=effect.squeeze
- local hshift=wdelta/2
- local dx=multiplier*vfactor
- local dy=vshift
- local factor=(1+effect.factor)*factor
- local hfactor=(1+effect.hfactor)*hfactor
- local vfactor=(1+effect.vfactor)*vfactor
- local vshift=vshift~=0 and upcommand[vshift] or false
- for unicode,character in next,characters do
- local oldwidth=character.width
- local oldheight=character.height
- local olddepth=character.depth
- if oldwidth and oldwidth>0 then
- character.width=oldwidth+wdelta
- local commands=character.commands
- local hshift=rightcommand[hshift]
- if vshift then
- if commands then
- prependcommands (commands,
- hshift,
- vshift
- )
- else
- character.commands={
- hshift,
- vshift,
- charcommand[unicode]
- }
- end
- else
- if commands then
- prependcommands (commands,
- hshift
- )
- else
- character.commands={
- hshift,
- charcommand[unicode]
- }
- end
- end
- end
- if oldheight and oldheight>0 then
- character.height=oldheight+hdelta
- end
- if olddepth and olddepth>0 then
- character.depth=olddepth+ddelta
- end
- end
- if mathparameters then
- setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
- setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
- end
- parameters.factor=factor
- parameters.hfactor=hfactor
- parameters.vfactor=vfactor
- if trace then
- report_effect("applying")
- report_effect(" effect : %s",effect.effect)
- report_effect(" width : %s => %s",effect.width,multiplier)
- report_effect(" factor : %s => %s",effect.factor,factor )
- report_effect(" hfactor : %s => %s",effect.hfactor,hfactor)
- report_effect(" vfactor : %s => %s",effect.vfactor,vfactor)
- report_effect(" wdelta : %s => %s",effect.wdelta,wdelta)
- report_effect(" hdelta : %s => %s",effect.hdelta,hdelta)
- report_effect(" ddelta : %s => %s",effect.ddelta,ddelta)
+ local effect=tfmdata.properties.effect
+ if effect then
+ local characters=tfmdata.characters
+ local parameters=tfmdata.parameters
+ local mathparameters=tfmdata.mathparameters
+ local multiplier=effect.width*100
+ local factor=parameters.factor
+ local hfactor=parameters.hfactor
+ local vfactor=parameters.vfactor
+ local wdelta=effect.wdelta*hfactor*multiplier
+ local hdelta=effect.hdelta*vfactor*multiplier
+ local ddelta=effect.ddelta*vfactor*multiplier
+ local vshift=effect.vshift*vfactor*multiplier
+ local squeeze=effect.squeeze
+ local hshift=wdelta/2
+ local dx=multiplier*vfactor
+ local dy=vshift
+ local factor=(1+effect.factor)*factor
+ local hfactor=(1+effect.hfactor)*hfactor
+ local vfactor=(1+effect.vfactor)*vfactor
+ local vshift=vshift~=0 and upcommand[vshift] or false
+ for unicode,character in next,characters do
+ local oldwidth=character.width
+ local oldheight=character.height
+ local olddepth=character.depth
+ if oldwidth and oldwidth>0 then
+ character.width=oldwidth+wdelta
+ local commands=character.commands
+ local hshift=rightcommand[hshift]
+ if vshift then
+ if commands then
+ prependcommands (commands,
+ hshift,
+ vshift
+ )
+ else
+ character.commands={
+ hshift,
+ vshift,
+ charcommand[unicode]
+ }
+ end
+ else
+ if commands then
+ prependcommands (commands,
+ hshift
+ )
+ else
+ character.commands={
+ hshift,
+ charcommand[unicode]
+ }
+ end
end
- end
+ end
+ if oldheight and oldheight>0 then
+ character.height=oldheight+hdelta
+ end
+ if olddepth and olddepth>0 then
+ character.depth=olddepth+ddelta
+ end
+ end
+ if mathparameters then
+ setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
+ setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
+ end
+ parameters.factor=factor
+ parameters.hfactor=hfactor
+ parameters.vfactor=vfactor
+ if trace then
+ report_effect("applying")
+ report_effect(" effect : %s",effect.effect)
+ report_effect(" width : %s => %s",effect.width,multiplier)
+ report_effect(" factor : %s => %s",effect.factor,factor )
+ report_effect(" hfactor : %s => %s",effect.hfactor,hfactor)
+ report_effect(" vfactor : %s => %s",effect.vfactor,vfactor)
+ report_effect(" wdelta : %s => %s",effect.wdelta,wdelta)
+ report_effect(" hdelta : %s => %s",effect.hdelta,hdelta)
+ report_effect(" ddelta : %s => %s",effect.ddelta,ddelta)
+ end
+ end
end
local specification={
- name="effect",
- description="apply effects to glyphs",
- initializers={
- base=initializeeffect,
- node=initializeeffect,
- },
- manipulators={
- base=manipulateeffect,
- node=manipulateeffect,
- },
+ name="effect",
+ description="apply effects to glyphs",
+ initializers={
+ base=initializeeffect,
+ node=initializeeffect,
+ },
+ manipulators={
+ base=manipulateeffect,
+ node=manipulateeffect,
+ },
}
registerotffeature(specification)
registerafmfeature(specification)
local function initializeoutline(tfmdata,value)
- value=tonumber(value)
- if not value then
- value=0
- else
- value=tonumber(value) or 0
- end
- local parameters=tfmdata.parameters
- local properties=tfmdata.properties
- parameters.mode=effects.outline
- parameters.width=value*1000
- properties.effect={
- effect=effect,
- width=width,
- }
+ value=tonumber(value)
+ if not value then
+ value=0
+ else
+ value=tonumber(value) or 0
+ end
+ local parameters=tfmdata.parameters
+ local properties=tfmdata.properties
+ parameters.mode=effects.outline
+ parameters.width=value*1000
+ properties.effect={
+ effect=effect,
+ width=width,
+ }
end
local specification={
- name="outline",
- description="outline glyphs",
- initializers={
- base=initializeoutline,
- node=initializeoutline,
- }
+ name="outline",
+ description="outline glyphs",
+ initializers={
+ base=initializeoutline,
+ node=initializeoutline,
+ }
}
registerotffeature(specification)
registerafmfeature(specification)
@@ -35370,2065 +35370,2065 @@ do -- begin closure to overcome local limits and interference
fonts.handlers.otf.addfeature {
["dataset"]={
- {
- ["data"]={
- ["À"]={ "A","̀" },
- ["Á"]={ "A","́" },
- ["Â"]={ "A","̂" },
- ["Ã"]={ "A","̃" },
- ["Ä"]={ "A","̈" },
- ["Å"]={ "A","̊" },
- ["Ç"]={ "C","̧" },
- ["È"]={ "E","̀" },
- ["É"]={ "E","́" },
- ["Ê"]={ "E","̂" },
- ["Ë"]={ "E","̈" },
- ["Ì"]={ "I","̀" },
- ["Í"]={ "I","́" },
- ["Î"]={ "I","̂" },
- ["Ï"]={ "I","̈" },
- ["Ñ"]={ "N","̃" },
- ["Ò"]={ "O","̀" },
- ["Ó"]={ "O","́" },
- ["Ô"]={ "O","̂" },
- ["Õ"]={ "O","̃" },
- ["Ö"]={ "O","̈" },
- ["Ù"]={ "U","̀" },
- ["Ú"]={ "U","́" },
- ["Û"]={ "U","̂" },
- ["Ü"]={ "U","̈" },
- ["Ý"]={ "Y","́" },
- ["à"]={ "a","̀" },
- ["á"]={ "a","́" },
- ["â"]={ "a","̂" },
- ["ã"]={ "a","̃" },
- ["ä"]={ "a","̈" },
- ["å"]={ "a","̊" },
- ["ç"]={ "c","̧" },
- ["è"]={ "e","̀" },
- ["é"]={ "e","́" },
- ["ê"]={ "e","̂" },
- ["ë"]={ "e","̈" },
- ["ì"]={ "i","̀" },
- ["í"]={ "i","́" },
- ["î"]={ "i","̂" },
- ["ï"]={ "i","̈" },
- ["ñ"]={ "n","̃" },
- ["ò"]={ "o","̀" },
- ["ó"]={ "o","́" },
- ["ô"]={ "o","̂" },
- ["õ"]={ "o","̃" },
- ["ö"]={ "o","̈" },
- ["ù"]={ "u","̀" },
- ["ú"]={ "u","́" },
- ["û"]={ "u","̂" },
- ["ü"]={ "u","̈" },
- ["ý"]={ "y","́" },
- ["ÿ"]={ "y","̈" },
- ["Ā"]={ "A","̄" },
- ["ā"]={ "a","̄" },
- ["Ă"]={ "A","̆" },
- ["ă"]={ "a","̆" },
- ["Ą"]={ "A","̨" },
- ["ą"]={ "a","̨" },
- ["Ć"]={ "C","́" },
- ["ć"]={ "c","́" },
- ["Ĉ"]={ "C","̂" },
- ["ĉ"]={ "c","̂" },
- ["Ċ"]={ "C","̇" },
- ["ċ"]={ "c","̇" },
- ["Č"]={ "C","̌" },
- ["č"]={ "c","̌" },
- ["Ď"]={ "D","̌" },
- ["ď"]={ "d","̌" },
- ["Ē"]={ "E","̄" },
- ["ē"]={ "e","̄" },
- ["Ĕ"]={ "E","̆" },
- ["ĕ"]={ "e","̆" },
- ["Ė"]={ "E","̇" },
- ["ė"]={ "e","̇" },
- ["Ę"]={ "E","̨" },
- ["ę"]={ "e","̨" },
- ["Ě"]={ "E","̌" },
- ["ě"]={ "e","̌" },
- ["Ĝ"]={ "G","̂" },
- ["ĝ"]={ "g","̂" },
- ["Ğ"]={ "G","̆" },
- ["ğ"]={ "g","̆" },
- ["Ġ"]={ "G","̇" },
- ["ġ"]={ "g","̇" },
- ["Ģ"]={ "G","̧" },
- ["ģ"]={ "g","̧" },
- ["Ĥ"]={ "H","̂" },
- ["ĥ"]={ "h","̂" },
- ["Ĩ"]={ "I","̃" },
- ["ĩ"]={ "i","̃" },
- ["Ī"]={ "I","̄" },
- ["ī"]={ "i","̄" },
- ["Ĭ"]={ "I","̆" },
- ["ĭ"]={ "i","̆" },
- ["Į"]={ "I","̨" },
- ["į"]={ "i","̨" },
- ["İ"]={ "I","̇" },
- ["Ĵ"]={ "J","̂" },
- ["ĵ"]={ "j","̂" },
- ["Ķ"]={ "K","̧" },
- ["ķ"]={ "k","̧" },
- ["Ĺ"]={ "L","́" },
- ["ĺ"]={ "l","́" },
- ["Ļ"]={ "L","̧" },
- ["ļ"]={ "l","̧" },
- ["Ľ"]={ "L","̌" },
- ["ľ"]={ "l","̌" },
- ["Ń"]={ "N","́" },
- ["ń"]={ "n","́" },
- ["Ņ"]={ "N","̧" },
- ["ņ"]={ "n","̧" },
- ["Ň"]={ "N","̌" },
- ["ň"]={ "n","̌" },
- ["Ō"]={ "O","̄" },
- ["ō"]={ "o","̄" },
- ["Ŏ"]={ "O","̆" },
- ["ŏ"]={ "o","̆" },
- ["Ő"]={ "O","̋" },
- ["ő"]={ "o","̋" },
- ["Ŕ"]={ "R","́" },
- ["ŕ"]={ "r","́" },
- ["Ŗ"]={ "R","̧" },
- ["ŗ"]={ "r","̧" },
- ["Ř"]={ "R","̌" },
- ["ř"]={ "r","̌" },
- ["Ś"]={ "S","́" },
- ["ś"]={ "s","́" },
- ["Ŝ"]={ "S","̂" },
- ["ŝ"]={ "s","̂" },
- ["Ş"]={ "S","̧" },
- ["ş"]={ "s","̧" },
- ["Š"]={ "S","̌" },
- ["š"]={ "s","̌" },
- ["Ţ"]={ "T","̧" },
- ["ţ"]={ "t","̧" },
- ["Ť"]={ "T","̌" },
- ["ť"]={ "t","̌" },
- ["Ũ"]={ "U","̃" },
- ["ũ"]={ "u","̃" },
- ["Ū"]={ "U","̄" },
- ["ū"]={ "u","̄" },
- ["Ŭ"]={ "U","̆" },
- ["ŭ"]={ "u","̆" },
- ["Ů"]={ "U","̊" },
- ["ů"]={ "u","̊" },
- ["Ű"]={ "U","̋" },
- ["ű"]={ "u","̋" },
- ["Ų"]={ "U","̨" },
- ["ų"]={ "u","̨" },
- ["Ŵ"]={ "W","̂" },
- ["ŵ"]={ "w","̂" },
- ["Ŷ"]={ "Y","̂" },
- ["ŷ"]={ "y","̂" },
- ["Ÿ"]={ "Y","̈" },
- ["Ź"]={ "Z","́" },
- ["ź"]={ "z","́" },
- ["Ż"]={ "Z","̇" },
- ["ż"]={ "z","̇" },
- ["Ž"]={ "Z","̌" },
- ["ž"]={ "z","̌" },
- ["Ơ"]={ "O","̛" },
- ["ơ"]={ "o","̛" },
- ["Ư"]={ "U","̛" },
- ["ư"]={ "u","̛" },
- ["Ǎ"]={ "A","̌" },
- ["ǎ"]={ "a","̌" },
- ["Ǐ"]={ "I","̌" },
- ["ǐ"]={ "i","̌" },
- ["Ǒ"]={ "O","̌" },
- ["ǒ"]={ "o","̌" },
- ["Ǔ"]={ "U","̌" },
- ["ǔ"]={ "u","̌" },
- ["Ǖ"]={ "Ü","̄" },
- ["ǖ"]={ "ü","̄" },
- ["Ǘ"]={ "Ü","́" },
- ["ǘ"]={ "ü","́" },
- ["Ǚ"]={ "Ü","̌" },
- ["ǚ"]={ "ü","̌" },
- ["Ǜ"]={ "Ü","̀" },
- ["ǜ"]={ "ü","̀" },
- ["Ǟ"]={ "Ä","̄" },
- ["ǟ"]={ "ä","̄" },
- ["Ǡ"]={ "Ȧ","̄" },
- ["ǡ"]={ "ȧ","̄" },
- ["Ǣ"]={ "Æ","̄" },
- ["ǣ"]={ "æ","̄" },
- ["Ǧ"]={ "G","̌" },
- ["ǧ"]={ "g","̌" },
- ["Ǩ"]={ "K","̌" },
- ["ǩ"]={ "k","̌" },
- ["Ǫ"]={ "O","̨" },
- ["ǫ"]={ "o","̨" },
- ["Ǭ"]={ "Ǫ","̄" },
- ["ǭ"]={ "ǫ","̄" },
- ["Ǯ"]={ "Ʒ","̌" },
- ["ǯ"]={ "ʒ","̌" },
- ["ǰ"]={ "j","̌" },
- ["Ǵ"]={ "G","́" },
- ["ǵ"]={ "g","́" },
- ["Ǹ"]={ "N","̀" },
- ["ǹ"]={ "n","̀" },
- ["Ǻ"]={ "Å","́" },
- ["ǻ"]={ "å","́" },
- ["Ǽ"]={ "Æ","́" },
- ["ǽ"]={ "æ","́" },
- ["Ǿ"]={ "Ø","́" },
- ["ǿ"]={ "ø","́" },
- ["Ȁ"]={ "A","̏" },
- ["ȁ"]={ "a","̏" },
- ["Ȃ"]={ "A","̑" },
- ["ȃ"]={ "a","̑" },
- ["Ȅ"]={ "E","̏" },
- ["ȅ"]={ "e","̏" },
- ["Ȇ"]={ "E","̑" },
- ["ȇ"]={ "e","̑" },
- ["Ȉ"]={ "I","̏" },
- ["ȉ"]={ "i","̏" },
- ["Ȋ"]={ "I","̑" },
- ["ȋ"]={ "i","̑" },
- ["Ȍ"]={ "O","̏" },
- ["ȍ"]={ "o","̏" },
- ["Ȏ"]={ "O","̑" },
- ["ȏ"]={ "o","̑" },
- ["Ȑ"]={ "R","̏" },
- ["ȑ"]={ "r","̏" },
- ["Ȓ"]={ "R","̑" },
- ["ȓ"]={ "r","̑" },
- ["Ȕ"]={ "U","̏" },
- ["ȕ"]={ "u","̏" },
- ["Ȗ"]={ "U","̑" },
- ["ȗ"]={ "u","̑" },
- ["Ș"]={ "S","̦" },
- ["ș"]={ "s","̦" },
- ["Ț"]={ "T","̦" },
- ["ț"]={ "t","̦" },
- ["Ȟ"]={ "H","̌" },
- ["ȟ"]={ "h","̌" },
- ["Ȧ"]={ "A","̇" },
- ["ȧ"]={ "a","̇" },
- ["Ȩ"]={ "E","̧" },
- ["ȩ"]={ "e","̧" },
- ["Ȫ"]={ "Ö","̄" },
- ["ȫ"]={ "ö","̄" },
- ["Ȭ"]={ "Õ","̄" },
- ["ȭ"]={ "õ","̄" },
- ["Ȯ"]={ "O","̇" },
- ["ȯ"]={ "o","̇" },
- ["Ȱ"]={ "Ȯ","̄" },
- ["ȱ"]={ "ȯ","̄" },
- ["Ȳ"]={ "Y","̄" },
- ["ȳ"]={ "y","̄" },
- ["̈́"]={ "̈","́" },
- ["΅"]={ "¨","́" },
- ["Ά"]={ "Α","́" },
- ["Έ"]={ "Ε","́" },
- ["Ή"]={ "Η","́" },
- ["Ί"]={ "Ι","́" },
- ["Ό"]={ "Ο","́" },
- ["Ύ"]={ "Υ","́" },
- ["Ώ"]={ "Ω","́" },
- ["ΐ"]={ "ϊ","́" },
- ["Ϊ"]={ "Ι","̈" },
- ["Ϋ"]={ "Υ","̈" },
- ["ά"]={ "α","́" },
- ["έ"]={ "ε","́" },
- ["ή"]={ "η","́" },
- ["ί"]={ "ι","́" },
- ["ΰ"]={ "ϋ","́" },
- ["ϊ"]={ "ι","̈" },
- ["ϋ"]={ "υ","̈" },
- ["ό"]={ "ο","́" },
- ["ύ"]={ "υ","́" },
- ["ώ"]={ "ω","́" },
- ["ϓ"]={ "ϒ","́" },
- ["ϔ"]={ "ϒ","̈" },
- ["Ѐ"]={ "Е","̀" },
- ["Ё"]={ "Е","̈" },
- ["Ѓ"]={ "Г","́" },
- ["Ї"]={ "І","̈" },
- ["Ќ"]={ "К","́" },
- ["Ѝ"]={ "И","̀" },
- ["Ў"]={ "У","̆" },
- ["Й"]={ "И","̆" },
- ["й"]={ "и","̆" },
- ["ѐ"]={ "е","̀" },
- ["ё"]={ "е","̈" },
- ["ѓ"]={ "г","́" },
- ["ї"]={ "і","̈" },
- ["ќ"]={ "к","́" },
- ["ѝ"]={ "и","̀" },
- ["ў"]={ "у","̆" },
- ["Ѷ"]={ "Ѵ","̏" },
- ["ѷ"]={ "ѵ","̏" },
- ["Ӂ"]={ "Ж","̆" },
- ["ӂ"]={ "ж","̆" },
- ["Ӑ"]={ "А","̆" },
- ["ӑ"]={ "а","̆" },
- ["Ӓ"]={ "А","̈" },
- ["ӓ"]={ "а","̈" },
- ["Ӗ"]={ "Е","̆" },
- ["ӗ"]={ "е","̆" },
- ["Ӛ"]={ "Ә","̈" },
- ["ӛ"]={ "ә","̈" },
- ["Ӝ"]={ "Ж","̈" },
- ["ӝ"]={ "ж","̈" },
- ["Ӟ"]={ "З","̈" },
- ["ӟ"]={ "з","̈" },
- ["Ӣ"]={ "И","̄" },
- ["ӣ"]={ "и","̄" },
- ["Ӥ"]={ "И","̈" },
- ["ӥ"]={ "и","̈" },
- ["Ӧ"]={ "О","̈" },
- ["ӧ"]={ "о","̈" },
- ["Ӫ"]={ "Ө","̈" },
- ["ӫ"]={ "ө","̈" },
- ["Ӭ"]={ "Э","̈" },
- ["ӭ"]={ "э","̈" },
- ["Ӯ"]={ "У","̄" },
- ["ӯ"]={ "у","̄" },
- ["Ӱ"]={ "У","̈" },
- ["ӱ"]={ "у","̈" },
- ["Ӳ"]={ "У","̋" },
- ["ӳ"]={ "у","̋" },
- ["Ӵ"]={ "Ч","̈" },
- ["ӵ"]={ "ч","̈" },
- ["Ӹ"]={ "Ы","̈" },
- ["ӹ"]={ "ы","̈" },
- ["آ"]={ "ا","ٓ" },
- ["أ"]={ "ا","ٔ" },
- ["ؤ"]={ "و","ٔ" },
- ["إ"]={ "ا","ٕ" },
- ["ئ"]={ "ي","ٔ" },
- ["ۀ"]={ "ە","ٔ" },
- ["ۂ"]={ "ہ","ٔ" },
- ["ۓ"]={ "ے","ٔ" },
- ["ऩ"]={ "न","़" },
- ["ऱ"]={ "र","़" },
- ["ऴ"]={ "ळ","़" },
- ["क़"]={ "क","़" },
- ["ख़"]={ "ख","़" },
- ["ग़"]={ "ग","़" },
- ["ज़"]={ "ज","़" },
- ["ड़"]={ "ड","़" },
- ["ढ़"]={ "ढ","़" },
- ["फ़"]={ "फ","़" },
- ["य़"]={ "य","़" },
- ["ো"]={ "ে","া" },
- ["ৌ"]={ "ে","ৗ" },
- ["ড়"]={ "ড","়" },
- ["ঢ়"]={ "ঢ","়" },
- ["য়"]={ "য","়" },
- ["ਲ਼"]={ "ਲ","਼" },
- ["ਸ਼"]={ "ਸ","਼" },
- ["ਖ਼"]={ "ਖ","਼" },
- ["ਗ਼"]={ "ਗ","਼" },
- ["ਜ਼"]={ "ਜ","਼" },
- ["ਫ਼"]={ "ਫ","਼" },
- ["ୈ"]={ "େ","ୖ" },
- ["ୋ"]={ "େ","ା" },
- ["ୌ"]={ "େ","ୗ" },
- ["ଡ଼"]={ "ଡ","଼" },
- ["ଢ଼"]={ "ଢ","଼" },
- ["ஔ"]={ "ஒ","ௗ" },
- ["ொ"]={ "ெ","ா" },
- ["ோ"]={ "ே","ா" },
- ["ௌ"]={ "ெ","ௗ" },
- ["ై"]={ "ె","ౖ" },
- ["ೀ"]={ "ಿ","ೕ" },
- ["ೇ"]={ "ೆ","ೕ" },
- ["ೈ"]={ "ೆ","ೖ" },
- ["ೊ"]={ "ೆ","ೂ" },
- ["ೋ"]={ "ೊ","ೕ" },
- ["ൊ"]={ "െ","ാ" },
- ["ോ"]={ "േ","ാ" },
- ["ൌ"]={ "െ","ൗ" },
- ["ේ"]={ "ෙ","්" },
- ["ො"]={ "ෙ","ා" },
- ["ෝ"]={ "ො","්" },
- ["ෞ"]={ "ෙ","ෟ" },
- ["གྷ"]={ "ག","ྷ" },
- ["ཌྷ"]={ "ཌ","ྷ" },
- ["དྷ"]={ "ད","ྷ" },
- ["བྷ"]={ "བ","ྷ" },
- ["ཛྷ"]={ "ཛ","ྷ" },
- ["ཀྵ"]={ "ཀ","ྵ" },
- ["ཱི"]={ "ཱ","ི" },
- ["ཱུ"]={ "ཱ","ུ" },
- ["ྲྀ"]={ "ྲ","ྀ" },
- ["ླྀ"]={ "ླ","ྀ" },
- ["ཱྀ"]={ "ཱ","ྀ" },
- ["ྒྷ"]={ "ྒ","ྷ" },
- ["ྜྷ"]={ "ྜ","ྷ" },
- ["ྡྷ"]={ "ྡ","ྷ" },
- ["ྦྷ"]={ "ྦ","ྷ" },
- ["ྫྷ"]={ "ྫ","ྷ" },
- ["ྐྵ"]={ "ྐ","ྵ" },
- ["ဦ"]={ "ဥ","ီ" },
- ["ᬆ"]={ "ᬅ","ᬵ" },
- ["ᬈ"]={ "ᬇ","ᬵ" },
- ["ᬊ"]={ "ᬉ","ᬵ" },
- ["ᬌ"]={ "ᬋ","ᬵ" },
- ["ᬎ"]={ "ᬍ","ᬵ" },
- ["ᬒ"]={ "ᬑ","ᬵ" },
- ["ᬻ"]={ "ᬺ","ᬵ" },
- ["ᬽ"]={ "ᬼ","ᬵ" },
- ["ᭀ"]={ "ᬾ","ᬵ" },
- ["ᭁ"]={ "ᬿ","ᬵ" },
- ["ᭃ"]={ "ᭂ","ᬵ" },
- ["Ḁ"]={ "A","̥" },
- ["ḁ"]={ "a","̥" },
- ["Ḃ"]={ "B","̇" },
- ["ḃ"]={ "b","̇" },
- ["Ḅ"]={ "B","̣" },
- ["ḅ"]={ "b","̣" },
- ["Ḇ"]={ "B","̱" },
- ["ḇ"]={ "b","̱" },
- ["Ḉ"]={ "Ç","́" },
- ["ḉ"]={ "ç","́" },
- ["Ḋ"]={ "D","̇" },
- ["ḋ"]={ "d","̇" },
- ["Ḍ"]={ "D","̣" },
- ["ḍ"]={ "d","̣" },
- ["Ḏ"]={ "D","̱" },
- ["ḏ"]={ "d","̱" },
- ["Ḑ"]={ "D","̧" },
- ["ḑ"]={ "d","̧" },
- ["Ḓ"]={ "D","̭" },
- ["ḓ"]={ "d","̭" },
- ["Ḕ"]={ "Ē","̀" },
- ["ḕ"]={ "ē","̀" },
- ["Ḗ"]={ "Ē","́" },
- ["ḗ"]={ "ē","́" },
- ["Ḙ"]={ "E","̭" },
- ["ḙ"]={ "e","̭" },
- ["Ḛ"]={ "E","̰" },
- ["ḛ"]={ "e","̰" },
- ["Ḝ"]={ "Ȩ","̆" },
- ["ḝ"]={ "ȩ","̆" },
- ["Ḟ"]={ "F","̇" },
- ["ḟ"]={ "f","̇" },
- ["Ḡ"]={ "G","̄" },
- ["ḡ"]={ "g","̄" },
- ["Ḣ"]={ "H","̇" },
- ["ḣ"]={ "h","̇" },
- ["Ḥ"]={ "H","̣" },
- ["ḥ"]={ "h","̣" },
- ["Ḧ"]={ "H","̈" },
- ["ḧ"]={ "h","̈" },
- ["Ḩ"]={ "H","̧" },
- ["ḩ"]={ "h","̧" },
- ["Ḫ"]={ "H","̮" },
- ["ḫ"]={ "h","̮" },
- ["Ḭ"]={ "I","̰" },
- ["ḭ"]={ "i","̰" },
- ["Ḯ"]={ "Ï","́" },
- ["ḯ"]={ "ï","́" },
- ["Ḱ"]={ "K","́" },
- ["ḱ"]={ "k","́" },
- ["Ḳ"]={ "K","̣" },
- ["ḳ"]={ "k","̣" },
- ["Ḵ"]={ "K","̱" },
- ["ḵ"]={ "k","̱" },
- ["Ḷ"]={ "L","̣" },
- ["ḷ"]={ "l","̣" },
- ["Ḹ"]={ "Ḷ","̄" },
- ["ḹ"]={ "ḷ","̄" },
- ["Ḻ"]={ "L","̱" },
- ["ḻ"]={ "l","̱" },
- ["Ḽ"]={ "L","̭" },
- ["ḽ"]={ "l","̭" },
- ["Ḿ"]={ "M","́" },
- ["ḿ"]={ "m","́" },
- ["Ṁ"]={ "M","̇" },
- ["ṁ"]={ "m","̇" },
- ["Ṃ"]={ "M","̣" },
- ["ṃ"]={ "m","̣" },
- ["Ṅ"]={ "N","̇" },
- ["ṅ"]={ "n","̇" },
- ["Ṇ"]={ "N","̣" },
- ["ṇ"]={ "n","̣" },
- ["Ṉ"]={ "N","̱" },
- ["ṉ"]={ "n","̱" },
- ["Ṋ"]={ "N","̭" },
- ["ṋ"]={ "n","̭" },
- ["Ṍ"]={ "Õ","́" },
- ["ṍ"]={ "õ","́" },
- ["Ṏ"]={ "Õ","̈" },
- ["ṏ"]={ "õ","̈" },
- ["Ṑ"]={ "Ō","̀" },
- ["ṑ"]={ "ō","̀" },
- ["Ṓ"]={ "Ō","́" },
- ["ṓ"]={ "ō","́" },
- ["Ṕ"]={ "P","́" },
- ["ṕ"]={ "p","́" },
- ["Ṗ"]={ "P","̇" },
- ["ṗ"]={ "p","̇" },
- ["Ṙ"]={ "R","̇" },
- ["ṙ"]={ "r","̇" },
- ["Ṛ"]={ "R","̣" },
- ["ṛ"]={ "r","̣" },
- ["Ṝ"]={ "Ṛ","̄" },
- ["ṝ"]={ "ṛ","̄" },
- ["Ṟ"]={ "R","̱" },
- ["ṟ"]={ "r","̱" },
- ["Ṡ"]={ "S","̇" },
- ["ṡ"]={ "s","̇" },
- ["Ṣ"]={ "S","̣" },
- ["ṣ"]={ "s","̣" },
- ["Ṥ"]={ "Ś","̇" },
- ["ṥ"]={ "ś","̇" },
- ["Ṧ"]={ "Š","̇" },
- ["ṧ"]={ "š","̇" },
- ["Ṩ"]={ "Ṣ","̇" },
- ["ṩ"]={ "ṣ","̇" },
- ["Ṫ"]={ "T","̇" },
- ["ṫ"]={ "t","̇" },
- ["Ṭ"]={ "T","̣" },
- ["ṭ"]={ "t","̣" },
- ["Ṯ"]={ "T","̱" },
- ["ṯ"]={ "t","̱" },
- ["Ṱ"]={ "T","̭" },
- ["ṱ"]={ "t","̭" },
- ["Ṳ"]={ "U","̤" },
- ["ṳ"]={ "u","̤" },
- ["Ṵ"]={ "U","̰" },
- ["ṵ"]={ "u","̰" },
- ["Ṷ"]={ "U","̭" },
- ["ṷ"]={ "u","̭" },
- ["Ṹ"]={ "Ũ","́" },
- ["ṹ"]={ "ũ","́" },
- ["Ṻ"]={ "Ū","̈" },
- ["ṻ"]={ "ū","̈" },
- ["Ṽ"]={ "V","̃" },
- ["ṽ"]={ "v","̃" },
- ["Ṿ"]={ "V","̣" },
- ["ṿ"]={ "v","̣" },
- ["Ẁ"]={ "W","̀" },
- ["ẁ"]={ "w","̀" },
- ["Ẃ"]={ "W","́" },
- ["ẃ"]={ "w","́" },
- ["Ẅ"]={ "W","̈" },
- ["ẅ"]={ "w","̈" },
- ["Ẇ"]={ "W","̇" },
- ["ẇ"]={ "w","̇" },
- ["Ẉ"]={ "W","̣" },
- ["ẉ"]={ "w","̣" },
- ["Ẋ"]={ "X","̇" },
- ["ẋ"]={ "x","̇" },
- ["Ẍ"]={ "X","̈" },
- ["ẍ"]={ "x","̈" },
- ["Ẏ"]={ "Y","̇" },
- ["ẏ"]={ "y","̇" },
- ["Ẑ"]={ "Z","̂" },
- ["ẑ"]={ "z","̂" },
- ["Ẓ"]={ "Z","̣" },
- ["ẓ"]={ "z","̣" },
- ["Ẕ"]={ "Z","̱" },
- ["ẕ"]={ "z","̱" },
- ["ẖ"]={ "h","̱" },
- ["ẗ"]={ "t","̈" },
- ["ẘ"]={ "w","̊" },
- ["ẙ"]={ "y","̊" },
- ["ẛ"]={ "ſ","̇" },
- ["Ạ"]={ "A","̣" },
- ["ạ"]={ "a","̣" },
- ["Ả"]={ "A","̉" },
- ["ả"]={ "a","̉" },
- ["Ấ"]={ "Â","́" },
- ["ấ"]={ "â","́" },
- ["Ầ"]={ "Â","̀" },
- ["ầ"]={ "â","̀" },
- ["Ẩ"]={ "Â","̉" },
- ["ẩ"]={ "â","̉" },
- ["Ẫ"]={ "Â","̃" },
- ["ẫ"]={ "â","̃" },
- ["Ậ"]={ "Ạ","̂" },
- ["ậ"]={ "ạ","̂" },
- ["Ắ"]={ "Ă","́" },
- ["ắ"]={ "ă","́" },
- ["Ằ"]={ "Ă","̀" },
- ["ằ"]={ "ă","̀" },
- ["Ẳ"]={ "Ă","̉" },
- ["ẳ"]={ "ă","̉" },
- ["Ẵ"]={ "Ă","̃" },
- ["ẵ"]={ "ă","̃" },
- ["Ặ"]={ "Ạ","̆" },
- ["ặ"]={ "ạ","̆" },
- ["Ẹ"]={ "E","̣" },
- ["ẹ"]={ "e","̣" },
- ["Ẻ"]={ "E","̉" },
- ["ẻ"]={ "e","̉" },
- ["Ẽ"]={ "E","̃" },
- ["ẽ"]={ "e","̃" },
- ["Ế"]={ "Ê","́" },
- ["ế"]={ "ê","́" },
- ["Ề"]={ "Ê","̀" },
- ["ề"]={ "ê","̀" },
- ["Ể"]={ "Ê","̉" },
- ["ể"]={ "ê","̉" },
- ["Ễ"]={ "Ê","̃" },
- ["ễ"]={ "ê","̃" },
- ["Ệ"]={ "Ẹ","̂" },
- ["ệ"]={ "ẹ","̂" },
- ["Ỉ"]={ "I","̉" },
- ["ỉ"]={ "i","̉" },
- ["Ị"]={ "I","̣" },
- ["ị"]={ "i","̣" },
- ["Ọ"]={ "O","̣" },
- ["ọ"]={ "o","̣" },
- ["Ỏ"]={ "O","̉" },
- ["ỏ"]={ "o","̉" },
- ["Ố"]={ "Ô","́" },
- ["ố"]={ "ô","́" },
- ["Ồ"]={ "Ô","̀" },
- ["ồ"]={ "ô","̀" },
- ["Ổ"]={ "Ô","̉" },
- ["ổ"]={ "ô","̉" },
- ["Ỗ"]={ "Ô","̃" },
- ["ỗ"]={ "ô","̃" },
- ["Ộ"]={ "Ọ","̂" },
- ["ộ"]={ "ọ","̂" },
- ["Ớ"]={ "Ơ","́" },
- ["ớ"]={ "ơ","́" },
- ["Ờ"]={ "Ơ","̀" },
- ["ờ"]={ "ơ","̀" },
- ["Ở"]={ "Ơ","̉" },
- ["ở"]={ "ơ","̉" },
- ["Ỡ"]={ "Ơ","̃" },
- ["ỡ"]={ "ơ","̃" },
- ["Ợ"]={ "Ơ","̣" },
- ["ợ"]={ "ơ","̣" },
- ["Ụ"]={ "U","̣" },
- ["ụ"]={ "u","̣" },
- ["Ủ"]={ "U","̉" },
- ["ủ"]={ "u","̉" },
- ["Ứ"]={ "Ư","́" },
- ["ứ"]={ "ư","́" },
- ["Ừ"]={ "Ư","̀" },
- ["ừ"]={ "ư","̀" },
- ["Ử"]={ "Ư","̉" },
- ["ử"]={ "ư","̉" },
- ["Ữ"]={ "Ư","̃" },
- ["ữ"]={ "ư","̃" },
- ["Ự"]={ "Ư","̣" },
- ["ự"]={ "ư","̣" },
- ["Ỳ"]={ "Y","̀" },
- ["ỳ"]={ "y","̀" },
- ["Ỵ"]={ "Y","̣" },
- ["ỵ"]={ "y","̣" },
- ["Ỷ"]={ "Y","̉" },
- ["ỷ"]={ "y","̉" },
- ["Ỹ"]={ "Y","̃" },
- ["ỹ"]={ "y","̃" },
- ["ἀ"]={ "α","̓" },
- ["ἁ"]={ "α","̔" },
- ["ἂ"]={ "ἀ","̀" },
- ["ἃ"]={ "ἁ","̀" },
- ["ἄ"]={ "ἀ","́" },
- ["ἅ"]={ "ἁ","́" },
- ["ἆ"]={ "ἀ","͂" },
- ["ἇ"]={ "ἁ","͂" },
- ["Ἀ"]={ "Α","̓" },
- ["Ἁ"]={ "Α","̔" },
- ["Ἂ"]={ "Ἀ","̀" },
- ["Ἃ"]={ "Ἁ","̀" },
- ["Ἄ"]={ "Ἀ","́" },
- ["Ἅ"]={ "Ἁ","́" },
- ["Ἆ"]={ "Ἀ","͂" },
- ["Ἇ"]={ "Ἁ","͂" },
- ["ἐ"]={ "ε","̓" },
- ["ἑ"]={ "ε","̔" },
- ["ἒ"]={ "ἐ","̀" },
- ["ἓ"]={ "ἑ","̀" },
- ["ἔ"]={ "ἐ","́" },
- ["ἕ"]={ "ἑ","́" },
- ["Ἐ"]={ "Ε","̓" },
- ["Ἑ"]={ "Ε","̔" },
- ["Ἒ"]={ "Ἐ","̀" },
- ["Ἓ"]={ "Ἑ","̀" },
- ["Ἔ"]={ "Ἐ","́" },
- ["Ἕ"]={ "Ἑ","́" },
- ["ἠ"]={ "η","̓" },
- ["ἡ"]={ "η","̔" },
- ["ἢ"]={ "ἠ","̀" },
- ["ἣ"]={ "ἡ","̀" },
- ["ἤ"]={ "ἠ","́" },
- ["ἥ"]={ "ἡ","́" },
- ["ἦ"]={ "ἠ","͂" },
- ["ἧ"]={ "ἡ","͂" },
- ["Ἠ"]={ "Η","̓" },
- ["Ἡ"]={ "Η","̔" },
- ["Ἢ"]={ "Ἠ","̀" },
- ["Ἣ"]={ "Ἡ","̀" },
- ["Ἤ"]={ "Ἠ","́" },
- ["Ἥ"]={ "Ἡ","́" },
- ["Ἦ"]={ "Ἠ","͂" },
- ["Ἧ"]={ "Ἡ","͂" },
- ["ἰ"]={ "ι","̓" },
- ["ἱ"]={ "ι","̔" },
- ["ἲ"]={ "ἰ","̀" },
- ["ἳ"]={ "ἱ","̀" },
- ["ἴ"]={ "ἰ","́" },
- ["ἵ"]={ "ἱ","́" },
- ["ἶ"]={ "ἰ","͂" },
- ["ἷ"]={ "ἱ","͂" },
- ["Ἰ"]={ "Ι","̓" },
- ["Ἱ"]={ "Ι","̔" },
- ["Ἲ"]={ "Ἰ","̀" },
- ["Ἳ"]={ "Ἱ","̀" },
- ["Ἴ"]={ "Ἰ","́" },
- ["Ἵ"]={ "Ἱ","́" },
- ["Ἶ"]={ "Ἰ","͂" },
- ["Ἷ"]={ "Ἱ","͂" },
- ["ὀ"]={ "ο","̓" },
- ["ὁ"]={ "ο","̔" },
- ["ὂ"]={ "ὀ","̀" },
- ["ὃ"]={ "ὁ","̀" },
- ["ὄ"]={ "ὀ","́" },
- ["ὅ"]={ "ὁ","́" },
- ["Ὀ"]={ "Ο","̓" },
- ["Ὁ"]={ "Ο","̔" },
- ["Ὂ"]={ "Ὀ","̀" },
- ["Ὃ"]={ "Ὁ","̀" },
- ["Ὄ"]={ "Ὀ","́" },
- ["Ὅ"]={ "Ὁ","́" },
- ["ὐ"]={ "υ","̓" },
- ["ὑ"]={ "υ","̔" },
- ["ὒ"]={ "ὐ","̀" },
- ["ὓ"]={ "ὑ","̀" },
- ["ὔ"]={ "ὐ","́" },
- ["ὕ"]={ "ὑ","́" },
- ["ὖ"]={ "ὐ","͂" },
- ["ὗ"]={ "ὑ","͂" },
- ["Ὑ"]={ "Υ","̔" },
- ["Ὓ"]={ "Ὑ","̀" },
- ["Ὕ"]={ "Ὑ","́" },
- ["Ὗ"]={ "Ὑ","͂" },
- ["ὠ"]={ "ω","̓" },
- ["ὡ"]={ "ω","̔" },
- ["ὢ"]={ "ὠ","̀" },
- ["ὣ"]={ "ὡ","̀" },
- ["ὤ"]={ "ὠ","́" },
- ["ὥ"]={ "ὡ","́" },
- ["ὦ"]={ "ὠ","͂" },
- ["ὧ"]={ "ὡ","͂" },
- ["Ὠ"]={ "Ω","̓" },
- ["Ὡ"]={ "Ω","̔" },
- ["Ὢ"]={ "Ὠ","̀" },
- ["Ὣ"]={ "Ὡ","̀" },
- ["Ὤ"]={ "Ὠ","́" },
- ["Ὥ"]={ "Ὡ","́" },
- ["Ὦ"]={ "Ὠ","͂" },
- ["Ὧ"]={ "Ὡ","͂" },
- ["ὰ"]={ "α","̀" },
- ["ὲ"]={ "ε","̀" },
- ["ὴ"]={ "η","̀" },
- ["ὶ"]={ "ι","̀" },
- ["ὸ"]={ "ο","̀" },
- ["ὺ"]={ "υ","̀" },
- ["ὼ"]={ "ω","̀" },
- ["ᾀ"]={ "ἀ","ͅ" },
- ["ᾁ"]={ "ἁ","ͅ" },
- ["ᾂ"]={ "ἂ","ͅ" },
- ["ᾃ"]={ "ἃ","ͅ" },
- ["ᾄ"]={ "ἄ","ͅ" },
- ["ᾅ"]={ "ἅ","ͅ" },
- ["ᾆ"]={ "ἆ","ͅ" },
- ["ᾇ"]={ "ἇ","ͅ" },
- ["ᾈ"]={ "Ἀ","ͅ" },
- ["ᾉ"]={ "Ἁ","ͅ" },
- ["ᾊ"]={ "Ἂ","ͅ" },
- ["ᾋ"]={ "Ἃ","ͅ" },
- ["ᾌ"]={ "Ἄ","ͅ" },
- ["ᾍ"]={ "Ἅ","ͅ" },
- ["ᾎ"]={ "Ἆ","ͅ" },
- ["ᾏ"]={ "Ἇ","ͅ" },
- ["ᾐ"]={ "ἠ","ͅ" },
- ["ᾑ"]={ "ἡ","ͅ" },
- ["ᾒ"]={ "ἢ","ͅ" },
- ["ᾓ"]={ "ἣ","ͅ" },
- ["ᾔ"]={ "ἤ","ͅ" },
- ["ᾕ"]={ "ἥ","ͅ" },
- ["ᾖ"]={ "ἦ","ͅ" },
- ["ᾗ"]={ "ἧ","ͅ" },
- ["ᾘ"]={ "Ἠ","ͅ" },
- ["ᾙ"]={ "Ἡ","ͅ" },
- ["ᾚ"]={ "Ἢ","ͅ" },
- ["ᾛ"]={ "Ἣ","ͅ" },
- ["ᾜ"]={ "Ἤ","ͅ" },
- ["ᾝ"]={ "Ἥ","ͅ" },
- ["ᾞ"]={ "Ἦ","ͅ" },
- ["ᾟ"]={ "Ἧ","ͅ" },
- ["ᾠ"]={ "ὠ","ͅ" },
- ["ᾡ"]={ "ὡ","ͅ" },
- ["ᾢ"]={ "ὢ","ͅ" },
- ["ᾣ"]={ "ὣ","ͅ" },
- ["ᾤ"]={ "ὤ","ͅ" },
- ["ᾥ"]={ "ὥ","ͅ" },
- ["ᾦ"]={ "ὦ","ͅ" },
- ["ᾧ"]={ "ὧ","ͅ" },
- ["ᾨ"]={ "Ὠ","ͅ" },
- ["ᾩ"]={ "Ὡ","ͅ" },
- ["ᾪ"]={ "Ὢ","ͅ" },
- ["ᾫ"]={ "Ὣ","ͅ" },
- ["ᾬ"]={ "Ὤ","ͅ" },
- ["ᾭ"]={ "Ὥ","ͅ" },
- ["ᾮ"]={ "Ὦ","ͅ" },
- ["ᾯ"]={ "Ὧ","ͅ" },
- ["ᾰ"]={ "α","̆" },
- ["ᾱ"]={ "α","̄" },
- ["ᾲ"]={ "ὰ","ͅ" },
- ["ᾳ"]={ "α","ͅ" },
- ["ᾴ"]={ "ά","ͅ" },
- ["ᾶ"]={ "α","͂" },
- ["ᾷ"]={ "ᾶ","ͅ" },
- ["Ᾰ"]={ "Α","̆" },
- ["Ᾱ"]={ "Α","̄" },
- ["Ὰ"]={ "Α","̀" },
- ["ᾼ"]={ "Α","ͅ" },
- ["῁"]={ "¨","͂" },
- ["ῂ"]={ "ὴ","ͅ" },
- ["ῃ"]={ "η","ͅ" },
- ["ῄ"]={ "ή","ͅ" },
- ["ῆ"]={ "η","͂" },
- ["ῇ"]={ "ῆ","ͅ" },
- ["Ὲ"]={ "Ε","̀" },
- ["Ὴ"]={ "Η","̀" },
- ["ῌ"]={ "Η","ͅ" },
- ["῍"]={ "᾿","̀" },
- ["῎"]={ "᾿","́" },
- ["῏"]={ "᾿","͂" },
- ["ῐ"]={ "ι","̆" },
- ["ῑ"]={ "ι","̄" },
- ["ῒ"]={ "ϊ","̀" },
- ["ῖ"]={ "ι","͂" },
- ["ῗ"]={ "ϊ","͂" },
- ["Ῐ"]={ "Ι","̆" },
- ["Ῑ"]={ "Ι","̄" },
- ["Ὶ"]={ "Ι","̀" },
- ["῝"]={ "῾","̀" },
- ["῞"]={ "῾","́" },
- ["῟"]={ "῾","͂" },
- ["ῠ"]={ "υ","̆" },
- ["ῡ"]={ "υ","̄" },
- ["ῢ"]={ "ϋ","̀" },
- ["ῤ"]={ "ρ","̓" },
- ["ῥ"]={ "ρ","̔" },
- ["ῦ"]={ "υ","͂" },
- ["ῧ"]={ "ϋ","͂" },
- ["Ῠ"]={ "Υ","̆" },
- ["Ῡ"]={ "Υ","̄" },
- ["Ὺ"]={ "Υ","̀" },
- ["Ῥ"]={ "Ρ","̔" },
- ["῭"]={ "¨","̀" },
- ["ῲ"]={ "ὼ","ͅ" },
- ["ῳ"]={ "ω","ͅ" },
- ["ῴ"]={ "ώ","ͅ" },
- ["ῶ"]={ "ω","͂" },
- ["ῷ"]={ "ῶ","ͅ" },
- ["Ὸ"]={ "Ο","̀" },
- ["Ὼ"]={ "Ω","̀" },
- ["ῼ"]={ "Ω","ͅ" },
- ["↚"]={ "←","̸" },
- ["↛"]={ "→","̸" },
- ["↮"]={ "↔","̸" },
- ["⇍"]={ "⇐","̸" },
- ["⇎"]={ "⇔","̸" },
- ["⇏"]={ "⇒","̸" },
- ["∄"]={ "∃","̸" },
- ["∉"]={ "∈","̸" },
- ["∌"]={ "∋","̸" },
- ["∤"]={ "∣","̸" },
- ["∦"]={ "∥","̸" },
- ["≁"]={ "∼","̸" },
- ["≄"]={ "≃","̸" },
- ["≇"]={ "≅","̸" },
- ["≉"]={ "≈","̸" },
- ["≠"]={ "=","̸" },
- ["≢"]={ "≡","̸" },
- ["≭"]={ "≍","̸" },
- ["≮"]={ "<","̸" },
- ["≯"]={ ">","̸" },
- ["≰"]={ "≤","̸" },
- ["≱"]={ "≥","̸" },
- ["≴"]={ "≲","̸" },
- ["≵"]={ "≳","̸" },
- ["≸"]={ "≶","̸" },
- ["≹"]={ "≷","̸" },
- ["⊀"]={ "≺","̸" },
- ["⊁"]={ "≻","̸" },
- ["⊄"]={ "⊂","̸" },
- ["⊅"]={ "⊃","̸" },
- ["⊈"]={ "⊆","̸" },
- ["⊉"]={ "⊇","̸" },
- ["⊬"]={ "⊢","̸" },
- ["⊭"]={ "⊨","̸" },
- ["⊮"]={ "⊩","̸" },
- ["⊯"]={ "⊫","̸" },
- ["⋠"]={ "≼","̸" },
- ["⋡"]={ "≽","̸" },
- ["⋢"]={ "⊑","̸" },
- ["⋣"]={ "⊒","̸" },
- ["⋪"]={ "⊲","̸" },
- ["⋫"]={ "⊳","̸" },
- ["⋬"]={ "⊴","̸" },
- ["⋭"]={ "⊵","̸" },
- ["⫝̸"]={ "⫝","̸" },
- ["が"]={ "か","゙" },
- ["ぎ"]={ "き","゙" },
- ["ぐ"]={ "く","゙" },
- ["げ"]={ "け","゙" },
- ["ご"]={ "こ","゙" },
- ["ざ"]={ "さ","゙" },
- ["じ"]={ "し","゙" },
- ["ず"]={ "す","゙" },
- ["ぜ"]={ "せ","゙" },
- ["ぞ"]={ "そ","゙" },
- ["だ"]={ "た","゙" },
- ["ぢ"]={ "ち","゙" },
- ["づ"]={ "つ","゙" },
- ["で"]={ "て","゙" },
- ["ど"]={ "と","゙" },
- ["ば"]={ "は","゙" },
- ["ぱ"]={ "は","゚" },
- ["び"]={ "ひ","゙" },
- ["ぴ"]={ "ひ","゚" },
- ["ぶ"]={ "ふ","゙" },
- ["ぷ"]={ "ふ","゚" },
- ["べ"]={ "へ","゙" },
- ["ぺ"]={ "へ","゚" },
- ["ぼ"]={ "ほ","゙" },
- ["ぽ"]={ "ほ","゚" },
- ["ゔ"]={ "う","゙" },
- ["ゞ"]={ "ゝ","゙" },
- ["ガ"]={ "カ","゙" },
- ["ギ"]={ "キ","゙" },
- ["グ"]={ "ク","゙" },
- ["ゲ"]={ "ケ","゙" },
- ["ゴ"]={ "コ","゙" },
- ["ザ"]={ "サ","゙" },
- ["ジ"]={ "シ","゙" },
- ["ズ"]={ "ス","゙" },
- ["ゼ"]={ "セ","゙" },
- ["ゾ"]={ "ソ","゙" },
- ["ダ"]={ "タ","゙" },
- ["ヂ"]={ "チ","゙" },
- ["ヅ"]={ "ツ","゙" },
- ["デ"]={ "テ","゙" },
- ["ド"]={ "ト","゙" },
- ["バ"]={ "ハ","゙" },
- ["パ"]={ "ハ","゚" },
- ["ビ"]={ "ヒ","゙" },
- ["ピ"]={ "ヒ","゚" },
- ["ブ"]={ "フ","゙" },
- ["プ"]={ "フ","゚" },
- ["ベ"]={ "ヘ","゙" },
- ["ペ"]={ "ヘ","゚" },
- ["ボ"]={ "ホ","゙" },
- ["ポ"]={ "ホ","゚" },
- ["ヴ"]={ "ウ","゙" },
- ["ヷ"]={ "ワ","゙" },
- ["ヸ"]={ "ヰ","゙" },
- ["ヹ"]={ "ヱ","゙" },
- ["ヺ"]={ "ヲ","゙" },
- ["ヾ"]={ "ヽ","゙" },
- ["יִ"]={ "י","ִ" },
- ["ײַ"]={ "ײ","ַ" },
- ["שׁ"]={ "ש","ׁ" },
- ["שׂ"]={ "ש","ׂ" },
- ["שּׁ"]={ "שּ","ׁ" },
- ["שּׂ"]={ "שּ","ׂ" },
- ["אַ"]={ "א","ַ" },
- ["אָ"]={ "א","ָ" },
- ["אּ"]={ "א","ּ" },
- ["בּ"]={ "ב","ּ" },
- ["גּ"]={ "ג","ּ" },
- ["דּ"]={ "ד","ּ" },
- ["הּ"]={ "ה","ּ" },
- ["וּ"]={ "ו","ּ" },
- ["זּ"]={ "ז","ּ" },
- ["טּ"]={ "ט","ּ" },
- ["יּ"]={ "י","ּ" },
- ["ךּ"]={ "ך","ּ" },
- ["כּ"]={ "כ","ּ" },
- ["לּ"]={ "ל","ּ" },
- ["מּ"]={ "מ","ּ" },
- ["נּ"]={ "נ","ּ" },
- ["סּ"]={ "ס","ּ" },
- ["ףּ"]={ "ף","ּ" },
- ["פּ"]={ "פ","ּ" },
- ["צּ"]={ "צ","ּ" },
- ["קּ"]={ "ק","ּ" },
- ["רּ"]={ "ר","ּ" },
- ["שּ"]={ "ש","ּ" },
- ["תּ"]={ "ת","ּ" },
- ["וֹ"]={ "ו","ֹ" },
- ["בֿ"]={ "ב","ֿ" },
- ["כֿ"]={ "כ","ֿ" },
- ["פֿ"]={ "פ","ֿ" },
- ["𑂚"]={ "𑂙","𑂺" },
- ["𑂜"]={ "𑂛","𑂺" },
- ["𑂫"]={ "𑂥","𑂺" },
- ["𑄮"]={ "𑄱","𑄧" },
- ["𑄯"]={ "𑄲","𑄧" },
- ["𑍋"]={ "𑍇","𑌾" },
- ["𑍌"]={ "𑍇","𑍗" },
- ["𑒻"]={ "𑒹","𑒺" },
- ["𑒼"]={ "𑒹","𑒰" },
- ["𑒾"]={ "𑒹","𑒽" },
- ["𑖺"]={ "𑖸","𑖯" },
- ["𑖻"]={ "𑖹","𑖯" },
- ["𝅗𝅥"]={ "𝅗","𝅥" },
- ["𝅘𝅥"]={ "𝅘","𝅥" },
- ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" },
- ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" },
- ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" },
- ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" },
- ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" },
- ["𝆹𝅥"]={ "𝆹","𝅥" },
- ["𝆺𝅥"]={ "𝆺","𝅥" },
- ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" },
- ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" },
- ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" },
- ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" },
+ {
+ ["data"]={
+ ["À"]={ "A","̀" },
+ ["Á"]={ "A","́" },
+ ["Â"]={ "A","̂" },
+ ["Ã"]={ "A","̃" },
+ ["Ä"]={ "A","̈" },
+ ["Å"]={ "A","̊" },
+ ["Ç"]={ "C","̧" },
+ ["È"]={ "E","̀" },
+ ["É"]={ "E","́" },
+ ["Ê"]={ "E","̂" },
+ ["Ë"]={ "E","̈" },
+ ["Ì"]={ "I","̀" },
+ ["Í"]={ "I","́" },
+ ["Î"]={ "I","̂" },
+ ["Ï"]={ "I","̈" },
+ ["Ñ"]={ "N","̃" },
+ ["Ò"]={ "O","̀" },
+ ["Ó"]={ "O","́" },
+ ["Ô"]={ "O","̂" },
+ ["Õ"]={ "O","̃" },
+ ["Ö"]={ "O","̈" },
+ ["Ù"]={ "U","̀" },
+ ["Ú"]={ "U","́" },
+ ["Û"]={ "U","̂" },
+ ["Ü"]={ "U","̈" },
+ ["Ý"]={ "Y","́" },
+ ["à"]={ "a","̀" },
+ ["á"]={ "a","́" },
+ ["â"]={ "a","̂" },
+ ["ã"]={ "a","̃" },
+ ["ä"]={ "a","̈" },
+ ["å"]={ "a","̊" },
+ ["ç"]={ "c","̧" },
+ ["è"]={ "e","̀" },
+ ["é"]={ "e","́" },
+ ["ê"]={ "e","̂" },
+ ["ë"]={ "e","̈" },
+ ["ì"]={ "i","̀" },
+ ["í"]={ "i","́" },
+ ["î"]={ "i","̂" },
+ ["ï"]={ "i","̈" },
+ ["ñ"]={ "n","̃" },
+ ["ò"]={ "o","̀" },
+ ["ó"]={ "o","́" },
+ ["ô"]={ "o","̂" },
+ ["õ"]={ "o","̃" },
+ ["ö"]={ "o","̈" },
+ ["ù"]={ "u","̀" },
+ ["ú"]={ "u","́" },
+ ["û"]={ "u","̂" },
+ ["ü"]={ "u","̈" },
+ ["ý"]={ "y","́" },
+ ["ÿ"]={ "y","̈" },
+ ["Ā"]={ "A","̄" },
+ ["ā"]={ "a","̄" },
+ ["Ă"]={ "A","̆" },
+ ["ă"]={ "a","̆" },
+ ["Ą"]={ "A","̨" },
+ ["ą"]={ "a","̨" },
+ ["Ć"]={ "C","́" },
+ ["ć"]={ "c","́" },
+ ["Ĉ"]={ "C","̂" },
+ ["ĉ"]={ "c","̂" },
+ ["Ċ"]={ "C","̇" },
+ ["ċ"]={ "c","̇" },
+ ["Č"]={ "C","̌" },
+ ["č"]={ "c","̌" },
+ ["Ď"]={ "D","̌" },
+ ["ď"]={ "d","̌" },
+ ["Ē"]={ "E","̄" },
+ ["ē"]={ "e","̄" },
+ ["Ĕ"]={ "E","̆" },
+ ["ĕ"]={ "e","̆" },
+ ["Ė"]={ "E","̇" },
+ ["ė"]={ "e","̇" },
+ ["Ę"]={ "E","̨" },
+ ["ę"]={ "e","̨" },
+ ["Ě"]={ "E","̌" },
+ ["ě"]={ "e","̌" },
+ ["Ĝ"]={ "G","̂" },
+ ["ĝ"]={ "g","̂" },
+ ["Ğ"]={ "G","̆" },
+ ["ğ"]={ "g","̆" },
+ ["Ġ"]={ "G","̇" },
+ ["ġ"]={ "g","̇" },
+ ["Ģ"]={ "G","̧" },
+ ["ģ"]={ "g","̧" },
+ ["Ĥ"]={ "H","̂" },
+ ["ĥ"]={ "h","̂" },
+ ["Ĩ"]={ "I","̃" },
+ ["ĩ"]={ "i","̃" },
+ ["Ī"]={ "I","̄" },
+ ["ī"]={ "i","̄" },
+ ["Ĭ"]={ "I","̆" },
+ ["ĭ"]={ "i","̆" },
+ ["Į"]={ "I","̨" },
+ ["į"]={ "i","̨" },
+ ["İ"]={ "I","̇" },
+ ["Ĵ"]={ "J","̂" },
+ ["ĵ"]={ "j","̂" },
+ ["Ķ"]={ "K","̧" },
+ ["ķ"]={ "k","̧" },
+ ["Ĺ"]={ "L","́" },
+ ["ĺ"]={ "l","́" },
+ ["Ļ"]={ "L","̧" },
+ ["ļ"]={ "l","̧" },
+ ["Ľ"]={ "L","̌" },
+ ["ľ"]={ "l","̌" },
+ ["Ń"]={ "N","́" },
+ ["ń"]={ "n","́" },
+ ["Ņ"]={ "N","̧" },
+ ["ņ"]={ "n","̧" },
+ ["Ň"]={ "N","̌" },
+ ["ň"]={ "n","̌" },
+ ["Ō"]={ "O","̄" },
+ ["ō"]={ "o","̄" },
+ ["Ŏ"]={ "O","̆" },
+ ["ŏ"]={ "o","̆" },
+ ["Ő"]={ "O","̋" },
+ ["ő"]={ "o","̋" },
+ ["Ŕ"]={ "R","́" },
+ ["ŕ"]={ "r","́" },
+ ["Ŗ"]={ "R","̧" },
+ ["ŗ"]={ "r","̧" },
+ ["Ř"]={ "R","̌" },
+ ["ř"]={ "r","̌" },
+ ["Ś"]={ "S","́" },
+ ["ś"]={ "s","́" },
+ ["Ŝ"]={ "S","̂" },
+ ["ŝ"]={ "s","̂" },
+ ["Ş"]={ "S","̧" },
+ ["ş"]={ "s","̧" },
+ ["Š"]={ "S","̌" },
+ ["š"]={ "s","̌" },
+ ["Ţ"]={ "T","̧" },
+ ["ţ"]={ "t","̧" },
+ ["Ť"]={ "T","̌" },
+ ["ť"]={ "t","̌" },
+ ["Ũ"]={ "U","̃" },
+ ["ũ"]={ "u","̃" },
+ ["Ū"]={ "U","̄" },
+ ["ū"]={ "u","̄" },
+ ["Ŭ"]={ "U","̆" },
+ ["ŭ"]={ "u","̆" },
+ ["Ů"]={ "U","̊" },
+ ["ů"]={ "u","̊" },
+ ["Ű"]={ "U","̋" },
+ ["ű"]={ "u","̋" },
+ ["Ų"]={ "U","̨" },
+ ["ų"]={ "u","̨" },
+ ["Ŵ"]={ "W","̂" },
+ ["ŵ"]={ "w","̂" },
+ ["Ŷ"]={ "Y","̂" },
+ ["ŷ"]={ "y","̂" },
+ ["Ÿ"]={ "Y","̈" },
+ ["Ź"]={ "Z","́" },
+ ["ź"]={ "z","́" },
+ ["Ż"]={ "Z","̇" },
+ ["ż"]={ "z","̇" },
+ ["Ž"]={ "Z","̌" },
+ ["ž"]={ "z","̌" },
+ ["Ơ"]={ "O","̛" },
+ ["ơ"]={ "o","̛" },
+ ["Ư"]={ "U","̛" },
+ ["ư"]={ "u","̛" },
+ ["Ǎ"]={ "A","̌" },
+ ["ǎ"]={ "a","̌" },
+ ["Ǐ"]={ "I","̌" },
+ ["ǐ"]={ "i","̌" },
+ ["Ǒ"]={ "O","̌" },
+ ["ǒ"]={ "o","̌" },
+ ["Ǔ"]={ "U","̌" },
+ ["ǔ"]={ "u","̌" },
+ ["Ǖ"]={ "Ü","̄" },
+ ["ǖ"]={ "ü","̄" },
+ ["Ǘ"]={ "Ü","́" },
+ ["ǘ"]={ "ü","́" },
+ ["Ǚ"]={ "Ü","̌" },
+ ["ǚ"]={ "ü","̌" },
+ ["Ǜ"]={ "Ü","̀" },
+ ["ǜ"]={ "ü","̀" },
+ ["Ǟ"]={ "Ä","̄" },
+ ["ǟ"]={ "ä","̄" },
+ ["Ǡ"]={ "Ȧ","̄" },
+ ["ǡ"]={ "ȧ","̄" },
+ ["Ǣ"]={ "Æ","̄" },
+ ["ǣ"]={ "æ","̄" },
+ ["Ǧ"]={ "G","̌" },
+ ["ǧ"]={ "g","̌" },
+ ["Ǩ"]={ "K","̌" },
+ ["ǩ"]={ "k","̌" },
+ ["Ǫ"]={ "O","̨" },
+ ["ǫ"]={ "o","̨" },
+ ["Ǭ"]={ "Ǫ","̄" },
+ ["ǭ"]={ "ǫ","̄" },
+ ["Ǯ"]={ "Ʒ","̌" },
+ ["ǯ"]={ "ʒ","̌" },
+ ["ǰ"]={ "j","̌" },
+ ["Ǵ"]={ "G","́" },
+ ["ǵ"]={ "g","́" },
+ ["Ǹ"]={ "N","̀" },
+ ["ǹ"]={ "n","̀" },
+ ["Ǻ"]={ "Å","́" },
+ ["ǻ"]={ "å","́" },
+ ["Ǽ"]={ "Æ","́" },
+ ["ǽ"]={ "æ","́" },
+ ["Ǿ"]={ "Ø","́" },
+ ["ǿ"]={ "ø","́" },
+ ["Ȁ"]={ "A","̏" },
+ ["ȁ"]={ "a","̏" },
+ ["Ȃ"]={ "A","̑" },
+ ["ȃ"]={ "a","̑" },
+ ["Ȅ"]={ "E","̏" },
+ ["ȅ"]={ "e","̏" },
+ ["Ȇ"]={ "E","̑" },
+ ["ȇ"]={ "e","̑" },
+ ["Ȉ"]={ "I","̏" },
+ ["ȉ"]={ "i","̏" },
+ ["Ȋ"]={ "I","̑" },
+ ["ȋ"]={ "i","̑" },
+ ["Ȍ"]={ "O","̏" },
+ ["ȍ"]={ "o","̏" },
+ ["Ȏ"]={ "O","̑" },
+ ["ȏ"]={ "o","̑" },
+ ["Ȑ"]={ "R","̏" },
+ ["ȑ"]={ "r","̏" },
+ ["Ȓ"]={ "R","̑" },
+ ["ȓ"]={ "r","̑" },
+ ["Ȕ"]={ "U","̏" },
+ ["ȕ"]={ "u","̏" },
+ ["Ȗ"]={ "U","̑" },
+ ["ȗ"]={ "u","̑" },
+ ["Ș"]={ "S","̦" },
+ ["ș"]={ "s","̦" },
+ ["Ț"]={ "T","̦" },
+ ["ț"]={ "t","̦" },
+ ["Ȟ"]={ "H","̌" },
+ ["ȟ"]={ "h","̌" },
+ ["Ȧ"]={ "A","̇" },
+ ["ȧ"]={ "a","̇" },
+ ["Ȩ"]={ "E","̧" },
+ ["ȩ"]={ "e","̧" },
+ ["Ȫ"]={ "Ö","̄" },
+ ["ȫ"]={ "ö","̄" },
+ ["Ȭ"]={ "Õ","̄" },
+ ["ȭ"]={ "õ","̄" },
+ ["Ȯ"]={ "O","̇" },
+ ["ȯ"]={ "o","̇" },
+ ["Ȱ"]={ "Ȯ","̄" },
+ ["ȱ"]={ "ȯ","̄" },
+ ["Ȳ"]={ "Y","̄" },
+ ["ȳ"]={ "y","̄" },
+ ["̈́"]={ "̈","́" },
+ ["΅"]={ "¨","́" },
+ ["Ά"]={ "Α","́" },
+ ["Έ"]={ "Ε","́" },
+ ["Ή"]={ "Η","́" },
+ ["Ί"]={ "Ι","́" },
+ ["Ό"]={ "Ο","́" },
+ ["Ύ"]={ "Υ","́" },
+ ["Ώ"]={ "Ω","́" },
+ ["ΐ"]={ "ϊ","́" },
+ ["Ϊ"]={ "Ι","̈" },
+ ["Ϋ"]={ "Υ","̈" },
+ ["ά"]={ "α","́" },
+ ["έ"]={ "ε","́" },
+ ["ή"]={ "η","́" },
+ ["ί"]={ "ι","́" },
+ ["ΰ"]={ "ϋ","́" },
+ ["ϊ"]={ "ι","̈" },
+ ["ϋ"]={ "υ","̈" },
+ ["ό"]={ "ο","́" },
+ ["ύ"]={ "υ","́" },
+ ["ώ"]={ "ω","́" },
+ ["ϓ"]={ "ϒ","́" },
+ ["ϔ"]={ "ϒ","̈" },
+ ["Ѐ"]={ "Е","̀" },
+ ["Ё"]={ "Е","̈" },
+ ["Ѓ"]={ "Г","́" },
+ ["Ї"]={ "І","̈" },
+ ["Ќ"]={ "К","́" },
+ ["Ѝ"]={ "И","̀" },
+ ["Ў"]={ "У","̆" },
+ ["Й"]={ "И","̆" },
+ ["й"]={ "и","̆" },
+ ["ѐ"]={ "е","̀" },
+ ["ё"]={ "е","̈" },
+ ["ѓ"]={ "г","́" },
+ ["ї"]={ "і","̈" },
+ ["ќ"]={ "к","́" },
+ ["ѝ"]={ "и","̀" },
+ ["ў"]={ "у","̆" },
+ ["Ѷ"]={ "Ѵ","̏" },
+ ["ѷ"]={ "ѵ","̏" },
+ ["Ӂ"]={ "Ж","̆" },
+ ["ӂ"]={ "ж","̆" },
+ ["Ӑ"]={ "А","̆" },
+ ["ӑ"]={ "а","̆" },
+ ["Ӓ"]={ "А","̈" },
+ ["ӓ"]={ "а","̈" },
+ ["Ӗ"]={ "Е","̆" },
+ ["ӗ"]={ "е","̆" },
+ ["Ӛ"]={ "Ә","̈" },
+ ["ӛ"]={ "ә","̈" },
+ ["Ӝ"]={ "Ж","̈" },
+ ["ӝ"]={ "ж","̈" },
+ ["Ӟ"]={ "З","̈" },
+ ["ӟ"]={ "з","̈" },
+ ["Ӣ"]={ "И","̄" },
+ ["ӣ"]={ "и","̄" },
+ ["Ӥ"]={ "И","̈" },
+ ["ӥ"]={ "и","̈" },
+ ["Ӧ"]={ "О","̈" },
+ ["ӧ"]={ "о","̈" },
+ ["Ӫ"]={ "Ө","̈" },
+ ["ӫ"]={ "ө","̈" },
+ ["Ӭ"]={ "Э","̈" },
+ ["ӭ"]={ "э","̈" },
+ ["Ӯ"]={ "У","̄" },
+ ["ӯ"]={ "у","̄" },
+ ["Ӱ"]={ "У","̈" },
+ ["ӱ"]={ "у","̈" },
+ ["Ӳ"]={ "У","̋" },
+ ["ӳ"]={ "у","̋" },
+ ["Ӵ"]={ "Ч","̈" },
+ ["ӵ"]={ "ч","̈" },
+ ["Ӹ"]={ "Ы","̈" },
+ ["ӹ"]={ "ы","̈" },
+ ["آ"]={ "ا","ٓ" },
+ ["أ"]={ "ا","ٔ" },
+ ["ؤ"]={ "و","ٔ" },
+ ["إ"]={ "ا","ٕ" },
+ ["ئ"]={ "ي","ٔ" },
+ ["ۀ"]={ "ە","ٔ" },
+ ["ۂ"]={ "ہ","ٔ" },
+ ["ۓ"]={ "ے","ٔ" },
+ ["ऩ"]={ "न","़" },
+ ["ऱ"]={ "र","़" },
+ ["ऴ"]={ "ळ","़" },
+ ["क़"]={ "क","़" },
+ ["ख़"]={ "ख","़" },
+ ["ग़"]={ "ग","़" },
+ ["ज़"]={ "ज","़" },
+ ["ड़"]={ "ड","़" },
+ ["ढ़"]={ "ढ","़" },
+ ["फ़"]={ "फ","़" },
+ ["य़"]={ "य","़" },
+ ["ো"]={ "ে","া" },
+ ["ৌ"]={ "ে","ৗ" },
+ ["ড়"]={ "ড","়" },
+ ["ঢ়"]={ "ঢ","়" },
+ ["য়"]={ "য","়" },
+ ["ਲ਼"]={ "ਲ","਼" },
+ ["ਸ਼"]={ "ਸ","਼" },
+ ["ਖ਼"]={ "ਖ","਼" },
+ ["ਗ਼"]={ "ਗ","਼" },
+ ["ਜ਼"]={ "ਜ","਼" },
+ ["ਫ਼"]={ "ਫ","਼" },
+ ["ୈ"]={ "େ","ୖ" },
+ ["ୋ"]={ "େ","ା" },
+ ["ୌ"]={ "େ","ୗ" },
+ ["ଡ଼"]={ "ଡ","଼" },
+ ["ଢ଼"]={ "ଢ","଼" },
+ ["ஔ"]={ "ஒ","ௗ" },
+ ["ொ"]={ "ெ","ா" },
+ ["ோ"]={ "ே","ா" },
+ ["ௌ"]={ "ெ","ௗ" },
+ ["ై"]={ "ె","ౖ" },
+ ["ೀ"]={ "ಿ","ೕ" },
+ ["ೇ"]={ "ೆ","ೕ" },
+ ["ೈ"]={ "ೆ","ೖ" },
+ ["ೊ"]={ "ೆ","ೂ" },
+ ["ೋ"]={ "ೊ","ೕ" },
+ ["ൊ"]={ "െ","ാ" },
+ ["ോ"]={ "േ","ാ" },
+ ["ൌ"]={ "െ","ൗ" },
+ ["ේ"]={ "ෙ","්" },
+ ["ො"]={ "ෙ","ා" },
+ ["ෝ"]={ "ො","්" },
+ ["ෞ"]={ "ෙ","ෟ" },
+ ["གྷ"]={ "ག","ྷ" },
+ ["ཌྷ"]={ "ཌ","ྷ" },
+ ["དྷ"]={ "ད","ྷ" },
+ ["བྷ"]={ "བ","ྷ" },
+ ["ཛྷ"]={ "ཛ","ྷ" },
+ ["ཀྵ"]={ "ཀ","ྵ" },
+ ["ཱི"]={ "ཱ","ི" },
+ ["ཱུ"]={ "ཱ","ུ" },
+ ["ྲྀ"]={ "ྲ","ྀ" },
+ ["ླྀ"]={ "ླ","ྀ" },
+ ["ཱྀ"]={ "ཱ","ྀ" },
+ ["ྒྷ"]={ "ྒ","ྷ" },
+ ["ྜྷ"]={ "ྜ","ྷ" },
+ ["ྡྷ"]={ "ྡ","ྷ" },
+ ["ྦྷ"]={ "ྦ","ྷ" },
+ ["ྫྷ"]={ "ྫ","ྷ" },
+ ["ྐྵ"]={ "ྐ","ྵ" },
+ ["ဦ"]={ "ဥ","ီ" },
+ ["ᬆ"]={ "ᬅ","ᬵ" },
+ ["ᬈ"]={ "ᬇ","ᬵ" },
+ ["ᬊ"]={ "ᬉ","ᬵ" },
+ ["ᬌ"]={ "ᬋ","ᬵ" },
+ ["ᬎ"]={ "ᬍ","ᬵ" },
+ ["ᬒ"]={ "ᬑ","ᬵ" },
+ ["ᬻ"]={ "ᬺ","ᬵ" },
+ ["ᬽ"]={ "ᬼ","ᬵ" },
+ ["ᭀ"]={ "ᬾ","ᬵ" },
+ ["ᭁ"]={ "ᬿ","ᬵ" },
+ ["ᭃ"]={ "ᭂ","ᬵ" },
+ ["Ḁ"]={ "A","̥" },
+ ["ḁ"]={ "a","̥" },
+ ["Ḃ"]={ "B","̇" },
+ ["ḃ"]={ "b","̇" },
+ ["Ḅ"]={ "B","̣" },
+ ["ḅ"]={ "b","̣" },
+ ["Ḇ"]={ "B","̱" },
+ ["ḇ"]={ "b","̱" },
+ ["Ḉ"]={ "Ç","́" },
+ ["ḉ"]={ "ç","́" },
+ ["Ḋ"]={ "D","̇" },
+ ["ḋ"]={ "d","̇" },
+ ["Ḍ"]={ "D","̣" },
+ ["ḍ"]={ "d","̣" },
+ ["Ḏ"]={ "D","̱" },
+ ["ḏ"]={ "d","̱" },
+ ["Ḑ"]={ "D","̧" },
+ ["ḑ"]={ "d","̧" },
+ ["Ḓ"]={ "D","̭" },
+ ["ḓ"]={ "d","̭" },
+ ["Ḕ"]={ "Ē","̀" },
+ ["ḕ"]={ "ē","̀" },
+ ["Ḗ"]={ "Ē","́" },
+ ["ḗ"]={ "ē","́" },
+ ["Ḙ"]={ "E","̭" },
+ ["ḙ"]={ "e","̭" },
+ ["Ḛ"]={ "E","̰" },
+ ["ḛ"]={ "e","̰" },
+ ["Ḝ"]={ "Ȩ","̆" },
+ ["ḝ"]={ "ȩ","̆" },
+ ["Ḟ"]={ "F","̇" },
+ ["ḟ"]={ "f","̇" },
+ ["Ḡ"]={ "G","̄" },
+ ["ḡ"]={ "g","̄" },
+ ["Ḣ"]={ "H","̇" },
+ ["ḣ"]={ "h","̇" },
+ ["Ḥ"]={ "H","̣" },
+ ["ḥ"]={ "h","̣" },
+ ["Ḧ"]={ "H","̈" },
+ ["ḧ"]={ "h","̈" },
+ ["Ḩ"]={ "H","̧" },
+ ["ḩ"]={ "h","̧" },
+ ["Ḫ"]={ "H","̮" },
+ ["ḫ"]={ "h","̮" },
+ ["Ḭ"]={ "I","̰" },
+ ["ḭ"]={ "i","̰" },
+ ["Ḯ"]={ "Ï","́" },
+ ["ḯ"]={ "ï","́" },
+ ["Ḱ"]={ "K","́" },
+ ["ḱ"]={ "k","́" },
+ ["Ḳ"]={ "K","̣" },
+ ["ḳ"]={ "k","̣" },
+ ["Ḵ"]={ "K","̱" },
+ ["ḵ"]={ "k","̱" },
+ ["Ḷ"]={ "L","̣" },
+ ["ḷ"]={ "l","̣" },
+ ["Ḹ"]={ "Ḷ","̄" },
+ ["ḹ"]={ "ḷ","̄" },
+ ["Ḻ"]={ "L","̱" },
+ ["ḻ"]={ "l","̱" },
+ ["Ḽ"]={ "L","̭" },
+ ["ḽ"]={ "l","̭" },
+ ["Ḿ"]={ "M","́" },
+ ["ḿ"]={ "m","́" },
+ ["Ṁ"]={ "M","̇" },
+ ["ṁ"]={ "m","̇" },
+ ["Ṃ"]={ "M","̣" },
+ ["ṃ"]={ "m","̣" },
+ ["Ṅ"]={ "N","̇" },
+ ["ṅ"]={ "n","̇" },
+ ["Ṇ"]={ "N","̣" },
+ ["ṇ"]={ "n","̣" },
+ ["Ṉ"]={ "N","̱" },
+ ["ṉ"]={ "n","̱" },
+ ["Ṋ"]={ "N","̭" },
+ ["ṋ"]={ "n","̭" },
+ ["Ṍ"]={ "Õ","́" },
+ ["ṍ"]={ "õ","́" },
+ ["Ṏ"]={ "Õ","̈" },
+ ["ṏ"]={ "õ","̈" },
+ ["Ṑ"]={ "Ō","̀" },
+ ["ṑ"]={ "ō","̀" },
+ ["Ṓ"]={ "Ō","́" },
+ ["ṓ"]={ "ō","́" },
+ ["Ṕ"]={ "P","́" },
+ ["ṕ"]={ "p","́" },
+ ["Ṗ"]={ "P","̇" },
+ ["ṗ"]={ "p","̇" },
+ ["Ṙ"]={ "R","̇" },
+ ["ṙ"]={ "r","̇" },
+ ["Ṛ"]={ "R","̣" },
+ ["ṛ"]={ "r","̣" },
+ ["Ṝ"]={ "Ṛ","̄" },
+ ["ṝ"]={ "ṛ","̄" },
+ ["Ṟ"]={ "R","̱" },
+ ["ṟ"]={ "r","̱" },
+ ["Ṡ"]={ "S","̇" },
+ ["ṡ"]={ "s","̇" },
+ ["Ṣ"]={ "S","̣" },
+ ["ṣ"]={ "s","̣" },
+ ["Ṥ"]={ "Ś","̇" },
+ ["ṥ"]={ "ś","̇" },
+ ["Ṧ"]={ "Š","̇" },
+ ["ṧ"]={ "š","̇" },
+ ["Ṩ"]={ "Ṣ","̇" },
+ ["ṩ"]={ "ṣ","̇" },
+ ["Ṫ"]={ "T","̇" },
+ ["ṫ"]={ "t","̇" },
+ ["Ṭ"]={ "T","̣" },
+ ["ṭ"]={ "t","̣" },
+ ["Ṯ"]={ "T","̱" },
+ ["ṯ"]={ "t","̱" },
+ ["Ṱ"]={ "T","̭" },
+ ["ṱ"]={ "t","̭" },
+ ["Ṳ"]={ "U","̤" },
+ ["ṳ"]={ "u","̤" },
+ ["Ṵ"]={ "U","̰" },
+ ["ṵ"]={ "u","̰" },
+ ["Ṷ"]={ "U","̭" },
+ ["ṷ"]={ "u","̭" },
+ ["Ṹ"]={ "Ũ","́" },
+ ["ṹ"]={ "ũ","́" },
+ ["Ṻ"]={ "Ū","̈" },
+ ["ṻ"]={ "ū","̈" },
+ ["Ṽ"]={ "V","̃" },
+ ["ṽ"]={ "v","̃" },
+ ["Ṿ"]={ "V","̣" },
+ ["ṿ"]={ "v","̣" },
+ ["Ẁ"]={ "W","̀" },
+ ["ẁ"]={ "w","̀" },
+ ["Ẃ"]={ "W","́" },
+ ["ẃ"]={ "w","́" },
+ ["Ẅ"]={ "W","̈" },
+ ["ẅ"]={ "w","̈" },
+ ["Ẇ"]={ "W","̇" },
+ ["ẇ"]={ "w","̇" },
+ ["Ẉ"]={ "W","̣" },
+ ["ẉ"]={ "w","̣" },
+ ["Ẋ"]={ "X","̇" },
+ ["ẋ"]={ "x","̇" },
+ ["Ẍ"]={ "X","̈" },
+ ["ẍ"]={ "x","̈" },
+ ["Ẏ"]={ "Y","̇" },
+ ["ẏ"]={ "y","̇" },
+ ["Ẑ"]={ "Z","̂" },
+ ["ẑ"]={ "z","̂" },
+ ["Ẓ"]={ "Z","̣" },
+ ["ẓ"]={ "z","̣" },
+ ["Ẕ"]={ "Z","̱" },
+ ["ẕ"]={ "z","̱" },
+ ["ẖ"]={ "h","̱" },
+ ["ẗ"]={ "t","̈" },
+ ["ẘ"]={ "w","̊" },
+ ["ẙ"]={ "y","̊" },
+ ["ẛ"]={ "ſ","̇" },
+ ["Ạ"]={ "A","̣" },
+ ["ạ"]={ "a","̣" },
+ ["Ả"]={ "A","̉" },
+ ["ả"]={ "a","̉" },
+ ["Ấ"]={ "Â","́" },
+ ["ấ"]={ "â","́" },
+ ["Ầ"]={ "Â","̀" },
+ ["ầ"]={ "â","̀" },
+ ["Ẩ"]={ "Â","̉" },
+ ["ẩ"]={ "â","̉" },
+ ["Ẫ"]={ "Â","̃" },
+ ["ẫ"]={ "â","̃" },
+ ["Ậ"]={ "Ạ","̂" },
+ ["ậ"]={ "ạ","̂" },
+ ["Ắ"]={ "Ă","́" },
+ ["ắ"]={ "ă","́" },
+ ["Ằ"]={ "Ă","̀" },
+ ["ằ"]={ "ă","̀" },
+ ["Ẳ"]={ "Ă","̉" },
+ ["ẳ"]={ "ă","̉" },
+ ["Ẵ"]={ "Ă","̃" },
+ ["ẵ"]={ "ă","̃" },
+ ["Ặ"]={ "Ạ","̆" },
+ ["ặ"]={ "ạ","̆" },
+ ["Ẹ"]={ "E","̣" },
+ ["ẹ"]={ "e","̣" },
+ ["Ẻ"]={ "E","̉" },
+ ["ẻ"]={ "e","̉" },
+ ["Ẽ"]={ "E","̃" },
+ ["ẽ"]={ "e","̃" },
+ ["Ế"]={ "Ê","́" },
+ ["ế"]={ "ê","́" },
+ ["Ề"]={ "Ê","̀" },
+ ["ề"]={ "ê","̀" },
+ ["Ể"]={ "Ê","̉" },
+ ["ể"]={ "ê","̉" },
+ ["Ễ"]={ "Ê","̃" },
+ ["ễ"]={ "ê","̃" },
+ ["Ệ"]={ "Ẹ","̂" },
+ ["ệ"]={ "ẹ","̂" },
+ ["Ỉ"]={ "I","̉" },
+ ["ỉ"]={ "i","̉" },
+ ["Ị"]={ "I","̣" },
+ ["ị"]={ "i","̣" },
+ ["Ọ"]={ "O","̣" },
+ ["ọ"]={ "o","̣" },
+ ["Ỏ"]={ "O","̉" },
+ ["ỏ"]={ "o","̉" },
+ ["Ố"]={ "Ô","́" },
+ ["ố"]={ "ô","́" },
+ ["Ồ"]={ "Ô","̀" },
+ ["ồ"]={ "ô","̀" },
+ ["Ổ"]={ "Ô","̉" },
+ ["ổ"]={ "ô","̉" },
+ ["Ỗ"]={ "Ô","̃" },
+ ["ỗ"]={ "ô","̃" },
+ ["Ộ"]={ "Ọ","̂" },
+ ["ộ"]={ "ọ","̂" },
+ ["Ớ"]={ "Ơ","́" },
+ ["ớ"]={ "ơ","́" },
+ ["Ờ"]={ "Ơ","̀" },
+ ["ờ"]={ "ơ","̀" },
+ ["Ở"]={ "Ơ","̉" },
+ ["ở"]={ "ơ","̉" },
+ ["Ỡ"]={ "Ơ","̃" },
+ ["ỡ"]={ "ơ","̃" },
+ ["Ợ"]={ "Ơ","̣" },
+ ["ợ"]={ "ơ","̣" },
+ ["Ụ"]={ "U","̣" },
+ ["ụ"]={ "u","̣" },
+ ["Ủ"]={ "U","̉" },
+ ["ủ"]={ "u","̉" },
+ ["Ứ"]={ "Ư","́" },
+ ["ứ"]={ "ư","́" },
+ ["Ừ"]={ "Ư","̀" },
+ ["ừ"]={ "ư","̀" },
+ ["Ử"]={ "Ư","̉" },
+ ["ử"]={ "ư","̉" },
+ ["Ữ"]={ "Ư","̃" },
+ ["ữ"]={ "ư","̃" },
+ ["Ự"]={ "Ư","̣" },
+ ["ự"]={ "ư","̣" },
+ ["Ỳ"]={ "Y","̀" },
+ ["ỳ"]={ "y","̀" },
+ ["Ỵ"]={ "Y","̣" },
+ ["ỵ"]={ "y","̣" },
+ ["Ỷ"]={ "Y","̉" },
+ ["ỷ"]={ "y","̉" },
+ ["Ỹ"]={ "Y","̃" },
+ ["ỹ"]={ "y","̃" },
+ ["ἀ"]={ "α","̓" },
+ ["ἁ"]={ "α","̔" },
+ ["ἂ"]={ "ἀ","̀" },
+ ["ἃ"]={ "ἁ","̀" },
+ ["ἄ"]={ "ἀ","́" },
+ ["ἅ"]={ "ἁ","́" },
+ ["ἆ"]={ "ἀ","͂" },
+ ["ἇ"]={ "ἁ","͂" },
+ ["Ἀ"]={ "Α","̓" },
+ ["Ἁ"]={ "Α","̔" },
+ ["Ἂ"]={ "Ἀ","̀" },
+ ["Ἃ"]={ "Ἁ","̀" },
+ ["Ἄ"]={ "Ἀ","́" },
+ ["Ἅ"]={ "Ἁ","́" },
+ ["Ἆ"]={ "Ἀ","͂" },
+ ["Ἇ"]={ "Ἁ","͂" },
+ ["ἐ"]={ "ε","̓" },
+ ["ἑ"]={ "ε","̔" },
+ ["ἒ"]={ "ἐ","̀" },
+ ["ἓ"]={ "ἑ","̀" },
+ ["ἔ"]={ "ἐ","́" },
+ ["ἕ"]={ "ἑ","́" },
+ ["Ἐ"]={ "Ε","̓" },
+ ["Ἑ"]={ "Ε","̔" },
+ ["Ἒ"]={ "Ἐ","̀" },
+ ["Ἓ"]={ "Ἑ","̀" },
+ ["Ἔ"]={ "Ἐ","́" },
+ ["Ἕ"]={ "Ἑ","́" },
+ ["ἠ"]={ "η","̓" },
+ ["ἡ"]={ "η","̔" },
+ ["ἢ"]={ "ἠ","̀" },
+ ["ἣ"]={ "ἡ","̀" },
+ ["ἤ"]={ "ἠ","́" },
+ ["ἥ"]={ "ἡ","́" },
+ ["ἦ"]={ "ἠ","͂" },
+ ["ἧ"]={ "ἡ","͂" },
+ ["Ἠ"]={ "Η","̓" },
+ ["Ἡ"]={ "Η","̔" },
+ ["Ἢ"]={ "Ἠ","̀" },
+ ["Ἣ"]={ "Ἡ","̀" },
+ ["Ἤ"]={ "Ἠ","́" },
+ ["Ἥ"]={ "Ἡ","́" },
+ ["Ἦ"]={ "Ἠ","͂" },
+ ["Ἧ"]={ "Ἡ","͂" },
+ ["ἰ"]={ "ι","̓" },
+ ["ἱ"]={ "ι","̔" },
+ ["ἲ"]={ "ἰ","̀" },
+ ["ἳ"]={ "ἱ","̀" },
+ ["ἴ"]={ "ἰ","́" },
+ ["ἵ"]={ "ἱ","́" },
+ ["ἶ"]={ "ἰ","͂" },
+ ["ἷ"]={ "ἱ","͂" },
+ ["Ἰ"]={ "Ι","̓" },
+ ["Ἱ"]={ "Ι","̔" },
+ ["Ἲ"]={ "Ἰ","̀" },
+ ["Ἳ"]={ "Ἱ","̀" },
+ ["Ἴ"]={ "Ἰ","́" },
+ ["Ἵ"]={ "Ἱ","́" },
+ ["Ἶ"]={ "Ἰ","͂" },
+ ["Ἷ"]={ "Ἱ","͂" },
+ ["ὀ"]={ "ο","̓" },
+ ["ὁ"]={ "ο","̔" },
+ ["ὂ"]={ "ὀ","̀" },
+ ["ὃ"]={ "ὁ","̀" },
+ ["ὄ"]={ "ὀ","́" },
+ ["ὅ"]={ "ὁ","́" },
+ ["Ὀ"]={ "Ο","̓" },
+ ["Ὁ"]={ "Ο","̔" },
+ ["Ὂ"]={ "Ὀ","̀" },
+ ["Ὃ"]={ "Ὁ","̀" },
+ ["Ὄ"]={ "Ὀ","́" },
+ ["Ὅ"]={ "Ὁ","́" },
+ ["ὐ"]={ "υ","̓" },
+ ["ὑ"]={ "υ","̔" },
+ ["ὒ"]={ "ὐ","̀" },
+ ["ὓ"]={ "ὑ","̀" },
+ ["ὔ"]={ "ὐ","́" },
+ ["ὕ"]={ "ὑ","́" },
+ ["ὖ"]={ "ὐ","͂" },
+ ["ὗ"]={ "ὑ","͂" },
+ ["Ὑ"]={ "Υ","̔" },
+ ["Ὓ"]={ "Ὑ","̀" },
+ ["Ὕ"]={ "Ὑ","́" },
+ ["Ὗ"]={ "Ὑ","͂" },
+ ["ὠ"]={ "ω","̓" },
+ ["ὡ"]={ "ω","̔" },
+ ["ὢ"]={ "ὠ","̀" },
+ ["ὣ"]={ "ὡ","̀" },
+ ["ὤ"]={ "ὠ","́" },
+ ["ὥ"]={ "ὡ","́" },
+ ["ὦ"]={ "ὠ","͂" },
+ ["ὧ"]={ "ὡ","͂" },
+ ["Ὠ"]={ "Ω","̓" },
+ ["Ὡ"]={ "Ω","̔" },
+ ["Ὢ"]={ "Ὠ","̀" },
+ ["Ὣ"]={ "Ὡ","̀" },
+ ["Ὤ"]={ "Ὠ","́" },
+ ["Ὥ"]={ "Ὡ","́" },
+ ["Ὦ"]={ "Ὠ","͂" },
+ ["Ὧ"]={ "Ὡ","͂" },
+ ["ὰ"]={ "α","̀" },
+ ["ὲ"]={ "ε","̀" },
+ ["ὴ"]={ "η","̀" },
+ ["ὶ"]={ "ι","̀" },
+ ["ὸ"]={ "ο","̀" },
+ ["ὺ"]={ "υ","̀" },
+ ["ὼ"]={ "ω","̀" },
+ ["ᾀ"]={ "ἀ","ͅ" },
+ ["ᾁ"]={ "ἁ","ͅ" },
+ ["ᾂ"]={ "ἂ","ͅ" },
+ ["ᾃ"]={ "ἃ","ͅ" },
+ ["ᾄ"]={ "ἄ","ͅ" },
+ ["ᾅ"]={ "ἅ","ͅ" },
+ ["ᾆ"]={ "ἆ","ͅ" },
+ ["ᾇ"]={ "ἇ","ͅ" },
+ ["ᾈ"]={ "Ἀ","ͅ" },
+ ["ᾉ"]={ "Ἁ","ͅ" },
+ ["ᾊ"]={ "Ἂ","ͅ" },
+ ["ᾋ"]={ "Ἃ","ͅ" },
+ ["ᾌ"]={ "Ἄ","ͅ" },
+ ["ᾍ"]={ "Ἅ","ͅ" },
+ ["ᾎ"]={ "Ἆ","ͅ" },
+ ["ᾏ"]={ "Ἇ","ͅ" },
+ ["ᾐ"]={ "ἠ","ͅ" },
+ ["ᾑ"]={ "ἡ","ͅ" },
+ ["ᾒ"]={ "ἢ","ͅ" },
+ ["ᾓ"]={ "ἣ","ͅ" },
+ ["ᾔ"]={ "ἤ","ͅ" },
+ ["ᾕ"]={ "ἥ","ͅ" },
+ ["ᾖ"]={ "ἦ","ͅ" },
+ ["ᾗ"]={ "ἧ","ͅ" },
+ ["ᾘ"]={ "Ἠ","ͅ" },
+ ["ᾙ"]={ "Ἡ","ͅ" },
+ ["ᾚ"]={ "Ἢ","ͅ" },
+ ["ᾛ"]={ "Ἣ","ͅ" },
+ ["ᾜ"]={ "Ἤ","ͅ" },
+ ["ᾝ"]={ "Ἥ","ͅ" },
+ ["ᾞ"]={ "Ἦ","ͅ" },
+ ["ᾟ"]={ "Ἧ","ͅ" },
+ ["ᾠ"]={ "ὠ","ͅ" },
+ ["ᾡ"]={ "ὡ","ͅ" },
+ ["ᾢ"]={ "ὢ","ͅ" },
+ ["ᾣ"]={ "ὣ","ͅ" },
+ ["ᾤ"]={ "ὤ","ͅ" },
+ ["ᾥ"]={ "ὥ","ͅ" },
+ ["ᾦ"]={ "ὦ","ͅ" },
+ ["ᾧ"]={ "ὧ","ͅ" },
+ ["ᾨ"]={ "Ὠ","ͅ" },
+ ["ᾩ"]={ "Ὡ","ͅ" },
+ ["ᾪ"]={ "Ὢ","ͅ" },
+ ["ᾫ"]={ "Ὣ","ͅ" },
+ ["ᾬ"]={ "Ὤ","ͅ" },
+ ["ᾭ"]={ "Ὥ","ͅ" },
+ ["ᾮ"]={ "Ὦ","ͅ" },
+ ["ᾯ"]={ "Ὧ","ͅ" },
+ ["ᾰ"]={ "α","̆" },
+ ["ᾱ"]={ "α","̄" },
+ ["ᾲ"]={ "ὰ","ͅ" },
+ ["ᾳ"]={ "α","ͅ" },
+ ["ᾴ"]={ "ά","ͅ" },
+ ["ᾶ"]={ "α","͂" },
+ ["ᾷ"]={ "ᾶ","ͅ" },
+ ["Ᾰ"]={ "Α","̆" },
+ ["Ᾱ"]={ "Α","̄" },
+ ["Ὰ"]={ "Α","̀" },
+ ["ᾼ"]={ "Α","ͅ" },
+ ["῁"]={ "¨","͂" },
+ ["ῂ"]={ "ὴ","ͅ" },
+ ["ῃ"]={ "η","ͅ" },
+ ["ῄ"]={ "ή","ͅ" },
+ ["ῆ"]={ "η","͂" },
+ ["ῇ"]={ "ῆ","ͅ" },
+ ["Ὲ"]={ "Ε","̀" },
+ ["Ὴ"]={ "Η","̀" },
+ ["ῌ"]={ "Η","ͅ" },
+ ["῍"]={ "᾿","̀" },
+ ["῎"]={ "᾿","́" },
+ ["῏"]={ "᾿","͂" },
+ ["ῐ"]={ "ι","̆" },
+ ["ῑ"]={ "ι","̄" },
+ ["ῒ"]={ "ϊ","̀" },
+ ["ῖ"]={ "ι","͂" },
+ ["ῗ"]={ "ϊ","͂" },
+ ["Ῐ"]={ "Ι","̆" },
+ ["Ῑ"]={ "Ι","̄" },
+ ["Ὶ"]={ "Ι","̀" },
+ ["῝"]={ "῾","̀" },
+ ["῞"]={ "῾","́" },
+ ["῟"]={ "῾","͂" },
+ ["ῠ"]={ "υ","̆" },
+ ["ῡ"]={ "υ","̄" },
+ ["ῢ"]={ "ϋ","̀" },
+ ["ῤ"]={ "ρ","̓" },
+ ["ῥ"]={ "ρ","̔" },
+ ["ῦ"]={ "υ","͂" },
+ ["ῧ"]={ "ϋ","͂" },
+ ["Ῠ"]={ "Υ","̆" },
+ ["Ῡ"]={ "Υ","̄" },
+ ["Ὺ"]={ "Υ","̀" },
+ ["Ῥ"]={ "Ρ","̔" },
+ ["῭"]={ "¨","̀" },
+ ["ῲ"]={ "ὼ","ͅ" },
+ ["ῳ"]={ "ω","ͅ" },
+ ["ῴ"]={ "ώ","ͅ" },
+ ["ῶ"]={ "ω","͂" },
+ ["ῷ"]={ "ῶ","ͅ" },
+ ["Ὸ"]={ "Ο","̀" },
+ ["Ὼ"]={ "Ω","̀" },
+ ["ῼ"]={ "Ω","ͅ" },
+ ["↚"]={ "←","̸" },
+ ["↛"]={ "→","̸" },
+ ["↮"]={ "↔","̸" },
+ ["⇍"]={ "⇐","̸" },
+ ["⇎"]={ "⇔","̸" },
+ ["⇏"]={ "⇒","̸" },
+ ["∄"]={ "∃","̸" },
+ ["∉"]={ "∈","̸" },
+ ["∌"]={ "∋","̸" },
+ ["∤"]={ "∣","̸" },
+ ["∦"]={ "∥","̸" },
+ ["≁"]={ "∼","̸" },
+ ["≄"]={ "≃","̸" },
+ ["≇"]={ "≅","̸" },
+ ["≉"]={ "≈","̸" },
+ ["≠"]={ "=","̸" },
+ ["≢"]={ "≡","̸" },
+ ["≭"]={ "≍","̸" },
+ ["≮"]={ "<","̸" },
+ ["≯"]={ ">","̸" },
+ ["≰"]={ "≤","̸" },
+ ["≱"]={ "≥","̸" },
+ ["≴"]={ "≲","̸" },
+ ["≵"]={ "≳","̸" },
+ ["≸"]={ "≶","̸" },
+ ["≹"]={ "≷","̸" },
+ ["⊀"]={ "≺","̸" },
+ ["⊁"]={ "≻","̸" },
+ ["⊄"]={ "⊂","̸" },
+ ["⊅"]={ "⊃","̸" },
+ ["⊈"]={ "⊆","̸" },
+ ["⊉"]={ "⊇","̸" },
+ ["⊬"]={ "⊢","̸" },
+ ["⊭"]={ "⊨","̸" },
+ ["⊮"]={ "⊩","̸" },
+ ["⊯"]={ "⊫","̸" },
+ ["⋠"]={ "≼","̸" },
+ ["⋡"]={ "≽","̸" },
+ ["⋢"]={ "⊑","̸" },
+ ["⋣"]={ "⊒","̸" },
+ ["⋪"]={ "⊲","̸" },
+ ["⋫"]={ "⊳","̸" },
+ ["⋬"]={ "⊴","̸" },
+ ["⋭"]={ "⊵","̸" },
+ ["⫝̸"]={ "⫝","̸" },
+ ["が"]={ "か","゙" },
+ ["ぎ"]={ "き","゙" },
+ ["ぐ"]={ "く","゙" },
+ ["げ"]={ "け","゙" },
+ ["ご"]={ "こ","゙" },
+ ["ざ"]={ "さ","゙" },
+ ["じ"]={ "し","゙" },
+ ["ず"]={ "す","゙" },
+ ["ぜ"]={ "せ","゙" },
+ ["ぞ"]={ "そ","゙" },
+ ["だ"]={ "た","゙" },
+ ["ぢ"]={ "ち","゙" },
+ ["づ"]={ "つ","゙" },
+ ["で"]={ "て","゙" },
+ ["ど"]={ "と","゙" },
+ ["ば"]={ "は","゙" },
+ ["ぱ"]={ "は","゚" },
+ ["び"]={ "ひ","゙" },
+ ["ぴ"]={ "ひ","゚" },
+ ["ぶ"]={ "ふ","゙" },
+ ["ぷ"]={ "ふ","゚" },
+ ["べ"]={ "へ","゙" },
+ ["ぺ"]={ "へ","゚" },
+ ["ぼ"]={ "ほ","゙" },
+ ["ぽ"]={ "ほ","゚" },
+ ["ゔ"]={ "う","゙" },
+ ["ゞ"]={ "ゝ","゙" },
+ ["ガ"]={ "カ","゙" },
+ ["ギ"]={ "キ","゙" },
+ ["グ"]={ "ク","゙" },
+ ["ゲ"]={ "ケ","゙" },
+ ["ゴ"]={ "コ","゙" },
+ ["ザ"]={ "サ","゙" },
+ ["ジ"]={ "シ","゙" },
+ ["ズ"]={ "ス","゙" },
+ ["ゼ"]={ "セ","゙" },
+ ["ゾ"]={ "ソ","゙" },
+ ["ダ"]={ "タ","゙" },
+ ["ヂ"]={ "チ","゙" },
+ ["ヅ"]={ "ツ","゙" },
+ ["デ"]={ "テ","゙" },
+ ["ド"]={ "ト","゙" },
+ ["バ"]={ "ハ","゙" },
+ ["パ"]={ "ハ","゚" },
+ ["ビ"]={ "ヒ","゙" },
+ ["ピ"]={ "ヒ","゚" },
+ ["ブ"]={ "フ","゙" },
+ ["プ"]={ "フ","゚" },
+ ["ベ"]={ "ヘ","゙" },
+ ["ペ"]={ "ヘ","゚" },
+ ["ボ"]={ "ホ","゙" },
+ ["ポ"]={ "ホ","゚" },
+ ["ヴ"]={ "ウ","゙" },
+ ["ヷ"]={ "ワ","゙" },
+ ["ヸ"]={ "ヰ","゙" },
+ ["ヹ"]={ "ヱ","゙" },
+ ["ヺ"]={ "ヲ","゙" },
+ ["ヾ"]={ "ヽ","゙" },
+ ["יִ"]={ "י","ִ" },
+ ["ײַ"]={ "ײ","ַ" },
+ ["שׁ"]={ "ש","ׁ" },
+ ["שׂ"]={ "ש","ׂ" },
+ ["שּׁ"]={ "שּ","ׁ" },
+ ["שּׂ"]={ "שּ","ׂ" },
+ ["אַ"]={ "א","ַ" },
+ ["אָ"]={ "א","ָ" },
+ ["אּ"]={ "א","ּ" },
+ ["בּ"]={ "ב","ּ" },
+ ["גּ"]={ "ג","ּ" },
+ ["דּ"]={ "ד","ּ" },
+ ["הּ"]={ "ה","ּ" },
+ ["וּ"]={ "ו","ּ" },
+ ["זּ"]={ "ז","ּ" },
+ ["טּ"]={ "ט","ּ" },
+ ["יּ"]={ "י","ּ" },
+ ["ךּ"]={ "ך","ּ" },
+ ["כּ"]={ "כ","ּ" },
+ ["לּ"]={ "ל","ּ" },
+ ["מּ"]={ "מ","ּ" },
+ ["נּ"]={ "נ","ּ" },
+ ["סּ"]={ "ס","ּ" },
+ ["ףּ"]={ "ף","ּ" },
+ ["פּ"]={ "פ","ּ" },
+ ["צּ"]={ "צ","ּ" },
+ ["קּ"]={ "ק","ּ" },
+ ["רּ"]={ "ר","ּ" },
+ ["שּ"]={ "ש","ּ" },
+ ["תּ"]={ "ת","ּ" },
+ ["וֹ"]={ "ו","ֹ" },
+ ["בֿ"]={ "ב","ֿ" },
+ ["כֿ"]={ "כ","ֿ" },
+ ["פֿ"]={ "פ","ֿ" },
+ ["𑂚"]={ "𑂙","𑂺" },
+ ["𑂜"]={ "𑂛","𑂺" },
+ ["𑂫"]={ "𑂥","𑂺" },
+ ["𑄮"]={ "𑄱","𑄧" },
+ ["𑄯"]={ "𑄲","𑄧" },
+ ["𑍋"]={ "𑍇","𑌾" },
+ ["𑍌"]={ "𑍇","𑍗" },
+ ["𑒻"]={ "𑒹","𑒺" },
+ ["𑒼"]={ "𑒹","𑒰" },
+ ["𑒾"]={ "𑒹","𑒽" },
+ ["𑖺"]={ "𑖸","𑖯" },
+ ["𑖻"]={ "𑖹","𑖯" },
+ ["𝅗𝅥"]={ "𝅗","𝅥" },
+ ["𝅘𝅥"]={ "𝅘","𝅥" },
+ ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" },
+ ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" },
+ ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" },
+ ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" },
+ ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" },
+ ["𝆹𝅥"]={ "𝆹","𝅥" },
+ ["𝆺𝅥"]={ "𝆺","𝅥" },
+ ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" },
+ ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" },
+ ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" },
+ ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" },
+ },
},
- },
- {
- ["data"]={
- ["À"]={ "A","̀" },
- ["Á"]={ "A","́" },
- ["Â"]={ "A","̂" },
- ["Ã"]={ "A","̃" },
- ["Ä"]={ "A","̈" },
- ["Å"]={ "A","̊" },
- ["Ç"]={ "C","̧" },
- ["È"]={ "E","̀" },
- ["É"]={ "E","́" },
- ["Ê"]={ "E","̂" },
- ["Ë"]={ "E","̈" },
- ["Ì"]={ "I","̀" },
- ["Í"]={ "I","́" },
- ["Î"]={ "I","̂" },
- ["Ï"]={ "I","̈" },
- ["Ñ"]={ "N","̃" },
- ["Ò"]={ "O","̀" },
- ["Ó"]={ "O","́" },
- ["Ô"]={ "O","̂" },
- ["Õ"]={ "O","̃" },
- ["Ö"]={ "O","̈" },
- ["Ù"]={ "U","̀" },
- ["Ú"]={ "U","́" },
- ["Û"]={ "U","̂" },
- ["Ü"]={ "U","̈" },
- ["Ý"]={ "Y","́" },
- ["à"]={ "a","̀" },
- ["á"]={ "a","́" },
- ["â"]={ "a","̂" },
- ["ã"]={ "a","̃" },
- ["ä"]={ "a","̈" },
- ["å"]={ "a","̊" },
- ["ç"]={ "c","̧" },
- ["è"]={ "e","̀" },
- ["é"]={ "e","́" },
- ["ê"]={ "e","̂" },
- ["ë"]={ "e","̈" },
- ["ì"]={ "i","̀" },
- ["í"]={ "i","́" },
- ["î"]={ "i","̂" },
- ["ï"]={ "i","̈" },
- ["ñ"]={ "n","̃" },
- ["ò"]={ "o","̀" },
- ["ó"]={ "o","́" },
- ["ô"]={ "o","̂" },
- ["õ"]={ "o","̃" },
- ["ö"]={ "o","̈" },
- ["ù"]={ "u","̀" },
- ["ú"]={ "u","́" },
- ["û"]={ "u","̂" },
- ["ü"]={ "u","̈" },
- ["ý"]={ "y","́" },
- ["ÿ"]={ "y","̈" },
- ["Ā"]={ "A","̄" },
- ["ā"]={ "a","̄" },
- ["Ă"]={ "A","̆" },
- ["ă"]={ "a","̆" },
- ["Ą"]={ "A","̨" },
- ["ą"]={ "a","̨" },
- ["Ć"]={ "C","́" },
- ["ć"]={ "c","́" },
- ["Ĉ"]={ "C","̂" },
- ["ĉ"]={ "c","̂" },
- ["Ċ"]={ "C","̇" },
- ["ċ"]={ "c","̇" },
- ["Č"]={ "C","̌" },
- ["č"]={ "c","̌" },
- ["Ď"]={ "D","̌" },
- ["ď"]={ "d","̌" },
- ["Ē"]={ "E","̄" },
- ["ē"]={ "e","̄" },
- ["Ĕ"]={ "E","̆" },
- ["ĕ"]={ "e","̆" },
- ["Ė"]={ "E","̇" },
- ["ė"]={ "e","̇" },
- ["Ę"]={ "E","̨" },
- ["ę"]={ "e","̨" },
- ["Ě"]={ "E","̌" },
- ["ě"]={ "e","̌" },
- ["Ĝ"]={ "G","̂" },
- ["ĝ"]={ "g","̂" },
- ["Ğ"]={ "G","̆" },
- ["ğ"]={ "g","̆" },
- ["Ġ"]={ "G","̇" },
- ["ġ"]={ "g","̇" },
- ["Ģ"]={ "G","̧" },
- ["ģ"]={ "g","̧" },
- ["Ĥ"]={ "H","̂" },
- ["ĥ"]={ "h","̂" },
- ["Ĩ"]={ "I","̃" },
- ["ĩ"]={ "i","̃" },
- ["Ī"]={ "I","̄" },
- ["ī"]={ "i","̄" },
- ["Ĭ"]={ "I","̆" },
- ["ĭ"]={ "i","̆" },
- ["Į"]={ "I","̨" },
- ["į"]={ "i","̨" },
- ["İ"]={ "I","̇" },
- ["Ĵ"]={ "J","̂" },
- ["ĵ"]={ "j","̂" },
- ["Ķ"]={ "K","̧" },
- ["ķ"]={ "k","̧" },
- ["Ĺ"]={ "L","́" },
- ["ĺ"]={ "l","́" },
- ["Ļ"]={ "L","̧" },
- ["ļ"]={ "l","̧" },
- ["Ľ"]={ "L","̌" },
- ["ľ"]={ "l","̌" },
- ["Ń"]={ "N","́" },
- ["ń"]={ "n","́" },
- ["Ņ"]={ "N","̧" },
- ["ņ"]={ "n","̧" },
- ["Ň"]={ "N","̌" },
- ["ň"]={ "n","̌" },
- ["Ō"]={ "O","̄" },
- ["ō"]={ "o","̄" },
- ["Ŏ"]={ "O","̆" },
- ["ŏ"]={ "o","̆" },
- ["Ő"]={ "O","̋" },
- ["ő"]={ "o","̋" },
- ["Ŕ"]={ "R","́" },
- ["ŕ"]={ "r","́" },
- ["Ŗ"]={ "R","̧" },
- ["ŗ"]={ "r","̧" },
- ["Ř"]={ "R","̌" },
- ["ř"]={ "r","̌" },
- ["Ś"]={ "S","́" },
- ["ś"]={ "s","́" },
- ["Ŝ"]={ "S","̂" },
- ["ŝ"]={ "s","̂" },
- ["Ş"]={ "S","̧" },
- ["ş"]={ "s","̧" },
- ["Š"]={ "S","̌" },
- ["š"]={ "s","̌" },
- ["Ţ"]={ "T","̧" },
- ["ţ"]={ "t","̧" },
- ["Ť"]={ "T","̌" },
- ["ť"]={ "t","̌" },
- ["Ũ"]={ "U","̃" },
- ["ũ"]={ "u","̃" },
- ["Ū"]={ "U","̄" },
- ["ū"]={ "u","̄" },
- ["Ŭ"]={ "U","̆" },
- ["ŭ"]={ "u","̆" },
- ["Ů"]={ "U","̊" },
- ["ů"]={ "u","̊" },
- ["Ű"]={ "U","̋" },
- ["ű"]={ "u","̋" },
- ["Ų"]={ "U","̨" },
- ["ų"]={ "u","̨" },
- ["Ŵ"]={ "W","̂" },
- ["ŵ"]={ "w","̂" },
- ["Ŷ"]={ "Y","̂" },
- ["ŷ"]={ "y","̂" },
- ["Ÿ"]={ "Y","̈" },
- ["Ź"]={ "Z","́" },
- ["ź"]={ "z","́" },
- ["Ż"]={ "Z","̇" },
- ["ż"]={ "z","̇" },
- ["Ž"]={ "Z","̌" },
- ["ž"]={ "z","̌" },
- ["Ơ"]={ "O","̛" },
- ["ơ"]={ "o","̛" },
- ["Ư"]={ "U","̛" },
- ["ư"]={ "u","̛" },
- ["Ǎ"]={ "A","̌" },
- ["ǎ"]={ "a","̌" },
- ["Ǐ"]={ "I","̌" },
- ["ǐ"]={ "i","̌" },
- ["Ǒ"]={ "O","̌" },
- ["ǒ"]={ "o","̌" },
- ["Ǔ"]={ "U","̌" },
- ["ǔ"]={ "u","̌" },
- ["Ǖ"]={ "Ü","̄" },
- ["ǖ"]={ "ü","̄" },
- ["Ǘ"]={ "Ü","́" },
- ["ǘ"]={ "ü","́" },
- ["Ǚ"]={ "Ü","̌" },
- ["ǚ"]={ "ü","̌" },
- ["Ǜ"]={ "Ü","̀" },
- ["ǜ"]={ "ü","̀" },
- ["Ǟ"]={ "Ä","̄" },
- ["ǟ"]={ "ä","̄" },
- ["Ǡ"]={ "Ȧ","̄" },
- ["ǡ"]={ "ȧ","̄" },
- ["Ǣ"]={ "Æ","̄" },
- ["ǣ"]={ "æ","̄" },
- ["Ǧ"]={ "G","̌" },
- ["ǧ"]={ "g","̌" },
- ["Ǩ"]={ "K","̌" },
- ["ǩ"]={ "k","̌" },
- ["Ǫ"]={ "O","̨" },
- ["ǫ"]={ "o","̨" },
- ["Ǭ"]={ "Ǫ","̄" },
- ["ǭ"]={ "ǫ","̄" },
- ["Ǯ"]={ "Ʒ","̌" },
- ["ǯ"]={ "ʒ","̌" },
- ["ǰ"]={ "j","̌" },
- ["Ǵ"]={ "G","́" },
- ["ǵ"]={ "g","́" },
- ["Ǹ"]={ "N","̀" },
- ["ǹ"]={ "n","̀" },
- ["Ǻ"]={ "Å","́" },
- ["ǻ"]={ "å","́" },
- ["Ǽ"]={ "Æ","́" },
- ["ǽ"]={ "æ","́" },
- ["Ǿ"]={ "Ø","́" },
- ["ǿ"]={ "ø","́" },
- ["Ȁ"]={ "A","̏" },
- ["ȁ"]={ "a","̏" },
- ["Ȃ"]={ "A","̑" },
- ["ȃ"]={ "a","̑" },
- ["Ȅ"]={ "E","̏" },
- ["ȅ"]={ "e","̏" },
- ["Ȇ"]={ "E","̑" },
- ["ȇ"]={ "e","̑" },
- ["Ȉ"]={ "I","̏" },
- ["ȉ"]={ "i","̏" },
- ["Ȋ"]={ "I","̑" },
- ["ȋ"]={ "i","̑" },
- ["Ȍ"]={ "O","̏" },
- ["ȍ"]={ "o","̏" },
- ["Ȏ"]={ "O","̑" },
- ["ȏ"]={ "o","̑" },
- ["Ȑ"]={ "R","̏" },
- ["ȑ"]={ "r","̏" },
- ["Ȓ"]={ "R","̑" },
- ["ȓ"]={ "r","̑" },
- ["Ȕ"]={ "U","̏" },
- ["ȕ"]={ "u","̏" },
- ["Ȗ"]={ "U","̑" },
- ["ȗ"]={ "u","̑" },
- ["Ș"]={ "S","̦" },
- ["ș"]={ "s","̦" },
- ["Ț"]={ "T","̦" },
- ["ț"]={ "t","̦" },
- ["Ȟ"]={ "H","̌" },
- ["ȟ"]={ "h","̌" },
- ["Ȧ"]={ "A","̇" },
- ["ȧ"]={ "a","̇" },
- ["Ȩ"]={ "E","̧" },
- ["ȩ"]={ "e","̧" },
- ["Ȫ"]={ "Ö","̄" },
- ["ȫ"]={ "ö","̄" },
- ["Ȭ"]={ "Õ","̄" },
- ["ȭ"]={ "õ","̄" },
- ["Ȯ"]={ "O","̇" },
- ["ȯ"]={ "o","̇" },
- ["Ȱ"]={ "Ȯ","̄" },
- ["ȱ"]={ "ȯ","̄" },
- ["Ȳ"]={ "Y","̄" },
- ["ȳ"]={ "y","̄" },
- ["̈́"]={ "̈","́" },
- ["΅"]={ "¨","́" },
- ["Ά"]={ "Α","́" },
- ["Έ"]={ "Ε","́" },
- ["Ή"]={ "Η","́" },
- ["Ί"]={ "Ι","́" },
- ["Ό"]={ "Ο","́" },
- ["Ύ"]={ "Υ","́" },
- ["Ώ"]={ "Ω","́" },
- ["ΐ"]={ "ϊ","́" },
- ["Ϊ"]={ "Ι","̈" },
- ["Ϋ"]={ "Υ","̈" },
- ["ά"]={ "α","́" },
- ["έ"]={ "ε","́" },
- ["ή"]={ "η","́" },
- ["ί"]={ "ι","́" },
- ["ΰ"]={ "ϋ","́" },
- ["ϊ"]={ "ι","̈" },
- ["ϋ"]={ "υ","̈" },
- ["ό"]={ "ο","́" },
- ["ύ"]={ "υ","́" },
- ["ώ"]={ "ω","́" },
- ["ϓ"]={ "ϒ","́" },
- ["ϔ"]={ "ϒ","̈" },
- ["Ѐ"]={ "Е","̀" },
- ["Ё"]={ "Е","̈" },
- ["Ѓ"]={ "Г","́" },
- ["Ї"]={ "І","̈" },
- ["Ќ"]={ "К","́" },
- ["Ѝ"]={ "И","̀" },
- ["Ў"]={ "У","̆" },
- ["Й"]={ "И","̆" },
- ["й"]={ "и","̆" },
- ["ѐ"]={ "е","̀" },
- ["ё"]={ "е","̈" },
- ["ѓ"]={ "г","́" },
- ["ї"]={ "і","̈" },
- ["ќ"]={ "к","́" },
- ["ѝ"]={ "и","̀" },
- ["ў"]={ "у","̆" },
- ["Ѷ"]={ "Ѵ","̏" },
- ["ѷ"]={ "ѵ","̏" },
- ["Ӂ"]={ "Ж","̆" },
- ["ӂ"]={ "ж","̆" },
- ["Ӑ"]={ "А","̆" },
- ["ӑ"]={ "а","̆" },
- ["Ӓ"]={ "А","̈" },
- ["ӓ"]={ "а","̈" },
- ["Ӗ"]={ "Е","̆" },
- ["ӗ"]={ "е","̆" },
- ["Ӛ"]={ "Ә","̈" },
- ["ӛ"]={ "ә","̈" },
- ["Ӝ"]={ "Ж","̈" },
- ["ӝ"]={ "ж","̈" },
- ["Ӟ"]={ "З","̈" },
- ["ӟ"]={ "з","̈" },
- ["Ӣ"]={ "И","̄" },
- ["ӣ"]={ "и","̄" },
- ["Ӥ"]={ "И","̈" },
- ["ӥ"]={ "и","̈" },
- ["Ӧ"]={ "О","̈" },
- ["ӧ"]={ "о","̈" },
- ["Ӫ"]={ "Ө","̈" },
- ["ӫ"]={ "ө","̈" },
- ["Ӭ"]={ "Э","̈" },
- ["ӭ"]={ "э","̈" },
- ["Ӯ"]={ "У","̄" },
- ["ӯ"]={ "у","̄" },
- ["Ӱ"]={ "У","̈" },
- ["ӱ"]={ "у","̈" },
- ["Ӳ"]={ "У","̋" },
- ["ӳ"]={ "у","̋" },
- ["Ӵ"]={ "Ч","̈" },
- ["ӵ"]={ "ч","̈" },
- ["Ӹ"]={ "Ы","̈" },
- ["ӹ"]={ "ы","̈" },
- ["آ"]={ "ا","ٓ" },
- ["أ"]={ "ا","ٔ" },
- ["ؤ"]={ "و","ٔ" },
- ["إ"]={ "ا","ٕ" },
- ["ئ"]={ "ي","ٔ" },
- ["ۀ"]={ "ە","ٔ" },
- ["ۂ"]={ "ہ","ٔ" },
- ["ۓ"]={ "ے","ٔ" },
- ["ऩ"]={ "न","़" },
- ["ऱ"]={ "र","़" },
- ["ऴ"]={ "ळ","़" },
- ["क़"]={ "क","़" },
- ["ख़"]={ "ख","़" },
- ["ग़"]={ "ग","़" },
- ["ज़"]={ "ज","़" },
- ["ड़"]={ "ड","़" },
- ["ढ़"]={ "ढ","़" },
- ["फ़"]={ "फ","़" },
- ["य़"]={ "य","़" },
- ["ো"]={ "ে","া" },
- ["ৌ"]={ "ে","ৗ" },
- ["ড়"]={ "ড","়" },
- ["ঢ়"]={ "ঢ","়" },
- ["য়"]={ "য","়" },
- ["ਲ਼"]={ "ਲ","਼" },
- ["ਸ਼"]={ "ਸ","਼" },
- ["ਖ਼"]={ "ਖ","਼" },
- ["ਗ਼"]={ "ਗ","਼" },
- ["ਜ਼"]={ "ਜ","਼" },
- ["ਫ਼"]={ "ਫ","਼" },
- ["ୈ"]={ "େ","ୖ" },
- ["ୋ"]={ "େ","ା" },
- ["ୌ"]={ "େ","ୗ" },
- ["ଡ଼"]={ "ଡ","଼" },
- ["ଢ଼"]={ "ଢ","଼" },
- ["ஔ"]={ "ஒ","ௗ" },
- ["ொ"]={ "ெ","ா" },
- ["ோ"]={ "ே","ா" },
- ["ௌ"]={ "ெ","ௗ" },
- ["ై"]={ "ె","ౖ" },
- ["ೀ"]={ "ಿ","ೕ" },
- ["ೇ"]={ "ೆ","ೕ" },
- ["ೈ"]={ "ೆ","ೖ" },
- ["ೊ"]={ "ೆ","ೂ" },
- ["ೋ"]={ "ೊ","ೕ" },
- ["ൊ"]={ "െ","ാ" },
- ["ോ"]={ "േ","ാ" },
- ["ൌ"]={ "െ","ൗ" },
- ["ේ"]={ "ෙ","්" },
- ["ො"]={ "ෙ","ා" },
- ["ෝ"]={ "ො","්" },
- ["ෞ"]={ "ෙ","ෟ" },
- ["གྷ"]={ "ག","ྷ" },
- ["ཌྷ"]={ "ཌ","ྷ" },
- ["དྷ"]={ "ད","ྷ" },
- ["བྷ"]={ "བ","ྷ" },
- ["ཛྷ"]={ "ཛ","ྷ" },
- ["ཀྵ"]={ "ཀ","ྵ" },
- ["ཱི"]={ "ཱ","ི" },
- ["ཱུ"]={ "ཱ","ུ" },
- ["ྲྀ"]={ "ྲ","ྀ" },
- ["ླྀ"]={ "ླ","ྀ" },
- ["ཱྀ"]={ "ཱ","ྀ" },
- ["ྒྷ"]={ "ྒ","ྷ" },
- ["ྜྷ"]={ "ྜ","ྷ" },
- ["ྡྷ"]={ "ྡ","ྷ" },
- ["ྦྷ"]={ "ྦ","ྷ" },
- ["ྫྷ"]={ "ྫ","ྷ" },
- ["ྐྵ"]={ "ྐ","ྵ" },
- ["ဦ"]={ "ဥ","ီ" },
- ["ᬆ"]={ "ᬅ","ᬵ" },
- ["ᬈ"]={ "ᬇ","ᬵ" },
- ["ᬊ"]={ "ᬉ","ᬵ" },
- ["ᬌ"]={ "ᬋ","ᬵ" },
- ["ᬎ"]={ "ᬍ","ᬵ" },
- ["ᬒ"]={ "ᬑ","ᬵ" },
- ["ᬻ"]={ "ᬺ","ᬵ" },
- ["ᬽ"]={ "ᬼ","ᬵ" },
- ["ᭀ"]={ "ᬾ","ᬵ" },
- ["ᭁ"]={ "ᬿ","ᬵ" },
- ["ᭃ"]={ "ᭂ","ᬵ" },
- ["Ḁ"]={ "A","̥" },
- ["ḁ"]={ "a","̥" },
- ["Ḃ"]={ "B","̇" },
- ["ḃ"]={ "b","̇" },
- ["Ḅ"]={ "B","̣" },
- ["ḅ"]={ "b","̣" },
- ["Ḇ"]={ "B","̱" },
- ["ḇ"]={ "b","̱" },
- ["Ḉ"]={ "Ç","́" },
- ["ḉ"]={ "ç","́" },
- ["Ḋ"]={ "D","̇" },
- ["ḋ"]={ "d","̇" },
- ["Ḍ"]={ "D","̣" },
- ["ḍ"]={ "d","̣" },
- ["Ḏ"]={ "D","̱" },
- ["ḏ"]={ "d","̱" },
- ["Ḑ"]={ "D","̧" },
- ["ḑ"]={ "d","̧" },
- ["Ḓ"]={ "D","̭" },
- ["ḓ"]={ "d","̭" },
- ["Ḕ"]={ "Ē","̀" },
- ["ḕ"]={ "ē","̀" },
- ["Ḗ"]={ "Ē","́" },
- ["ḗ"]={ "ē","́" },
- ["Ḙ"]={ "E","̭" },
- ["ḙ"]={ "e","̭" },
- ["Ḛ"]={ "E","̰" },
- ["ḛ"]={ "e","̰" },
- ["Ḝ"]={ "Ȩ","̆" },
- ["ḝ"]={ "ȩ","̆" },
- ["Ḟ"]={ "F","̇" },
- ["ḟ"]={ "f","̇" },
- ["Ḡ"]={ "G","̄" },
- ["ḡ"]={ "g","̄" },
- ["Ḣ"]={ "H","̇" },
- ["ḣ"]={ "h","̇" },
- ["Ḥ"]={ "H","̣" },
- ["ḥ"]={ "h","̣" },
- ["Ḧ"]={ "H","̈" },
- ["ḧ"]={ "h","̈" },
- ["Ḩ"]={ "H","̧" },
- ["ḩ"]={ "h","̧" },
- ["Ḫ"]={ "H","̮" },
- ["ḫ"]={ "h","̮" },
- ["Ḭ"]={ "I","̰" },
- ["ḭ"]={ "i","̰" },
- ["Ḯ"]={ "Ï","́" },
- ["ḯ"]={ "ï","́" },
- ["Ḱ"]={ "K","́" },
- ["ḱ"]={ "k","́" },
- ["Ḳ"]={ "K","̣" },
- ["ḳ"]={ "k","̣" },
- ["Ḵ"]={ "K","̱" },
- ["ḵ"]={ "k","̱" },
- ["Ḷ"]={ "L","̣" },
- ["ḷ"]={ "l","̣" },
- ["Ḹ"]={ "Ḷ","̄" },
- ["ḹ"]={ "ḷ","̄" },
- ["Ḻ"]={ "L","̱" },
- ["ḻ"]={ "l","̱" },
- ["Ḽ"]={ "L","̭" },
- ["ḽ"]={ "l","̭" },
- ["Ḿ"]={ "M","́" },
- ["ḿ"]={ "m","́" },
- ["Ṁ"]={ "M","̇" },
- ["ṁ"]={ "m","̇" },
- ["Ṃ"]={ "M","̣" },
- ["ṃ"]={ "m","̣" },
- ["Ṅ"]={ "N","̇" },
- ["ṅ"]={ "n","̇" },
- ["Ṇ"]={ "N","̣" },
- ["ṇ"]={ "n","̣" },
- ["Ṉ"]={ "N","̱" },
- ["ṉ"]={ "n","̱" },
- ["Ṋ"]={ "N","̭" },
- ["ṋ"]={ "n","̭" },
- ["Ṍ"]={ "Õ","́" },
- ["ṍ"]={ "õ","́" },
- ["Ṏ"]={ "Õ","̈" },
- ["ṏ"]={ "õ","̈" },
- ["Ṑ"]={ "Ō","̀" },
- ["ṑ"]={ "ō","̀" },
- ["Ṓ"]={ "Ō","́" },
- ["ṓ"]={ "ō","́" },
- ["Ṕ"]={ "P","́" },
- ["ṕ"]={ "p","́" },
- ["Ṗ"]={ "P","̇" },
- ["ṗ"]={ "p","̇" },
- ["Ṙ"]={ "R","̇" },
- ["ṙ"]={ "r","̇" },
- ["Ṛ"]={ "R","̣" },
- ["ṛ"]={ "r","̣" },
- ["Ṝ"]={ "Ṛ","̄" },
- ["ṝ"]={ "ṛ","̄" },
- ["Ṟ"]={ "R","̱" },
- ["ṟ"]={ "r","̱" },
- ["Ṡ"]={ "S","̇" },
- ["ṡ"]={ "s","̇" },
- ["Ṣ"]={ "S","̣" },
- ["ṣ"]={ "s","̣" },
- ["Ṥ"]={ "Ś","̇" },
- ["ṥ"]={ "ś","̇" },
- ["Ṧ"]={ "Š","̇" },
- ["ṧ"]={ "š","̇" },
- ["Ṩ"]={ "Ṣ","̇" },
- ["ṩ"]={ "ṣ","̇" },
- ["Ṫ"]={ "T","̇" },
- ["ṫ"]={ "t","̇" },
- ["Ṭ"]={ "T","̣" },
- ["ṭ"]={ "t","̣" },
- ["Ṯ"]={ "T","̱" },
- ["ṯ"]={ "t","̱" },
- ["Ṱ"]={ "T","̭" },
- ["ṱ"]={ "t","̭" },
- ["Ṳ"]={ "U","̤" },
- ["ṳ"]={ "u","̤" },
- ["Ṵ"]={ "U","̰" },
- ["ṵ"]={ "u","̰" },
- ["Ṷ"]={ "U","̭" },
- ["ṷ"]={ "u","̭" },
- ["Ṹ"]={ "Ũ","́" },
- ["ṹ"]={ "ũ","́" },
- ["Ṻ"]={ "Ū","̈" },
- ["ṻ"]={ "ū","̈" },
- ["Ṽ"]={ "V","̃" },
- ["ṽ"]={ "v","̃" },
- ["Ṿ"]={ "V","̣" },
- ["ṿ"]={ "v","̣" },
- ["Ẁ"]={ "W","̀" },
- ["ẁ"]={ "w","̀" },
- ["Ẃ"]={ "W","́" },
- ["ẃ"]={ "w","́" },
- ["Ẅ"]={ "W","̈" },
- ["ẅ"]={ "w","̈" },
- ["Ẇ"]={ "W","̇" },
- ["ẇ"]={ "w","̇" },
- ["Ẉ"]={ "W","̣" },
- ["ẉ"]={ "w","̣" },
- ["Ẋ"]={ "X","̇" },
- ["ẋ"]={ "x","̇" },
- ["Ẍ"]={ "X","̈" },
- ["ẍ"]={ "x","̈" },
- ["Ẏ"]={ "Y","̇" },
- ["ẏ"]={ "y","̇" },
- ["Ẑ"]={ "Z","̂" },
- ["ẑ"]={ "z","̂" },
- ["Ẓ"]={ "Z","̣" },
- ["ẓ"]={ "z","̣" },
- ["Ẕ"]={ "Z","̱" },
- ["ẕ"]={ "z","̱" },
- ["ẖ"]={ "h","̱" },
- ["ẗ"]={ "t","̈" },
- ["ẘ"]={ "w","̊" },
- ["ẙ"]={ "y","̊" },
- ["ẛ"]={ "ſ","̇" },
- ["Ạ"]={ "A","̣" },
- ["ạ"]={ "a","̣" },
- ["Ả"]={ "A","̉" },
- ["ả"]={ "a","̉" },
- ["Ấ"]={ "Â","́" },
- ["ấ"]={ "â","́" },
- ["Ầ"]={ "Â","̀" },
- ["ầ"]={ "â","̀" },
- ["Ẩ"]={ "Â","̉" },
- ["ẩ"]={ "â","̉" },
- ["Ẫ"]={ "Â","̃" },
- ["ẫ"]={ "â","̃" },
- ["Ậ"]={ "Ạ","̂" },
- ["ậ"]={ "ạ","̂" },
- ["Ắ"]={ "Ă","́" },
- ["ắ"]={ "ă","́" },
- ["Ằ"]={ "Ă","̀" },
- ["ằ"]={ "ă","̀" },
- ["Ẳ"]={ "Ă","̉" },
- ["ẳ"]={ "ă","̉" },
- ["Ẵ"]={ "Ă","̃" },
- ["ẵ"]={ "ă","̃" },
- ["Ặ"]={ "Ạ","̆" },
- ["ặ"]={ "ạ","̆" },
- ["Ẹ"]={ "E","̣" },
- ["ẹ"]={ "e","̣" },
- ["Ẻ"]={ "E","̉" },
- ["ẻ"]={ "e","̉" },
- ["Ẽ"]={ "E","̃" },
- ["ẽ"]={ "e","̃" },
- ["Ế"]={ "Ê","́" },
- ["ế"]={ "ê","́" },
- ["Ề"]={ "Ê","̀" },
- ["ề"]={ "ê","̀" },
- ["Ể"]={ "Ê","̉" },
- ["ể"]={ "ê","̉" },
- ["Ễ"]={ "Ê","̃" },
- ["ễ"]={ "ê","̃" },
- ["Ệ"]={ "Ẹ","̂" },
- ["ệ"]={ "ẹ","̂" },
- ["Ỉ"]={ "I","̉" },
- ["ỉ"]={ "i","̉" },
- ["Ị"]={ "I","̣" },
- ["ị"]={ "i","̣" },
- ["Ọ"]={ "O","̣" },
- ["ọ"]={ "o","̣" },
- ["Ỏ"]={ "O","̉" },
- ["ỏ"]={ "o","̉" },
- ["Ố"]={ "Ô","́" },
- ["ố"]={ "ô","́" },
- ["Ồ"]={ "Ô","̀" },
- ["ồ"]={ "ô","̀" },
- ["Ổ"]={ "Ô","̉" },
- ["ổ"]={ "ô","̉" },
- ["Ỗ"]={ "Ô","̃" },
- ["ỗ"]={ "ô","̃" },
- ["Ộ"]={ "Ọ","̂" },
- ["ộ"]={ "ọ","̂" },
- ["Ớ"]={ "Ơ","́" },
- ["ớ"]={ "ơ","́" },
- ["Ờ"]={ "Ơ","̀" },
- ["ờ"]={ "ơ","̀" },
- ["Ở"]={ "Ơ","̉" },
- ["ở"]={ "ơ","̉" },
- ["Ỡ"]={ "Ơ","̃" },
- ["ỡ"]={ "ơ","̃" },
- ["Ợ"]={ "Ơ","̣" },
- ["ợ"]={ "ơ","̣" },
- ["Ụ"]={ "U","̣" },
- ["ụ"]={ "u","̣" },
- ["Ủ"]={ "U","̉" },
- ["ủ"]={ "u","̉" },
- ["Ứ"]={ "Ư","́" },
- ["ứ"]={ "ư","́" },
- ["Ừ"]={ "Ư","̀" },
- ["ừ"]={ "ư","̀" },
- ["Ử"]={ "Ư","̉" },
- ["ử"]={ "ư","̉" },
- ["Ữ"]={ "Ư","̃" },
- ["ữ"]={ "ư","̃" },
- ["Ự"]={ "Ư","̣" },
- ["ự"]={ "ư","̣" },
- ["Ỳ"]={ "Y","̀" },
- ["ỳ"]={ "y","̀" },
- ["Ỵ"]={ "Y","̣" },
- ["ỵ"]={ "y","̣" },
- ["Ỷ"]={ "Y","̉" },
- ["ỷ"]={ "y","̉" },
- ["Ỹ"]={ "Y","̃" },
- ["ỹ"]={ "y","̃" },
- ["ἀ"]={ "α","̓" },
- ["ἁ"]={ "α","̔" },
- ["ἂ"]={ "ἀ","̀" },
- ["ἃ"]={ "ἁ","̀" },
- ["ἄ"]={ "ἀ","́" },
- ["ἅ"]={ "ἁ","́" },
- ["ἆ"]={ "ἀ","͂" },
- ["ἇ"]={ "ἁ","͂" },
- ["Ἀ"]={ "Α","̓" },
- ["Ἁ"]={ "Α","̔" },
- ["Ἂ"]={ "Ἀ","̀" },
- ["Ἃ"]={ "Ἁ","̀" },
- ["Ἄ"]={ "Ἀ","́" },
- ["Ἅ"]={ "Ἁ","́" },
- ["Ἆ"]={ "Ἀ","͂" },
- ["Ἇ"]={ "Ἁ","͂" },
- ["ἐ"]={ "ε","̓" },
- ["ἑ"]={ "ε","̔" },
- ["ἒ"]={ "ἐ","̀" },
- ["ἓ"]={ "ἑ","̀" },
- ["ἔ"]={ "ἐ","́" },
- ["ἕ"]={ "ἑ","́" },
- ["Ἐ"]={ "Ε","̓" },
- ["Ἑ"]={ "Ε","̔" },
- ["Ἒ"]={ "Ἐ","̀" },
- ["Ἓ"]={ "Ἑ","̀" },
- ["Ἔ"]={ "Ἐ","́" },
- ["Ἕ"]={ "Ἑ","́" },
- ["ἠ"]={ "η","̓" },
- ["ἡ"]={ "η","̔" },
- ["ἢ"]={ "ἠ","̀" },
- ["ἣ"]={ "ἡ","̀" },
- ["ἤ"]={ "ἠ","́" },
- ["ἥ"]={ "ἡ","́" },
- ["ἦ"]={ "ἠ","͂" },
- ["ἧ"]={ "ἡ","͂" },
- ["Ἠ"]={ "Η","̓" },
- ["Ἡ"]={ "Η","̔" },
- ["Ἢ"]={ "Ἠ","̀" },
- ["Ἣ"]={ "Ἡ","̀" },
- ["Ἤ"]={ "Ἠ","́" },
- ["Ἥ"]={ "Ἡ","́" },
- ["Ἦ"]={ "Ἠ","͂" },
- ["Ἧ"]={ "Ἡ","͂" },
- ["ἰ"]={ "ι","̓" },
- ["ἱ"]={ "ι","̔" },
- ["ἲ"]={ "ἰ","̀" },
- ["ἳ"]={ "ἱ","̀" },
- ["ἴ"]={ "ἰ","́" },
- ["ἵ"]={ "ἱ","́" },
- ["ἶ"]={ "ἰ","͂" },
- ["ἷ"]={ "ἱ","͂" },
- ["Ἰ"]={ "Ι","̓" },
- ["Ἱ"]={ "Ι","̔" },
- ["Ἲ"]={ "Ἰ","̀" },
- ["Ἳ"]={ "Ἱ","̀" },
- ["Ἴ"]={ "Ἰ","́" },
- ["Ἵ"]={ "Ἱ","́" },
- ["Ἶ"]={ "Ἰ","͂" },
- ["Ἷ"]={ "Ἱ","͂" },
- ["ὀ"]={ "ο","̓" },
- ["ὁ"]={ "ο","̔" },
- ["ὂ"]={ "ὀ","̀" },
- ["ὃ"]={ "ὁ","̀" },
- ["ὄ"]={ "ὀ","́" },
- ["ὅ"]={ "ὁ","́" },
- ["Ὀ"]={ "Ο","̓" },
- ["Ὁ"]={ "Ο","̔" },
- ["Ὂ"]={ "Ὀ","̀" },
- ["Ὃ"]={ "Ὁ","̀" },
- ["Ὄ"]={ "Ὀ","́" },
- ["Ὅ"]={ "Ὁ","́" },
- ["ὐ"]={ "υ","̓" },
- ["ὑ"]={ "υ","̔" },
- ["ὒ"]={ "ὐ","̀" },
- ["ὓ"]={ "ὑ","̀" },
- ["ὔ"]={ "ὐ","́" },
- ["ὕ"]={ "ὑ","́" },
- ["ὖ"]={ "ὐ","͂" },
- ["ὗ"]={ "ὑ","͂" },
- ["Ὑ"]={ "Υ","̔" },
- ["Ὓ"]={ "Ὑ","̀" },
- ["Ὕ"]={ "Ὑ","́" },
- ["Ὗ"]={ "Ὑ","͂" },
- ["ὠ"]={ "ω","̓" },
- ["ὡ"]={ "ω","̔" },
- ["ὢ"]={ "ὠ","̀" },
- ["ὣ"]={ "ὡ","̀" },
- ["ὤ"]={ "ὠ","́" },
- ["ὥ"]={ "ὡ","́" },
- ["ὦ"]={ "ὠ","͂" },
- ["ὧ"]={ "ὡ","͂" },
- ["Ὠ"]={ "Ω","̓" },
- ["Ὡ"]={ "Ω","̔" },
- ["Ὢ"]={ "Ὠ","̀" },
- ["Ὣ"]={ "Ὡ","̀" },
- ["Ὤ"]={ "Ὠ","́" },
- ["Ὥ"]={ "Ὡ","́" },
- ["Ὦ"]={ "Ὠ","͂" },
- ["Ὧ"]={ "Ὡ","͂" },
- ["ὰ"]={ "α","̀" },
- ["ὲ"]={ "ε","̀" },
- ["ὴ"]={ "η","̀" },
- ["ὶ"]={ "ι","̀" },
- ["ὸ"]={ "ο","̀" },
- ["ὺ"]={ "υ","̀" },
- ["ὼ"]={ "ω","̀" },
- ["ᾀ"]={ "ἀ","ͅ" },
- ["ᾁ"]={ "ἁ","ͅ" },
- ["ᾂ"]={ "ἂ","ͅ" },
- ["ᾃ"]={ "ἃ","ͅ" },
- ["ᾄ"]={ "ἄ","ͅ" },
- ["ᾅ"]={ "ἅ","ͅ" },
- ["ᾆ"]={ "ἆ","ͅ" },
- ["ᾇ"]={ "ἇ","ͅ" },
- ["ᾈ"]={ "Ἀ","ͅ" },
- ["ᾉ"]={ "Ἁ","ͅ" },
- ["ᾊ"]={ "Ἂ","ͅ" },
- ["ᾋ"]={ "Ἃ","ͅ" },
- ["ᾌ"]={ "Ἄ","ͅ" },
- ["ᾍ"]={ "Ἅ","ͅ" },
- ["ᾎ"]={ "Ἆ","ͅ" },
- ["ᾏ"]={ "Ἇ","ͅ" },
- ["ᾐ"]={ "ἠ","ͅ" },
- ["ᾑ"]={ "ἡ","ͅ" },
- ["ᾒ"]={ "ἢ","ͅ" },
- ["ᾓ"]={ "ἣ","ͅ" },
- ["ᾔ"]={ "ἤ","ͅ" },
- ["ᾕ"]={ "ἥ","ͅ" },
- ["ᾖ"]={ "ἦ","ͅ" },
- ["ᾗ"]={ "ἧ","ͅ" },
- ["ᾘ"]={ "Ἠ","ͅ" },
- ["ᾙ"]={ "Ἡ","ͅ" },
- ["ᾚ"]={ "Ἢ","ͅ" },
- ["ᾛ"]={ "Ἣ","ͅ" },
- ["ᾜ"]={ "Ἤ","ͅ" },
- ["ᾝ"]={ "Ἥ","ͅ" },
- ["ᾞ"]={ "Ἦ","ͅ" },
- ["ᾟ"]={ "Ἧ","ͅ" },
- ["ᾠ"]={ "ὠ","ͅ" },
- ["ᾡ"]={ "ὡ","ͅ" },
- ["ᾢ"]={ "ὢ","ͅ" },
- ["ᾣ"]={ "ὣ","ͅ" },
- ["ᾤ"]={ "ὤ","ͅ" },
- ["ᾥ"]={ "ὥ","ͅ" },
- ["ᾦ"]={ "ὦ","ͅ" },
- ["ᾧ"]={ "ὧ","ͅ" },
- ["ᾨ"]={ "Ὠ","ͅ" },
- ["ᾩ"]={ "Ὡ","ͅ" },
- ["ᾪ"]={ "Ὢ","ͅ" },
- ["ᾫ"]={ "Ὣ","ͅ" },
- ["ᾬ"]={ "Ὤ","ͅ" },
- ["ᾭ"]={ "Ὥ","ͅ" },
- ["ᾮ"]={ "Ὦ","ͅ" },
- ["ᾯ"]={ "Ὧ","ͅ" },
- ["ᾰ"]={ "α","̆" },
- ["ᾱ"]={ "α","̄" },
- ["ᾲ"]={ "ὰ","ͅ" },
- ["ᾳ"]={ "α","ͅ" },
- ["ᾴ"]={ "ά","ͅ" },
- ["ᾶ"]={ "α","͂" },
- ["ᾷ"]={ "ᾶ","ͅ" },
- ["Ᾰ"]={ "Α","̆" },
- ["Ᾱ"]={ "Α","̄" },
- ["Ὰ"]={ "Α","̀" },
- ["ᾼ"]={ "Α","ͅ" },
- ["῁"]={ "¨","͂" },
- ["ῂ"]={ "ὴ","ͅ" },
- ["ῃ"]={ "η","ͅ" },
- ["ῄ"]={ "ή","ͅ" },
- ["ῆ"]={ "η","͂" },
- ["ῇ"]={ "ῆ","ͅ" },
- ["Ὲ"]={ "Ε","̀" },
- ["Ὴ"]={ "Η","̀" },
- ["ῌ"]={ "Η","ͅ" },
- ["῍"]={ "᾿","̀" },
- ["῎"]={ "᾿","́" },
- ["῏"]={ "᾿","͂" },
- ["ῐ"]={ "ι","̆" },
- ["ῑ"]={ "ι","̄" },
- ["ῒ"]={ "ϊ","̀" },
- ["ῖ"]={ "ι","͂" },
- ["ῗ"]={ "ϊ","͂" },
- ["Ῐ"]={ "Ι","̆" },
- ["Ῑ"]={ "Ι","̄" },
- ["Ὶ"]={ "Ι","̀" },
- ["῝"]={ "῾","̀" },
- ["῞"]={ "῾","́" },
- ["῟"]={ "῾","͂" },
- ["ῠ"]={ "υ","̆" },
- ["ῡ"]={ "υ","̄" },
- ["ῢ"]={ "ϋ","̀" },
- ["ῤ"]={ "ρ","̓" },
- ["ῥ"]={ "ρ","̔" },
- ["ῦ"]={ "υ","͂" },
- ["ῧ"]={ "ϋ","͂" },
- ["Ῠ"]={ "Υ","̆" },
- ["Ῡ"]={ "Υ","̄" },
- ["Ὺ"]={ "Υ","̀" },
- ["Ῥ"]={ "Ρ","̔" },
- ["῭"]={ "¨","̀" },
- ["ῲ"]={ "ὼ","ͅ" },
- ["ῳ"]={ "ω","ͅ" },
- ["ῴ"]={ "ώ","ͅ" },
- ["ῶ"]={ "ω","͂" },
- ["ῷ"]={ "ῶ","ͅ" },
- ["Ὸ"]={ "Ο","̀" },
- ["Ὼ"]={ "Ω","̀" },
- ["ῼ"]={ "Ω","ͅ" },
- ["↚"]={ "←","̸" },
- ["↛"]={ "→","̸" },
- ["↮"]={ "↔","̸" },
- ["⇍"]={ "⇐","̸" },
- ["⇎"]={ "⇔","̸" },
- ["⇏"]={ "⇒","̸" },
- ["∄"]={ "∃","̸" },
- ["∉"]={ "∈","̸" },
- ["∌"]={ "∋","̸" },
- ["∤"]={ "∣","̸" },
- ["∦"]={ "∥","̸" },
- ["≁"]={ "∼","̸" },
- ["≄"]={ "≃","̸" },
- ["≇"]={ "≅","̸" },
- ["≉"]={ "≈","̸" },
- ["≠"]={ "=","̸" },
- ["≢"]={ "≡","̸" },
- ["≭"]={ "≍","̸" },
- ["≮"]={ "<","̸" },
- ["≯"]={ ">","̸" },
- ["≰"]={ "≤","̸" },
- ["≱"]={ "≥","̸" },
- ["≴"]={ "≲","̸" },
- ["≵"]={ "≳","̸" },
- ["≸"]={ "≶","̸" },
- ["≹"]={ "≷","̸" },
- ["⊀"]={ "≺","̸" },
- ["⊁"]={ "≻","̸" },
- ["⊄"]={ "⊂","̸" },
- ["⊅"]={ "⊃","̸" },
- ["⊈"]={ "⊆","̸" },
- ["⊉"]={ "⊇","̸" },
- ["⊬"]={ "⊢","̸" },
- ["⊭"]={ "⊨","̸" },
- ["⊮"]={ "⊩","̸" },
- ["⊯"]={ "⊫","̸" },
- ["⋠"]={ "≼","̸" },
- ["⋡"]={ "≽","̸" },
- ["⋢"]={ "⊑","̸" },
- ["⋣"]={ "⊒","̸" },
- ["⋪"]={ "⊲","̸" },
- ["⋫"]={ "⊳","̸" },
- ["⋬"]={ "⊴","̸" },
- ["⋭"]={ "⊵","̸" },
- ["⫝̸"]={ "⫝","̸" },
- ["が"]={ "か","゙" },
- ["ぎ"]={ "き","゙" },
- ["ぐ"]={ "く","゙" },
- ["げ"]={ "け","゙" },
- ["ご"]={ "こ","゙" },
- ["ざ"]={ "さ","゙" },
- ["じ"]={ "し","゙" },
- ["ず"]={ "す","゙" },
- ["ぜ"]={ "せ","゙" },
- ["ぞ"]={ "そ","゙" },
- ["だ"]={ "た","゙" },
- ["ぢ"]={ "ち","゙" },
- ["づ"]={ "つ","゙" },
- ["で"]={ "て","゙" },
- ["ど"]={ "と","゙" },
- ["ば"]={ "は","゙" },
- ["ぱ"]={ "は","゚" },
- ["び"]={ "ひ","゙" },
- ["ぴ"]={ "ひ","゚" },
- ["ぶ"]={ "ふ","゙" },
- ["ぷ"]={ "ふ","゚" },
- ["べ"]={ "へ","゙" },
- ["ぺ"]={ "へ","゚" },
- ["ぼ"]={ "ほ","゙" },
- ["ぽ"]={ "ほ","゚" },
- ["ゔ"]={ "う","゙" },
- ["ゞ"]={ "ゝ","゙" },
- ["ガ"]={ "カ","゙" },
- ["ギ"]={ "キ","゙" },
- ["グ"]={ "ク","゙" },
- ["ゲ"]={ "ケ","゙" },
- ["ゴ"]={ "コ","゙" },
- ["ザ"]={ "サ","゙" },
- ["ジ"]={ "シ","゙" },
- ["ズ"]={ "ス","゙" },
- ["ゼ"]={ "セ","゙" },
- ["ゾ"]={ "ソ","゙" },
- ["ダ"]={ "タ","゙" },
- ["ヂ"]={ "チ","゙" },
- ["ヅ"]={ "ツ","゙" },
- ["デ"]={ "テ","゙" },
- ["ド"]={ "ト","゙" },
- ["バ"]={ "ハ","゙" },
- ["パ"]={ "ハ","゚" },
- ["ビ"]={ "ヒ","゙" },
- ["ピ"]={ "ヒ","゚" },
- ["ブ"]={ "フ","゙" },
- ["プ"]={ "フ","゚" },
- ["ベ"]={ "ヘ","゙" },
- ["ペ"]={ "ヘ","゚" },
- ["ボ"]={ "ホ","゙" },
- ["ポ"]={ "ホ","゚" },
- ["ヴ"]={ "ウ","゙" },
- ["ヷ"]={ "ワ","゙" },
- ["ヸ"]={ "ヰ","゙" },
- ["ヹ"]={ "ヱ","゙" },
- ["ヺ"]={ "ヲ","゙" },
- ["ヾ"]={ "ヽ","゙" },
- ["יִ"]={ "י","ִ" },
- ["ײַ"]={ "ײ","ַ" },
- ["שׁ"]={ "ש","ׁ" },
- ["שׂ"]={ "ש","ׂ" },
- ["שּׁ"]={ "שּ","ׁ" },
- ["שּׂ"]={ "שּ","ׂ" },
- ["אַ"]={ "א","ַ" },
- ["אָ"]={ "א","ָ" },
- ["אּ"]={ "א","ּ" },
- ["בּ"]={ "ב","ּ" },
- ["גּ"]={ "ג","ּ" },
- ["דּ"]={ "ד","ּ" },
- ["הּ"]={ "ה","ּ" },
- ["וּ"]={ "ו","ּ" },
- ["זּ"]={ "ז","ּ" },
- ["טּ"]={ "ט","ּ" },
- ["יּ"]={ "י","ּ" },
- ["ךּ"]={ "ך","ּ" },
- ["כּ"]={ "כ","ּ" },
- ["לּ"]={ "ל","ּ" },
- ["מּ"]={ "מ","ּ" },
- ["נּ"]={ "נ","ּ" },
- ["סּ"]={ "ס","ּ" },
- ["ףּ"]={ "ף","ּ" },
- ["פּ"]={ "פ","ּ" },
- ["צּ"]={ "צ","ּ" },
- ["קּ"]={ "ק","ּ" },
- ["רּ"]={ "ר","ּ" },
- ["שּ"]={ "ש","ּ" },
- ["תּ"]={ "ת","ּ" },
- ["וֹ"]={ "ו","ֹ" },
- ["בֿ"]={ "ב","ֿ" },
- ["כֿ"]={ "כ","ֿ" },
- ["פֿ"]={ "פ","ֿ" },
- ["𑂚"]={ "𑂙","𑂺" },
- ["𑂜"]={ "𑂛","𑂺" },
- ["𑂫"]={ "𑂥","𑂺" },
- ["𑄮"]={ "𑄱","𑄧" },
- ["𑄯"]={ "𑄲","𑄧" },
- ["𑍋"]={ "𑍇","𑌾" },
- ["𑍌"]={ "𑍇","𑍗" },
- ["𑒻"]={ "𑒹","𑒺" },
- ["𑒼"]={ "𑒹","𑒰" },
- ["𑒾"]={ "𑒹","𑒽" },
- ["𑖺"]={ "𑖸","𑖯" },
- ["𑖻"]={ "𑖹","𑖯" },
- ["𝅗𝅥"]={ "𝅗","𝅥" },
- ["𝅘𝅥"]={ "𝅘","𝅥" },
- ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" },
- ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" },
- ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" },
- ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" },
- ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" },
- ["𝆹𝅥"]={ "𝆹","𝅥" },
- ["𝆺𝅥"]={ "𝆺","𝅥" },
- ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" },
- ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" },
- ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" },
- ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" },
+ {
+ ["data"]={
+ ["À"]={ "A","̀" },
+ ["Á"]={ "A","́" },
+ ["Â"]={ "A","̂" },
+ ["Ã"]={ "A","̃" },
+ ["Ä"]={ "A","̈" },
+ ["Å"]={ "A","̊" },
+ ["Ç"]={ "C","̧" },
+ ["È"]={ "E","̀" },
+ ["É"]={ "E","́" },
+ ["Ê"]={ "E","̂" },
+ ["Ë"]={ "E","̈" },
+ ["Ì"]={ "I","̀" },
+ ["Í"]={ "I","́" },
+ ["Î"]={ "I","̂" },
+ ["Ï"]={ "I","̈" },
+ ["Ñ"]={ "N","̃" },
+ ["Ò"]={ "O","̀" },
+ ["Ó"]={ "O","́" },
+ ["Ô"]={ "O","̂" },
+ ["Õ"]={ "O","̃" },
+ ["Ö"]={ "O","̈" },
+ ["Ù"]={ "U","̀" },
+ ["Ú"]={ "U","́" },
+ ["Û"]={ "U","̂" },
+ ["Ü"]={ "U","̈" },
+ ["Ý"]={ "Y","́" },
+ ["à"]={ "a","̀" },
+ ["á"]={ "a","́" },
+ ["â"]={ "a","̂" },
+ ["ã"]={ "a","̃" },
+ ["ä"]={ "a","̈" },
+ ["å"]={ "a","̊" },
+ ["ç"]={ "c","̧" },
+ ["è"]={ "e","̀" },
+ ["é"]={ "e","́" },
+ ["ê"]={ "e","̂" },
+ ["ë"]={ "e","̈" },
+ ["ì"]={ "i","̀" },
+ ["í"]={ "i","́" },
+ ["î"]={ "i","̂" },
+ ["ï"]={ "i","̈" },
+ ["ñ"]={ "n","̃" },
+ ["ò"]={ "o","̀" },
+ ["ó"]={ "o","́" },
+ ["ô"]={ "o","̂" },
+ ["õ"]={ "o","̃" },
+ ["ö"]={ "o","̈" },
+ ["ù"]={ "u","̀" },
+ ["ú"]={ "u","́" },
+ ["û"]={ "u","̂" },
+ ["ü"]={ "u","̈" },
+ ["ý"]={ "y","́" },
+ ["ÿ"]={ "y","̈" },
+ ["Ā"]={ "A","̄" },
+ ["ā"]={ "a","̄" },
+ ["Ă"]={ "A","̆" },
+ ["ă"]={ "a","̆" },
+ ["Ą"]={ "A","̨" },
+ ["ą"]={ "a","̨" },
+ ["Ć"]={ "C","́" },
+ ["ć"]={ "c","́" },
+ ["Ĉ"]={ "C","̂" },
+ ["ĉ"]={ "c","̂" },
+ ["Ċ"]={ "C","̇" },
+ ["ċ"]={ "c","̇" },
+ ["Č"]={ "C","̌" },
+ ["č"]={ "c","̌" },
+ ["Ď"]={ "D","̌" },
+ ["ď"]={ "d","̌" },
+ ["Ē"]={ "E","̄" },
+ ["ē"]={ "e","̄" },
+ ["Ĕ"]={ "E","̆" },
+ ["ĕ"]={ "e","̆" },
+ ["Ė"]={ "E","̇" },
+ ["ė"]={ "e","̇" },
+ ["Ę"]={ "E","̨" },
+ ["ę"]={ "e","̨" },
+ ["Ě"]={ "E","̌" },
+ ["ě"]={ "e","̌" },
+ ["Ĝ"]={ "G","̂" },
+ ["ĝ"]={ "g","̂" },
+ ["Ğ"]={ "G","̆" },
+ ["ğ"]={ "g","̆" },
+ ["Ġ"]={ "G","̇" },
+ ["ġ"]={ "g","̇" },
+ ["Ģ"]={ "G","̧" },
+ ["ģ"]={ "g","̧" },
+ ["Ĥ"]={ "H","̂" },
+ ["ĥ"]={ "h","̂" },
+ ["Ĩ"]={ "I","̃" },
+ ["ĩ"]={ "i","̃" },
+ ["Ī"]={ "I","̄" },
+ ["ī"]={ "i","̄" },
+ ["Ĭ"]={ "I","̆" },
+ ["ĭ"]={ "i","̆" },
+ ["Į"]={ "I","̨" },
+ ["į"]={ "i","̨" },
+ ["İ"]={ "I","̇" },
+ ["Ĵ"]={ "J","̂" },
+ ["ĵ"]={ "j","̂" },
+ ["Ķ"]={ "K","̧" },
+ ["ķ"]={ "k","̧" },
+ ["Ĺ"]={ "L","́" },
+ ["ĺ"]={ "l","́" },
+ ["Ļ"]={ "L","̧" },
+ ["ļ"]={ "l","̧" },
+ ["Ľ"]={ "L","̌" },
+ ["ľ"]={ "l","̌" },
+ ["Ń"]={ "N","́" },
+ ["ń"]={ "n","́" },
+ ["Ņ"]={ "N","̧" },
+ ["ņ"]={ "n","̧" },
+ ["Ň"]={ "N","̌" },
+ ["ň"]={ "n","̌" },
+ ["Ō"]={ "O","̄" },
+ ["ō"]={ "o","̄" },
+ ["Ŏ"]={ "O","̆" },
+ ["ŏ"]={ "o","̆" },
+ ["Ő"]={ "O","̋" },
+ ["ő"]={ "o","̋" },
+ ["Ŕ"]={ "R","́" },
+ ["ŕ"]={ "r","́" },
+ ["Ŗ"]={ "R","̧" },
+ ["ŗ"]={ "r","̧" },
+ ["Ř"]={ "R","̌" },
+ ["ř"]={ "r","̌" },
+ ["Ś"]={ "S","́" },
+ ["ś"]={ "s","́" },
+ ["Ŝ"]={ "S","̂" },
+ ["ŝ"]={ "s","̂" },
+ ["Ş"]={ "S","̧" },
+ ["ş"]={ "s","̧" },
+ ["Š"]={ "S","̌" },
+ ["š"]={ "s","̌" },
+ ["Ţ"]={ "T","̧" },
+ ["ţ"]={ "t","̧" },
+ ["Ť"]={ "T","̌" },
+ ["ť"]={ "t","̌" },
+ ["Ũ"]={ "U","̃" },
+ ["ũ"]={ "u","̃" },
+ ["Ū"]={ "U","̄" },
+ ["ū"]={ "u","̄" },
+ ["Ŭ"]={ "U","̆" },
+ ["ŭ"]={ "u","̆" },
+ ["Ů"]={ "U","̊" },
+ ["ů"]={ "u","̊" },
+ ["Ű"]={ "U","̋" },
+ ["ű"]={ "u","̋" },
+ ["Ų"]={ "U","̨" },
+ ["ų"]={ "u","̨" },
+ ["Ŵ"]={ "W","̂" },
+ ["ŵ"]={ "w","̂" },
+ ["Ŷ"]={ "Y","̂" },
+ ["ŷ"]={ "y","̂" },
+ ["Ÿ"]={ "Y","̈" },
+ ["Ź"]={ "Z","́" },
+ ["ź"]={ "z","́" },
+ ["Ż"]={ "Z","̇" },
+ ["ż"]={ "z","̇" },
+ ["Ž"]={ "Z","̌" },
+ ["ž"]={ "z","̌" },
+ ["Ơ"]={ "O","̛" },
+ ["ơ"]={ "o","̛" },
+ ["Ư"]={ "U","̛" },
+ ["ư"]={ "u","̛" },
+ ["Ǎ"]={ "A","̌" },
+ ["ǎ"]={ "a","̌" },
+ ["Ǐ"]={ "I","̌" },
+ ["ǐ"]={ "i","̌" },
+ ["Ǒ"]={ "O","̌" },
+ ["ǒ"]={ "o","̌" },
+ ["Ǔ"]={ "U","̌" },
+ ["ǔ"]={ "u","̌" },
+ ["Ǖ"]={ "Ü","̄" },
+ ["ǖ"]={ "ü","̄" },
+ ["Ǘ"]={ "Ü","́" },
+ ["ǘ"]={ "ü","́" },
+ ["Ǚ"]={ "Ü","̌" },
+ ["ǚ"]={ "ü","̌" },
+ ["Ǜ"]={ "Ü","̀" },
+ ["ǜ"]={ "ü","̀" },
+ ["Ǟ"]={ "Ä","̄" },
+ ["ǟ"]={ "ä","̄" },
+ ["Ǡ"]={ "Ȧ","̄" },
+ ["ǡ"]={ "ȧ","̄" },
+ ["Ǣ"]={ "Æ","̄" },
+ ["ǣ"]={ "æ","̄" },
+ ["Ǧ"]={ "G","̌" },
+ ["ǧ"]={ "g","̌" },
+ ["Ǩ"]={ "K","̌" },
+ ["ǩ"]={ "k","̌" },
+ ["Ǫ"]={ "O","̨" },
+ ["ǫ"]={ "o","̨" },
+ ["Ǭ"]={ "Ǫ","̄" },
+ ["ǭ"]={ "ǫ","̄" },
+ ["Ǯ"]={ "Ʒ","̌" },
+ ["ǯ"]={ "ʒ","̌" },
+ ["ǰ"]={ "j","̌" },
+ ["Ǵ"]={ "G","́" },
+ ["ǵ"]={ "g","́" },
+ ["Ǹ"]={ "N","̀" },
+ ["ǹ"]={ "n","̀" },
+ ["Ǻ"]={ "Å","́" },
+ ["ǻ"]={ "å","́" },
+ ["Ǽ"]={ "Æ","́" },
+ ["ǽ"]={ "æ","́" },
+ ["Ǿ"]={ "Ø","́" },
+ ["ǿ"]={ "ø","́" },
+ ["Ȁ"]={ "A","̏" },
+ ["ȁ"]={ "a","̏" },
+ ["Ȃ"]={ "A","̑" },
+ ["ȃ"]={ "a","̑" },
+ ["Ȅ"]={ "E","̏" },
+ ["ȅ"]={ "e","̏" },
+ ["Ȇ"]={ "E","̑" },
+ ["ȇ"]={ "e","̑" },
+ ["Ȉ"]={ "I","̏" },
+ ["ȉ"]={ "i","̏" },
+ ["Ȋ"]={ "I","̑" },
+ ["ȋ"]={ "i","̑" },
+ ["Ȍ"]={ "O","̏" },
+ ["ȍ"]={ "o","̏" },
+ ["Ȏ"]={ "O","̑" },
+ ["ȏ"]={ "o","̑" },
+ ["Ȑ"]={ "R","̏" },
+ ["ȑ"]={ "r","̏" },
+ ["Ȓ"]={ "R","̑" },
+ ["ȓ"]={ "r","̑" },
+ ["Ȕ"]={ "U","̏" },
+ ["ȕ"]={ "u","̏" },
+ ["Ȗ"]={ "U","̑" },
+ ["ȗ"]={ "u","̑" },
+ ["Ș"]={ "S","̦" },
+ ["ș"]={ "s","̦" },
+ ["Ț"]={ "T","̦" },
+ ["ț"]={ "t","̦" },
+ ["Ȟ"]={ "H","̌" },
+ ["ȟ"]={ "h","̌" },
+ ["Ȧ"]={ "A","̇" },
+ ["ȧ"]={ "a","̇" },
+ ["Ȩ"]={ "E","̧" },
+ ["ȩ"]={ "e","̧" },
+ ["Ȫ"]={ "Ö","̄" },
+ ["ȫ"]={ "ö","̄" },
+ ["Ȭ"]={ "Õ","̄" },
+ ["ȭ"]={ "õ","̄" },
+ ["Ȯ"]={ "O","̇" },
+ ["ȯ"]={ "o","̇" },
+ ["Ȱ"]={ "Ȯ","̄" },
+ ["ȱ"]={ "ȯ","̄" },
+ ["Ȳ"]={ "Y","̄" },
+ ["ȳ"]={ "y","̄" },
+ ["̈́"]={ "̈","́" },
+ ["΅"]={ "¨","́" },
+ ["Ά"]={ "Α","́" },
+ ["Έ"]={ "Ε","́" },
+ ["Ή"]={ "Η","́" },
+ ["Ί"]={ "Ι","́" },
+ ["Ό"]={ "Ο","́" },
+ ["Ύ"]={ "Υ","́" },
+ ["Ώ"]={ "Ω","́" },
+ ["ΐ"]={ "ϊ","́" },
+ ["Ϊ"]={ "Ι","̈" },
+ ["Ϋ"]={ "Υ","̈" },
+ ["ά"]={ "α","́" },
+ ["έ"]={ "ε","́" },
+ ["ή"]={ "η","́" },
+ ["ί"]={ "ι","́" },
+ ["ΰ"]={ "ϋ","́" },
+ ["ϊ"]={ "ι","̈" },
+ ["ϋ"]={ "υ","̈" },
+ ["ό"]={ "ο","́" },
+ ["ύ"]={ "υ","́" },
+ ["ώ"]={ "ω","́" },
+ ["ϓ"]={ "ϒ","́" },
+ ["ϔ"]={ "ϒ","̈" },
+ ["Ѐ"]={ "Е","̀" },
+ ["Ё"]={ "Е","̈" },
+ ["Ѓ"]={ "Г","́" },
+ ["Ї"]={ "І","̈" },
+ ["Ќ"]={ "К","́" },
+ ["Ѝ"]={ "И","̀" },
+ ["Ў"]={ "У","̆" },
+ ["Й"]={ "И","̆" },
+ ["й"]={ "и","̆" },
+ ["ѐ"]={ "е","̀" },
+ ["ё"]={ "е","̈" },
+ ["ѓ"]={ "г","́" },
+ ["ї"]={ "і","̈" },
+ ["ќ"]={ "к","́" },
+ ["ѝ"]={ "и","̀" },
+ ["ў"]={ "у","̆" },
+ ["Ѷ"]={ "Ѵ","̏" },
+ ["ѷ"]={ "ѵ","̏" },
+ ["Ӂ"]={ "Ж","̆" },
+ ["ӂ"]={ "ж","̆" },
+ ["Ӑ"]={ "А","̆" },
+ ["ӑ"]={ "а","̆" },
+ ["Ӓ"]={ "А","̈" },
+ ["ӓ"]={ "а","̈" },
+ ["Ӗ"]={ "Е","̆" },
+ ["ӗ"]={ "е","̆" },
+ ["Ӛ"]={ "Ә","̈" },
+ ["ӛ"]={ "ә","̈" },
+ ["Ӝ"]={ "Ж","̈" },
+ ["ӝ"]={ "ж","̈" },
+ ["Ӟ"]={ "З","̈" },
+ ["ӟ"]={ "з","̈" },
+ ["Ӣ"]={ "И","̄" },
+ ["ӣ"]={ "и","̄" },
+ ["Ӥ"]={ "И","̈" },
+ ["ӥ"]={ "и","̈" },
+ ["Ӧ"]={ "О","̈" },
+ ["ӧ"]={ "о","̈" },
+ ["Ӫ"]={ "Ө","̈" },
+ ["ӫ"]={ "ө","̈" },
+ ["Ӭ"]={ "Э","̈" },
+ ["ӭ"]={ "э","̈" },
+ ["Ӯ"]={ "У","̄" },
+ ["ӯ"]={ "у","̄" },
+ ["Ӱ"]={ "У","̈" },
+ ["ӱ"]={ "у","̈" },
+ ["Ӳ"]={ "У","̋" },
+ ["ӳ"]={ "у","̋" },
+ ["Ӵ"]={ "Ч","̈" },
+ ["ӵ"]={ "ч","̈" },
+ ["Ӹ"]={ "Ы","̈" },
+ ["ӹ"]={ "ы","̈" },
+ ["آ"]={ "ا","ٓ" },
+ ["أ"]={ "ا","ٔ" },
+ ["ؤ"]={ "و","ٔ" },
+ ["إ"]={ "ا","ٕ" },
+ ["ئ"]={ "ي","ٔ" },
+ ["ۀ"]={ "ە","ٔ" },
+ ["ۂ"]={ "ہ","ٔ" },
+ ["ۓ"]={ "ے","ٔ" },
+ ["ऩ"]={ "न","़" },
+ ["ऱ"]={ "र","़" },
+ ["ऴ"]={ "ळ","़" },
+ ["क़"]={ "क","़" },
+ ["ख़"]={ "ख","़" },
+ ["ग़"]={ "ग","़" },
+ ["ज़"]={ "ज","़" },
+ ["ड़"]={ "ड","़" },
+ ["ढ़"]={ "ढ","़" },
+ ["फ़"]={ "फ","़" },
+ ["य़"]={ "य","़" },
+ ["ো"]={ "ে","া" },
+ ["ৌ"]={ "ে","ৗ" },
+ ["ড়"]={ "ড","়" },
+ ["ঢ়"]={ "ঢ","়" },
+ ["য়"]={ "য","়" },
+ ["ਲ਼"]={ "ਲ","਼" },
+ ["ਸ਼"]={ "ਸ","਼" },
+ ["ਖ਼"]={ "ਖ","਼" },
+ ["ਗ਼"]={ "ਗ","਼" },
+ ["ਜ਼"]={ "ਜ","਼" },
+ ["ਫ਼"]={ "ਫ","਼" },
+ ["ୈ"]={ "େ","ୖ" },
+ ["ୋ"]={ "େ","ା" },
+ ["ୌ"]={ "େ","ୗ" },
+ ["ଡ଼"]={ "ଡ","଼" },
+ ["ଢ଼"]={ "ଢ","଼" },
+ ["ஔ"]={ "ஒ","ௗ" },
+ ["ொ"]={ "ெ","ா" },
+ ["ோ"]={ "ே","ா" },
+ ["ௌ"]={ "ெ","ௗ" },
+ ["ై"]={ "ె","ౖ" },
+ ["ೀ"]={ "ಿ","ೕ" },
+ ["ೇ"]={ "ೆ","ೕ" },
+ ["ೈ"]={ "ೆ","ೖ" },
+ ["ೊ"]={ "ೆ","ೂ" },
+ ["ೋ"]={ "ೊ","ೕ" },
+ ["ൊ"]={ "െ","ാ" },
+ ["ോ"]={ "േ","ാ" },
+ ["ൌ"]={ "െ","ൗ" },
+ ["ේ"]={ "ෙ","්" },
+ ["ො"]={ "ෙ","ා" },
+ ["ෝ"]={ "ො","්" },
+ ["ෞ"]={ "ෙ","ෟ" },
+ ["གྷ"]={ "ག","ྷ" },
+ ["ཌྷ"]={ "ཌ","ྷ" },
+ ["དྷ"]={ "ད","ྷ" },
+ ["བྷ"]={ "བ","ྷ" },
+ ["ཛྷ"]={ "ཛ","ྷ" },
+ ["ཀྵ"]={ "ཀ","ྵ" },
+ ["ཱི"]={ "ཱ","ི" },
+ ["ཱུ"]={ "ཱ","ུ" },
+ ["ྲྀ"]={ "ྲ","ྀ" },
+ ["ླྀ"]={ "ླ","ྀ" },
+ ["ཱྀ"]={ "ཱ","ྀ" },
+ ["ྒྷ"]={ "ྒ","ྷ" },
+ ["ྜྷ"]={ "ྜ","ྷ" },
+ ["ྡྷ"]={ "ྡ","ྷ" },
+ ["ྦྷ"]={ "ྦ","ྷ" },
+ ["ྫྷ"]={ "ྫ","ྷ" },
+ ["ྐྵ"]={ "ྐ","ྵ" },
+ ["ဦ"]={ "ဥ","ီ" },
+ ["ᬆ"]={ "ᬅ","ᬵ" },
+ ["ᬈ"]={ "ᬇ","ᬵ" },
+ ["ᬊ"]={ "ᬉ","ᬵ" },
+ ["ᬌ"]={ "ᬋ","ᬵ" },
+ ["ᬎ"]={ "ᬍ","ᬵ" },
+ ["ᬒ"]={ "ᬑ","ᬵ" },
+ ["ᬻ"]={ "ᬺ","ᬵ" },
+ ["ᬽ"]={ "ᬼ","ᬵ" },
+ ["ᭀ"]={ "ᬾ","ᬵ" },
+ ["ᭁ"]={ "ᬿ","ᬵ" },
+ ["ᭃ"]={ "ᭂ","ᬵ" },
+ ["Ḁ"]={ "A","̥" },
+ ["ḁ"]={ "a","̥" },
+ ["Ḃ"]={ "B","̇" },
+ ["ḃ"]={ "b","̇" },
+ ["Ḅ"]={ "B","̣" },
+ ["ḅ"]={ "b","̣" },
+ ["Ḇ"]={ "B","̱" },
+ ["ḇ"]={ "b","̱" },
+ ["Ḉ"]={ "Ç","́" },
+ ["ḉ"]={ "ç","́" },
+ ["Ḋ"]={ "D","̇" },
+ ["ḋ"]={ "d","̇" },
+ ["Ḍ"]={ "D","̣" },
+ ["ḍ"]={ "d","̣" },
+ ["Ḏ"]={ "D","̱" },
+ ["ḏ"]={ "d","̱" },
+ ["Ḑ"]={ "D","̧" },
+ ["ḑ"]={ "d","̧" },
+ ["Ḓ"]={ "D","̭" },
+ ["ḓ"]={ "d","̭" },
+ ["Ḕ"]={ "Ē","̀" },
+ ["ḕ"]={ "ē","̀" },
+ ["Ḗ"]={ "Ē","́" },
+ ["ḗ"]={ "ē","́" },
+ ["Ḙ"]={ "E","̭" },
+ ["ḙ"]={ "e","̭" },
+ ["Ḛ"]={ "E","̰" },
+ ["ḛ"]={ "e","̰" },
+ ["Ḝ"]={ "Ȩ","̆" },
+ ["ḝ"]={ "ȩ","̆" },
+ ["Ḟ"]={ "F","̇" },
+ ["ḟ"]={ "f","̇" },
+ ["Ḡ"]={ "G","̄" },
+ ["ḡ"]={ "g","̄" },
+ ["Ḣ"]={ "H","̇" },
+ ["ḣ"]={ "h","̇" },
+ ["Ḥ"]={ "H","̣" },
+ ["ḥ"]={ "h","̣" },
+ ["Ḧ"]={ "H","̈" },
+ ["ḧ"]={ "h","̈" },
+ ["Ḩ"]={ "H","̧" },
+ ["ḩ"]={ "h","̧" },
+ ["Ḫ"]={ "H","̮" },
+ ["ḫ"]={ "h","̮" },
+ ["Ḭ"]={ "I","̰" },
+ ["ḭ"]={ "i","̰" },
+ ["Ḯ"]={ "Ï","́" },
+ ["ḯ"]={ "ï","́" },
+ ["Ḱ"]={ "K","́" },
+ ["ḱ"]={ "k","́" },
+ ["Ḳ"]={ "K","̣" },
+ ["ḳ"]={ "k","̣" },
+ ["Ḵ"]={ "K","̱" },
+ ["ḵ"]={ "k","̱" },
+ ["Ḷ"]={ "L","̣" },
+ ["ḷ"]={ "l","̣" },
+ ["Ḹ"]={ "Ḷ","̄" },
+ ["ḹ"]={ "ḷ","̄" },
+ ["Ḻ"]={ "L","̱" },
+ ["ḻ"]={ "l","̱" },
+ ["Ḽ"]={ "L","̭" },
+ ["ḽ"]={ "l","̭" },
+ ["Ḿ"]={ "M","́" },
+ ["ḿ"]={ "m","́" },
+ ["Ṁ"]={ "M","̇" },
+ ["ṁ"]={ "m","̇" },
+ ["Ṃ"]={ "M","̣" },
+ ["ṃ"]={ "m","̣" },
+ ["Ṅ"]={ "N","̇" },
+ ["ṅ"]={ "n","̇" },
+ ["Ṇ"]={ "N","̣" },
+ ["ṇ"]={ "n","̣" },
+ ["Ṉ"]={ "N","̱" },
+ ["ṉ"]={ "n","̱" },
+ ["Ṋ"]={ "N","̭" },
+ ["ṋ"]={ "n","̭" },
+ ["Ṍ"]={ "Õ","́" },
+ ["ṍ"]={ "õ","́" },
+ ["Ṏ"]={ "Õ","̈" },
+ ["ṏ"]={ "õ","̈" },
+ ["Ṑ"]={ "Ō","̀" },
+ ["ṑ"]={ "ō","̀" },
+ ["Ṓ"]={ "Ō","́" },
+ ["ṓ"]={ "ō","́" },
+ ["Ṕ"]={ "P","́" },
+ ["ṕ"]={ "p","́" },
+ ["Ṗ"]={ "P","̇" },
+ ["ṗ"]={ "p","̇" },
+ ["Ṙ"]={ "R","̇" },
+ ["ṙ"]={ "r","̇" },
+ ["Ṛ"]={ "R","̣" },
+ ["ṛ"]={ "r","̣" },
+ ["Ṝ"]={ "Ṛ","̄" },
+ ["ṝ"]={ "ṛ","̄" },
+ ["Ṟ"]={ "R","̱" },
+ ["ṟ"]={ "r","̱" },
+ ["Ṡ"]={ "S","̇" },
+ ["ṡ"]={ "s","̇" },
+ ["Ṣ"]={ "S","̣" },
+ ["ṣ"]={ "s","̣" },
+ ["Ṥ"]={ "Ś","̇" },
+ ["ṥ"]={ "ś","̇" },
+ ["Ṧ"]={ "Š","̇" },
+ ["ṧ"]={ "š","̇" },
+ ["Ṩ"]={ "Ṣ","̇" },
+ ["ṩ"]={ "ṣ","̇" },
+ ["Ṫ"]={ "T","̇" },
+ ["ṫ"]={ "t","̇" },
+ ["Ṭ"]={ "T","̣" },
+ ["ṭ"]={ "t","̣" },
+ ["Ṯ"]={ "T","̱" },
+ ["ṯ"]={ "t","̱" },
+ ["Ṱ"]={ "T","̭" },
+ ["ṱ"]={ "t","̭" },
+ ["Ṳ"]={ "U","̤" },
+ ["ṳ"]={ "u","̤" },
+ ["Ṵ"]={ "U","̰" },
+ ["ṵ"]={ "u","̰" },
+ ["Ṷ"]={ "U","̭" },
+ ["ṷ"]={ "u","̭" },
+ ["Ṹ"]={ "Ũ","́" },
+ ["ṹ"]={ "ũ","́" },
+ ["Ṻ"]={ "Ū","̈" },
+ ["ṻ"]={ "ū","̈" },
+ ["Ṽ"]={ "V","̃" },
+ ["ṽ"]={ "v","̃" },
+ ["Ṿ"]={ "V","̣" },
+ ["ṿ"]={ "v","̣" },
+ ["Ẁ"]={ "W","̀" },
+ ["ẁ"]={ "w","̀" },
+ ["Ẃ"]={ "W","́" },
+ ["ẃ"]={ "w","́" },
+ ["Ẅ"]={ "W","̈" },
+ ["ẅ"]={ "w","̈" },
+ ["Ẇ"]={ "W","̇" },
+ ["ẇ"]={ "w","̇" },
+ ["Ẉ"]={ "W","̣" },
+ ["ẉ"]={ "w","̣" },
+ ["Ẋ"]={ "X","̇" },
+ ["ẋ"]={ "x","̇" },
+ ["Ẍ"]={ "X","̈" },
+ ["ẍ"]={ "x","̈" },
+ ["Ẏ"]={ "Y","̇" },
+ ["ẏ"]={ "y","̇" },
+ ["Ẑ"]={ "Z","̂" },
+ ["ẑ"]={ "z","̂" },
+ ["Ẓ"]={ "Z","̣" },
+ ["ẓ"]={ "z","̣" },
+ ["Ẕ"]={ "Z","̱" },
+ ["ẕ"]={ "z","̱" },
+ ["ẖ"]={ "h","̱" },
+ ["ẗ"]={ "t","̈" },
+ ["ẘ"]={ "w","̊" },
+ ["ẙ"]={ "y","̊" },
+ ["ẛ"]={ "ſ","̇" },
+ ["Ạ"]={ "A","̣" },
+ ["ạ"]={ "a","̣" },
+ ["Ả"]={ "A","̉" },
+ ["ả"]={ "a","̉" },
+ ["Ấ"]={ "Â","́" },
+ ["ấ"]={ "â","́" },
+ ["Ầ"]={ "Â","̀" },
+ ["ầ"]={ "â","̀" },
+ ["Ẩ"]={ "Â","̉" },
+ ["ẩ"]={ "â","̉" },
+ ["Ẫ"]={ "Â","̃" },
+ ["ẫ"]={ "â","̃" },
+ ["Ậ"]={ "Ạ","̂" },
+ ["ậ"]={ "ạ","̂" },
+ ["Ắ"]={ "Ă","́" },
+ ["ắ"]={ "ă","́" },
+ ["Ằ"]={ "Ă","̀" },
+ ["ằ"]={ "ă","̀" },
+ ["Ẳ"]={ "Ă","̉" },
+ ["ẳ"]={ "ă","̉" },
+ ["Ẵ"]={ "Ă","̃" },
+ ["ẵ"]={ "ă","̃" },
+ ["Ặ"]={ "Ạ","̆" },
+ ["ặ"]={ "ạ","̆" },
+ ["Ẹ"]={ "E","̣" },
+ ["ẹ"]={ "e","̣" },
+ ["Ẻ"]={ "E","̉" },
+ ["ẻ"]={ "e","̉" },
+ ["Ẽ"]={ "E","̃" },
+ ["ẽ"]={ "e","̃" },
+ ["Ế"]={ "Ê","́" },
+ ["ế"]={ "ê","́" },
+ ["Ề"]={ "Ê","̀" },
+ ["ề"]={ "ê","̀" },
+ ["Ể"]={ "Ê","̉" },
+ ["ể"]={ "ê","̉" },
+ ["Ễ"]={ "Ê","̃" },
+ ["ễ"]={ "ê","̃" },
+ ["Ệ"]={ "Ẹ","̂" },
+ ["ệ"]={ "ẹ","̂" },
+ ["Ỉ"]={ "I","̉" },
+ ["ỉ"]={ "i","̉" },
+ ["Ị"]={ "I","̣" },
+ ["ị"]={ "i","̣" },
+ ["Ọ"]={ "O","̣" },
+ ["ọ"]={ "o","̣" },
+ ["Ỏ"]={ "O","̉" },
+ ["ỏ"]={ "o","̉" },
+ ["Ố"]={ "Ô","́" },
+ ["ố"]={ "ô","́" },
+ ["Ồ"]={ "Ô","̀" },
+ ["ồ"]={ "ô","̀" },
+ ["Ổ"]={ "Ô","̉" },
+ ["ổ"]={ "ô","̉" },
+ ["Ỗ"]={ "Ô","̃" },
+ ["ỗ"]={ "ô","̃" },
+ ["Ộ"]={ "Ọ","̂" },
+ ["ộ"]={ "ọ","̂" },
+ ["Ớ"]={ "Ơ","́" },
+ ["ớ"]={ "ơ","́" },
+ ["Ờ"]={ "Ơ","̀" },
+ ["ờ"]={ "ơ","̀" },
+ ["Ở"]={ "Ơ","̉" },
+ ["ở"]={ "ơ","̉" },
+ ["Ỡ"]={ "Ơ","̃" },
+ ["ỡ"]={ "ơ","̃" },
+ ["Ợ"]={ "Ơ","̣" },
+ ["ợ"]={ "ơ","̣" },
+ ["Ụ"]={ "U","̣" },
+ ["ụ"]={ "u","̣" },
+ ["Ủ"]={ "U","̉" },
+ ["ủ"]={ "u","̉" },
+ ["Ứ"]={ "Ư","́" },
+ ["ứ"]={ "ư","́" },
+ ["Ừ"]={ "Ư","̀" },
+ ["ừ"]={ "ư","̀" },
+ ["Ử"]={ "Ư","̉" },
+ ["ử"]={ "ư","̉" },
+ ["Ữ"]={ "Ư","̃" },
+ ["ữ"]={ "ư","̃" },
+ ["Ự"]={ "Ư","̣" },
+ ["ự"]={ "ư","̣" },
+ ["Ỳ"]={ "Y","̀" },
+ ["ỳ"]={ "y","̀" },
+ ["Ỵ"]={ "Y","̣" },
+ ["ỵ"]={ "y","̣" },
+ ["Ỷ"]={ "Y","̉" },
+ ["ỷ"]={ "y","̉" },
+ ["Ỹ"]={ "Y","̃" },
+ ["ỹ"]={ "y","̃" },
+ ["ἀ"]={ "α","̓" },
+ ["ἁ"]={ "α","̔" },
+ ["ἂ"]={ "ἀ","̀" },
+ ["ἃ"]={ "ἁ","̀" },
+ ["ἄ"]={ "ἀ","́" },
+ ["ἅ"]={ "ἁ","́" },
+ ["ἆ"]={ "ἀ","͂" },
+ ["ἇ"]={ "ἁ","͂" },
+ ["Ἀ"]={ "Α","̓" },
+ ["Ἁ"]={ "Α","̔" },
+ ["Ἂ"]={ "Ἀ","̀" },
+ ["Ἃ"]={ "Ἁ","̀" },
+ ["Ἄ"]={ "Ἀ","́" },
+ ["Ἅ"]={ "Ἁ","́" },
+ ["Ἆ"]={ "Ἀ","͂" },
+ ["Ἇ"]={ "Ἁ","͂" },
+ ["ἐ"]={ "ε","̓" },
+ ["ἑ"]={ "ε","̔" },
+ ["ἒ"]={ "ἐ","̀" },
+ ["ἓ"]={ "ἑ","̀" },
+ ["ἔ"]={ "ἐ","́" },
+ ["ἕ"]={ "ἑ","́" },
+ ["Ἐ"]={ "Ε","̓" },
+ ["Ἑ"]={ "Ε","̔" },
+ ["Ἒ"]={ "Ἐ","̀" },
+ ["Ἓ"]={ "Ἑ","̀" },
+ ["Ἔ"]={ "Ἐ","́" },
+ ["Ἕ"]={ "Ἑ","́" },
+ ["ἠ"]={ "η","̓" },
+ ["ἡ"]={ "η","̔" },
+ ["ἢ"]={ "ἠ","̀" },
+ ["ἣ"]={ "ἡ","̀" },
+ ["ἤ"]={ "ἠ","́" },
+ ["ἥ"]={ "ἡ","́" },
+ ["ἦ"]={ "ἠ","͂" },
+ ["ἧ"]={ "ἡ","͂" },
+ ["Ἠ"]={ "Η","̓" },
+ ["Ἡ"]={ "Η","̔" },
+ ["Ἢ"]={ "Ἠ","̀" },
+ ["Ἣ"]={ "Ἡ","̀" },
+ ["Ἤ"]={ "Ἠ","́" },
+ ["Ἥ"]={ "Ἡ","́" },
+ ["Ἦ"]={ "Ἠ","͂" },
+ ["Ἧ"]={ "Ἡ","͂" },
+ ["ἰ"]={ "ι","̓" },
+ ["ἱ"]={ "ι","̔" },
+ ["ἲ"]={ "ἰ","̀" },
+ ["ἳ"]={ "ἱ","̀" },
+ ["ἴ"]={ "ἰ","́" },
+ ["ἵ"]={ "ἱ","́" },
+ ["ἶ"]={ "ἰ","͂" },
+ ["ἷ"]={ "ἱ","͂" },
+ ["Ἰ"]={ "Ι","̓" },
+ ["Ἱ"]={ "Ι","̔" },
+ ["Ἲ"]={ "Ἰ","̀" },
+ ["Ἳ"]={ "Ἱ","̀" },
+ ["Ἴ"]={ "Ἰ","́" },
+ ["Ἵ"]={ "Ἱ","́" },
+ ["Ἶ"]={ "Ἰ","͂" },
+ ["Ἷ"]={ "Ἱ","͂" },
+ ["ὀ"]={ "ο","̓" },
+ ["ὁ"]={ "ο","̔" },
+ ["ὂ"]={ "ὀ","̀" },
+ ["ὃ"]={ "ὁ","̀" },
+ ["ὄ"]={ "ὀ","́" },
+ ["ὅ"]={ "ὁ","́" },
+ ["Ὀ"]={ "Ο","̓" },
+ ["Ὁ"]={ "Ο","̔" },
+ ["Ὂ"]={ "Ὀ","̀" },
+ ["Ὃ"]={ "Ὁ","̀" },
+ ["Ὄ"]={ "Ὀ","́" },
+ ["Ὅ"]={ "Ὁ","́" },
+ ["ὐ"]={ "υ","̓" },
+ ["ὑ"]={ "υ","̔" },
+ ["ὒ"]={ "ὐ","̀" },
+ ["ὓ"]={ "ὑ","̀" },
+ ["ὔ"]={ "ὐ","́" },
+ ["ὕ"]={ "ὑ","́" },
+ ["ὖ"]={ "ὐ","͂" },
+ ["ὗ"]={ "ὑ","͂" },
+ ["Ὑ"]={ "Υ","̔" },
+ ["Ὓ"]={ "Ὑ","̀" },
+ ["Ὕ"]={ "Ὑ","́" },
+ ["Ὗ"]={ "Ὑ","͂" },
+ ["ὠ"]={ "ω","̓" },
+ ["ὡ"]={ "ω","̔" },
+ ["ὢ"]={ "ὠ","̀" },
+ ["ὣ"]={ "ὡ","̀" },
+ ["ὤ"]={ "ὠ","́" },
+ ["ὥ"]={ "ὡ","́" },
+ ["ὦ"]={ "ὠ","͂" },
+ ["ὧ"]={ "ὡ","͂" },
+ ["Ὠ"]={ "Ω","̓" },
+ ["Ὡ"]={ "Ω","̔" },
+ ["Ὢ"]={ "Ὠ","̀" },
+ ["Ὣ"]={ "Ὡ","̀" },
+ ["Ὤ"]={ "Ὠ","́" },
+ ["Ὥ"]={ "Ὡ","́" },
+ ["Ὦ"]={ "Ὠ","͂" },
+ ["Ὧ"]={ "Ὡ","͂" },
+ ["ὰ"]={ "α","̀" },
+ ["ὲ"]={ "ε","̀" },
+ ["ὴ"]={ "η","̀" },
+ ["ὶ"]={ "ι","̀" },
+ ["ὸ"]={ "ο","̀" },
+ ["ὺ"]={ "υ","̀" },
+ ["ὼ"]={ "ω","̀" },
+ ["ᾀ"]={ "ἀ","ͅ" },
+ ["ᾁ"]={ "ἁ","ͅ" },
+ ["ᾂ"]={ "ἂ","ͅ" },
+ ["ᾃ"]={ "ἃ","ͅ" },
+ ["ᾄ"]={ "ἄ","ͅ" },
+ ["ᾅ"]={ "ἅ","ͅ" },
+ ["ᾆ"]={ "ἆ","ͅ" },
+ ["ᾇ"]={ "ἇ","ͅ" },
+ ["ᾈ"]={ "Ἀ","ͅ" },
+ ["ᾉ"]={ "Ἁ","ͅ" },
+ ["ᾊ"]={ "Ἂ","ͅ" },
+ ["ᾋ"]={ "Ἃ","ͅ" },
+ ["ᾌ"]={ "Ἄ","ͅ" },
+ ["ᾍ"]={ "Ἅ","ͅ" },
+ ["ᾎ"]={ "Ἆ","ͅ" },
+ ["ᾏ"]={ "Ἇ","ͅ" },
+ ["ᾐ"]={ "ἠ","ͅ" },
+ ["ᾑ"]={ "ἡ","ͅ" },
+ ["ᾒ"]={ "ἢ","ͅ" },
+ ["ᾓ"]={ "ἣ","ͅ" },
+ ["ᾔ"]={ "ἤ","ͅ" },
+ ["ᾕ"]={ "ἥ","ͅ" },
+ ["ᾖ"]={ "ἦ","ͅ" },
+ ["ᾗ"]={ "ἧ","ͅ" },
+ ["ᾘ"]={ "Ἠ","ͅ" },
+ ["ᾙ"]={ "Ἡ","ͅ" },
+ ["ᾚ"]={ "Ἢ","ͅ" },
+ ["ᾛ"]={ "Ἣ","ͅ" },
+ ["ᾜ"]={ "Ἤ","ͅ" },
+ ["ᾝ"]={ "Ἥ","ͅ" },
+ ["ᾞ"]={ "Ἦ","ͅ" },
+ ["ᾟ"]={ "Ἧ","ͅ" },
+ ["ᾠ"]={ "ὠ","ͅ" },
+ ["ᾡ"]={ "ὡ","ͅ" },
+ ["ᾢ"]={ "ὢ","ͅ" },
+ ["ᾣ"]={ "ὣ","ͅ" },
+ ["ᾤ"]={ "ὤ","ͅ" },
+ ["ᾥ"]={ "ὥ","ͅ" },
+ ["ᾦ"]={ "ὦ","ͅ" },
+ ["ᾧ"]={ "ὧ","ͅ" },
+ ["ᾨ"]={ "Ὠ","ͅ" },
+ ["ᾩ"]={ "Ὡ","ͅ" },
+ ["ᾪ"]={ "Ὢ","ͅ" },
+ ["ᾫ"]={ "Ὣ","ͅ" },
+ ["ᾬ"]={ "Ὤ","ͅ" },
+ ["ᾭ"]={ "Ὥ","ͅ" },
+ ["ᾮ"]={ "Ὦ","ͅ" },
+ ["ᾯ"]={ "Ὧ","ͅ" },
+ ["ᾰ"]={ "α","̆" },
+ ["ᾱ"]={ "α","̄" },
+ ["ᾲ"]={ "ὰ","ͅ" },
+ ["ᾳ"]={ "α","ͅ" },
+ ["ᾴ"]={ "ά","ͅ" },
+ ["ᾶ"]={ "α","͂" },
+ ["ᾷ"]={ "ᾶ","ͅ" },
+ ["Ᾰ"]={ "Α","̆" },
+ ["Ᾱ"]={ "Α","̄" },
+ ["Ὰ"]={ "Α","̀" },
+ ["ᾼ"]={ "Α","ͅ" },
+ ["῁"]={ "¨","͂" },
+ ["ῂ"]={ "ὴ","ͅ" },
+ ["ῃ"]={ "η","ͅ" },
+ ["ῄ"]={ "ή","ͅ" },
+ ["ῆ"]={ "η","͂" },
+ ["ῇ"]={ "ῆ","ͅ" },
+ ["Ὲ"]={ "Ε","̀" },
+ ["Ὴ"]={ "Η","̀" },
+ ["ῌ"]={ "Η","ͅ" },
+ ["῍"]={ "᾿","̀" },
+ ["῎"]={ "᾿","́" },
+ ["῏"]={ "᾿","͂" },
+ ["ῐ"]={ "ι","̆" },
+ ["ῑ"]={ "ι","̄" },
+ ["ῒ"]={ "ϊ","̀" },
+ ["ῖ"]={ "ι","͂" },
+ ["ῗ"]={ "ϊ","͂" },
+ ["Ῐ"]={ "Ι","̆" },
+ ["Ῑ"]={ "Ι","̄" },
+ ["Ὶ"]={ "Ι","̀" },
+ ["῝"]={ "῾","̀" },
+ ["῞"]={ "῾","́" },
+ ["῟"]={ "῾","͂" },
+ ["ῠ"]={ "υ","̆" },
+ ["ῡ"]={ "υ","̄" },
+ ["ῢ"]={ "ϋ","̀" },
+ ["ῤ"]={ "ρ","̓" },
+ ["ῥ"]={ "ρ","̔" },
+ ["ῦ"]={ "υ","͂" },
+ ["ῧ"]={ "ϋ","͂" },
+ ["Ῠ"]={ "Υ","̆" },
+ ["Ῡ"]={ "Υ","̄" },
+ ["Ὺ"]={ "Υ","̀" },
+ ["Ῥ"]={ "Ρ","̔" },
+ ["῭"]={ "¨","̀" },
+ ["ῲ"]={ "ὼ","ͅ" },
+ ["ῳ"]={ "ω","ͅ" },
+ ["ῴ"]={ "ώ","ͅ" },
+ ["ῶ"]={ "ω","͂" },
+ ["ῷ"]={ "ῶ","ͅ" },
+ ["Ὸ"]={ "Ο","̀" },
+ ["Ὼ"]={ "Ω","̀" },
+ ["ῼ"]={ "Ω","ͅ" },
+ ["↚"]={ "←","̸" },
+ ["↛"]={ "→","̸" },
+ ["↮"]={ "↔","̸" },
+ ["⇍"]={ "⇐","̸" },
+ ["⇎"]={ "⇔","̸" },
+ ["⇏"]={ "⇒","̸" },
+ ["∄"]={ "∃","̸" },
+ ["∉"]={ "∈","̸" },
+ ["∌"]={ "∋","̸" },
+ ["∤"]={ "∣","̸" },
+ ["∦"]={ "∥","̸" },
+ ["≁"]={ "∼","̸" },
+ ["≄"]={ "≃","̸" },
+ ["≇"]={ "≅","̸" },
+ ["≉"]={ "≈","̸" },
+ ["≠"]={ "=","̸" },
+ ["≢"]={ "≡","̸" },
+ ["≭"]={ "≍","̸" },
+ ["≮"]={ "<","̸" },
+ ["≯"]={ ">","̸" },
+ ["≰"]={ "≤","̸" },
+ ["≱"]={ "≥","̸" },
+ ["≴"]={ "≲","̸" },
+ ["≵"]={ "≳","̸" },
+ ["≸"]={ "≶","̸" },
+ ["≹"]={ "≷","̸" },
+ ["⊀"]={ "≺","̸" },
+ ["⊁"]={ "≻","̸" },
+ ["⊄"]={ "⊂","̸" },
+ ["⊅"]={ "⊃","̸" },
+ ["⊈"]={ "⊆","̸" },
+ ["⊉"]={ "⊇","̸" },
+ ["⊬"]={ "⊢","̸" },
+ ["⊭"]={ "⊨","̸" },
+ ["⊮"]={ "⊩","̸" },
+ ["⊯"]={ "⊫","̸" },
+ ["⋠"]={ "≼","̸" },
+ ["⋡"]={ "≽","̸" },
+ ["⋢"]={ "⊑","̸" },
+ ["⋣"]={ "⊒","̸" },
+ ["⋪"]={ "⊲","̸" },
+ ["⋫"]={ "⊳","̸" },
+ ["⋬"]={ "⊴","̸" },
+ ["⋭"]={ "⊵","̸" },
+ ["⫝̸"]={ "⫝","̸" },
+ ["が"]={ "か","゙" },
+ ["ぎ"]={ "き","゙" },
+ ["ぐ"]={ "く","゙" },
+ ["げ"]={ "け","゙" },
+ ["ご"]={ "こ","゙" },
+ ["ざ"]={ "さ","゙" },
+ ["じ"]={ "し","゙" },
+ ["ず"]={ "す","゙" },
+ ["ぜ"]={ "せ","゙" },
+ ["ぞ"]={ "そ","゙" },
+ ["だ"]={ "た","゙" },
+ ["ぢ"]={ "ち","゙" },
+ ["づ"]={ "つ","゙" },
+ ["で"]={ "て","゙" },
+ ["ど"]={ "と","゙" },
+ ["ば"]={ "は","゙" },
+ ["ぱ"]={ "は","゚" },
+ ["び"]={ "ひ","゙" },
+ ["ぴ"]={ "ひ","゚" },
+ ["ぶ"]={ "ふ","゙" },
+ ["ぷ"]={ "ふ","゚" },
+ ["べ"]={ "へ","゙" },
+ ["ぺ"]={ "へ","゚" },
+ ["ぼ"]={ "ほ","゙" },
+ ["ぽ"]={ "ほ","゚" },
+ ["ゔ"]={ "う","゙" },
+ ["ゞ"]={ "ゝ","゙" },
+ ["ガ"]={ "カ","゙" },
+ ["ギ"]={ "キ","゙" },
+ ["グ"]={ "ク","゙" },
+ ["ゲ"]={ "ケ","゙" },
+ ["ゴ"]={ "コ","゙" },
+ ["ザ"]={ "サ","゙" },
+ ["ジ"]={ "シ","゙" },
+ ["ズ"]={ "ス","゙" },
+ ["ゼ"]={ "セ","゙" },
+ ["ゾ"]={ "ソ","゙" },
+ ["ダ"]={ "タ","゙" },
+ ["ヂ"]={ "チ","゙" },
+ ["ヅ"]={ "ツ","゙" },
+ ["デ"]={ "テ","゙" },
+ ["ド"]={ "ト","゙" },
+ ["バ"]={ "ハ","゙" },
+ ["パ"]={ "ハ","゚" },
+ ["ビ"]={ "ヒ","゙" },
+ ["ピ"]={ "ヒ","゚" },
+ ["ブ"]={ "フ","゙" },
+ ["プ"]={ "フ","゚" },
+ ["ベ"]={ "ヘ","゙" },
+ ["ペ"]={ "ヘ","゚" },
+ ["ボ"]={ "ホ","゙" },
+ ["ポ"]={ "ホ","゚" },
+ ["ヴ"]={ "ウ","゙" },
+ ["ヷ"]={ "ワ","゙" },
+ ["ヸ"]={ "ヰ","゙" },
+ ["ヹ"]={ "ヱ","゙" },
+ ["ヺ"]={ "ヲ","゙" },
+ ["ヾ"]={ "ヽ","゙" },
+ ["יִ"]={ "י","ִ" },
+ ["ײַ"]={ "ײ","ַ" },
+ ["שׁ"]={ "ש","ׁ" },
+ ["שׂ"]={ "ש","ׂ" },
+ ["שּׁ"]={ "שּ","ׁ" },
+ ["שּׂ"]={ "שּ","ׂ" },
+ ["אַ"]={ "א","ַ" },
+ ["אָ"]={ "א","ָ" },
+ ["אּ"]={ "א","ּ" },
+ ["בּ"]={ "ב","ּ" },
+ ["גּ"]={ "ג","ּ" },
+ ["דּ"]={ "ד","ּ" },
+ ["הּ"]={ "ה","ּ" },
+ ["וּ"]={ "ו","ּ" },
+ ["זּ"]={ "ז","ּ" },
+ ["טּ"]={ "ט","ּ" },
+ ["יּ"]={ "י","ּ" },
+ ["ךּ"]={ "ך","ּ" },
+ ["כּ"]={ "כ","ּ" },
+ ["לּ"]={ "ל","ּ" },
+ ["מּ"]={ "מ","ּ" },
+ ["נּ"]={ "נ","ּ" },
+ ["סּ"]={ "ס","ּ" },
+ ["ףּ"]={ "ף","ּ" },
+ ["פּ"]={ "פ","ּ" },
+ ["צּ"]={ "צ","ּ" },
+ ["קּ"]={ "ק","ּ" },
+ ["רּ"]={ "ר","ּ" },
+ ["שּ"]={ "ש","ּ" },
+ ["תּ"]={ "ת","ּ" },
+ ["וֹ"]={ "ו","ֹ" },
+ ["בֿ"]={ "ב","ֿ" },
+ ["כֿ"]={ "כ","ֿ" },
+ ["פֿ"]={ "פ","ֿ" },
+ ["𑂚"]={ "𑂙","𑂺" },
+ ["𑂜"]={ "𑂛","𑂺" },
+ ["𑂫"]={ "𑂥","𑂺" },
+ ["𑄮"]={ "𑄱","𑄧" },
+ ["𑄯"]={ "𑄲","𑄧" },
+ ["𑍋"]={ "𑍇","𑌾" },
+ ["𑍌"]={ "𑍇","𑍗" },
+ ["𑒻"]={ "𑒹","𑒺" },
+ ["𑒼"]={ "𑒹","𑒰" },
+ ["𑒾"]={ "𑒹","𑒽" },
+ ["𑖺"]={ "𑖸","𑖯" },
+ ["𑖻"]={ "𑖹","𑖯" },
+ ["𝅗𝅥"]={ "𝅗","𝅥" },
+ ["𝅘𝅥"]={ "𝅘","𝅥" },
+ ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" },
+ ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" },
+ ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" },
+ ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" },
+ ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" },
+ ["𝆹𝅥"]={ "𝆹","𝅥" },
+ ["𝆺𝅥"]={ "𝆺","𝅥" },
+ ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" },
+ ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" },
+ ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" },
+ ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" },
+ },
},
},
- },
["name"]="collapse",
["prepend"]=true,
["type"]="ligature",
@@ -37439,11 +37439,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['luatex-fonts-gbn']={
- version=1.001,
- comment="companion to luatex-*.tex",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luatex-*.tex",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if context then
--removed
@@ -37475,231 +37475,231 @@ local d_ligaturing=nuts.ligaturing
local d_kerning=nuts.kerning
local basemodepass=true
local function l_warning() logs.report("fonts","don't call 'node.ligaturing' directly") l_warning=nil end
-local function k_warning() logs.report("fonts","don't call 'node.kerning' directly") k_warning=nil end
+local function k_warning() logs.report("fonts","don't call 'node.kerning' directly") k_warning=nil end
function node.ligaturing(...)
- if basemodepass and l_warning then
- l_warning()
- end
- return n_ligaturing(...)
+ if basemodepass and l_warning then
+ l_warning()
+ end
+ return n_ligaturing(...)
end
function node.kerning(...)
- if basemodepass and k_warning then
- k_warning()
- end
- return n_kerning(...)
+ if basemodepass and k_warning then
+ k_warning()
+ end
+ return n_kerning(...)
end
function nuts.ligaturing(...)
- if basemodepass and l_warning then
- l_warning()
- end
- return d_ligaturing(...)
+ if basemodepass and l_warning then
+ l_warning()
+ end
+ return d_ligaturing(...)
end
function nuts.kerning(...)
- if basemodepass and k_warning then
- k_warning()
- end
- return d_kerning(...)
+ if basemodepass and k_warning then
+ k_warning()
+ end
+ return d_kerning(...)
end
function nodes.handlers.setbasemodepass(v)
- basemodepass=v
+ basemodepass=v
end
local function nodepass(head,groupcode,size,packtype,direction)
- local fontdata=fonts.hashes.identifiers
- if fontdata then
- local usedfonts={}
- local basefonts={}
- local prevfont=nil
- local basefont=nil
- local variants=nil
- local redundant=nil
- local nofused=0
- for n in traverse_id(glyph_code,head) do
- local font=getfont(n)
- if font~=prevfont then
- if basefont then
- basefont[2]=getprev(n)
- end
- prevfont=font
- local used=usedfonts[font]
- if not used then
- local tfmdata=fontdata[font]
- if tfmdata then
- local shared=tfmdata.shared
- if shared then
- local processors=shared.processes
- if processors and #processors>0 then
- usedfonts[font]=processors
- nofused=nofused+1
- elseif basemodepass then
- basefont={ n,nil }
- basefonts[#basefonts+1]=basefont
- end
- end
- local resources=tfmdata.resources
- variants=resources and resources.variants
- variants=variants and next(variants) and variants or false
- end
- else
- local tfmdata=fontdata[prevfont]
- if tfmdata then
- local resources=tfmdata.resources
- variants=resources and resources.variants
- variants=variants and next(variants) and variants or false
- end
- end
- end
- if variants then
- local char=getchar(n)
- if (char>=0xFE00 and char<=0xFE0F) or (char>=0xE0100 and char<=0xE01EF) then
- local hash=variants[char]
- if hash then
- local p=getprev(n)
- if p and getid(p)==glyph_code then
- local variant=hash[getchar(p)]
- if variant then
- setchar(p,variant)
- end
- end
- end
- if not redundant then
- redundant={ n }
- else
- redundant[#redundant+1]=n
- end
- end
+ local fontdata=fonts.hashes.identifiers
+ if fontdata then
+ local usedfonts={}
+ local basefonts={}
+ local prevfont=nil
+ local basefont=nil
+ local variants=nil
+ local redundant=nil
+ local nofused=0
+ for n in traverse_id(glyph_code,head) do
+ local font=getfont(n)
+ if font~=prevfont then
+ if basefont then
+ basefont[2]=getprev(n)
+ end
+ prevfont=font
+ local used=usedfonts[font]
+ if not used then
+ local tfmdata=fontdata[font]
+ if tfmdata then
+ local shared=tfmdata.shared
+ if shared then
+ local processors=shared.processes
+ if processors and #processors>0 then
+ usedfonts[font]=processors
+ nofused=nofused+1
+ elseif basemodepass then
+ basefont={ n,nil }
+ basefonts[#basefonts+1]=basefont
+ end
end
+ local resources=tfmdata.resources
+ variants=resources and resources.variants
+ variants=variants and next(variants) and variants or false
+ end
+ else
+ local tfmdata=fontdata[prevfont]
+ if tfmdata then
+ local resources=tfmdata.resources
+ variants=resources and resources.variants
+ variants=variants and next(variants) and variants or false
+ end
end
- local nofbasefonts=#basefonts
- if redundant then
- for i=1,#redundant do
- local r=redundant[i]
- local p,n=getboth(r)
- if r==head then
- head=n
- setprev(n)
- else
- setlink(p,n)
- end
- if nofbasefonts>0 then
- for i=1,nofbasefonts do
- local bi=basefonts[i]
- if r==bi[1] then
- bi[1]=n
- end
- if r==bi[2] then
- bi[2]=n
- end
- end
- end
- flush_node(r)
- end
- end
- for d in traverse_id(disc_code,head) do
- local _,_,r=getdisc(d)
- if r then
- for n in traverse_id(glyph_code,r) do
- local font=getfont(n)
- if font~=prevfont then
- prevfont=font
- local used=usedfonts[font]
- if not used then
- local tfmdata=fontdata[font]
- if tfmdata then
- local shared=tfmdata.shared
- if shared then
- local processors=shared.processes
- if processors and #processors>0 then
- usedfonts[font]=processors
- nofused=nofused+1
- end
- end
- end
- end
- end
- end
+ end
+ if variants then
+ local char=getchar(n)
+ if (char>=0xFE00 and char<=0xFE0F) or (char>=0xE0100 and char<=0xE01EF) then
+ local hash=variants[char]
+ if hash then
+ local p=getprev(n)
+ if p and getid(p)==glyph_code then
+ local variant=hash[getchar(p)]
+ if variant then
+ setchar(p,variant)
+ end
end
+ end
+ if not redundant then
+ redundant={ n }
+ else
+ redundant[#redundant+1]=n
+ end
end
- if next(usedfonts) then
- for font,processors in next,usedfonts do
- for i=1,#processors do
- head=processors[i](head,font,0,direction,nofused) or head
- end
+ end
+ end
+ local nofbasefonts=#basefonts
+ if redundant then
+ for i=1,#redundant do
+ local r=redundant[i]
+ local p,n=getboth(r)
+ if r==head then
+ head=n
+ setprev(n)
+ else
+ setlink(p,n)
+ end
+ if nofbasefonts>0 then
+ for i=1,nofbasefonts do
+ local bi=basefonts[i]
+ if r==bi[1] then
+ bi[1]=n
end
+ if r==bi[2] then
+ bi[2]=n
+ end
+ end
end
- if basemodepass and nofbasefonts>0 then
- for i=1,nofbasefonts do
- local range=basefonts[i]
- local start=range[1]
- local stop=range[2]
- if start then
- local front=head==start
- local prev,next
- if stop then
- next=getnext(stop)
- start,stop=d_ligaturing(start,stop)
- start,stop=d_kerning(start,stop)
- else
- prev=getprev(start)
- start=d_ligaturing(start)
- start=d_kerning(start)
- end
- if prev then
- setlink(prev,start)
- end
- if next then
- setlink(stop,next)
- end
- if front and head~=start then
- head=start
- end
+ flush_node(r)
+ end
+ end
+ for d in traverse_id(disc_code,head) do
+ local _,_,r=getdisc(d)
+ if r then
+ for n in traverse_id(glyph_code,r) do
+ local font=getfont(n)
+ if font~=prevfont then
+ prevfont=font
+ local used=usedfonts[font]
+ if not used then
+ local tfmdata=fontdata[font]
+ if tfmdata then
+ local shared=tfmdata.shared
+ if shared then
+ local processors=shared.processes
+ if processors and #processors>0 then
+ usedfonts[font]=processors
+ nofused=nofused+1
+ end
end
+ end
end
+ end
end
+ end
end
- return head
+ if next(usedfonts) then
+ for font,processors in next,usedfonts do
+ for i=1,#processors do
+ head=processors[i](head,font,0,direction,nofused) or head
+ end
+ end
+ end
+ if basemodepass and nofbasefonts>0 then
+ for i=1,nofbasefonts do
+ local range=basefonts[i]
+ local start=range[1]
+ local stop=range[2]
+ if start then
+ local front=head==start
+ local prev,next
+ if stop then
+ next=getnext(stop)
+ start,stop=d_ligaturing(start,stop)
+ start,stop=d_kerning(start,stop)
+ else
+ prev=getprev(start)
+ start=d_ligaturing(start)
+ start=d_kerning(start)
+ end
+ if prev then
+ setlink(prev,start)
+ end
+ if next then
+ setlink(stop,next)
+ end
+ if front and head~=start then
+ head=start
+ end
+ end
+ end
+ end
+ end
+ return head
end
local function basepass(head)
- if basemodepass then
- head=d_ligaturing(head)
- head=d_kerning(head)
- end
- return head
+ if basemodepass then
+ head=d_ligaturing(head)
+ head=d_kerning(head)
+ end
+ return head
end
local protectpass=node.direct.protect_glyphs
local injectpass=nodes.injections.handler
function nodes.handlers.nodepass(head,...)
- if head then
- return tonode(nodepass(tonut(head),...))
- end
+ if head then
+ return tonode(nodepass(tonut(head),...))
+ end
end
function nodes.handlers.basepass(head)
- if head then
- return tonode(basepass(tonut(head)))
- end
+ if head then
+ return tonode(basepass(tonut(head)))
+ end
end
function nodes.handlers.injectpass(head)
- if head then
- return tonode(injectpass(tonut(head)))
- end
+ if head then
+ return tonode(injectpass(tonut(head)))
+ end
end
function nodes.handlers.protectpass(head)
- if head then
- protectpass(tonut(head))
- return head
- end
+ if head then
+ protectpass(tonut(head))
+ return head
+ end
end
function nodes.simple_font_handler(head,groupcode,size,packtype,direction)
- if head then
- head=tonut(head)
- head=nodepass(head,groupcode,size,packtype,direction)
- head=injectpass(head)
- if not basemodepass then
- head=basepass(head)
- end
- protectpass(head)
- head=tonode(head)
- end
- return head
+ if head then
+ head=tonut(head)
+ head=nodepass(head,groupcode,size,packtype,direction)
+ head=injectpass(head)
+ if not basemodepass then
+ head=basepass(head)
+ end
+ protectpass(head)
+ head=tonode(head)
+ end
+ return head
end
end -- closure