summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2010-05-08 13:33:00 +0200
committerHans Hagen <pragma@wxs.nl>2010-05-08 13:33:00 +0200
commit8ad1a9bed2cf3271f1922759060c2ba1c8e3ced1 (patch)
tree5958b9a4206fab98782cd05e4f7a9532524dd3ab /scripts
parent66a308adb8acc92c16afd883827e6e835d721a8e (diff)
downloadcontext-8ad1a9bed2cf3271f1922759060c2ba1c8e3ced1.tar.gz
stable 2010.05.08 13:33
Diffstat (limited to 'scripts')
-rw-r--r--scripts/context/lua/luatools.lua10
-rw-r--r--scripts/context/lua/mtx-mptopdf.lua22
-rw-r--r--scripts/context/lua/mtxrun.lua281
-rw-r--r--scripts/context/perl/mptopdf.pl8
-rw-r--r--scripts/context/stubs/mswin/luatools.lua10
-rw-r--r--scripts/context/stubs/mswin/mtxrun.dllbin9216 -> 9216 bytes
-rwxr-xr-xscripts/context/stubs/mswin/mtxrun.exebin6144 -> 6144 bytes
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua281
-rw-r--r--scripts/context/stubs/source/mtxrun_dll.c117
-rwxr-xr-xscripts/context/stubs/unix/luatools10
-rwxr-xr-xscripts/context/stubs/unix/mtxrun281
11 files changed, 688 insertions, 332 deletions
diff --git a/scripts/context/lua/luatools.lua b/scripts/context/lua/luatools.lua
index 35a61ea43..ccedd97cd 100644
--- a/scripts/context/lua/luatools.lua
+++ b/scripts/context/lua/luatools.lua
@@ -7419,11 +7419,13 @@ function statistics.check_fmt_status(texname)
local luv = dofile(luvname)
if luv and luv.sourcefile then
local sourcehash = md5.hex(io.loaddata(resolvers.find_file(luv.sourcefile)) or "unknown")
- if luv.enginebanner and luv.enginebanner ~= enginebanner then
- return "engine mismatch"
+ local luvbanner = luv.enginebanner or "?"
+ if luvbanner ~= enginebanner then
+ return string.format("engine mismatch (luv:%s <> bin:%s)",luvbanner,enginebanner)
end
- if luv.sourcehash and luv.sourcehash ~= sourcehash then
- return "source mismatch"
+ local luvhash = luv.sourcehash or "?"
+ if luvhash ~= sourcehash then
+ return string.format("source mismatch (luv:%s <> bin:%s)",luvhash,sourcehash)
end
else
return "invalid status file"
diff --git a/scripts/context/lua/mtx-mptopdf.lua b/scripts/context/lua/mtx-mptopdf.lua
index 69950e008..6fa5bbcb8 100644
--- a/scripts/context/lua/mtx-mptopdf.lua
+++ b/scripts/context/lua/mtx-mptopdf.lua
@@ -1,6 +1,6 @@
if not modules then modules = { } end modules ['mtx-mptopdf'] = {
version = 1.303,
- comment = "companion to mtxrun.lua",
+ comment = "companion to mtxrun.lua, patched by HH so errors are his",
author = "Taco Hoekwater, Elvenkind BV, Dordrecht NL",
copyright = "Elvenkind BV / ConTeXt Development Team",
license = "see context related readme files"
@@ -32,16 +32,18 @@ function scripts.mptopdf.aux.do_convert (fname)
else
command = string.format('%s \\\\relax "%s"',command,fname)
end
- os.execute(command)
- local name, suffix = file.nameonly(fname), file.extname(fname)
- local pdfsrc = name .. ".pdf"
- if lfs.isfile(pdfsrc) then
- pdfdest = name .. "-" .. suffix .. ".pdf"
- os.rename(pdfsrc, pdfdest)
- if lfs.isfile(pdfsrc) then -- rename failed
- file.copy(pdfsrc, pdfdest)
+ local result = os.execute(command)
+ if result == 0 then
+ local name, suffix = file.nameonly(fname), file.extname(fname)
+ local pdfsrc = name .. ".pdf"
+ if lfs.isfile(pdfsrc) then
+ pdfdest = name .. "-" .. suffix .. ".pdf"
+ os.rename(pdfsrc, pdfdest)
+ if lfs.isfile(pdfsrc) then -- rename failed
+ file.copy(pdfsrc, pdfdest)
+ end
+ done = 1
end
- done = 1
end
end
return done, pdfdest
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 3c72f59d1..cefa3192b 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -3950,7 +3950,7 @@ element.</p>
local nsremap, resolvens = xml.xmlns, xml.resolvens
local stack, top, dt, at, xmlns, errorstr, entities = { }, { }, { }, { }, { }, nil, { }
-local strip, cleanup, utfize, resolve, resolve_predefined = false, false, false, false, false
+local strip, cleanup, utfize, resolve, resolve_predefined, unify_predefined = false, false, false, false, false, false
local dcache, hcache, acache = { }, { }, { }
local mt = { }
@@ -4078,22 +4078,72 @@ function xml.unknown_dec_entity_format(str) return (str == "" and "&error;") or
function xml.unknown_hex_entity_format(str) return format("&#x%s;",str) end
function xml.unknown_any_entity_format(str) return format("&#x%s;",str) end
+local function fromhex(s)
+ local n = tonumber(s,16)
+ if n then
+ return utfchar(n)
+ else
+ return format("h:%s",s), true
+ end
+end
+
+local function fromdec(s)
+ local n = tonumber(s)
+ if n then
+ return utfchar(n)
+ else
+ return format("d:%s",s), true
+ end
+end
+
+-- one level expansion (simple case), no checking done
+
+local rest = (1-P(";"))^0
+local many = P(1)^0
+
+local parsedentity =
+ P("&") * (P("#x")*(rest/fromhex) + P("#")*(rest/fromdec)) * P(";") * P(-1) +
+ (P("#x")*(many/fromhex) + P("#")*(many/fromdec))
+
+-- parsing in the xml file
+
+local predefined_unified = {
+ [38] = "&amp;",
+ [42] = "&quot;",
+ [47] = "&apos;",
+ [74] = "&lt;",
+ [76] = "&gr;",
+}
+
+local predefined_simplified = {
+ [38] = "&", amp = "&",
+ [42] = '"', quot = '"',
+ [47] = "'", apos = "'",
+ [74] = "<", lt = "<",
+ [76] = ">", gt = ">",
+}
+
local function handle_hex_entity(str)
local h = hcache[str]
if not h then
- if utfize then
- local n = tonumber(str,16)
+ local n = tonumber(str,16)
+ h = unify_predefined and predefined_unified[n]
+ if h then
+ if trace_entities then
+ logs.report("xml","utfize, converting hex entity &#x%s; into %s",str,h)
+ end
+ elseif utfize then
h = (n and utfchar(n)) or xml.unknown_hex_entity_format(str) or ""
if not n then
logs.report("xml","utfize, ignoring hex entity &#x%s;",str)
elseif trace_entities then
- logs.report("xml","utfize, converting hex entity &#x%s; into %s",str,c)
+ logs.report("xml","utfize, converting hex entity &#x%s; into %s",str,h)
end
else
if trace_entities then
logs.report("xml","found entity &#x%s;",str)
end
- h = "&#c" .. str .. ";"
+ h = "&#x" .. str .. ";"
end
hcache[str] = h
end
@@ -4103,13 +4153,18 @@ end
local function handle_dec_entity(str)
local d = dcache[str]
if not d then
- if utfize then
- local n = tonumber(str)
+ local n = tonumber(str)
+ d = unify_predefined and predefined_unified[n]
+ if d then
+ if trace_entities then
+ logs.report("xml","utfize, converting dec entity &#%s; into %s",str,d)
+ end
+ elseif utfize then
d = (n and utfchar(n)) or xml.unknown_dec_entity_format(str) or ""
if not n then
logs.report("xml","utfize, ignoring dec entity &#%s;",str)
elseif trace_entities then
- logs.report("xml","utfize, converting dec entity &#%s; into %s",str,c)
+ logs.report("xml","utfize, converting dec entity &#%s; into %s",str,h)
end
else
if trace_entities then
@@ -4122,48 +4177,13 @@ local function handle_dec_entity(str)
return d
end
--- one level expansion (simple case)
-
-local function fromhex(s)
- local n = tonumber(s,16)
- if n then
- return utfchar(n)
- else
- return format("h:%s",s), true
- end
-end
-
-local function fromdec(s)
- local n = tonumber(s)
- if n then
- return utfchar(n)
- else
- return format("d:%s",s), true
- end
-end
-
-local rest = (1-P(";"))^0
-local many = P(1)^0
-
-local parsedentity =
- P("&") * (P("#x")*(rest/fromhex) + P("#")*(rest/fromdec)) * P(";") * P(-1) +
- (P("#x")*(many/fromhex) + P("#")*(many/fromdec))
-
xml.parsedentitylpeg = parsedentity
-local predefined = {
- amp = "&",
- lt = "<",
- gt = ">",
- quot = '"',
- apos = "'",
-}
-
local function handle_any_entity(str)
if resolve then
local a = acache[str] -- per instance ! todo
if not a then
- a = resolve_predefined and predefined[str]
+ a = resolve_predefined and predefined_simplified[str]
if a then
-- one of the predefined
elseif type(resolve) == "function" then
@@ -4209,7 +4229,7 @@ local function handle_any_entity(str)
if trace_entities then
logs.report("xml","found entity &%s;",str)
end
- a = resolve_predefined and predefined[str]
+ a = resolve_predefined and predefined_simplified[str]
if a then
-- one of the predefined
acache[str] = a
@@ -4359,6 +4379,7 @@ local function xmlconvert(data, settings)
utfize = settings.utfize_entities
resolve = settings.resolve_entities
resolve_predefined = settings.resolve_predefined_entities -- in case we have escaped entities
+ unify_predefined = settings.unify_predefined_entities -- &#038; -> &amp;
cleanup = settings.text_cleanup
stack, top, at, xmlns, errorstr, result, entities = { }, { }, { }, { }, nil, nil, settings.entities or { }
acache, hcache, dcache = { }, { }, { } -- not stored
@@ -4465,21 +4486,19 @@ the whole file first. The function accepts a string representing
a filename or a file handle.</p>
--ldx]]--
-function xml.load(filename)
+function xml.load(filename,settings)
+ local data = ""
if type(filename) == "string" then
+ -- local data = io.loaddata(filename) - -todo: check type in io.loaddata
local f = io.open(filename,'r')
if f then
- local root = xmlconvert(f:read("*all"))
+ data = f:read("*all")
f:close()
- return root
- else
- return xmlconvert("")
end
elseif filename then -- filehandle
- return xmlconvert(filename:read("*all"))
- else
- return xmlconvert("")
+ data = filename:read("*all")
end
+ return xmlconvert(data,settings)
end
--[[ldx--
@@ -5109,17 +5128,17 @@ apply_axis['child'] = function(list)
for l=1,#list do
local ll = list[l]
local dt = ll.dt
-local en = 0
+ local en = 0
for k=1,#dt do
local dk = dt[k]
if dk.tg then
collected[#collected+1] = dk
dk.ni = k -- refresh
-en = en + 1
-dk.ei = en
+ en = en + 1
+ dk.ei = en
end
end
-ll.en = en
+ ll.en = en
end
return collected
end
@@ -5127,18 +5146,18 @@ end
local function collect(list,collected)
local dt = list.dt
if dt then
-local en = 0
+ local en = 0
for k=1,#dt do
local dk = dt[k]
if dk.tg then
collected[#collected+1] = dk
dk.ni = k -- refresh
-en = en + 1
-dk.ei = en
+ en = en + 1
+ dk.ei = en
collect(dk,collected)
end
end
-list.en = en
+ list.en = en
end
end
apply_axis['descendant'] = function(list)
@@ -5152,18 +5171,18 @@ end
local function collect(list,collected)
local dt = list.dt
if dt then
-local en = 0
+ local en = 0
for k=1,#dt do
local dk = dt[k]
if dk.tg then
collected[#collected+1] = dk
dk.ni = k -- refresh
-en = en + 1
-dk.ei = en
+ en = en + 1
+ dk.ei = en
collect(dk,collected)
end
end
-list.en = en
+ list.en = en
end
end
apply_axis['descendant-or-self'] = function(list)
@@ -5800,17 +5819,17 @@ parse_pattern = function (pattern) -- the gain of caching is rather minimal
add_comment(parsed, "initial-child removed") -- we could also make it a auto-self
remove(parsed,1)
end
-local np = #parsed -- can have changed
-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
+ local np = #parsed -- can have changed
+ 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
else
parsed = { pattern = pattern }
@@ -5836,6 +5855,10 @@ end
-- caching found lookups saves not that much (max .1 sec on a 8 sec run)
-- and it also messes up finalizers
+-- watch out: when there is a finalizer, it's always called as there
+-- can be cases that a finalizer returns (or does) something in case
+-- there is no match; an example of this is count()
+
local profiled = { } xml.profiled = profiled
local function profiled_apply(list,parsed,nofparsed,order)
@@ -5863,6 +5886,12 @@ local function profiled_apply(list,parsed,nofparsed,order)
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
@@ -5894,10 +5923,16 @@ local function traced_apply(list,parsed,nofparsed,order)
logs.report("lpath", "% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
elseif kind == "finalizer" then
collected = pi.finalizer(collected)
- logs.report("lpath", "% 10i : fi : %s : %s(%s)",(collected and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
+ logs.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)
+ logs.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
@@ -5922,6 +5957,10 @@ local function normal_apply(list,parsed,nofparsed,order)
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) -- can be anything
+ end
return nil
end
end
@@ -6698,7 +6737,7 @@ function xml.strip_whitespace(root, pattern, nolines) -- strips all leading and
end
end
else
---~ str.ni = i
+ --~ str.ni = i
t[#t+1] = str
end
end
@@ -6708,6 +6747,78 @@ function xml.strip_whitespace(root, pattern, nolines) -- strips all leading and
end
end
+function xml.strip_whitespace(root, pattern, nolines, anywhere) -- strips all leading and trailing spacing
+ local collected = xmlparseapply({ root },pattern) -- beware, indices no longer are valid now
+ if collected then
+ for i=1,#collected do
+ local e = collected[i]
+ local edt = e.dt
+ if edt then
+ if anywhere then
+ local t = { }
+ for e=1,#edt do
+ local str = edt[e]
+ if type(str) ~= "string" then
+ t[#t+1] = str
+ elseif str ~= "" then
+ -- todo: lpeg for each case
+ if nolines then
+ str = gsub(str,"%s+"," ")
+ end
+ str = gsub(str,"^%s*(.-)%s*$","%1")
+ if str ~= "" then
+ t[#t+1] = str
+ end
+ end
+ end
+ e.dt = t
+ else
+ -- we can assume a regular sparse xml table with no successive strings
+ -- otherwise we should use a while loop
+ if #edt > 0 then
+ -- strip front
+ local str = edt[1]
+ if type(str) ~= "string" then
+ -- nothing
+ elseif str == "" then
+ remove(edt,1)
+ else
+ if nolines then
+ str = gsub(str,"%s+"," ")
+ end
+ str = gsub(str,"^%s+","")
+ if str == "" then
+ remove(edt,1)
+ else
+ edt[1] = str
+ end
+ end
+ end
+ if #edt > 1 then
+ -- strip end
+ local str = edt[#edt]
+ if type(str) ~= "string" then
+ -- nothing
+ elseif str == "" then
+ remove(edt)
+ else
+ if nolines then
+ str = gsub(str,"%s+"," ")
+ end
+ str = gsub(str,"%s+$","")
+ if str == "" then
+ remove(edt)
+ else
+ edt[#edt] = str
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
local function rename_space(root, oldspace, newspace) -- fast variant
local ndt = #root.dt
for i=1,ndt or 0 do
@@ -10623,11 +10734,13 @@ function statistics.check_fmt_status(texname)
local luv = dofile(luvname)
if luv and luv.sourcefile then
local sourcehash = md5.hex(io.loaddata(resolvers.find_file(luv.sourcefile)) or "unknown")
- if luv.enginebanner and luv.enginebanner ~= enginebanner then
- return "engine mismatch"
+ local luvbanner = luv.enginebanner or "?"
+ if luvbanner ~= enginebanner then
+ return string.format("engine mismatch (luv:%s <> bin:%s)",luvbanner,enginebanner)
end
- if luv.sourcehash and luv.sourcehash ~= sourcehash then
- return "source mismatch"
+ local luvhash = luv.sourcehash or "?"
+ if luvhash ~= sourcehash then
+ return string.format("source mismatch (luv:%s <> bin:%s)",luvhash,sourcehash)
end
else
return "invalid status file"
@@ -10982,7 +11095,7 @@ local _path_, libpaths, _cpath_, clibpaths
function package.libpaths()
if not _path_ or package.path ~= _path_ then
_path_ = package.path
- libpaths = file.split_path(_path_)
+ libpaths = file.split_path(_path_,";")
end
return libpaths
end
@@ -10990,7 +11103,7 @@ end
function package.clibpaths()
if not _cpath_ or package.cpath ~= _cpath_ then
_cpath_ = package.cpath
- clibpaths = file.split_path(_cpath_)
+ clibpaths = file.split_path(_cpath_,";")
end
return clibpaths
end
diff --git a/scripts/context/perl/mptopdf.pl b/scripts/context/perl/mptopdf.pl
index a6b946baa..41d1ae1f7 100644
--- a/scripts/context/perl/mptopdf.pl
+++ b/scripts/context/perl/mptopdf.pl
@@ -104,7 +104,7 @@ if (($pattern eq '')||($Help)) {
my $error = system ($runner) ;
if ($error) {
print "\n$program : error while processing mp file\n" ;
- exit ;
+ exit 1 ;
} else {
$pattern =~ s/\.mp$//io ;
@files = glob "$pattern.*" ;
@@ -131,7 +131,11 @@ foreach my $file (@files) {
} else {
$command = "$command \\\\relax $file" ;
}
- system($command) ;
+ my $error = system($command) ;
+ if ($error) {
+ print "\n$program : error while processing tex file\n" ;
+ exit 1 ;
+ }
my $pdfsrc = basename($_).".pdf";
rename ($pdfsrc, "$_-$1.pdf") ;
if (-e $pdfsrc) {
diff --git a/scripts/context/stubs/mswin/luatools.lua b/scripts/context/stubs/mswin/luatools.lua
index 35a61ea43..ccedd97cd 100644
--- a/scripts/context/stubs/mswin/luatools.lua
+++ b/scripts/context/stubs/mswin/luatools.lua
@@ -7419,11 +7419,13 @@ function statistics.check_fmt_status(texname)
local luv = dofile(luvname)
if luv and luv.sourcefile then
local sourcehash = md5.hex(io.loaddata(resolvers.find_file(luv.sourcefile)) or "unknown")
- if luv.enginebanner and luv.enginebanner ~= enginebanner then
- return "engine mismatch"
+ local luvbanner = luv.enginebanner or "?"
+ if luvbanner ~= enginebanner then
+ return string.format("engine mismatch (luv:%s <> bin:%s)",luvbanner,enginebanner)
end
- if luv.sourcehash and luv.sourcehash ~= sourcehash then
- return "source mismatch"
+ local luvhash = luv.sourcehash or "?"
+ if luvhash ~= sourcehash then
+ return string.format("source mismatch (luv:%s <> bin:%s)",luvhash,sourcehash)
end
else
return "invalid status file"
diff --git a/scripts/context/stubs/mswin/mtxrun.dll b/scripts/context/stubs/mswin/mtxrun.dll
index 1ccb76efc..23e476cac 100644
--- a/scripts/context/stubs/mswin/mtxrun.dll
+++ b/scripts/context/stubs/mswin/mtxrun.dll
Binary files differ
diff --git a/scripts/context/stubs/mswin/mtxrun.exe b/scripts/context/stubs/mswin/mtxrun.exe
index 35c8c24d7..745eaf224 100755
--- a/scripts/context/stubs/mswin/mtxrun.exe
+++ b/scripts/context/stubs/mswin/mtxrun.exe
Binary files differ
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 3c72f59d1..cefa3192b 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -3950,7 +3950,7 @@ element.</p>
local nsremap, resolvens = xml.xmlns, xml.resolvens
local stack, top, dt, at, xmlns, errorstr, entities = { }, { }, { }, { }, { }, nil, { }
-local strip, cleanup, utfize, resolve, resolve_predefined = false, false, false, false, false
+local strip, cleanup, utfize, resolve, resolve_predefined, unify_predefined = false, false, false, false, false, false
local dcache, hcache, acache = { }, { }, { }
local mt = { }
@@ -4078,22 +4078,72 @@ function xml.unknown_dec_entity_format(str) return (str == "" and "&error;") or
function xml.unknown_hex_entity_format(str) return format("&#x%s;",str) end
function xml.unknown_any_entity_format(str) return format("&#x%s;",str) end
+local function fromhex(s)
+ local n = tonumber(s,16)
+ if n then
+ return utfchar(n)
+ else
+ return format("h:%s",s), true
+ end
+end
+
+local function fromdec(s)
+ local n = tonumber(s)
+ if n then
+ return utfchar(n)
+ else
+ return format("d:%s",s), true
+ end
+end
+
+-- one level expansion (simple case), no checking done
+
+local rest = (1-P(";"))^0
+local many = P(1)^0
+
+local parsedentity =
+ P("&") * (P("#x")*(rest/fromhex) + P("#")*(rest/fromdec)) * P(";") * P(-1) +
+ (P("#x")*(many/fromhex) + P("#")*(many/fromdec))
+
+-- parsing in the xml file
+
+local predefined_unified = {
+ [38] = "&amp;",
+ [42] = "&quot;",
+ [47] = "&apos;",
+ [74] = "&lt;",
+ [76] = "&gr;",
+}
+
+local predefined_simplified = {
+ [38] = "&", amp = "&",
+ [42] = '"', quot = '"',
+ [47] = "'", apos = "'",
+ [74] = "<", lt = "<",
+ [76] = ">", gt = ">",
+}
+
local function handle_hex_entity(str)
local h = hcache[str]
if not h then
- if utfize then
- local n = tonumber(str,16)
+ local n = tonumber(str,16)
+ h = unify_predefined and predefined_unified[n]
+ if h then
+ if trace_entities then
+ logs.report("xml","utfize, converting hex entity &#x%s; into %s",str,h)
+ end
+ elseif utfize then
h = (n and utfchar(n)) or xml.unknown_hex_entity_format(str) or ""
if not n then
logs.report("xml","utfize, ignoring hex entity &#x%s;",str)
elseif trace_entities then
- logs.report("xml","utfize, converting hex entity &#x%s; into %s",str,c)
+ logs.report("xml","utfize, converting hex entity &#x%s; into %s",str,h)
end
else
if trace_entities then
logs.report("xml","found entity &#x%s;",str)
end
- h = "&#c" .. str .. ";"
+ h = "&#x" .. str .. ";"
end
hcache[str] = h
end
@@ -4103,13 +4153,18 @@ end
local function handle_dec_entity(str)
local d = dcache[str]
if not d then
- if utfize then
- local n = tonumber(str)
+ local n = tonumber(str)
+ d = unify_predefined and predefined_unified[n]
+ if d then
+ if trace_entities then
+ logs.report("xml","utfize, converting dec entity &#%s; into %s",str,d)
+ end
+ elseif utfize then
d = (n and utfchar(n)) or xml.unknown_dec_entity_format(str) or ""
if not n then
logs.report("xml","utfize, ignoring dec entity &#%s;",str)
elseif trace_entities then
- logs.report("xml","utfize, converting dec entity &#%s; into %s",str,c)
+ logs.report("xml","utfize, converting dec entity &#%s; into %s",str,h)
end
else
if trace_entities then
@@ -4122,48 +4177,13 @@ local function handle_dec_entity(str)
return d
end
--- one level expansion (simple case)
-
-local function fromhex(s)
- local n = tonumber(s,16)
- if n then
- return utfchar(n)
- else
- return format("h:%s",s), true
- end
-end
-
-local function fromdec(s)
- local n = tonumber(s)
- if n then
- return utfchar(n)
- else
- return format("d:%s",s), true
- end
-end
-
-local rest = (1-P(";"))^0
-local many = P(1)^0
-
-local parsedentity =
- P("&") * (P("#x")*(rest/fromhex) + P("#")*(rest/fromdec)) * P(";") * P(-1) +
- (P("#x")*(many/fromhex) + P("#")*(many/fromdec))
-
xml.parsedentitylpeg = parsedentity
-local predefined = {
- amp = "&",
- lt = "<",
- gt = ">",
- quot = '"',
- apos = "'",
-}
-
local function handle_any_entity(str)
if resolve then
local a = acache[str] -- per instance ! todo
if not a then
- a = resolve_predefined and predefined[str]
+ a = resolve_predefined and predefined_simplified[str]
if a then
-- one of the predefined
elseif type(resolve) == "function" then
@@ -4209,7 +4229,7 @@ local function handle_any_entity(str)
if trace_entities then
logs.report("xml","found entity &%s;",str)
end
- a = resolve_predefined and predefined[str]
+ a = resolve_predefined and predefined_simplified[str]
if a then
-- one of the predefined
acache[str] = a
@@ -4359,6 +4379,7 @@ local function xmlconvert(data, settings)
utfize = settings.utfize_entities
resolve = settings.resolve_entities
resolve_predefined = settings.resolve_predefined_entities -- in case we have escaped entities
+ unify_predefined = settings.unify_predefined_entities -- &#038; -> &amp;
cleanup = settings.text_cleanup
stack, top, at, xmlns, errorstr, result, entities = { }, { }, { }, { }, nil, nil, settings.entities or { }
acache, hcache, dcache = { }, { }, { } -- not stored
@@ -4465,21 +4486,19 @@ the whole file first. The function accepts a string representing
a filename or a file handle.</p>
--ldx]]--
-function xml.load(filename)
+function xml.load(filename,settings)
+ local data = ""
if type(filename) == "string" then
+ -- local data = io.loaddata(filename) - -todo: check type in io.loaddata
local f = io.open(filename,'r')
if f then
- local root = xmlconvert(f:read("*all"))
+ data = f:read("*all")
f:close()
- return root
- else
- return xmlconvert("")
end
elseif filename then -- filehandle
- return xmlconvert(filename:read("*all"))
- else
- return xmlconvert("")
+ data = filename:read("*all")
end
+ return xmlconvert(data,settings)
end
--[[ldx--
@@ -5109,17 +5128,17 @@ apply_axis['child'] = function(list)
for l=1,#list do
local ll = list[l]
local dt = ll.dt
-local en = 0
+ local en = 0
for k=1,#dt do
local dk = dt[k]
if dk.tg then
collected[#collected+1] = dk
dk.ni = k -- refresh
-en = en + 1
-dk.ei = en
+ en = en + 1
+ dk.ei = en
end
end
-ll.en = en
+ ll.en = en
end
return collected
end
@@ -5127,18 +5146,18 @@ end
local function collect(list,collected)
local dt = list.dt
if dt then
-local en = 0
+ local en = 0
for k=1,#dt do
local dk = dt[k]
if dk.tg then
collected[#collected+1] = dk
dk.ni = k -- refresh
-en = en + 1
-dk.ei = en
+ en = en + 1
+ dk.ei = en
collect(dk,collected)
end
end
-list.en = en
+ list.en = en
end
end
apply_axis['descendant'] = function(list)
@@ -5152,18 +5171,18 @@ end
local function collect(list,collected)
local dt = list.dt
if dt then
-local en = 0
+ local en = 0
for k=1,#dt do
local dk = dt[k]
if dk.tg then
collected[#collected+1] = dk
dk.ni = k -- refresh
-en = en + 1
-dk.ei = en
+ en = en + 1
+ dk.ei = en
collect(dk,collected)
end
end
-list.en = en
+ list.en = en
end
end
apply_axis['descendant-or-self'] = function(list)
@@ -5800,17 +5819,17 @@ parse_pattern = function (pattern) -- the gain of caching is rather minimal
add_comment(parsed, "initial-child removed") -- we could also make it a auto-self
remove(parsed,1)
end
-local np = #parsed -- can have changed
-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
+ local np = #parsed -- can have changed
+ 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
else
parsed = { pattern = pattern }
@@ -5836,6 +5855,10 @@ end
-- caching found lookups saves not that much (max .1 sec on a 8 sec run)
-- and it also messes up finalizers
+-- watch out: when there is a finalizer, it's always called as there
+-- can be cases that a finalizer returns (or does) something in case
+-- there is no match; an example of this is count()
+
local profiled = { } xml.profiled = profiled
local function profiled_apply(list,parsed,nofparsed,order)
@@ -5863,6 +5886,12 @@ local function profiled_apply(list,parsed,nofparsed,order)
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
@@ -5894,10 +5923,16 @@ local function traced_apply(list,parsed,nofparsed,order)
logs.report("lpath", "% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
elseif kind == "finalizer" then
collected = pi.finalizer(collected)
- logs.report("lpath", "% 10i : fi : %s : %s(%s)",(collected and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
+ logs.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)
+ logs.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
@@ -5922,6 +5957,10 @@ local function normal_apply(list,parsed,nofparsed,order)
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) -- can be anything
+ end
return nil
end
end
@@ -6698,7 +6737,7 @@ function xml.strip_whitespace(root, pattern, nolines) -- strips all leading and
end
end
else
---~ str.ni = i
+ --~ str.ni = i
t[#t+1] = str
end
end
@@ -6708,6 +6747,78 @@ function xml.strip_whitespace(root, pattern, nolines) -- strips all leading and
end
end
+function xml.strip_whitespace(root, pattern, nolines, anywhere) -- strips all leading and trailing spacing
+ local collected = xmlparseapply({ root },pattern) -- beware, indices no longer are valid now
+ if collected then
+ for i=1,#collected do
+ local e = collected[i]
+ local edt = e.dt
+ if edt then
+ if anywhere then
+ local t = { }
+ for e=1,#edt do
+ local str = edt[e]
+ if type(str) ~= "string" then
+ t[#t+1] = str
+ elseif str ~= "" then
+ -- todo: lpeg for each case
+ if nolines then
+ str = gsub(str,"%s+"," ")
+ end
+ str = gsub(str,"^%s*(.-)%s*$","%1")
+ if str ~= "" then
+ t[#t+1] = str
+ end
+ end
+ end
+ e.dt = t
+ else
+ -- we can assume a regular sparse xml table with no successive strings
+ -- otherwise we should use a while loop
+ if #edt > 0 then
+ -- strip front
+ local str = edt[1]
+ if type(str) ~= "string" then
+ -- nothing
+ elseif str == "" then
+ remove(edt,1)
+ else
+ if nolines then
+ str = gsub(str,"%s+"," ")
+ end
+ str = gsub(str,"^%s+","")
+ if str == "" then
+ remove(edt,1)
+ else
+ edt[1] = str
+ end
+ end
+ end
+ if #edt > 1 then
+ -- strip end
+ local str = edt[#edt]
+ if type(str) ~= "string" then
+ -- nothing
+ elseif str == "" then
+ remove(edt)
+ else
+ if nolines then
+ str = gsub(str,"%s+"," ")
+ end
+ str = gsub(str,"%s+$","")
+ if str == "" then
+ remove(edt)
+ else
+ edt[#edt] = str
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
local function rename_space(root, oldspace, newspace) -- fast variant
local ndt = #root.dt
for i=1,ndt or 0 do
@@ -10623,11 +10734,13 @@ function statistics.check_fmt_status(texname)
local luv = dofile(luvname)
if luv and luv.sourcefile then
local sourcehash = md5.hex(io.loaddata(resolvers.find_file(luv.sourcefile)) or "unknown")
- if luv.enginebanner and luv.enginebanner ~= enginebanner then
- return "engine mismatch"
+ local luvbanner = luv.enginebanner or "?"
+ if luvbanner ~= enginebanner then
+ return string.format("engine mismatch (luv:%s <> bin:%s)",luvbanner,enginebanner)
end
- if luv.sourcehash and luv.sourcehash ~= sourcehash then
- return "source mismatch"
+ local luvhash = luv.sourcehash or "?"
+ if luvhash ~= sourcehash then
+ return string.format("source mismatch (luv:%s <> bin:%s)",luvhash,sourcehash)
end
else
return "invalid status file"
@@ -10982,7 +11095,7 @@ local _path_, libpaths, _cpath_, clibpaths
function package.libpaths()
if not _path_ or package.path ~= _path_ then
_path_ = package.path
- libpaths = file.split_path(_path_)
+ libpaths = file.split_path(_path_,";")
end
return libpaths
end
@@ -10990,7 +11103,7 @@ end
function package.clibpaths()
if not _cpath_ or package.cpath ~= _cpath_ then
_cpath_ = package.cpath
- clibpaths = file.split_path(_cpath_)
+ clibpaths = file.split_path(_cpath_,";")
end
return clibpaths
end
diff --git a/scripts/context/stubs/source/mtxrun_dll.c b/scripts/context/stubs/source/mtxrun_dll.c
index 540bed38b..5b7cd31a0 100644
--- a/scripts/context/stubs/source/mtxrun_dll.c
+++ b/scripts/context/stubs/source/mtxrun_dll.c
@@ -5,8 +5,8 @@
Public Domain
Originally written in 2010 by Tomasz M. Trzeciak and Hans Hagen
- This program is derived from the 'runscript' program originally
- written in 2009 by T.M. Trzeciak. It has been adapted for use in
+ This program is derived from the 'runscript' program originally
+ written in 2009 by T.M. Trzeciak. It has been adapted for use in
ConTeXt MkIV.
Comment:
@@ -18,26 +18,26 @@
mtxrun --script font --reload
Here mtxrun is a lua script. In order to avoid the usage of a cmd
- file on windows this runner will start texlua directly. If the
- shared library luatex.dll is available, texlua will be started in
- the same process avoiding thus any additional overhead. Otherwise
+ file on windows this runner will start texlua directly. If the
+ shared library luatex.dll is available, texlua will be started in
+ the same process avoiding thus any additional overhead. Otherwise
it will be spawned in a new proces.
We also don't want to use other runners, like those that use kpse
to locate the script as this is exactly what mtxrun itself is doing
already. Therefore the runscript program is adapted to a more direct
approach suitable for mtxrun.
-
+
Compilation:
with gcc (size optimized):
- gcc -Os -s -shared -o mtxrun.dll mtxrun_dll.c
+ gcc -Os -s -shared -o mtxrun.dll mtxrun_dll.c
gcc -Os -s -o mtxrun.exe mtxrun_exe.c -L./ -lmtxrun
with tcc (extra small size):
-
- tcc -shared -o mtxrun.dll mtxrun_dll.c
+
+ tcc -shared -o mtxrun.dll mtxrun_dll.c
tcc -o mtxrun.exe mtxrun_exe.c mtxrun.def
************************************************************************/
@@ -60,46 +60,45 @@ static char cmdline[MAX_CMD];
static char dirpath[MAX_PATH];
static char progname[MAX_PATH];
static char scriptpath[MAX_PATH];
+static char luatexpath[MAX_PATH];
HMODULE dllluatex = NULL;
typedef int ( *mainlikeproc )( int, char ** );
#ifdef STATIC
-int main( int argc, char *argv[] )
+int main( int argc, char *argv[] )
#else
-__declspec(dllexport) int dllrunscript( int argc, char *argv[] )
+__declspec(dllexport) int dllrunscript( int argc, char *argv[] )
#endif
{
- char *s, *argstr, **lua_argv;
+ char *s, *luatexfname, *argstr, **lua_argv;
int k, quoted, lua_argc;
int passprogname = 0;
// directory of this module/executable
-
- HMODULE module_handle = GetModuleHandle( "mtxrun.dll" );
+
+ HMODULE module_handle = GetModuleHandle( "mtxrun.dll" );
// if ( module_handle == NULL ) exe path will be used, which is OK too
k = (int) GetModuleFileName( module_handle, dirpath, MAX_PATH );
- if ( !k || ( k == MAX_PATH ) )
+ if ( !k || ( k == MAX_PATH ) )
DIE( "unable to determine a valid module name\n" );
s = strrchr(dirpath, '\\');
if ( s == NULL ) DIE( "no directory part in module path: %s\n", dirpath );
*(++s) = '\0'; //remove file name, leave trailing backslash
-
+
// program name
-
+
k = strlen(argv[0]);
- while ( k && (argv[0][k] != '/') && (argv[0][k] != '\\') ) k--;
- if ((argv[0][k] == '/') || (argv[0][k] == '\\')) k++; // correct for slash
- // while ( k && (argv[0][k-1] != '/') && (argv[0][k-1] != '\\') ) k--;
+ while ( k && (argv[0][k-1] != '/') && (argv[0][k-1] != '\\') ) k--;
strcpy(progname, &argv[0][k]);
s = progname;
if ( s = strrchr(s, '.') ) *s = '\0'; // remove file extension part
-
+
// script path
-
+
strcpy( scriptpath, dirpath );
k = strlen(progname);
if ( k < 6 ) k = 6; // in case the program name is shorter than "mtxrun"
- if ( strlen(dirpath) + k + 4 >= MAX_PATH )
+ if ( strlen(dirpath) + k + 4 >= MAX_PATH )
DIE( "path too long: %s%s\n", dirpath, progname );
if ( ( strcmpi(progname,"mtxrun") == 0 ) || ( strcmpi(progname,"luatools") == 0 ) ) {
strcat( scriptpath, progname );
@@ -108,19 +107,31 @@ __declspec(dllexport) int dllrunscript( int argc, char *argv[] )
strcat( scriptpath, "mtxrun.lua" );
if ( strcmpi(progname,"texmfstart") != 0 ) passprogname = 1;
}
- if ( GetFileAttributes(scriptpath) == INVALID_FILE_ATTRIBUTES )
+ if ( GetFileAttributes(scriptpath) == INVALID_FILE_ATTRIBUTES )
DIE( "file not found: %s\n", scriptpath );
+
+ // find texlua.exe
+
+ if ( !SearchPath(
+ getenv( "PATH" ), // path to search (optional)
+ "texlua.exe", // file name to search
+ NULL, // file extension to add (optional)
+ MAX_PATH, // output buffer size
+ luatexpath, // output buffer pointer
+ &luatexfname ) // pointer to a file part in the output buffer (optional)
+ ) DIE( "unable to locate texlua.exe on the search path" );
- // link with luatex.dll if available
+ // link directly with luatex.dll if available in texlua's dir
- if ( dllluatex = LoadLibrary("luatex.dll") )
+ strcpy( luatexfname, "luatex.dll" );
+ if ( dllluatex = LoadLibrary(luatexpath) )
{
mainlikeproc dllluatexmain = (mainlikeproc) GetProcAddress( dllluatex, "dllluatexmain" );
- if ( dllluatexmain == NULL )
+ if ( dllluatexmain == NULL )
DIE( "unable to locate dllluatexmain procedure in luatex.dll" );
-
+
// set up argument list for texlua script
-
+
lua_argv = (char **)malloc( (argc + 4) * sizeof(char *) );
if ( lua_argv == NULL ) DIE( "out of memory\n" );
lua_argv[lua_argc=0] = texlua_name;
@@ -128,29 +139,23 @@ __declspec(dllexport) int dllrunscript( int argc, char *argv[] )
if (passprogname) {
lua_argv[++lua_argc] = "--script";
lua_argv[++lua_argc] = progname;
- }
+ }
for ( k = 1; k < argc; k++ ) lua_argv[++lua_argc] = argv[k];
lua_argv[++lua_argc] = NULL;
// call texlua interpreter
// dllluatexmain never returns, but we pretend that it does
-
+
k = dllluatexmain( lua_argc, lua_argv );
if (lua_argv) free( lua_argv );
return k;
}
-
+
// we are still here, so no luatex.dll; spawn texlua.exe instead
+ strcpy( luatexfname, "texlua.exe" );
strcpy( cmdline, "\"" );
- if ( !SearchPath(
- getenv( "PATH" ), // path to search (optional)
- "texlua.exe", // file name to search
- NULL, // file extension to add (optional)
- MAX_CMD - 3, // output buffer size
- &cmdline[1], // output buffer pointer
- NULL ) // pointer to a file part variable (optional)
- ) DIE( "unable to locate texlua.exe on the search path" );
+ strcat( cmdline, luatexpath );
strcat( cmdline, "\" \"" );
strcat( cmdline, scriptpath );
strcat( cmdline, "\"" );
@@ -158,24 +163,24 @@ __declspec(dllexport) int dllrunscript( int argc, char *argv[] )
strcat( cmdline, " --script " );
strcat( cmdline, progname );
}
-
+
argstr = GetCommandLine(); // get the command line of this process
if ( argstr == NULL ) DIE( "unable to retrieve the command line string\n" );
// skip over argv[0] in the argument string
// (it can contain embedded double quotes if launched from cmd.exe!)
-
- for ( quoted = 0; (*argstr) && ( !IS_WHITESPACE(*argstr) || quoted ); argstr++ )
+
+ for ( quoted = 0; (*argstr) && ( !IS_WHITESPACE(*argstr) || quoted ); argstr++ )
if (*argstr == '"') quoted = !quoted;
-
+
// pass through all the arguments
-
- if ( strlen(cmdline) + strlen(argstr) >= MAX_CMD )
+
+ if ( strlen(cmdline) + strlen(argstr) >= MAX_CMD )
DIE( "command line string too long:\n%s%s\n", cmdline, argstr );
- strcat( cmdline, argstr );
-
+ strcat( cmdline, argstr );
+
// create child process
-
+
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
@@ -187,7 +192,7 @@ __declspec(dllexport) int dllrunscript( int argc, char *argv[] )
si.hStdOutput = GetStdHandle( STD_OUTPUT_HANDLE );
si.hStdError = GetStdHandle( STD_ERROR_HANDLE );
ZeroMemory( &pi, sizeof(pi) );
-
+
if( !CreateProcess(
NULL, // module name (uses command line if NULL)
cmdline, // command line
@@ -200,17 +205,17 @@ __declspec(dllexport) int dllrunscript( int argc, char *argv[] )
&si, // STARTUPINFO structure
&pi ) // PROCESS_INFORMATION structure
) DIE( "command execution failed: %s\n", cmdline );
-
+
DWORD ret = 0;
CloseHandle( pi.hThread ); // thread handle is not needed
if ( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_OBJECT_0 ) {
- if ( !GetExitCodeProcess( pi.hProcess, &ret) )
+ if ( !GetExitCodeProcess( pi.hProcess, &ret) )
DIE( "unable to retrieve process exit code: %s\n", cmdline );
} else DIE( "failed to wait for process termination: %s\n", cmdline );
CloseHandle( pi.hProcess );
-
+
// propagate exit code from the child process
-
- return ret;
-
+
+ return ret;
+
}
diff --git a/scripts/context/stubs/unix/luatools b/scripts/context/stubs/unix/luatools
index 35a61ea43..ccedd97cd 100755
--- a/scripts/context/stubs/unix/luatools
+++ b/scripts/context/stubs/unix/luatools
@@ -7419,11 +7419,13 @@ function statistics.check_fmt_status(texname)
local luv = dofile(luvname)
if luv and luv.sourcefile then
local sourcehash = md5.hex(io.loaddata(resolvers.find_file(luv.sourcefile)) or "unknown")
- if luv.enginebanner and luv.enginebanner ~= enginebanner then
- return "engine mismatch"
+ local luvbanner = luv.enginebanner or "?"
+ if luvbanner ~= enginebanner then
+ return string.format("engine mismatch (luv:%s <> bin:%s)",luvbanner,enginebanner)
end
- if luv.sourcehash and luv.sourcehash ~= sourcehash then
- return "source mismatch"
+ local luvhash = luv.sourcehash or "?"
+ if luvhash ~= sourcehash then
+ return string.format("source mismatch (luv:%s <> bin:%s)",luvhash,sourcehash)
end
else
return "invalid status file"
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 3c72f59d1..cefa3192b 100755
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -3950,7 +3950,7 @@ element.</p>
local nsremap, resolvens = xml.xmlns, xml.resolvens
local stack, top, dt, at, xmlns, errorstr, entities = { }, { }, { }, { }, { }, nil, { }
-local strip, cleanup, utfize, resolve, resolve_predefined = false, false, false, false, false
+local strip, cleanup, utfize, resolve, resolve_predefined, unify_predefined = false, false, false, false, false, false
local dcache, hcache, acache = { }, { }, { }
local mt = { }
@@ -4078,22 +4078,72 @@ function xml.unknown_dec_entity_format(str) return (str == "" and "&error;") or
function xml.unknown_hex_entity_format(str) return format("&#x%s;",str) end
function xml.unknown_any_entity_format(str) return format("&#x%s;",str) end
+local function fromhex(s)
+ local n = tonumber(s,16)
+ if n then
+ return utfchar(n)
+ else
+ return format("h:%s",s), true
+ end
+end
+
+local function fromdec(s)
+ local n = tonumber(s)
+ if n then
+ return utfchar(n)
+ else
+ return format("d:%s",s), true
+ end
+end
+
+-- one level expansion (simple case), no checking done
+
+local rest = (1-P(";"))^0
+local many = P(1)^0
+
+local parsedentity =
+ P("&") * (P("#x")*(rest/fromhex) + P("#")*(rest/fromdec)) * P(";") * P(-1) +
+ (P("#x")*(many/fromhex) + P("#")*(many/fromdec))
+
+-- parsing in the xml file
+
+local predefined_unified = {
+ [38] = "&amp;",
+ [42] = "&quot;",
+ [47] = "&apos;",
+ [74] = "&lt;",
+ [76] = "&gr;",
+}
+
+local predefined_simplified = {
+ [38] = "&", amp = "&",
+ [42] = '"', quot = '"',
+ [47] = "'", apos = "'",
+ [74] = "<", lt = "<",
+ [76] = ">", gt = ">",
+}
+
local function handle_hex_entity(str)
local h = hcache[str]
if not h then
- if utfize then
- local n = tonumber(str,16)
+ local n = tonumber(str,16)
+ h = unify_predefined and predefined_unified[n]
+ if h then
+ if trace_entities then
+ logs.report("xml","utfize, converting hex entity &#x%s; into %s",str,h)
+ end
+ elseif utfize then
h = (n and utfchar(n)) or xml.unknown_hex_entity_format(str) or ""
if not n then
logs.report("xml","utfize, ignoring hex entity &#x%s;",str)
elseif trace_entities then
- logs.report("xml","utfize, converting hex entity &#x%s; into %s",str,c)
+ logs.report("xml","utfize, converting hex entity &#x%s; into %s",str,h)
end
else
if trace_entities then
logs.report("xml","found entity &#x%s;",str)
end
- h = "&#c" .. str .. ";"
+ h = "&#x" .. str .. ";"
end
hcache[str] = h
end
@@ -4103,13 +4153,18 @@ end
local function handle_dec_entity(str)
local d = dcache[str]
if not d then
- if utfize then
- local n = tonumber(str)
+ local n = tonumber(str)
+ d = unify_predefined and predefined_unified[n]
+ if d then
+ if trace_entities then
+ logs.report("xml","utfize, converting dec entity &#%s; into %s",str,d)
+ end
+ elseif utfize then
d = (n and utfchar(n)) or xml.unknown_dec_entity_format(str) or ""
if not n then
logs.report("xml","utfize, ignoring dec entity &#%s;",str)
elseif trace_entities then
- logs.report("xml","utfize, converting dec entity &#%s; into %s",str,c)
+ logs.report("xml","utfize, converting dec entity &#%s; into %s",str,h)
end
else
if trace_entities then
@@ -4122,48 +4177,13 @@ local function handle_dec_entity(str)
return d
end
--- one level expansion (simple case)
-
-local function fromhex(s)
- local n = tonumber(s,16)
- if n then
- return utfchar(n)
- else
- return format("h:%s",s), true
- end
-end
-
-local function fromdec(s)
- local n = tonumber(s)
- if n then
- return utfchar(n)
- else
- return format("d:%s",s), true
- end
-end
-
-local rest = (1-P(";"))^0
-local many = P(1)^0
-
-local parsedentity =
- P("&") * (P("#x")*(rest/fromhex) + P("#")*(rest/fromdec)) * P(";") * P(-1) +
- (P("#x")*(many/fromhex) + P("#")*(many/fromdec))
-
xml.parsedentitylpeg = parsedentity
-local predefined = {
- amp = "&",
- lt = "<",
- gt = ">",
- quot = '"',
- apos = "'",
-}
-
local function handle_any_entity(str)
if resolve then
local a = acache[str] -- per instance ! todo
if not a then
- a = resolve_predefined and predefined[str]
+ a = resolve_predefined and predefined_simplified[str]
if a then
-- one of the predefined
elseif type(resolve) == "function" then
@@ -4209,7 +4229,7 @@ local function handle_any_entity(str)
if trace_entities then
logs.report("xml","found entity &%s;",str)
end
- a = resolve_predefined and predefined[str]
+ a = resolve_predefined and predefined_simplified[str]
if a then
-- one of the predefined
acache[str] = a
@@ -4359,6 +4379,7 @@ local function xmlconvert(data, settings)
utfize = settings.utfize_entities
resolve = settings.resolve_entities
resolve_predefined = settings.resolve_predefined_entities -- in case we have escaped entities
+ unify_predefined = settings.unify_predefined_entities -- &#038; -> &amp;
cleanup = settings.text_cleanup
stack, top, at, xmlns, errorstr, result, entities = { }, { }, { }, { }, nil, nil, settings.entities or { }
acache, hcache, dcache = { }, { }, { } -- not stored
@@ -4465,21 +4486,19 @@ the whole file first. The function accepts a string representing
a filename or a file handle.</p>
--ldx]]--
-function xml.load(filename)
+function xml.load(filename,settings)
+ local data = ""
if type(filename) == "string" then
+ -- local data = io.loaddata(filename) - -todo: check type in io.loaddata
local f = io.open(filename,'r')
if f then
- local root = xmlconvert(f:read("*all"))
+ data = f:read("*all")
f:close()
- return root
- else
- return xmlconvert("")
end
elseif filename then -- filehandle
- return xmlconvert(filename:read("*all"))
- else
- return xmlconvert("")
+ data = filename:read("*all")
end
+ return xmlconvert(data,settings)
end
--[[ldx--
@@ -5109,17 +5128,17 @@ apply_axis['child'] = function(list)
for l=1,#list do
local ll = list[l]
local dt = ll.dt
-local en = 0
+ local en = 0
for k=1,#dt do
local dk = dt[k]
if dk.tg then
collected[#collected+1] = dk
dk.ni = k -- refresh
-en = en + 1
-dk.ei = en
+ en = en + 1
+ dk.ei = en
end
end
-ll.en = en
+ ll.en = en
end
return collected
end
@@ -5127,18 +5146,18 @@ end
local function collect(list,collected)
local dt = list.dt
if dt then
-local en = 0
+ local en = 0
for k=1,#dt do
local dk = dt[k]
if dk.tg then
collected[#collected+1] = dk
dk.ni = k -- refresh
-en = en + 1
-dk.ei = en
+ en = en + 1
+ dk.ei = en
collect(dk,collected)
end
end
-list.en = en
+ list.en = en
end
end
apply_axis['descendant'] = function(list)
@@ -5152,18 +5171,18 @@ end
local function collect(list,collected)
local dt = list.dt
if dt then
-local en = 0
+ local en = 0
for k=1,#dt do
local dk = dt[k]
if dk.tg then
collected[#collected+1] = dk
dk.ni = k -- refresh
-en = en + 1
-dk.ei = en
+ en = en + 1
+ dk.ei = en
collect(dk,collected)
end
end
-list.en = en
+ list.en = en
end
end
apply_axis['descendant-or-self'] = function(list)
@@ -5800,17 +5819,17 @@ parse_pattern = function (pattern) -- the gain of caching is rather minimal
add_comment(parsed, "initial-child removed") -- we could also make it a auto-self
remove(parsed,1)
end
-local np = #parsed -- can have changed
-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
+ local np = #parsed -- can have changed
+ 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
else
parsed = { pattern = pattern }
@@ -5836,6 +5855,10 @@ end
-- caching found lookups saves not that much (max .1 sec on a 8 sec run)
-- and it also messes up finalizers
+-- watch out: when there is a finalizer, it's always called as there
+-- can be cases that a finalizer returns (or does) something in case
+-- there is no match; an example of this is count()
+
local profiled = { } xml.profiled = profiled
local function profiled_apply(list,parsed,nofparsed,order)
@@ -5863,6 +5886,12 @@ local function profiled_apply(list,parsed,nofparsed,order)
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
@@ -5894,10 +5923,16 @@ local function traced_apply(list,parsed,nofparsed,order)
logs.report("lpath", "% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
elseif kind == "finalizer" then
collected = pi.finalizer(collected)
- logs.report("lpath", "% 10i : fi : %s : %s(%s)",(collected and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
+ logs.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)
+ logs.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
@@ -5922,6 +5957,10 @@ local function normal_apply(list,parsed,nofparsed,order)
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) -- can be anything
+ end
return nil
end
end
@@ -6698,7 +6737,7 @@ function xml.strip_whitespace(root, pattern, nolines) -- strips all leading and
end
end
else
---~ str.ni = i
+ --~ str.ni = i
t[#t+1] = str
end
end
@@ -6708,6 +6747,78 @@ function xml.strip_whitespace(root, pattern, nolines) -- strips all leading and
end
end
+function xml.strip_whitespace(root, pattern, nolines, anywhere) -- strips all leading and trailing spacing
+ local collected = xmlparseapply({ root },pattern) -- beware, indices no longer are valid now
+ if collected then
+ for i=1,#collected do
+ local e = collected[i]
+ local edt = e.dt
+ if edt then
+ if anywhere then
+ local t = { }
+ for e=1,#edt do
+ local str = edt[e]
+ if type(str) ~= "string" then
+ t[#t+1] = str
+ elseif str ~= "" then
+ -- todo: lpeg for each case
+ if nolines then
+ str = gsub(str,"%s+"," ")
+ end
+ str = gsub(str,"^%s*(.-)%s*$","%1")
+ if str ~= "" then
+ t[#t+1] = str
+ end
+ end
+ end
+ e.dt = t
+ else
+ -- we can assume a regular sparse xml table with no successive strings
+ -- otherwise we should use a while loop
+ if #edt > 0 then
+ -- strip front
+ local str = edt[1]
+ if type(str) ~= "string" then
+ -- nothing
+ elseif str == "" then
+ remove(edt,1)
+ else
+ if nolines then
+ str = gsub(str,"%s+"," ")
+ end
+ str = gsub(str,"^%s+","")
+ if str == "" then
+ remove(edt,1)
+ else
+ edt[1] = str
+ end
+ end
+ end
+ if #edt > 1 then
+ -- strip end
+ local str = edt[#edt]
+ if type(str) ~= "string" then
+ -- nothing
+ elseif str == "" then
+ remove(edt)
+ else
+ if nolines then
+ str = gsub(str,"%s+"," ")
+ end
+ str = gsub(str,"%s+$","")
+ if str == "" then
+ remove(edt)
+ else
+ edt[#edt] = str
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
local function rename_space(root, oldspace, newspace) -- fast variant
local ndt = #root.dt
for i=1,ndt or 0 do
@@ -10623,11 +10734,13 @@ function statistics.check_fmt_status(texname)
local luv = dofile(luvname)
if luv and luv.sourcefile then
local sourcehash = md5.hex(io.loaddata(resolvers.find_file(luv.sourcefile)) or "unknown")
- if luv.enginebanner and luv.enginebanner ~= enginebanner then
- return "engine mismatch"
+ local luvbanner = luv.enginebanner or "?"
+ if luvbanner ~= enginebanner then
+ return string.format("engine mismatch (luv:%s <> bin:%s)",luvbanner,enginebanner)
end
- if luv.sourcehash and luv.sourcehash ~= sourcehash then
- return "source mismatch"
+ local luvhash = luv.sourcehash or "?"
+ if luvhash ~= sourcehash then
+ return string.format("source mismatch (luv:%s <> bin:%s)",luvhash,sourcehash)
end
else
return "invalid status file"
@@ -10982,7 +11095,7 @@ local _path_, libpaths, _cpath_, clibpaths
function package.libpaths()
if not _path_ or package.path ~= _path_ then
_path_ = package.path
- libpaths = file.split_path(_path_)
+ libpaths = file.split_path(_path_,";")
end
return libpaths
end
@@ -10990,7 +11103,7 @@ end
function package.clibpaths()
if not _cpath_ or package.cpath ~= _cpath_ then
_cpath_ = package.cpath
- clibpaths = file.split_path(_cpath_)
+ clibpaths = file.split_path(_cpath_,";")
end
return clibpaths
end